Panduan ini menjelaskan cara mem-build ekstensi yang lebih andal dengan menguji penghentian pekerja layanan menggunakan Puppeteer. Siap menangani penghentian kapan saja waktu adalah hal penting karena ini dapat terjadi tanpa peringatan yang mengakibatkan status non-persisten pekerja layanan hilang. Akibatnya, ekstensi harus menyimpan status penting dan dapat menangani permintaan segera setelah dimulai lagi ketika ada yang akan ditangani.
Sebelum memulai
Clone atau download repositori chrome-extensions-samples.
Kita akan menggunakan
ekstensi pengujian di
/functional-samples/tutorial.terminate-sw/test-extension
yang mengirim pesan
ke pekerja layanan setiap kali tombol diklik dan menambahkan teks ke halaman
apakah respons diterima.
Anda juga harus menginstal Node.JS yang merupakan runtime tempat Puppeteer dibuat.
Langkah 1: Mulai project Node.js Anda
Buat file berikut di direktori baru. Bersama-sama mereka membuat Project Node.js dan menyediakan struktur dasar rangkaian pengujian Puppeteer menggunakan Jest sebagai runner pengujian. Lihat Menguji Ekstensi Chrome dengan Puppeteer untuk mempelajari penyiapan ini secara lebih mendetail.
package.json:
{
"name": "puppeteer-demo",
"version": "1.0",
"dependencies": {
"jest": "^29.7.0",
"puppeteer": "^22.1.0"
},
"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,
args: [
`--disable-extensions-except=${EXTENSION_PATH}`,
`--load-extension=${EXTENSION_PATH}`
]
});
});
afterEach(async () => {
await browser.close();
browser = undefined;
});
Perhatikan bahwa pengujian kita memuat test-extension
dari repositori contoh.
Pengendali untuk chrome.runtime.onMessage
bergantung pada status yang ditetapkan dalam pengendali
untuk peristiwa chrome.runtime.onInstalled
. Akibatnya, konten data
akan hilang ketika pekerja layanan dihentikan dan merespons permintaan
pesan akan gagal. Kita akan memperbaikinya setelah menulis pengujian.
service-worker-broken.js:
let data;
chrome.runtime.onInstalled.addListener(() => {
data = { version: chrome.runtime.getManifest().version };
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
sendResponse(data.version);
});
Langkah 2: Instal dependensi
Jalankan npm install
untuk menginstal dependensi yang diperlukan.
Langkah 3: Tulis pengujian dasar
Tambahkan pengujian berikut ke bagian bawah index.test.js
. Tindakan ini akan membuka pengujian
dari ekstensi pengujian, mengklik elemen tombol, dan menunggu respons
dari pekerja layanan.
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');
});
Anda dapat menjalankan pengujian dengan npm start
dan akan melihat pengujian tersebut selesai
memulai proyek.
Langkah 4: Hentikan pekerja layanan
Tambahkan fungsi bantuan berikut yang menghentikan pekerja layanan Anda:
/**
* 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();
}
Terakhir, update pengujian Anda dengan kode berikut. Sekarang, hentikan pekerja layanan dan klik tombol lagi untuk memeriksa apakah Anda menerima respons.
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');
});
Langkah 5: Jalankan pengujian
Jalankan npm start
. Pengujian Anda akan gagal, yang menunjukkan bahwa pekerja layanan
tidak merespons setelah dihentikan.
Langkah 6: Perbaiki pekerja layanan
Selanjutnya, perbaiki pekerja layanan dengan menghilangkan ketergantungannya pada status sementara. Perbarui
ekstensi pengujian untuk menggunakan kode berikut, yang disimpan di
service-worker-fixed.js
di repositori.
service-worker-fixed.js:
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.local.set({ version: chrome.runtime.getManifest().version });
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
chrome.storage.local.get('version').then((data) => {
sendResponse(data.version);
});
return true;
});
Di sini, kita menyimpan versi ke chrome.storage.local
, bukan variabel global
untuk mempertahankan status di antara masa aktif pekerja layanan. Karena penyimpanan hanya dapat
diakses secara asinkron, kami juga menampilkan true (benar) dari pemroses onMessage
ke
pastikan callback sendResponse
tetap aktif.
Langkah 7: Jalankan lagi pengujian
Jalankan pengujian lagi dengan npm start
. Setelah itu, seharusnya berhasil.
Langkah berikutnya
Sekarang Anda dapat menerapkan pendekatan yang sama ke ekstensi Anda sendiri. Pertimbangkan berikut ini:
- Membuat paket pengujian agar dapat dijalankan dengan atau tanpa layanan tak terduga pemutusan hubungan kerja karyawan. Kemudian, Anda dapat menjalankan kedua mode satu per satu untuk memperjelas penyebab kegagalan.
- Tulis kode untuk menghentikan pekerja layanan pada titik acak dalam pengujian. Ini bisa menjadi cara yang baik untuk menemukan masalah yang mungkin sulit diprediksi.
- Belajarlah dari kegagalan uji dan coba buat kode secara defensif di masa mendatang. Sebagai misalnya, tambahkan aturan lint untuk mencegah penggunaan variabel global dan coba memindahkan data ke status yang lebih persisten.