Przetestuj Bluetooth Web Bluetooth za pomocą Puppeteer

François Beaufort
François Beaufort

Interfejs Web Bluetooth jest obsługiwany od wersji 56 przeglądarki Chrome i pozwala deweloperom pisać aplikacje internetowe, które komunikują się bezpośrednio z urządzeniami Bluetooth użytkowników. Przykładem jest możliwość przesyłania kodu na zgodne urządzenia Bluetooth w edytorze internetowym Espruino. Testowanie tych aplikacji jest teraz możliwe za pomocą Puppeteer.

W tym poście na blogu wyjaśniamy, jak za pomocą Puppeteer obsługiwać i testować aplikację internetową z Bluetoothem. Najważniejsza jest tu możliwość korzystania z selektora urządzeń Bluetooth w Chrome.

Jeśli nie wiesz, jak korzystać z Bluetooth w Chrome, obejrzyj ten film, który pokazuje prośbę o Bluetooth w edytorze internetowym Espruino:

Użytkownik wybiera urządzenie Bluetooth Puck.js w edytorze internetowym Espruino.

Aby skorzystać z tego wpisu na blogu, musisz mieć aplikację internetową obsługującą Bluetooth, urządzenie Bluetooth, z którym może się komunikować, oraz Puppeteer w wersji v21.4.0 lub nowszej.

Uruchom przeglądarkę.

Podobnie jak w przypadku większości skryptów Puppeteer, zacznij od uruchomienia przeglądarki za pomocą Puppeteer.launch(). Aby uzyskać dostęp do funkcji Bluetooth, musisz podać kilka dodatkowych argumentów:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: false,
  args: ["--enable-features=WebBluetooth"],
});

Do otwierania pierwszej strony zwykle zalecamy użycie kontekstu przeglądarki w trybie incognito. Pomaga to zapobiec wyciekom uprawnień między testami uruchamianymi za pomocą skryptu (chociaż istnieje pewien stan wspólny na poziomie systemu operacyjnego, którego nie może zapobiec Puppeteer). Potwierdza to poniższy kod:

const browserContext = await browser.createIncognitoBrowserContext();
const page = await browserContext.newPage();

Następnie możesz przejść do adresu URL aplikacji internetowej, którą testujesz, za pomocą Page.goto().

Otwórz prośbę o urządzenie Bluetooth

Po użyciu Puppeteer do otwarcia strony aplikacji internetowej za pomocą Puppeteer możesz połączyć się z urządzeniem Bluetooth, aby odczytać dane. W następnym kroku zakładamy, że masz w swojej aplikacji internetowej przycisk, który uruchamia JavaScript, w tym wywołanie navigator.bluetooth.requestDevice().

Użyj Page.locator().click(), aby nacisnąć przycisk, i Page.waitForDevicePrompt(), aby rozpoznać, kiedy pojawi się selektor urządzeń Bluetooth. Przed kliknięciem przycisku musisz zadzwonić pod numer waitForDevicePrompt(), ponieważ w przeciwnym razie prompt zostanie otwarty wcześniej i nie będzie można go wykryć.

Obie te metody Puppeteer zwracają obietnice, więc Promise.all() jest wygodnym sposobem na wywołanie ich w prawidłowej kolejności:

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

Obietnica zwrócona przez funkcję waitForDevicePrompt() przedstawia obiekt DeviceRequestPrompt, którego użyjesz obok wyboru urządzenia Bluetooth, z którym chcesz się połączyć.

Wybieranie urządzenia

Użyj przycisków DeviceRequestPrompt.waitForDevice()DeviceRequestPrompt.select(), aby znaleźć odpowiednie urządzenie Bluetooth i się z nim połączyć.

DeviceRequestPrompt.waitForDevice() wywołuje podany adres funkcji z powrotem za każdym razem, gdy Chrome znajdzie urządzenie Bluetooth z niektórymi podstawowymi informacjami o tym urządzeniu. Gdy funkcja wywołania zwraca po raz pierwszy wartość true, waitForDevice() jest rozwiązywane do dopasowanego DeviceRequestPromptDevice. Przesuń to urządzenie do DeviceRequestPrompt.select(), aby je wybrać i połączyć z urządzeniem Bluetooth.

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

Gdy DeviceRequestPrompt.select() zostanie rozwiązane, Chrome połączy się z urządzeniem, a strona internetowa będzie mogła uzyskać do niego dostęp.

Czytaj z urządzenia

W tym momencie Twoja aplikacja internetowa będzie połączona z wybranym urządzeniem Bluetooth i będzie mogła odczytywać z niego informacje. Może to wyglądać tak:

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

Pełny opis tej sekwencji wywołań interfejsu API znajdziesz w artykule Komunikacja z urządzeniami Bluetooth za pomocą JavaScripta.

Wiesz już, jak użyć Puppeteer do zautomatyzowania korzystania z aplikacji internetowej obsługującej Bluetooth, zastępując krok polegający na wybraniu urządzenia w menu wyboru urządzenia Bluetooth. Jest to przydatne w ogóle, ale ma bezpośrednie zastosowanie do tworzenia kompleksowych testów takich aplikacji internetowych.

Tworzenie testu

Dotychczasowy kod nie jest jeszcze gotowy do przeprowadzenia pełnego testu, ponieważ brakuje w nim informacji z aplikacji internetowej, które należy przekazać do skryptu Puppeteer. Gdy to zrobisz, możesz z łatwością sprawdzić, czy poprawnie odczytane i zgłoszone dane zostały odczytane i zgłoszone za pomocą biblioteki testowej (np. TAP lub mokha).

Jednym z najprostszych sposobów jest zapisanie danych w DOM. W JavaScript można to zrobić na wiele sposobów bez dodatkowych bibliotek. Wracając do hipotetycznej aplikacji internetowej, może ona zmieniać kolor wskaźnika stanu, gdy odczytuje dane z urządzenia Bluetooth lub wydrukuje dane dosłowne w polu. Na przykład:

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

W Puppeteer Page.$eval() umożliwia wyodrębnianie tych danych z DOM strony i przekazywanie ich do skryptu testowego. $eval() używa tej samej logiki co document.querySelector(), aby znaleźć element, a potem wywołuje podawaną funkcję wywołania zwrotnego z tym elementem jako argumentem. Gdy już masz to jako zmienną, użyj biblioteki twierdzeń, aby sprawdzić, czy dane są zgodne z oczekiwaniami.

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

Dodatkowe materiały

Bardziej złożone przykłady testów aplikacji internetowych obsługujących Bluetooth za pomocą Puppeteer znajdziesz w tym repozytorium: https://github.com/WebBluetoothCG/manual-tests/. Zestaw testów jest utrzymywany przez grupę społeczności Web Bluetooth i może być uruchamiany w przeglądarce lub lokalnie. Test „Właściwość tylko do odczytu” jest najbardziej podobny do przykładu użytego w tym poście na blogu.

Poświadczenia

Dziękujemy Vincentowi Scheibowi za rozpoczęcie tego projektu i cenne opinie na temat tego posta.