בדיקת Bluetooth באינטרנט באמצעות Puppeteer

François Beaufort
François Beaufort

יש תמיכה ב-Bluetooth באינטרנט החל מגרסה 56 של Chrome, ומפתחים יכולים לכתוב אפליקציות אינטרנט שמשוחחות ישירות עם המשתמשים מכשירי Bluetooth. היכולת של עורך האינטרנט של Espruino להעלות קוד למכשירי Bluetooth תואמים היא אחת הדוגמאות האלה. עכשיו אפשר לבדוק את האפליקציות האלה באמצעות Puppeteer.

הפוסט בבלוג הזה מסביר איך להשתמש ב-Puppeteer כדי לתפעל ולבדוק אפליקציית אינטרנט שמופעלת ב-Bluetooth. החלק המרכזי בעניין הזה הוא היכולת של Puppeteer להפעיל את בורר מכשירי ה-Bluetooth של Chrome.

אם אתם לא יודעים איך להשתמש ב-Bluetooth באינטרנט ב-Chrome, בסרטון הבא מוצגת הנחיית ה-Bluetooth בעורך האינטרנט של Espruino:

המשתמש בוחר מכשיר Bluetooth מסוג Puck.js בעורך האינטרנט של Espruino.

כדי לעקוב אחר פוסט זה בבלוג, אתה זקוק לאפליקציית אינטרנט עם Bluetooth, למכשיר Bluetooth שאיתו תהיה אפשרות לתקשר ולהשתמש ב-Puppeteer v21.4.0 ואילך.

הפעלת הדפדפן

כמו ברוב הסקריפטים של Puppeteer, צריך להתחיל בהפעלת הדפדפן באמצעות Puppeteer.launch(). כדי לגשת לתכונות Bluetooth, עליכם לספק כמה ארגומנטים נוספים:

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().

פתיחת ההודעה במכשיר ה-Bluetooth

אחרי שהשתמשתם ב-Puppeteer כדי לפתוח את הדף של אפליקציית האינטרנט עם Puppeteer, תוכלו להתחבר למכשיר ה-Bluetooth כדי לקרוא נתונים. השלב הבא מבוסס על ההנחה שיש באפליקציית האינטרנט לחצן שמריץ JavaScript, כולל קריאה ל-navigator.bluetooth.requestDevice().

לוחצים על Page.locator().click() כדי ללחוץ על הלחצן, ועל Page.waitForDevicePrompt() כדי לזהות מתי מופיע בורר מכשיר ה-Bluetooth. חובה להתקשר למספר waitForDevicePrompt() לפני לחיצה על הלחצן, אחרת ההצעה לפעולה כבר תיפתח ולא ניתן יהיה לזהות אותה.

שתי השיטות האלה של Puppeteer מחזירות הבטחות, ולכן Promise.all() היא דרך נוחה לקרוא להן בסדר הנכון יחד:

const [devicePrompt] = await Promise.all([
  page.waitForDevicePrompt(),
  page.locator("#start-test-button").click(),
]);

ההבטחה שמוחזרת על ידי waitForDevicePrompt() מובילה לאובייקט DeviceRequestPrompt שבו משתמשים כדי לבחור את מכשיר ה-Bluetooth שרוצים להתחבר אליו.

בחירת מכשיר

להשתמש ב-DeviceRequestPrompt.waitForDevice() וב-DeviceRequestPrompt.select() כדי למצוא את מכשיר ה-Bluetooth הנכון ולהתחבר אליו.

DeviceRequestPrompt.waitForDevice() מפעיל את הקריאה החוזרת (callback) שסופקה בכל פעם ש-Chrome מוצא מכשיר Bluetooth עם מידע בסיסי על המכשיר. בפעם הראשונה שהקריאה החוזרת מחזירה True, הערך של waitForDevice() הופך ל-DeviceRequestPromptDevice שנמצאה בו התאמה. צריך להעביר את המכשיר הזה אל DeviceRequestPrompt.select() כדי לבחור את מכשיר ה-Bluetooth ולהתחבר אליו.

const bluetoothDevice = await devicePrompt.waitForDevice(
  (d) => d.name == wantedDeviceName,
);
await devicePrompt.select(bluetoothDevice);

אחרי שהבעיה DeviceRequestPrompt.select() תיפתר, Chrome יחובר למכשיר ודף האינטרנט יוכל לגשת אליו.

הקראה מהמכשיר

בשלב הזה, אפליקציית האינטרנט שלך תחובר למכשיר ה-Bluetooth שנבחר ותוכל לקרוא ממנו מידע. הדוגמה הזו יכולה להיראות כך:

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, ראו תקשורת עם מכשירי Bluetooth באמצעות JavaScript.

בשלב הזה, למדתם איך להשתמש ב-Puppeteer כדי להפוך את השימוש ב-Bluetooth לאפליקציית אינטרנט שמופעלת ב-Bluetooth באופן אוטומטי, על ידי החלפת השלב האנושי של בחירת מכשיר מתפריט הבורר של מכשירי Bluetooth. לרוב זה יכול להיות שימושי, אבל רלוונטי ישירות לכתיבת בדיקה מקצה לקצה לאפליקציית אינטרנט כזו.

יצירת בדיקה

החלק החסר בשימוש בקוד עד לכתיבה של בדיקה מלאה הוא שליפת מידע מאפליקציית האינטרנט לסקריפט של Puppeteer. אחרי שמגדירים את האפשרות הזאת, אפשר להשתמש בספריית בדיקות (כמו TAP או mocha) כדי לוודא שהנתונים הנכונים נקראו ודווחו.

אחת הדרכים הקלות ביותר לעשות זאת היא לכתוב נתונים ל-DOM. ב-JavaScript יש הרבה דרכים לעשות זאת בלי ספריות נוספות. בחזרה לאפליקציית האינטרנט ההיפותטית, היא עשויה לשנות את הצבע של אינדיקטור הסטטוס כאשר היא קוראת נתונים ממכשיר ה-Bluetooth או מדפיסה את הנתונים המילוליים בשדה. לדוגמה:

const dataDisplayElement = document.querySelector('#data-display');
dataDisplayElement.innerText = dataView.getUint8();

מ-Puppeteer, Page.$eval() מאפשר לשלוף את הנתונים האלה מה-DOM של הדף לתוך סקריפט בדיקה. כדי למצוא רכיב, הפונקציה $eval() משתמשת באותה לוגיקה כמו document.querySelector(), ואז מפעילה את פונקציית הקריאה החוזרת עם הרכיב הזה כארגומנט. אחרי שמשתמשים במשתנה הזה, משתמשים בספריית טענות הנכוֹנוּת (assertion) כדי לבדוק אם הנתונים הם מה שאנחנו מצפים לקבל.

const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);

מקורות מידע נוספים

דוגמאות מורכבות יותר לבדיקות כתיבה של אפליקציות אינטרנט שתומכות ב-Bluetooth באמצעות Puppeteer זמינות במאגר הזה: https://github.com/WebBluetoothCG/manual-tests/. קבוצה קהילתית של Bluetooth באינטרנט כוללת את החבילה הזו של בדיקות, שכולן ניתנות להרצה מדפדפן או באופן מקומי. המאפיין 'קריאה בלבד' הבדיקה הכי דומה לדוגמה שבה השתמשתם בפוסט הזה בבלוג.

אימות חתימות

תודה לווינסנט שייב (Vינסנט שייב) שהתחיל את הפרויקט ונתן משוב חשוב על הפוסט הזה.