Chrome รองรับเว็บบลูทูธมาตั้งแต่เวอร์ชัน 56 และช่วยให้นักพัฒนาแอปเขียนเว็บแอปที่สื่อสารกับอุปกรณ์บลูทูธของผู้ใช้โดยตรงได้ ความสามารถของเครื่องมือแก้ไขเว็บของ Espruino ในการอัปโหลดโค้ดไปยังอุปกรณ์บลูทูธที่เข้ากันได้คือตัวอย่างหนึ่ง ตอนนี้คุณสามารถทดสอบแอปพลิเคชันเหล่านี้ได้ด้วย Puppeteer
บล็อกโพสต์นี้แนะนำวิธีใช้ Puppeteer เพื่อใช้งานและทดสอบเว็บแอปที่ใช้บลูทูธได้ ส่วนสำคัญของฟีเจอร์นี้คือความสามารถของ Puppeteer ในการใช้งานตัวเลือกอุปกรณ์บลูทูธของ Chrome
หากคุณไม่คุ้นเคยกับการใช้เว็บบลูทูธใน Chrome วิดีโอต่อไปนี้จะแสดงข้อความแจ้งเกี่ยวกับบลูทูธในโปรแกรมแก้ไขเว็บของ Espruino
หากต้องการทําตามบล็อกโพสต์นี้ คุณจะต้องมีเว็บแอปที่เปิดใช้บลูทูธ อุปกรณ์บลูทูธที่สื่อสารได้ และใช้ Puppeteer v21.4.0 ขึ้นไป
เปิดเบราว์เซอร์
เช่นเดียวกับสคริปต์ Puppeteer ส่วนใหญ่ ให้เริ่มต้นด้วยการเปิดเบราว์เซอร์ด้วย Puppeteer.launch()
คุณต้องมีอาร์กิวเมนต์เพิ่มเติมจึงจะเข้าถึงฟีเจอร์บลูทูธได้
- ปิดใช้โหมด Headless: ซึ่งหมายความว่า Puppeteer จะเปิดหน้าต่างเบราว์เซอร์ Chrome ที่มองเห็นได้เพื่อทำการทดสอบ ใช้โหมดไม่มีส่วนหัวแบบใหม่หากต้องการเรียกใช้โดยไม่มี UI โหมดแบบไร้หัวรุ่นเดิมไม่รองรับการแสดงข้อความแจ้งบลูทูธ
- ส่งอาร์กิวเมนต์เพิ่มเติมไปยัง Chromium: ส่งอาร์กิวเมนต์"เปิดใช้ Web Bluetooth" สำหรับสภาพแวดล้อม 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 ทั้ง 2 รายการนี้แสดงผล Promise Promise.all()
จึงเป็นวิธีที่สะดวกในการเรียกใช้เมธอดเหล่านี้ตามลําดับที่ถูกต้อง
const [devicePrompt] = await Promise.all([
page.waitForDevicePrompt(),
page.locator("#start-test-button").click(),
]);
Promise ที่ 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();
Page.$eval()
จาก Puppeteer มีวิธีดึงข้อมูลนี้ออกจาก DOM ของหน้าเว็บและใส่ลงในสคริปต์ทดสอบ $eval()
ใช้ตรรกะเดียวกับ document.querySelector()
เพื่อค้นหาองค์ประกอบ แล้วเรียกใช้ฟังก์ชัน Callback ที่มีให้โดยมีองค์ประกอบนั้นเป็นอาร์กิวเมนต์ เมื่อคุณมีข้อมูลนี้เป็นตัวแปรแล้ว ให้ใช้ไลบรารีการยืนยันเพื่อทดสอบว่าข้อมูลเป็นอย่างที่คาดไว้หรือไม่
const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);
แหล่งข้อมูลเพิ่มเติม
หากต้องการดูตัวอย่างที่ซับซ้อนมากขึ้นของการเขียนการทดสอบสำหรับเว็บแอปที่ใช้ Puppeteer ซึ่งใช้บลูทูธได้ โปรดดูที่เก็บนี้ https://github.com/WebBluetoothCG/manual-tests/ กลุ่มชุมชน Web Bluetooth เป็นผู้ดูแลชุดการทดสอบนี้ ซึ่งทั้งหมดสามารถเรียกใช้จากเบราว์เซอร์หรือในเครื่องได้ การทดสอบ"ลักษณะที่อ่านอย่างเดียว" คล้ายกับตัวอย่างที่ใช้ในบล็อกโพสต์นี้มากที่สุด
บริการรับรองคำให้การ
ขอขอบคุณ Vincent Scheib ที่เริ่มต้นโปรเจ็กต์นี้และแสดงความคิดเห็นที่มีคุณค่าในโพสต์นี้