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 przez Puppeteer 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:

  • Wyłącz tryb bez interfejsu: oznacza to, że Puppeteer otworzy widoczne okno przeglądarki Chrome, aby przeprowadzić test. Jeśli wolisz uruchamiać go bez interfejsu, użyj nowego trybu bez interfejsu. Starszy tryb bezprzewodowy nie obsługuje wyświetlania promptów Bluetooth.
  • Dodatkowe argumenty do Chromium: w przypadku środowisk Linuksa prześlij argument „enable Web Bluetooth”.
import puppeteer from 'puppeteer';

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

Podczas otwierania pierwszej strony zalecamy używanie kontekstu przeglądarki w trybie incognito. Pomaga to zapobiegać wyciekom uprawnień między testami uruchamianymi przez skrypt (chociaż w przypadku niektórych stanów na poziomie systemu operacyjnego Puppeteer nie może zapobiec wyciekom). Przykładowy 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. Ten kolejny krok zakłada, że w aplikacji internetowej masz przycisk, który uruchamia kod JavaScript, m.in. wywołanie funkcji 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 zwracana przez waitForDevicePrompt() jest rozwiązywana do obiektu DeviceRequestPrompt, którego użyjesz później do wybrania 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.

Odczytywanie 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 Komunikowanie się z urządzeniami Bluetooth za pomocą JavaScripta.

W tym momencie 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. Ta metoda może być przydatna w ogóle, ale ma bezpośrednie zastosowanie do tworzenia kompleksowych testów 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 użyć biblioteki testów (np. TAP lub mocha), aby sprawdzić, czy odczyto i zgłoszono prawidłowe dane.

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 wydrukować dane dosłowne w polu. Na przykład:

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

W Puppeteer funkcja Page.$eval() umożliwia wyodrębnianie tych danych z DOM strony i przekazywanie ich do skryptu testowego. Funkcja $eval() używa tej samej logiki co funkcja 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.