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 pengguna Perangkat Bluetooth. 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 membahas cara menggunakan Puppeteer untuk mengoperasikan dan menguji aplikasi web yang mendukung Bluetooth. Bagian penting dari hal ini adalah kemampuan Puppeteer untuk mengoperasikan pemilih perangkat Bluetooth Chrome.

Jika Anda tidak terbiasa menggunakan Web Bluetooth 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 berkomunikasi dengannya, dan menggunakan Puppeteer v21.4.0 atau yang lebih baru.

Meluncurkan browser

Seperti pada 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 ditampilkannya perintah Bluetooth.
  • Argumen tambahan ke Chromium: Meneruskan "aktifkan Web Bluetooth" argumen 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 tersebut:

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

Selanjutnya, Anda dapat membuka URL aplikasi web yang sedang 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, jika tidak, perintah sudah terbuka, dan perintah tidak akan dapat mendeteksinya.

Karena kedua metode Puppeteer ini menampilkan promise, Promise.all() merupakan cara yang mudah untuk memanggil keduanya dalam urutan yang benar bersama-sama:

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

Promise yang ditampilkan oleh waitForDevicePrompt() di-resolve menjadi objek DeviceRequestPrompt yang akan Anda gunakan di samping 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 benar, waitForDevice() akan me-resolve ke DeviceRequestPromptDevice yang cocok. Teruskan perangkat itu ke DeviceRequestPrompt.select() untuk memilih dan terhubung 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 telah mengetahui cara menggunakan Puppeteer untuk mengotomatisasi penggunaan aplikasi web berkemampuan Bluetooth dengan mengganti langkah manual untuk memilih perangkat dari menu pemilih perangkat Bluetooth. Meskipun cara ini mungkin berguna secara umum, cara ini langsung berlaku untuk penulisan pengujian menyeluruh untuk aplikasi web semacam itu.

Membuat pengujian

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

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, aplikasi web mungkin akan mengubah warna indikator status saat aplikasi 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 mengambil data ini dari DOM halaman dan masuk ke dalam skrip pengujian. $eval() menggunakan logika yang sama dengan document.querySelector() untuk menemukan sebuah 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 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. "Karakteristik Hanya Baca" tes 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 tentang postingan ini.