Puppeteer ile hizmet çalışanı feshini test etme

Bu kılavuzda, hizmeti test ederek daha sağlam uzantıların nasıl oluşturulacağı açıklanmaktadır. Puppeteer kullanarak çalışan feshi. Hizmet işçisinin sonlandırılması herhangi bir zamanda uyarı yapılmadan gerçekleşebileceğinden ve hizmet işçisindeki kalıcı olmayan durumların kaybedilmesine neden olabileceğinden, sonlandırma işlemini herhangi bir zamanda gerçekleştirmeye hazırlıklı olmak önemlidir. Sonuç olarak, uzantılar önemli durumu ve bir sorun olduğunda yeniden başlatılır başlatmaz istekleri bir etkinliktir.

Başlamadan önce

chrome-extensions-samples deposunu klonlayın veya indirin. /functional-samples/tutorial.terminate-sw/test-extension dosyasında, bir düğme her tıklandığında hizmet işleyiciye mesaj gönderen ve yanıt alınırsa sayfaya metin ekleyen test uzantısını kullanacağız.

Ayrıca, Puppeteer'ın üzerine inşa edildiği çalışma zamanı olan Node.JS'yi de yüklemeniz gerekir.

1. Adım: Node.js projenizi başlatın

Yeni bir dizinde aşağıdaki dosyaları oluşturun. Birlikte yeni bir Node.js projesi içeren ve Puppeteer test paketinin temel yapısını sağlayan Jest'i test koşucusu olarak kullanıyor. Bu kurulum hakkında daha fazla bilgi edinmek için Chrome Uzantıları'nı Puppeteer ile test etme başlıklı makaleyi inceleyin.

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

Testimizin test-extension dosyasını örnekler deposundan yüklediğini unutmayın. chrome.runtime.onMessage için işleyici, chrome.runtime.onInstalled etkinliği için işleyicide ayarlanan durumu kullanır. Bu nedenle, data içeriğinin Service Worker sonlandırıldığında ve gelecekte herhangi bir yanıt vermesi durumunda kaybolacak başarısız olur. Testimizi yazdıktan sonra bu sorunu düzelteceğiz.

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

2. Adım: Bağımlılıkları yükleyin

Gerekli bağımlılıkları yüklemek için npm install komutunu çalıştırın.

3. Adım: Temel bir test yazın

Aşağıdaki testi index.test.js sayfasının alt kısmına ekleyin. Bu işlem, testi açar. sayfasına yönlendirilir, düğme öğesini tıklar ve yanıt almayı bekler. hizmet çalışanıdır.

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');
});

Testinizi npm start ile çalıştırırsanız testin tamamlandığını görürsünüz bahsettik.

4. Adım: Hizmet çalışanını sonlandırın

Hizmet çalışanınızı sonlandıran aşağıdaki yardımcı işlevi ekleyin:

/**
 * 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();
}

Son olarak testinizi aşağıdaki kodla güncelleyin. Şimdi hizmeti sonlandırın bir yanıt alın ve yanıt alıp almadığınızı kontrol etmek için düğmeyi tekrar tıklayın.

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');
});

5. Adım: Testinizi çalıştırın

npm start çalıştır. Testiniz başarısız olacaktır. Bu durum, hizmet çalışanının özelliği sonlandırıldıktan sonra yanıt vermedi.

6. Adım: Hizmet çalışanını düzeltin

Ardından hizmet çalışanının geçici duruma bağlılığını kaldırarak sorunu düzeltin. test-extension uzantısını, depodaki service-worker-fixed.js klasöründe depolanan aşağıdaki kodu kullanacak şekilde güncelleyin.

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

Burada, sürümü genel değişken yerine chrome.storage.local değerine kaydederiz hizmet çalışanı ömürleri arasındaki durumu korumak için. Depolama alanına yalnızca eşzamansız olarak erişilebildiğinden, sendResponse geri çağırma işlevinin etkin kalmasını sağlamak için onMessage dinleyicisinden de true döndürürüz.

7. Adım: Testinizi tekrar çalıştırın

npm start ile testi tekrar çalıştırın. Artık başarılı olmalıdır.

Sonraki adımlar

Artık aynı yaklaşımı kendi uzantınıza uygulayabilirsiniz. Şunu göz önünde bulundurun: takip etmek için:

  • Beklenmedik hizmet ile veya beklenmedik hizmet olmadan çalışmayı destekleyecek test paketinizi oluşturun olabilir. Ardından, daha net hale getirmek için her iki modu da ayrı ayrı çalıştırabilirsiniz. bir hatanın nedeni olabilir.
  • Hizmet çalışanını bir testin rastgele noktalarında sonlandıracak kod yazın. Bu, tahmin edilmesi zor olabilecek sorunları keşfetmenin iyi bir yolu olabilir.
  • Başarısız testlerden ders çıkarın ve gelecekte savunma amaçlı kod yazın. Örneğin, genel değişkenlerin kullanımını caydırmak için bir linting kuralı ekleyin ve verileri daha kalıcı bir duruma taşımayı deneyin.