Przetestuj Bluetooth Web Bluetooth za pomocą Puppeteer

François Beaufort
François Beaufort

Internetowy Bluetooth jest obsługiwany od Chrome w wersji 56 i umożliwia programistom pisanie aplikacji internetowych, które komunikują się bezpośrednio z użytkownikami Urządzenia Bluetooth. Jednym z przykładów jest możliwość przesyłania kodu na zgodne urządzenia Bluetooth przez edytor stron internetowych Espruino. Testowanie tych aplikacji jest teraz możliwe dzięki Puppeteer.

W tym poście omawiamy, jak za pomocą aplikacji Puppeteer obsługiwać i testować aplikację internetową z obsługą Bluetootha. Kluczową częścią tego procesu jest możliwość obsługi funkcji wyboru urządzeń Bluetooth w Chrome.

Jeśli nie wiesz, jak używać Web Bluetooth w Chrome, obejrzyj ten film, aby zobaczyć pytanie o Bluetooth w edytorze internetowym Espruino:

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

Aby śledzić tego posta, musisz mieć aplikację internetową z włączoną obsługą Bluetootha i urządzeniem Bluetooth, z którym może się ona komunikować, oraz używać aplikacji Puppeteer w wersji 21.4.0 lub nowszej.v21.4.0

Uruchom przeglądarkę

Tak jak w przypadku większości skryptów Puppeteer, zacznij od uruchomienia przeglądarki za pomocą tagu 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 komunikat urządzenia Bluetooth

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

Użyj przycisku Page.locator().click(), aby go nacisnąć, a Page.waitForDevicePrompt(), aby wykryć, kiedy pojawi się wybór urządzenia Bluetooth. Przed kliknięciem przycisku musisz wywołać funkcję waitForDevicePrompt(). W przeciwnym razie prompt zostanie już otwarty i nie będzie mógł go wykryć.

Obie te metody Puppeteer zwracają obietnice, dlatego Promise.all() to wygodny sposób na wywoływanie ich razem we właściwej 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 DeviceRequestPrompt.waitForDevice() i DeviceRequestPrompt.select(), aby znaleźć odpowiednie urządzenie Bluetooth i się z nim połączyć.

DeviceRequestPrompt.waitForDevice() wywołuje dostarczone wywołanie zwrotne za każdym razem, gdy Chrome znajdzie urządzenie Bluetooth z podstawowymi informacjami o urządzeniu. Za pierwszym razem, gdy wywołanie zwrotne zwróci wartość „true” (prawda), waitForDevice() przyjmuje wartość pasującą do DeviceRequestPromptDevice. Przekaż to urządzenie urządzeniu DeviceRequestPrompt.select(), aby je wybrać i połączyć się z nim.

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

Po rozwiązaniu problemu DeviceRequestPrompt.select() przeglądarka Chrome łączy się z urządzeniem i strona internetowa ma do niego dostęp.

Czytaj z urządzenia

W tym momencie aplikacja internetowa połączy się 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();

Bardziej szczegółowe instrukcje dotyczące tej sekwencji wywołań interfejsu API znajdziesz w artykule Komunikacja z urządzeniami Bluetooth przez JavaScript.

Teraz wiesz już, jak używać Puppeteer do zautomatyzowania obsługi aplikacji internetowej z obsługą Bluetooth przez zastąpienie czynności wykonywanej przez człowieka w menu wyboru urządzenia Bluetooth. Może to być przydatne, ale ma też zastosowanie w przypadku pisania kompleksowego testu takiej aplikacji internetowej.

Tworzenie testu

W dotychczasowym i pełnym teście brakuje informacji z aplikacji internetowej i przekazania informacji 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 modelu DOM. JavaScript ma mnóstwo sposobów na to, by robić to bez dodatkowych bibliotek. Wracając do Twojej hipotetycznej aplikacji internetowej, możesz zmienić kolor wskaźnika stanu po odczytaniu danych z urządzenia Bluetooth lub wydrukowaniu danych literału w polu. Na przykład:

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

Z platformy Puppeteer Page.$eval() umożliwia pobranie tych danych z DOM strony do skryptu testowego. Funkcja $eval() wyszukuje element w ten sam sposób co w przypadku document.querySelector(), a następnie uruchamia podaną funkcję wywołania zwrotnego z tym elementem jako argumentem. Gdy masz już tę 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 aplikacji internetowych z obsługą Bluetootha w aplikacji Puppeteer znajdziesz w tym repozytorium: https://github.com/WebBluetoothCG/manual-tests/. Ten pakiet testów przeprowadza Web Bluetooth Community Group (grupa społeczna Web Bluetooth), które można uruchomić w przeglądarce lub lokalnie. „Cechy tylko do odczytu” test jest bardzo podobny do przykładu użytego w tym poście na blogu.

Poświadczenia

Dziękujemy Vincentowi Scheibowi za rozpoczęcie projektu i przekazanie cennych opinii na temat tego posta.