Przetestuj Bluetooth Web Bluetooth za pomocą Puppeteer

François Beaufort
François Beaufort

Web Bluetooth jest obsługiwany od Chrome 56 i umożliwia deweloperom pisanie aplikacji internetowych, które komunikują się bezpośrednio z urządzeniami Bluetooth użytkowników. Przykładem jest możliwość przesyłania kodu do zgodnych urządzeń Bluetooth przez edytor internetowy Espruino. Testowanie tych aplikacji jest teraz możliwe dzięki aplikacji Puppeteer.

W tym poście na blogu omawiamy, jak za pomocą Puppeteer obsługiwać i testować aplikację internetową zgodną z Bluetoothem. Kluczowym elementem jest umiejętność Puppeteer do obsługi selektora urządzenia Bluetooth w Chrome.

Jeśli nie wiesz, jak korzystać z Web Bluetooth w Chrome, obejrzyj ten film przedstawiający podpowiedź Bluetooth w edytorze internetowym Espruino:

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

Aby obserwować tego posta na blogu, potrzebujesz aplikacji internetowej obsługującej Bluetooth i urządzenia Bluetooth, z którym może się ono komunikować oraz korzystającego z 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 z użyciem 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"],
});

Ogólnie zalecamy, aby przy otwieraniu pierwszej strony korzystać z kontekstu przeglądarki w trybie incognito. Pomaga to zapobiegać wyciekom uprawnień między testami uruchomionymi za pomocą skryptu (chociaż istnieje pewien stan współużytkowania na poziomie systemu operacyjnego, którego nie może zablokować Puppeteer). Oto przykład kodu:

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

Następnie możesz otworzyć adres URL aplikacji internetowej, którą testujesz za pomocą Page.goto().

Otwórz komunikat urządzenia Bluetooth

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

Naciśnij Page.locator().click(), aby nacisnąć ten przycisk, oraz Page.waitForDevicePrompt(), aby rozpoznać, kiedy pojawi się selektor urządzenia Bluetooth. Przed kliknięciem przycisku musisz zadzwonić pod numer waitForDevicePrompt(). W przeciwnym razie komunikat zostanie otwarty i nie będzie w stanie go wykryć.

Ponieważ obie te metody Puppeteer zwracają obietnice, metoda Promise.all() jest wygodnym sposobem wywołania ich we właściwej kolejności:

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

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

Wybieranie urządzenia

Użyj narzędzi DeviceRequestPrompt.waitForDevice() i DeviceRequestPrompt.select(), by znaleźć odpowiednie urządzenie Bluetooth i się z nim połączyć.

DeviceRequestPrompt.waitForDevice() wywołuje podane wywołanie zwrotne za każdym razem, gdy Chrome znajdzie urządzenie Bluetooth, używając podstawowych informacji o urządzeniu. Za pierwszym razem, gdy wywołanie zwrotne zwraca wartość „prawda”, waitForDevice() przekierowuje się na pasującą wartość DeviceRequestPromptDevice. Przekaż to urządzenie do: DeviceRequestPrompt.select(), aby wybrać i połączyć się z nim.

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

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

Odczytywanie z urządzenia

Na tym etapie aplikacja internetowa zostanie 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();

Szczegółowy opis tej sekwencji wywołań interfejsu API znajdziesz w artykule Komunikacja z urządzeniami Bluetooth przez JavaScript.

Wiesz już, jak używać Puppeteer do zautomatyzowania używania aplikacji internetowej z obsługą Bluetootha. Nie musisz już wykonywać czynności, które wykonuje człowiek, wybierając urządzenie z menu wyboru urządzenia Bluetooth. Takie rozwiązanie może być przydatne, ale sprawdza się też w przypadku pisania kompleksowego testu takiej aplikacji internetowej.

Tworzenie testu

Aby zaliczyć cały kod do napisania pełnego testu, musisz uzyskać informacje z aplikacji internetowej i dołączyć do skryptu Puppeteer. Po otrzymaniu tych informacji możesz łatwo sprawdzić, czy prawidłowo odczytane dane zostały odczytane i zgłoszone, używając biblioteki testowej (np. TAP lub mokki).

Jednym z najprostszych sposobów jest zapisanie danych w modelu DOM. Bez dodatkowych bibliotek JavaScript można to zrobić na wiele sposobów. Powrót do hipotetycznej aplikacji internetowej może zmienić kolor wskaźnika stanu podczas odczytywania danych z urządzenia Bluetooth lub wydrukowania dosłownych danych w polu. Na przykład:

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

Z platformy Puppeteer narzędzie Page.$eval() umożliwia pobranie tych danych z DOM strony do skryptu testowego. $eval() wyszukuje element, korzystając z tej samej logiki co document.querySelector(), a potem uruchamia podaną funkcję wywołania zwrotnego z tym elementem jako argumentem. Gdy ustawisz tę wartość jako zmienną, użyj biblioteki asercji, 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 pisania testów pisania dla aplikacji internetowych obsługujących Bluetooth za pomocą Puppeteer znajdziesz w tym repozytorium: https://github.com/WebBluetoothCG/manual-tests/. Zespół Web Bluetooth Community Group prowadzi taki zestaw testów, z których wszystkie można uruchamiać w przeglądarce lub lokalnie. Test „Cechy 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 projektu i przekazanie cennej opinii na temat tego posta.