Menguji Bluetooth Web dengan Puppeteer

François Beaufort
François Beaufort

Bluetooth Web telah didukung sejak Chrome 56, dan memungkinkan developer menulis aplikasi web yang berkomunikasi langsung dengan perangkat Bluetooth pengguna. Kemampuan editor web Espruino untuk mengupload kode ke perangkat Bluetooth yang kompatibel adalah salah satu contohnya. Pengujian aplikasi ini kini dapat dilakukan dengan Puppeteer.

Postingan blog ini menjelaskan cara menggunakan Puppeteer untuk mengoperasikan dan menguji aplikasi web yang kompatibel dengan Bluetooth. Bagian utamanya adalah kemampuan Puppeteer untuk mengoperasikan pemilih perangkat Bluetooth Chrome.

Jika Anda tidak terbiasa menggunakan Web Bluetooth di Chrome, video berikut menampilkan perintah Bluetooth di editor web Espruino:

Pengguna memilih perangkat bluetooth Puck.js di editor web Espruino.

Untuk mengikuti postingan blog ini, Anda memerlukan aplikasi web berkemampuan Bluetooth, perangkat Bluetooth yang dapat berkomunikasi dengannya, dan menggunakan Puppeteer v21.4.0 atau yang lebih baru.

Meluncurkan browser

Seperti sebagian besar skrip Puppeteer, mulailah dengan meluncurkan browser dengan Puppeteer.launch(). Untuk mengakses fitur Bluetooth, Anda perlu menyediakan beberapa argumen tambahan:

  • Nonaktifkan mode headless: Hal ini berarti Puppeteer akan membuka jendela browser Chrome yang terlihat untuk menjalankan pengujian. Gunakan mode headless baru jika Anda lebih suka menjalankannya tanpa UI. Mode headless lama tidak mendukung tampilan perintah Bluetooth.
  • Argumen tambahan ke Chromium: Teruskan argumen"enable Web Bluetooth" untuk lingkungan Linux.
import puppeteer from 'puppeteer';

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

Saat membuka halaman pertama, sebaiknya gunakan konteks browser Samaran. Hal ini membantu mencegah kebocoran izin di antara pengujian yang dijalankan dengan skrip Anda (meskipun ada beberapa status bersama tingkat OS yang tidak dapat dicegah oleh Puppeteer). Kode berikut menunjukkan hal ini:

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

Selanjutnya, Anda dapat membuka URL aplikasi web yang sedang Anda uji dengan Page.goto().

Membuka perintah perangkat Bluetooth

Setelah menggunakan Puppeteer untuk membuka halaman aplikasi web dengan Puppeteer, Anda dapat terhubung ke perangkat Bluetooth untuk membaca data. Langkah berikutnya ini mengasumsikan bahwa Anda memiliki tombol di aplikasi web yang menjalankan beberapa JavaScript, termasuk panggilan ke navigator.bluetooth.requestDevice().

Gunakan Page.locator().click() untuk menekan tombol tersebut, dan Page.waitForDevicePrompt() untuk mengenali saat pemilih perangkat Bluetooth muncul. Anda harus memanggil waitForDevicePrompt() sebelum mengklik tombol. Jika tidak, perintah akan terbuka, dan tidak akan dapat mendeteksinya.

Karena kedua metode Puppeteer ini menampilkan promise, Promise.all() adalah cara praktis untuk memanggilnya dalam urutan yang benar secara bersamaan:

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

Promise yang ditampilkan oleh waitForDevicePrompt() di-resolve ke objek DeviceRequestPrompt yang akan Anda gunakan berikutnya untuk memilih perangkat Bluetooth yang ingin dihubungkan.

Pilih perangkat

Gunakan DeviceRequestPrompt.waitForDevice() dan DeviceRequestPrompt.select() untuk menemukan dan menghubungkan ke perangkat Bluetooth yang benar.

DeviceRequestPrompt.waitForDevice() memanggil callback yang disediakan setiap kali Chrome menemukan perangkat Bluetooth dengan beberapa info dasar tentang perangkat. Saat pertama kali callback menampilkan true, waitForDevice() akan di-resolve ke DeviceRequestPromptDevice yang cocok. Teruskan perangkat tersebut ke DeviceRequestPrompt.select() untuk memilih dan menghubungkan ke perangkat Bluetooth tersebut.

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

Setelah DeviceRequestPrompt.select() di-resolve, Chrome akan terhubung ke perangkat, dan halaman web dapat mengaksesnya.

Membaca dari perangkat

Pada tahap ini, aplikasi web Anda akan terhubung ke perangkat Bluetooth yang dipilih dan dapat membaca informasi darinya. Ini mungkin terlihat seperti:

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();

Untuk panduan yang lebih mendalam tentang urutan panggilan API ini, lihat Berkomunikasi dengan perangkat Bluetooth melalui JavaScript.

Pada tahap ini, Anda sudah mengetahui cara menggunakan Puppeteer untuk mengotomatiskan penggunaan aplikasi web yang mengaktifkan Bluetooth dengan mengganti langkah manusia dalam memilih perangkat dari menu pemilih perangkat Bluetooth. Meskipun umumnya berguna, hal ini langsung berlaku untuk menulis pengujian menyeluruh untuk aplikasi web tersebut.

Membuat pengujian

Bagian yang hilang dari mengambil kode sejauh ini untuk menulis pengujian lengkap adalah mendapatkan informasi dari aplikasi web dan memasukkannya ke skrip Puppeteer Anda. Setelah memilikinya, Anda dapat menggunakan library pengujian (seperti TAP atau mocha) dengan mudah untuk memverifikasi bahwa data yang benar telah dibaca dan dilaporkan.

Salah satu cara termudah untuk melakukannya adalah dengan menulis data ke DOM. JavaScript memiliki banyak cara untuk melakukannya tanpa library tambahan. Kembali ke aplikasi web hipotetis Anda, aplikasi tersebut mungkin mengubah warna indikator status saat membaca data dari perangkat Bluetooth atau mencetak data literal di kolom. Contoh:

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

Dari Puppeteer, Page.$eval() memberi Anda cara untuk mengambil data ini dari DOM halaman dan memasukkannya ke dalam skrip pengujian. $eval() menggunakan logika yang sama dengan document.querySelector() untuk menemukan elemen, lalu menjalankan fungsi callback yang disediakan dengan elemen tersebut sebagai argumen. Setelah Anda memilikinya sebagai variabel, gunakan library pernyataan untuk menguji apakah datanya sesuai dengan yang kita harapkan.

const dataText = await page.$eval('#data-display', (el) => el.innerText);
equal(17, dataText);

Referensi lainnya

Untuk melihat contoh penulisan pengujian yang lebih kompleks untuk aplikasi web yang kompatibel dengan Bluetooth dengan Puppeteer, lihat repositori ini: https://github.com/WebBluetoothCG/manual-tests/. Grup Komunitas Web Bluetooth mengelola rangkaian pengujian ini, yang semuanya dapat dijalankan dari browser atau secara lokal. Pengujian "Karakteristik Hanya Baca" paling mirip dengan contoh yang digunakan dalam postingan blog ini.

Ucapan terima kasih

Terima kasih kepada Vincent Scheib yang telah memulai project ini dan memberikan masukan berharga pada postingan ini.