এই নির্দেশিকাটি Puppeteer ব্যবহার করে সার্ভিস ওয়ার্কার টার্মিনেশন পরীক্ষা করার মাধ্যমে আরও শক্তিশালী এক্সটেনশন তৈরি করার পদ্ধতি ব্যাখ্যা করে। যেকোনো সময় টার্মিনেশন সামলানোর জন্য প্রস্তুত থাকা গুরুত্বপূর্ণ, কারণ এটি কোনো পূর্ব সতর্কবার্তা ছাড়াই ঘটতে পারে, যার ফলে সার্ভিস ওয়ার্কারের যেকোনো নন-পার্সিস্টেন্ট স্টেট হারিয়ে যেতে পারে। ফলস্বরূপ, এক্সটেনশনগুলোকে অবশ্যই গুরুত্বপূর্ণ স্টেট সংরক্ষণ করতে হবে এবং পুনরায় চালু হওয়ার সাথে সাথেই কোনো ইভেন্ট ঘটলে অনুরোধগুলো সামলাতে সক্ষম হতে হবে।
শুরু করার আগে
chrome-extensions-samples রিপোজিটরিটি ক্লোন বা ডাউনলোড করুন। আমরা /functional-samples/tutorial.terminate-sw/test-extension এ থাকা টেস্ট এক্সটেনশনটি ব্যবহার করব, যেটি প্রতিবার বাটন ক্লিক করা হলে সার্ভিস ওয়ার্কারে একটি মেসেজ পাঠায় এবং কোনো রেসপন্স পেলে পেজে টেক্সট যোগ করে।
আপনাকে Node.JS- ও ইনস্টল করতে হবে, যার ওপর ভিত্তি করে Puppeteer তৈরি করা হয়েছে।
ধাপ ১: আপনার Node.js প্রজেক্ট শুরু করুন।
একটি নতুন ডিরেক্টরিতে নিম্নলিখিত ফাইলগুলি তৈরি করুন। এগুলি একত্রে একটি নতুন Node.js প্রজেক্ট তৈরি করে এবং Jest-কে টেস্ট রানার হিসেবে ব্যবহার করে একটি Puppeteer টেস্ট স্যুটের প্রাথমিক কাঠামো প্রদান করে। এই সেটআপ সম্পর্কে আরও বিস্তারিত জানতে “Test Chrome Extensions with Puppeteer” দেখুন।
প্যাকেজ.json:
{
"name": "puppeteer-demo",
"version": "1.0",
"dependencies": {
"jest": "^29.7.0",
"puppeteer": "^24.8.1"
},
"scripts": {
"start": "jest ."
},
"devDependencies": {
"@jest/globals": "^29.7.0"
}
}
index.test.js:
const puppeteer = require('puppeteer');
const SAMPLES_REPO_PATH = 'PATH_TO_SAMPLES_REPOSITORY';
const EXTENSION_PATH = `${SAMPLES_REPO_PATH}/functional-samples/tutorial.terminate-sw/test-extension`;
const EXTENSION_ID = 'gjgkofgpcmpfpggbgjgdfaaifcmoklbl';
let browser;
beforeEach(async () => {
browser = await puppeteer.launch({
// Set to 'new' to hide Chrome if running as part of an automated build.
headless: false,
pipe: true,
enableExtensions: [EXTENSION_PATH]
});
});
afterEach(async () => {
await browser.close();
browser = undefined;
});
লক্ষ্য করুন যে আমাদের টেস্টটি স্যাম্পলস রিপোজিটরি থেকে test-extension লোড করে। browser.runtime.onMessage এর হ্যান্ডলারটি browser.runtime.onInstalled ইভেন্টের হ্যান্ডলারে সেট করা স্টেটের উপর নির্ভর করে। ফলে, সার্ভিস ওয়ার্কারটি টার্মিনেট হয়ে গেলে data বিষয়বস্তু হারিয়ে যাবে এবং ভবিষ্যতের যেকোনো মেসেজের উত্তর দেওয়া ব্যর্থ হবে। আমাদের টেস্ট লেখার পরে আমরা এটি ঠিক করব।
service-worker-broken.js:
let data;
browser.runtime.onInstalled.addListener(() => {
data = { version: browser.runtime.getManifest().version };
});
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
sendResponse(data.version);
});
ধাপ ২: নির্ভরতাগুলো ইনস্টল করুন
প্রয়োজনীয় ডিপেন্ডেন্সিগুলো ইনস্টল করতে npm install চালান।
ধাপ ৩: একটি প্রাথমিক পরীক্ষা লিখুন
index.test.js ফাইলের শেষে নিম্নলিখিত টেস্টটি যোগ করুন। এটি আমাদের টেস্ট এক্সটেনশন থেকে টেস্ট পেজটি খোলে, বাটন এলিমেন্টটিতে ক্লিক করে এবং সার্ভিস ওয়ার্কারের কাছ থেকে একটি প্রতিক্রিয়ার জন্য অপেক্ষা করে।
test('can message service worker', async () => {
const page = await browser.newPage();
await page.goto(`chrome-extension://${EXTENSION_ID}/page.html`);
// Message without terminating service worker
await page.click('button');
await page.waitForSelector('#response-0');
});
আপনি npm start দিয়ে আপনার পরীক্ষাটি চালাতে পারেন এবং দেখবেন যে এটি সফলভাবে সম্পন্ন হয়েছে।
ধাপ ৪: পরিষেবা কর্মীকে বরখাস্ত করুন
নিম্নলিখিত হেল্পার ফাংশনটি যোগ করুন যা আপনার সার্ভিস ওয়ার্কারটি বন্ধ করে দেয়:
/**
* Stops the service worker associated with a given extension ID. This is done
* by creating a new Chrome DevTools Protocol session, finding the target ID
* associated with the worker and running the Target.closeTarget command.
*
* @param {Page} browser Browser instance
* @param {string} extensionId Extension ID of worker to terminate
*/
async function stopServiceWorker(browser, extensionId) {
const host = `chrome-extension://${extensionId}`;
const target = await browser.waitForTarget((t) => {
return t.type() === 'service_worker' && t.url().startsWith(host);
});
const worker = await target.worker();
await worker.close();
}
অবশেষে, নিম্নলিখিত কোড দিয়ে আপনার টেস্টটি আপডেট করুন। এখন সার্ভিস ওয়ার্কারটি বন্ধ করুন এবং আপনি কোনো প্রতিক্রিয়া পেয়েছেন কিনা তা পরীক্ষা করতে বাটনটিতে আবার ক্লিক করুন।
test('can message service worker when terminated', async () => {
const page = await browser.newPage();
await page.goto(`chrome-extension://${EXTENSION_ID}/page.html`);
// Message without terminating service worker
await page.click('button');
await page.waitForSelector('#response-0');
// Terminate service worker
await stopServiceWorker(page, EXTENSION_ID);
// Try to send another message
await page.click('button');
await page.waitForSelector('#response-1');
});
ধাপ ৫: আপনার পরীক্ষাটি চালান।
npm start চালান। আপনার টেস্টটি ফেইল করবে, যা নির্দেশ করে যে সার্ভিস ওয়ার্কারটি টার্মিনেট হওয়ার পর আর সাড়া দেয়নি।
ধাপ ৬: সার্ভিস ওয়ার্কারটি ঠিক করুন
এরপরে, টেম্পোরারি স্টেটের উপর নির্ভরতা দূর করে সার্ভিস ওয়ার্কারটিকে ঠিক করুন। রিপোজিটরিতে service-worker-fixed.js ফাইলে সংরক্ষিত নিম্নলিখিত কোডটি ব্যবহার করার জন্য টেস্ট-এক্সটেনশনটি আপডেট করুন।
service-worker-fixed.js:
browser.runtime.onInstalled.addListener(() => {
browser.storage.local.set({ version: browser.runtime.getManifest().version });
});
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
browser.storage.local.get('version').then((data) => {
sendResponse(data.version);
});
return true;
});
এখানে, সার্ভিস ওয়ার্কারের জীবনকাল জুড়ে স্টেটটি অক্ষুণ্ণ রাখতে আমরা ভার্সনটি একটি গ্লোবাল ভেরিয়েবলের পরিবর্তে browser.storage.local এ সেভ করি। যেহেতু স্টোরেজ শুধুমাত্র অ্যাসিঙ্ক্রোনাসভাবে অ্যাক্সেস করা যায়, তাই sendResponse কলব্যাকটি যেন সচল থাকে তা নিশ্চিত করতে আমরা onMessage লিসেনার থেকে true রিটার্ন করি।
ধাপ ৭: আপনার পরীক্ষাটি আবার চালান।
npm start দিয়ে পরীক্ষাটি আবার চালান। এবার এটি সফল হওয়ার কথা।
পরবর্তী পদক্ষেপ
এখন আপনি আপনার নিজের এক্সটেনশনেও একই পদ্ধতি প্রয়োগ করতে পারেন। নিম্নলিখিত বিষয়গুলো বিবেচনা করুন:
- আপনার টেস্ট স্যুটটি এমনভাবে তৈরি করুন যাতে এটি সার্ভিস ওয়ার্কারের অপ্রত্যাশিত টার্মিনেশন সহ বা ছাড়াই চলতে পারে। এরপর ব্যর্থতার কারণটি আরও স্পষ্ট করার জন্য আপনি উভয় মোড আলাদাভাবে চালাতে পারবেন।
- টেস্ট চলাকালীন সময়ে এলোমেলোভাবে সার্ভিস ওয়ার্কারকে বন্ধ করার জন্য কোড লিখুন। এটি এমন সব সমস্যা খুঁজে বের করার একটি ভালো উপায় হতে পারে, যা আগে থেকে অনুমান করা কঠিন।
- টেস্ট ব্যর্থতা থেকে শিখুন এবং ভবিষ্যতে সতর্কতামূলকভাবে কোড করার চেষ্টা করুন। উদাহরণস্বরূপ, গ্লোবাল ভেরিয়েবলের ব্যবহার নিরুৎসাহিত করতে একটি লিন্টিং নিয়ম যোগ করুন এবং ডেটাকে আরও স্থায়ী স্টেটে সরিয়ে নেওয়ার চেষ্টা করুন।