Kiểm thử Bluetooth cho web bằng Puppeteer

François Beaufort
François Beaufort

Bluetooth dành cho web đã được hỗ trợ kể từ Chrome 56 và cho phép các nhà phát triển viết ứng dụng web trò chuyện trực tiếp với thiết bị Bluetooth của người dùng. Khả năng tải mã lên thiết bị Bluetooth tương thích của trình chỉnh sửa web Espruino là một ví dụ. Giờ đây, bạn có thể thử nghiệm các ứng dụng này bằng Puppeteer.

Bài đăng trên blog này hướng dẫn cách sử dụng Puppeteer để vận hành và kiểm thử ứng dụng web có hỗ trợ Bluetooth. Phần quan trọng của bài đăng này là khả năng vận hành trình chọn thiết bị Bluetooth của Chrome.

Nếu bạn chưa quen với việc sử dụng Bluetooth trên web trong Chrome, video sau đây sẽ hiển thị lời nhắc Bluetooth trong trình chỉnh sửa web của Espruino:

Người dùng chọn một thiết bị bluetooth Puck.js trong trình chỉnh sửa web của Espruino.

Để theo dõi bài đăng trên blog này, bạn cần có ứng dụng web có hỗ trợ Bluetooth, thiết bị Bluetooth mà ứng dụng có thể giao tiếp và sử dụng Puppeteer v21.4.0 trở lên.

Khởi chạy trình duyệt

Giống như hầu hết các tập lệnh Puppeteer, hãy bắt đầu bằng cách khởi chạy trình duyệt bằng Puppeteer.launch(). Để truy cập các tính năng Bluetooth, bạn cần cung cấp thêm một số đối số:

import puppeteer from 'puppeteer';

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

Khi mở trang đầu tiên, bạn nên sử dụng ngữ cảnh trình duyệt ẩn danh. Điều này giúp ngăn chặn tình trạng rò rỉ quyền giữa các lượt kiểm thử chạy với tập lệnh của bạn (mặc dù có một số trạng thái được chia sẻ ở cấp hệ điều hành mà Puppeteer không thể ngăn chặn). Mã sau đây minh hoạ điều này:

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

Sau đó, bạn có thể chuyển đến URL của ứng dụng web mà bạn đang kiểm thử Page.goto().

Mở lời nhắc của thiết bị Bluetooth

Sau khi sử dụng Puppeteer để mở trang của ứng dụng web bằng Puppeteer, bạn có thể kết nối với thiết bị Bluetooth để đọc dữ liệu. Bước tiếp theo này giả định bạn có một nút trên ứng dụng web chạy một số JavaScript, bao gồm cả lệnh gọi đến navigator.bluetooth.requestDevice().

Dùng Page.locator().click() để nhấn nút đó, và nhấn vào Page.waitForDevicePrompt() để nhận ra thời điểm trình chọn thiết bị Bluetooth xuất hiện. Bạn phải gọi waitForDevicePrompt() trước khi nhấp vào nút, nếu không, lời nhắc đã mở và không thể phát hiện thấy lời nhắc.

Vì cả hai phương thức Puppeteer này đều trả về lời hứa, nên Promise.all() là một cách thuận tiện để gọi chúng theo đúng thứ tự cùng nhau:

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

Lời hứa do waitForDevicePrompt() trả về sẽ phân giải thành đối tượng DeviceRequestPrompt mà bạn sẽ sử dụng tiếp theo để chọn thiết bị Bluetooth bạn muốn kết nối.

Chọn thiết bị

Sử dụng DeviceRequestPrompt.waitForDevice()DeviceRequestPrompt.select() để tìm và kết nối với đúng thiết bị Bluetooth.

DeviceRequestPrompt.waitForDevice() gọi lệnh gọi lại đã cung cấp mỗi khi Chrome tìm thấy một thiết bị Bluetooth có một số thông tin cơ bản về thiết bị. Trong lần đầu tiên lệnh gọi lại trả về giá trị true, waitForDevice() sẽ phân giải thành DeviceRequestPromptDevice trùng khớp. Truyền thiết bị đó đến DeviceRequestPrompt.select() để chọn và kết nối với thiết bị Bluetooth đó.

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

Sau khi DeviceRequestPrompt.select() giải quyết, Chrome sẽ được kết nối với thiết bị và trang web có thể truy cập thiết bị đó.

Đọc từ thiết bị

Tại thời điểm này, ứng dụng web của bạn sẽ được kết nối với thiết bị Bluetooth đã chọn và có thể đọc thông tin trên thiết bị đó. Mã này có thể có dạng như sau:

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

Để xem hướng dẫn từng bước chi tiết hơn về trình tự các lệnh gọi API này, hãy xem bài viết Giao tiếp với thiết bị Bluetooth qua JavaScript.

Đến đây, bạn đã biết cách sử dụng Puppeteer để tự động dùng ứng dụng web có hỗ trợ Bluetooth bằng cách thay thế bước chọn thiết bị từ trình đơn bộ chọn thiết bị Bluetooth do con người thực hiện. Mặc dù cách này nhìn chung có thể hữu ích, nhưng bạn có thể áp dụng trực tiếp để viết chương trình kiểm thử toàn diện cho một ứng dụng web như vậy.

Tạo chương trình kiểm thử

Phần còn thiếu từ việc lấy mã cho đến khi viết kiểm thử đầy đủ là đưa thông tin ra khỏi ứng dụng web và đưa thông tin vào tập lệnh Puppeteer của bạn. Sau khi truy cập vào trang web, bạn có thể dễ dàng sử dụng thư viện kiểm thử (như TAP hoặc mocha) để xác minh dữ liệu chính xác đã được đọc và báo cáo.

Một trong những cách dễ nhất để thực hiện việc này là ghi dữ liệu vào DOM. JavaScript có nhiều cách để thực hiện việc này mà không cần thêm thư viện. Quay lại với ứng dụng web giả định của bạn, chỉ báo trạng thái có thể thay đổi màu sắc khi đọc dữ liệu từ thiết bị Bluetooth hoặc in dữ liệu cố định trong một trường. Ví dụ:

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

Từ Puppeteer, Page.$eval() cung cấp cho bạn cách kéo dữ liệu này ra khỏi DOM của trang và đưa vào tập lệnh thử nghiệm. $eval() sử dụng logic tương tự như document.querySelector() để tìm một phần tử, sau đó chạy hàm callback đã cung cấp với phần tử đó làm đối số. Sau khi bạn có biến này dưới dạng một biến, hãy sử dụng thư viện câu nhận định của bạn để kiểm tra xem dữ liệu có đúng như chúng ta mong đợi hay không.

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

Tài nguyên bổ sung

Để xem các ví dụ phức tạp hơn về cách viết kiểm thử cho ứng dụng web hỗ trợ Bluetooth bằng Puppeteer, hãy xem kho lưu trữ sau: https://github.com/WebBluetoothCG/manual-tests/. Nhóm cộng đồng Web Bluetooth duy trì bộ thử nghiệm này, tất cả đều có thể chạy trên trình duyệt hoặc cục bộ. Quy trình kiểm thử"Đặc điểm chỉ đọc" giống nhất với ví dụ được dùng trong bài đăng trên blog này.

Thư cảm ơn

Cảm ơn Vincent Scheib đã bắt đầu dự án này và đưa ra ý kiến phản hồi có giá trị về bài đăng này.