Веб-Bluetooth поддерживается начиная с Chrome 56 и позволяет разработчикам создавать веб-приложения, которые напрямую взаимодействуют с устройствами Bluetooth пользователей. Одним из таких примеров является возможность веб-редактора Espruino загружать код на совместимые устройства Bluetooth. Тестирование этих приложений теперь возможно с помощью Puppeteer .
В этом сообщении блога рассказывается, как использовать Puppeteer для работы и тестирования веб-приложения с поддержкой Bluetooth. Ключевой частью этого является способность Puppeteer управлять устройством выбора Bluetooth-устройства Chrome.
Если вы не знакомы с использованием Web Bluetooth в Chrome, в следующем видео показано приглашение Bluetooth в веб-редакторе Espruino:
Чтобы следить за этим сообщением в блоге, вам понадобится веб-приложение с поддержкой Bluetooth, устройство Bluetooth, с которым оно может взаимодействовать, и использовать Puppeteer v21.4.0 или более позднюю версию.
Запустите браузер
Как и в большинстве сценариев Puppeteer, начните с запуска браузера с помощью Puppeteer.launch()
. Чтобы получить доступ к функциям Bluetooth, вам необходимо предоставить несколько дополнительных аргументов:
- Отключить безгласный режим: это означает, что Puppeteer откроет видимое окно браузера Chrome для запуска теста. Используйте новый безгласный режим, если вы предпочитаете запускать его без пользовательского интерфейса. Устаревший безгласный режим не поддерживает отображение подсказок Bluetooth.
- Дополнительные аргументы для Chromium: передайте аргумент «включить Web Bluetooth» для сред Linux.
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()
вызывает предоставленный обратный вызов каждый раз, когда 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. Хотя в целом это может быть полезно, это напрямую применимо к написанию сквозного теста для такого веб-приложения.
Создать тест
Недостающим звеном от написания кода до написания полноценного теста является получение информации из веб-приложения в ваш скрипт Puppeteer. Если у вас это есть, довольно просто использовать библиотеку тестирования (например, TAP или mocha ), чтобы убедиться, что правильные данные были прочитаны и отправлены в отчет.
Один из самых простых способов сделать это — записать данные в DOM. В JavaScript есть множество способов сделать это без дополнительных библиотек. Возвращаясь к вашему гипотетическому веб-приложению, оно может изменить цвет индикатора состояния, когда считывает данные с устройства Bluetooth или печатает буквальные данные в поле. Например:
const dataDisplayElement = document.querySelector('#data-display');
dataDisplayElement.innerText = dataView.getUint8();
В Puppeteer Page.$eval()
дает вам возможность извлечь эти данные из DOM страницы в тестовый скрипт. $eval()
использует ту же логику, что и document.querySelector()
чтобы найти элемент, а затем запускает предоставленную функцию обратного вызова с этим элементом в качестве аргумента. Получив это как переменную, используйте свою библиотеку утверждений, чтобы проверить, соответствуют ли данные нашим ожиданиям.
const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);
Дополнительные ресурсы
Чтобы увидеть более сложные примеры написания тестов для веб-приложений с поддержкой Bluetooth с помощью Puppeteer, посетите этот репозиторий: https://github.com/WebBluetoothCG/manual-tests/ . Группа сообщества Web Bluetooth поддерживает этот набор тестов, каждый из которых можно запускать из браузера или локально. Тест «Характеристика только для чтения» наиболее похож на пример, использованный в этой записи блога.
Благодарности
Спасибо Винсенту Шейбу за начало этого проекта и ценный отзыв по этому посту.