Le Bluetooth Web est compatible avec Chrome 56 et permet aux développeurs d'écrire des applications Web qui communiquent directement avec les appareils Bluetooth des utilisateurs. L'éditeur Web Espruino permet d'importer du code sur des appareils Bluetooth compatibles. Il est désormais possible de tester ces applications avec Puppeteer.
Cet article de blog explique comment utiliser Puppeteer pour exploiter et tester une application Web compatible avec le Bluetooth. L'élément clé de cette approche est la capacité de Puppeteer à utiliser le sélecteur d'appareils Bluetooth de Chrome.
Si vous ne savez pas comment utiliser le Web Bluetooth dans Chrome, la vidéo suivante montre l'invite Bluetooth dans l'éditeur Web Espruino:
Pour suivre cet article de blog, vous aurez besoin d'une application Web compatible Bluetooth, d'un appareil Bluetooth avec lequel elle peut communiquer et d'une version de Puppeteer v21.4.0 ou ultérieure.
Lancer le navigateur
Comme pour la plupart des scripts Puppeteer, commencez par lancer le navigateur avec Puppeteer.launch()
. Pour accéder aux fonctionnalités Bluetooth, vous devez fournir quelques arguments supplémentaires:
- Désactiver le mode sans interface utilisateur: cela signifie que Puppeteer ouvrira une fenêtre de navigateur Chrome visible pour exécuter le test. Utilisez le nouveau mode headless si vous préférez l'exécuter sans interface utilisateur. L'ancien mode sans tête ne permet pas d'afficher d'invites Bluetooth.
- Arguments supplémentaires à Chromium: transmettez un argument"enable Web Bluetooth" pour les environnements Linux.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: false,
args: ["--enable-features=WebBluetooth"],
});
Lorsque vous ouvrez la première page, il est généralement recommandé d'utiliser un contexte de navigateur en navigation privée. Cela permet d'éviter les fuites d'autorisations entre les tests exécutés avec votre script (bien qu'il existe un état partagé au niveau de l'OS que Puppeteer ne peut pas empêcher). Le code suivant illustre cela:
const browserContext = await browser.createIncognitoBrowserContext();
const page = await browserContext.newPage();
Vous pouvez ensuite accéder à l'URL de l'application Web que vous testez avec Page.goto()
.
Ouvrir l'invite de l'appareil Bluetooth
Une fois que vous avez utilisé Puppeteer pour ouvrir la page de l'application Web, vous pouvez vous connecter à l'appareil Bluetooth pour lire les données. Cette étape suppose que votre application Web comporte un bouton qui exécute du code JavaScript, y compris un appel à navigator.bluetooth.requestDevice()
.
Utilisez Page.locator().click()
pour appuyer sur ce bouton et Page.waitForDevicePrompt()
pour détecter quand le sélecteur d'appareil Bluetooth s'affiche. Vous devez appeler waitForDevicePrompt()
avant de cliquer sur le bouton. Sinon, l'invite s'ouvrira déjà et elle ne pourra pas la détecter.
Étant donné que ces deux méthodes Puppeteer renvoient des promesses, Promise.all()
est un moyen pratique de les appeler ensemble dans le bon ordre:
const [devicePrompt] = await Promise.all([
page.waitForDevicePrompt(),
page.locator("#start-test-button").click(),
]);
La promesse renvoyée par waitForDevicePrompt()
se résout en un objet DeviceRequestPrompt
que vous utiliserez ensuite pour sélectionner l'appareil Bluetooth auquel vous souhaitez vous connecter.
Sélectionner un appareil
Utilisez DeviceRequestPrompt.waitForDevice()
et DeviceRequestPrompt.select()
pour trouver et vous connecter au bon appareil Bluetooth.
DeviceRequestPrompt.waitForDevice()
appelle le rappel fourni chaque fois que Chrome détecte un appareil Bluetooth avec des informations de base sur l'appareil. La première fois que le rappel renvoie la valeur "true", waitForDevice()
est résolu en DeviceRequestPromptDevice
correspondant. Transmettez cet appareil à DeviceRequestPrompt.select()
pour le sélectionner et vous y connecter.
const bluetoothDevice = await devicePrompt.waitForDevice(
(d) => d.name == wantedDeviceName,
);
await devicePrompt.select(bluetoothDevice);
Une fois DeviceRequestPrompt.select()
résolu, Chrome est connecté à l'appareil et la page Web peut y accéder.
Lire les données de l'appareil
À ce stade, votre application Web est connectée à l'appareil Bluetooth choisi et peut en lire les informations. Cela peut se présenter comme suit:
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();
Pour une présentation plus détaillée de cette séquence d'appels d'API, consultez Communiquer avec des appareils Bluetooth via JavaScript.
À ce stade, vous savez utiliser Puppeteer pour automatiser l'utilisation d'une application Web compatible avec le Bluetooth en remplaçant l'étape manuelle de sélection d'un appareil dans le menu de sélection des appareils Bluetooth. Bien que cela puisse être utile en général, cela s'applique directement à la rédaction d'un test de bout en bout pour une telle application Web.
Créer un test
La pièce manquante pour passer du code actuel à l'écriture d'un test complet consiste à extraire des informations de l'application Web et à les insérer dans votre script Puppeteer. Une fois que vous avez obtenu ces informations, il est assez simple d'utiliser une bibliothèque de test (comme TAP ou mocha) pour vérifier que les données correctes ont été lues et enregistrées.
Pour ce faire, le moyen le plus simple consiste à écrire des données dans le DOM. JavaScript propose de nombreuses façons de procéder sans bibliothèques supplémentaires. Pour revenir à votre application Web hypothétique, elle peut changer la couleur d'un indicateur d'état lorsqu'elle lit des données à partir de l'appareil Bluetooth ou imprimer les données littérales dans un champ. Exemple :
const dataDisplayElement = document.querySelector('#data-display');
dataDisplayElement.innerText = dataView.getUint8();
Dans Puppeteer, Page.$eval()
vous permet d'extraire ces données du DOM de la page et de les placer dans un script de test. $eval()
utilise la même logique que document.querySelector()
pour rechercher un élément, puis exécute la fonction de rappel fournie avec cet élément en tant qu'argument. Une fois que vous avez défini cette valeur en tant que variable, utilisez votre bibliothèque d'assertions pour vérifier si les données correspondent à ce que nous attendons.
const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);
Ressources supplémentaires
Pour voir des exemples plus complexes d'écriture de tests pour des applications Web compatibles avec le Bluetooth avec Puppeteer, consultez ce dépôt: https://github.com/WebBluetoothCG/manual-tests/. Le groupe de la communauté Web Bluetooth gère cette suite de tests, qui peuvent tous être exécutés à partir d'un navigateur ou en local. Le test "Caractéristique en lecture seule" est le plus proche de l'exemple utilisé dans cet article de blog.
Remerciements
Merci à Vincent Scheib d'avoir lancé ce projet et de nous avoir fourni des commentaires précieux sur cet article.