Puppeteer की मदद से वेब ब्लूटूथ की जांच करना

François Beaufort
François Beaufort

वेब ब्लूटूथ की सुविधा, Chrome 56 से काम करती है. इसकी मदद से, डेवलपर ऐसे वेब ऐप्लिकेशन लिख सकते हैं जो सीधे उपयोगकर्ताओं के ब्लूटूथ डिवाइसों से कनेक्ट होते हैं. Espruino वेब एडिटर की मदद से, ब्लूटूथ की सुविधा वाले डिवाइसों पर कोड अपलोड किया जा सकता है. Puppeteer की मदद से, अब इन ऐप्लिकेशन की जांच की जा सकती है.

इस ब्लॉग पोस्ट में, ब्लूटूथ की सुविधा वाले वेब ऐप्लिकेशन को चलाने और उसकी जांच करने के लिए Puppeteer का इस्तेमाल करने के तरीके के बारे में बताया गया है. Chrome के ब्लूटूथ डिवाइस चुनने के टूल को चलाने की Puppeteer की क्षमता की अहम जानकारी है.

अगर आपको Chrome में वेब ब्लूटूथ का इस्तेमाल करने के बारे में नहीं पता है, तो नीचे दिए गए वीडियो में Espruino वेब एडिटर में ब्लूटूथ प्रॉम्प्ट दिखाया गया है:

उपयोगकर्ता, Espruino वेब एडिटर में Puck.js ब्लूटूथ डिवाइस चुनता है.

इस ब्लॉग पोस्ट में बताए गए तरीके को अपनाने के लिए, आपके पास ब्लूटूथ की सुविधा वाला वेब ऐप्लिकेशन और ब्लूटूथ डिवाइस होना चाहिए. साथ ही, आपके पास Puppeteer v21.4.0 या इसके बाद का वर्शन होना चाहिए.

ब्राउज़र लॉन्च करना

ज़्यादातर Puppeteer स्क्रिप्ट की तरह ही, ब्राउज़र को Puppeteer.launch() के साथ लॉन्च करके शुरू करें. ब्लूटूथ की सुविधाओं को ऐक्सेस करने के लिए, आपको कुछ और आर्ग्युमेंट देने होंगे:

import puppeteer from 'puppeteer';

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

पहला पेज खोलते समय, आम तौर पर गुप्त ब्राउज़र संदर्भ का इस्तेमाल करने की सलाह दी जाती है. इससे, आपकी स्क्रिप्ट के साथ चलने वाले टेस्ट के बीच अनुमतियों को लीक होने से रोकने में मदद मिलती है. हालांकि, ओएस लेवल पर शेयर की जाने वाली कुछ स्थितियां ऐसी होती हैं जिन्हें Puppeteer से रोका नहीं जा सकता. नीचे दिया गया कोड इसका उदाहरण है:

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

इसके बाद, उस वेब ऐप्लिकेशन के यूआरएल पर जाएं जिसे Page.goto() की मदद से टेस्ट किया जा रहा है.

ब्लूटूथ डिवाइस का प्रॉम्प्ट खोलना

Puppeteer की मदद से वेब ऐप्लिकेशन का पेज खोलने के बाद, डेटा पढ़ने के लिए ब्लूटूथ डिवाइस से कनेक्ट किया जा सकता है. अगले चरण में यह मान लिया जाता है कि आपके वेब ऐप्लिकेशन पर एक ऐसा बटन मौजूद है जो navigator.bluetooth.requestDevice() को कॉल करने के साथ-साथ कुछ JavaScript चलाता है.

उस बटन को दबाने के लिए, Page.locator().click() का इस्तेमाल करें. साथ ही, ब्लूटूथ डिवाइस चुनने वाला विकल्प दिखने पर, Page.waitForDevicePrompt() का इस्तेमाल करें. बटन पर क्लिक करने से पहले, आपको waitForDevicePrompt() को कॉल करना ज़रूरी है. ऐसा न करने पर, प्रॉम्प्ट पहले ही खुल जाएगा और उसे पहचाना नहीं जा सकेगा.

Puppeteer के इन दोनों तरीकों में, प्रॉमिस प्रॉमिस पाना मुश्किल होता है. इसलिए, Promise.all() को सही क्रम में एक साथ कॉल करने का एक आसान तरीका है:

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

waitForDevicePrompt() से मिलने वाला प्रॉमिस, DeviceRequestPrompt ऑब्जेक्ट में बदल जाता है. इसका इस्तेमाल, उस ब्लूटूथ डिवाइस को चुनने के लिए किया जाएगा जिससे आपको कनेक्ट करना है.

कोई डिवाइस चुनें

सही ब्लूटूथ डिवाइस ढूंढने और उससे कनेक्ट करने के लिए, DeviceRequestPrompt.waitForDevice() और DeviceRequestPrompt.select() का इस्तेमाल करें.

DeviceRequestPrompt.waitForDevice(), जब भी Chrome को कोई ब्लूटूथ डिवाइस मिलता है, तो दिए गए कॉलबैक को कॉल करता है. इसमें डिवाइस की बुनियादी जानकारी होती है. जब पहली बार कॉलबैक सही के तौर पर दिखता है, तो waitForDevice(), मैच होने वाले DeviceRequestPromptDevice पर पहुंच जाता है. उस ब्लूटूथ डिवाइस को चुनने और उससे कनेक्ट करने के लिए, उस डिवाइस को DeviceRequestPrompt.select() से पास करें.

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

DeviceRequestPrompt.select() ठीक होने के बाद, Chrome डिवाइस से कनेक्ट हो जाता है और वेब पेज उसे ऐक्सेस कर पाता है.

डिवाइस से पढ़ना

इसके बाद, आपका वेब ऐप्लिकेशन चुने गए ब्लूटूथ डिवाइस से कनेक्ट हो जाएगा और उससे जानकारी पढ़ पाएगा. यह कुछ ऐसा दिख सकता है:

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

एपीआई कॉल के इस क्रम के बारे में ज़्यादा जानने के लिए, JavaScript की मदद से ब्लूटूथ डिवाइसों से कम्यूनिकेट करना लेख पढ़ें.

अब आपके पास Puppeteer का इस्तेमाल करके, ब्लूटूथ की सुविधा वाले वेब ऐप्लिकेशन का इस्तेमाल अपने-आप करने का तरीका है. इसके लिए, ब्लूटूथ डिवाइस चुनने वाले मेन्यू से किसी डिवाइस को चुनने की प्रक्रिया को हटाना होगा. यह आम तौर पर काम का हो सकता है, लेकिन यह ऐसे वेब ऐप्लिकेशन के लिए एंड-टू-एंड टेस्ट लिखने पर सीधे लागू होता है.

टेस्ट बनाना

कोड को लेकर अब तक पूरी जांच करने के लिए, वेब ऐप्लिकेशन से जानकारी को Puppeteer स्क्रिप्ट में डालना ज़रूरी है. इसके बाद, TAP या mocha जैसी टेस्टिंग लाइब्रेरी का इस्तेमाल करके, यह पुष्टि करना आसान हो जाता है कि सही डेटा को पढ़ा और रिपोर्ट किया गया है.

ऐसा करने का सबसे आसान तरीका, डीओएम में डेटा लिखना है. JavaScript में अतिरिक्त लाइब्रेरी के बिना यह काम करने के कई तरीके हैं. अपने वेब ऐप्लिकेशन के उदाहरण पर वापस आकर, यह देखा जा सकता है कि ब्लूटूथ डिवाइस से डेटा पढ़ने पर, यह स्टेटस इंडिकेटर का रंग बदल सकता है या किसी फ़ील्ड में लिटरल डेटा प्रिंट कर सकता है. उदाहरण के लिए:

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

Puppeteer में, Page.$eval() की मदद से, इस डेटा को पेज के DOM से बाहर निकालकर टेस्ट स्क्रिप्ट में डाला जा सकता है. $eval(), किसी एलिमेंट को ढूंढने के लिए document.querySelector() के लॉजिक का इस्तेमाल करता है. इसके बाद, दिए गए कॉलबैक फ़ंक्शन को आर्ग्युमेंट के तौर पर उस एलिमेंट के साथ चलाता है. जब यह वैरिएबल बन जाए, तो अपनी एश्योरेशन लाइब्रेरी का इस्तेमाल करके जांच करें कि डेटा हमारी उम्मीद के मुताबिक है या नहीं.

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

अन्य संसाधन

Puppeteer की मदद से, ब्लूटूथ की सुविधा वाले वेब ऐप्लिकेशन के लिए टेस्ट लिखने के ज़्यादा जटिल उदाहरण देखने के लिए, यह रिपॉज़िटरी देखें: https://github.com/WebBluetoothCG/manual-tests/. Web Bluetooth कम्यूनिटी ग्रुप, टेस्ट के इस सुइट को मैनेज करता है. इन सभी टेस्ट को ब्राउज़र या स्थानीय तौर पर चलाया जा सकता है. "रीड-ओनली एट्रिब्यूट" टेस्ट, इस ब्लॉग पोस्ट में इस्तेमाल किए गए उदाहरण से काफ़ी मिलता-जुलता है.

लोगों का आभार

इस प्रोजेक्ट को शुरू करने और इस पोस्ट पर अहम सुझाव देने के लिए, विंसेंट शेब को धन्यवाद.