ระบบรองรับเว็บบลูทูธมาตั้งแต่ Chrome 56 แล้ว และช่วยให้นักพัฒนาซอฟต์แวร์เขียนเว็บแอปที่สื่อสารกับอุปกรณ์บลูทูธของผู้ใช้ได้โดยตรง ตัวอย่างหนึ่งเช่นความสามารถของโปรแกรมแก้ไขเว็บ Espruino ในการอัปโหลดโค้ดไปยังอุปกรณ์บลูทูธที่ใช้งานร่วมกันได้ ปัจจุบันคุณทดสอบแอปพลิเคชันเหล่านี้ได้ด้วย Puppeteer
บล็อกโพสต์นี้อธิบายถึงวิธีการใช้ Puppeteer เพื่อใช้งานและทดสอบเว็บแอปที่ใช้งานบลูทูธ ส่วนสำคัญของเรื่องนี้คือความสามารถของ Puppeteer ในการใช้งานตัวเลือกอุปกรณ์บลูทูธของ Chrome
หากคุณไม่คุ้นเคยกับการใช้เว็บบลูทูธใน Chrome วิดีโอต่อไปนี้จะแสดงข้อความแจ้งเกี่ยวกับบลูทูธในเครื่องมือแก้ไขเว็บ Espruino
ในการติดตามบล็อกโพสต์นี้ คุณจะต้องมีเว็บแอปที่เปิดใช้บลูทูธ อุปกรณ์บลูทูธที่สื่อสารกันได้ และใช้ Puppeteer v21.4.0 ขึ้นไป
เปิดเบราว์เซอร์
เช่นเดียวกับสคริปต์ Puppeteer ส่วนใหญ่ ให้เริ่มต้นด้วยการเปิดเบราว์เซอร์ด้วย Puppeteer.launch()
คุณจะต้องใส่อาร์กิวเมนต์เพิ่มเติมอีก 2-3 อาร์กิวเมนต์เพื่อเข้าถึงฟีเจอร์บลูทูธ
- ปิดใช้โหมดไม่มีส่วนหัว: ซึ่งหมายความว่า Puppeteer จะเปิดหน้าต่างเบราว์เซอร์ Chrome ที่มองเห็นได้เพื่อทำการทดสอบ ใช้โหมดไม่มีส่วนหัวใหม่หากคุณต้องการเรียกใช้โดยไม่มี UI โหมดไม่มีส่วนหัวเดิมไม่รองรับการแสดงข้อความแจ้งผ่านบลูทูธ
- อาร์กิวเมนต์เพิ่มเติมไปยัง Chromium: ส่งอาร์กิวเมนต์"เปิดใช้เว็บบลูทูธ" สําหรับสภาพแวดล้อม Linux
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: false,
args: ["--enable-features=WebBluetooth"],
});
เมื่อเปิดหน้าแรก โดยทั่วไปเราแนะนำให้ใช้บริบทของเบราว์เซอร์ที่ไม่ระบุตัวตน วิธีนี้จะช่วยป้องกันไม่ให้สิทธิ์รั่วไหลระหว่างการทดสอบที่เรียกใช้สคริปต์ (แม้ว่าจะมีสถานะที่แชร์ในระดับระบบปฏิบัติการบางอย่างที่ Puppeteer ป้องกันไม่ได้) โค้ดต่อไปนี้แสดงให้เห็นถึงสิ่งต่อไปนี้
const browserContext = await browser.createIncognitoBrowserContext();
const page = await browserContext.newPage();
จากนั้นคุณจะไปที่ URL ของเว็บแอปที่กำลังทดสอบด้วย Page.goto()
ได้
เปิดข้อความแจ้งของอุปกรณ์บลูทูธ
เมื่อคุณใช้ Puppeteer เปิดหน้าของเว็บแอปด้วย Puppeteer แล้ว คุณสามารถเชื่อมต่อกับอุปกรณ์บลูทูธเพื่ออ่านข้อมูลได้ ขั้นตอนถัดไปนี้จะสมมติว่าคุณมีปุ่มในเว็บแอปที่เรียกใช้ JavaScript รวมถึงการเรียก navigator.bluetooth.requestDevice()
ใช้ Page.locator().click()
เพื่อกดปุ่มนั้นและ Page.waitForDevicePrompt()
เพื่อจดจำเมื่อตัวเลือกอุปกรณ์บลูทูธปรากฏขึ้น คุณต้องโทรหา waitForDevicePrompt()
ก่อนคลิกปุ่ม มิฉะนั้นข้อความแจ้งจะเปิดขึ้นแล้วและจะตรวจไม่พบได้
เนื่องจากวิธี Puppeteer ทั้งสองนี้ให้คำมั่นสัญญาไว้ ดังนั้น Promise.all()
จึงเป็นวิธีที่สะดวกในการเรียกทั้งสองแบบตามลำดับที่ถูกต้องด้วยกัน
const [devicePrompt] = await Promise.all([
page.waitForDevicePrompt(),
page.locator("#start-test-button").click(),
]);
คำมั่นสัญญาที่ส่งกลับมาโดย waitForDevicePrompt()
จะเปลี่ยนเป็นออบเจ็กต์ DeviceRequestPrompt
ซึ่งคุณจะต้องใช้ถัดจากการเลือกอุปกรณ์บลูทูธที่ต้องการเชื่อมต่อ
เลือกอุปกรณ์
ใช้ DeviceRequestPrompt.waitForDevice()
และ DeviceRequestPrompt.select()
เพื่อค้นหาและเชื่อมต่อกับอุปกรณ์บลูทูธที่ถูกต้อง
DeviceRequestPrompt.waitForDevice()
จะโทรหาโค้ดเรียกกลับที่ให้ไว้ทุกครั้งที่ Chrome พบอุปกรณ์บลูทูธพร้อมด้วยข้อมูลพื้นฐานเกี่ยวกับอุปกรณ์ เมื่อโค้ดเรียกกลับแสดงค่า "จริง" เป็นครั้งแรก waitForDevice()
จะเปลี่ยนเป็น DeviceRequestPromptDevice
ที่ตรงกัน ส่งอุปกรณ์นั้นไปที่ DeviceRequestPrompt.select()
เพื่อเลือกและเชื่อมต่อกับอุปกรณ์บลูทูธดังกล่าว
const bluetoothDevice = await devicePrompt.waitForDevice(
(d) => d.name == wantedDeviceName,
);
await devicePrompt.select(bluetoothDevice);
เมื่อแก้ไข DeviceRequestPrompt.select()
แล้ว Chrome จะเชื่อมต่อกับอุปกรณ์และหน้าเว็บจะเข้าถึงได้
อ่านจากอุปกรณ์
ในจุดนี้ เว็บแอปของคุณจะเชื่อมต่อกับอุปกรณ์บลูทูธที่เลือกไว้และสามารถอ่านข้อมูลจากอุปกรณ์นั้นได้ ซึ่งจะมีลักษณะดังนี้
const serviceId = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: [serviceId] }],
});
const gattServer = await device.gatt.connect();
const service = await gattServer.getPrimaryService(serviceId);
const characteristic = await service.getCharacteristic(
"0b30afd0-193e-11eb-adc1-0242ac120002",
);
const dataView = await characteristic.readValue();
สำหรับคำแนะนำโดยละเอียดเพิ่มเติมเกี่ยวกับลำดับการเรียก API นี้ โปรดดูการสื่อสารกับอุปกรณ์บลูทูธผ่าน JavaScript
ในขั้นนี้ คุณทราบวิธีใช้ Puppeteer เพื่อทำให้การใช้งานเว็บแอปที่เปิดใช้บลูทูธเป็นแบบอัตโนมัติโดยการเปลี่ยนขั้นตอนโดยมนุษย์ในการเลือกอุปกรณ์จากเมนูตัวเลือกอุปกรณ์บลูทูธ แม้ว่าวิธีนี้อาจมีประโยชน์โดยทั่วไป แต่ก็ใช้ได้โดยตรงกับการเขียนการทดสอบตั้งแต่ต้นจนจบสำหรับเว็บแอปนั้นๆ
สร้างการทดสอบ
สิ่งที่ขาดไปตั้งแต่การกรอกโค้ดไปจนถึงการเขียนการทดสอบเต็มรูปแบบคือการนำข้อมูลจากเว็บแอปและลงในสคริปต์ Puppeteer ของคุณ เมื่อมีแล้ว ก็ค่อนข้างตรงไปตรงมาในการใช้ไลบรารีการทดสอบ (เช่น TAP หรือ mocha) เพื่อยืนยันว่ามีการอ่านและรายงานข้อมูลที่ถูกต้อง
วิธีที่ง่ายที่สุดวิธีหนึ่งคือการเขียนข้อมูลไปยัง DOM JavaScript มีหลายวิธีในการดำเนินการนี้โดยไม่ต้องใช้ไลบรารีเพิ่มเติม ย้อนกลับไปที่เว็บแอปสมมติ ซึ่งอาจเปลี่ยนสีของสัญญาณบอกสถานะเมื่ออ่านข้อมูลจากอุปกรณ์บลูทูธหรือพิมพ์ข้อมูลตามตัวอักษรลงในช่อง เช่น
const dataDisplayElement = document.querySelector('#data-display');
dataDisplayElement.innerText = dataView.getUint8();
จาก Puppeteer Page.$eval()
จะช่วยคุณดึงข้อมูลนี้ออกจาก DOM ของหน้าและลงในสคริปต์ทดสอบ $eval()
ใช้ตรรกะเดียวกับ document.querySelector()
เพื่อค้นหาองค์ประกอบ จากนั้นเรียกใช้ฟังก์ชันเรียกกลับที่ให้ไว้กับองค์ประกอบนั้นเป็นอาร์กิวเมนต์ เมื่อคุณมีตัวแปรนี้เป็นตัวแปรแล้ว ให้ใช้ไลบรารีการยืนยันเพื่อทดสอบว่าข้อมูลเป็นไปตามที่เราคาดหวังหรือไม่
const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);
แหล่งข้อมูลเพิ่มเติม
หากต้องการดูตัวอย่างที่ซับซ้อนยิ่งขึ้นของการทดสอบการเขียนสำหรับเว็บแอปที่เปิดใช้บลูทูธด้วย Puppeteer โปรดดูที่เก็บนี้ https://github.com/WebBluetoothCG/manual-tests/ กลุ่มชุมชน Web Bluetooth จะเก็บชุดการทดสอบนี้ไว้ ซึ่งทั้งหมดนี้เรียกใช้ได้จากเบราว์เซอร์หรือในเครื่อง การทดสอบ"ลักษณะเฉพาะแบบอ่านอย่างเดียว" คล้ายกับตัวอย่างที่ใช้ในบล็อกโพสต์นี้มากที่สุด
บริการรับรองคำให้การ
ขอขอบคุณ Vincent Scheib ที่เริ่มต้นโครงการนี้และให้ความคิดเห็นที่มีค่าเกี่ยวกับโพสต์นี้