वेब ब्लूटूथ की सुविधा, Chrome 56 से काम करती है. इसकी मदद से, डेवलपर ऐसे वेब ऐप्लिकेशन लिख सकते हैं जो सीधे उपयोगकर्ताओं के ब्लूटूथ डिवाइसों से कनेक्ट होते हैं. Espruino वेब एडिटर की मदद से, ब्लूटूथ की सुविधा वाले डिवाइसों पर कोड अपलोड किया जा सकता है. Puppeteer की मदद से, अब इन ऐप्लिकेशन की जांच की जा सकती है.
इस ब्लॉग पोस्ट में, ब्लूटूथ की सुविधा वाले वेब ऐप्लिकेशन को चलाने और उसकी जांच करने के लिए, Puppeteer का इस्तेमाल करने का तरीका बताया गया है. इसमें सबसे अहम बात यह है कि Puppeteer, Chrome के ब्लूटूथ डिवाइस चुनने वाले टूल को चला सकता है.
अगर आपको Chrome में वेब ब्लूटूथ का इस्तेमाल करने के बारे में नहीं पता है, तो नीचे दिए गए वीडियो में Espruino वेब एडिटर में ब्लूटूथ प्रॉम्प्ट दिखाया गया है:
इस ब्लॉग पोस्ट में बताए गए तरीके को अपनाने के लिए, आपके पास ब्लूटूथ की सुविधा वाला वेब ऐप्लिकेशन और ब्लूटूथ डिवाइस होना चाहिए. साथ ही, आपके पास Puppeteer v21.4.0 या इसके बाद का वर्शन होना चाहिए.
ब्राउज़र लॉन्च करना
ज़्यादातर Puppeteer स्क्रिप्ट की तरह, Puppeteer.launch()
से ब्राउज़र लॉन्च करके शुरू करें. ब्लूटूथ की सुविधाओं को ऐक्सेस करने के लिए, आपको कुछ और आर्ग्युमेंट देने होंगे:
- हेडलेस मोड बंद करना: इसका मतलब है कि Puppeteer, टेस्ट चलाने के लिए Chrome ब्राउज़र की विंडो खोलेगा. अगर आपको इसे यूज़र इंटरफ़ेस के बिना चलाना है, तो नए हेडलेस मोड का इस्तेमाल करें. लेगसी हेडलेस मोड में, ब्लूटूथ प्रॉम्प्ट नहीं दिखाए जा सकते.
- Chromium के लिए अतिरिक्त आर्ग्युमेंट: Linux एनवायरमेंट के लिए, "वेब ब्लूटूथ चालू करें" आर्ग्युमेंट पास करें.
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 कम्यूनिटी ग्रुप, टेस्ट के इस सुइट को मैनेज करता है. इन सभी टेस्ट को ब्राउज़र या स्थानीय तौर पर चलाया जा सकता है. "रीड-ओनली एट्रिब्यूट" टेस्ट, इस ब्लॉग पोस्ट में इस्तेमाल किए गए उदाहरण से काफ़ी मिलता-जुलता है.
लोगों का आभार
इस प्रोजेक्ट को शुरू करने और इस पोस्ट पर अहम सुझाव देने के लिए, विंसेंट शेब को धन्यवाद.