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 berbicara langsung dengan perangkat Bluetooth pengguna. Kemampuan editor web Espruino untuk mengupload kode ke perangkat Bluetooth yang kompatibel adalah salah satu contohnya. Sekarang pengujian aplikasi ini dapat dilakukan dengan Puppeteer.

Postingan blog ini membahas cara menggunakan Puppeteer untuk mengoperasikan dan menguji aplikasi web berkemampuan Bluetooth. Bagian utamanya adalah kemampuan Puppeteer untuk mengoperasikan pemilih perangkat Bluetooth Chrome.

Jika Anda tidak terbiasa menggunakan Bluetooth Web di Chrome, video berikut akan 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 digunakan untuk berkomunikasi, dan menggunakan Puppeteer v21.4.0 atau versi lebih baru.

Meluncurkan browser

Seperti kebanyakan skrip Puppeteer, mulailah dengan meluncurkan browser dengan Puppeteer.launch(). Untuk mengakses fitur Bluetooth, Anda harus memberikan beberapa argumen tambahan:

  • Nonaktifkan mode headless: Ini berarti Puppeteer akan membuka jendela browser Chrome yang terlihat untuk menjalankan pengujian. Gunakan mode headless baru jika Anda lebih memilih untuk menjalankannya tanpa UI. Mode headless lama tidak mendukung tampilan perintah Bluetooth.
  • Argumen tambahan ke Chromium: Teruskan argumen"aktifkan Bluetooth Web" 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. Tindakan 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 tersebut:

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

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

Buka 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 tersebut. Jika tidak, prompt sudah terbuka, dan perintah tidak akan dapat mendeteksinya.

Karena kedua metode Puppeteer ini menampilkan promise, Promise.all() adalah cara yang mudah 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 di samping memilih perangkat Bluetooth yang ingin dihubungkan.

Pilih perangkat

Gunakan DeviceRequestPrompt.waitForDevice() dan DeviceRequestPrompt.select() untuk menemukan serta 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 benar, waitForDevice() akan me-resolve ke DeviceRequestPromptDevice yang cocok. Teruskan perangkat tersebut ke DeviceRequestPrompt.select() untuk memilih dan menghubungkan ke perangkat Bluetooth.

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

Setelah DeviceRequestPrompt.select() di-resolve, Chrome 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 dari perangkat tersebut. 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 tahu cara menggunakan Puppeteer untuk mengotomatiskan penggunaan aplikasi web berkemampuan Bluetooth dengan mengganti langkah manusia dalam memilih perangkat dari menu pemilih perangkat Bluetooth. Meskipun mungkin berguna secara umum, ini juga berlaku secara langsung untuk menulis pengujian menyeluruh untuk aplikasi web semacam itu.

Membuat pengujian

Bagian yang hilang dari mengambil kode sejauh ini untuk menulis pengujian penuh adalah mendapatkan informasi dari aplikasi web dan ke dalam skrip Puppeteer Anda. Setelah Anda memiliki ini, Anda dapat menggunakan library pengujian (seperti TAP atau mocha) 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 fiktif Anda mungkin mengubah warna indikator status saat membaca data dari perangkat Bluetooth atau mencetak data literal dalam kolom. Contoh:

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

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

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

Referensi tambahan

Untuk melihat contoh yang lebih kompleks terkait penulisan pengujian untuk aplikasi web berkemampuan Bluetooth dengan Puppeteer, lihat repositori ini: https://github.com/WebBluetoothCG/manual-tests/. Grup Komunitas Bluetooth Web 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 karena telah memulai proyek ini dan memberikan masukan yang berharga di postingan ini.