اختبار إضافات Chrome باستخدام Puppeteer

توفّر Puppeteer إطار عمل لإنشاء اختبارات مبرمَجة للمواقع الإلكترونية، ويتضمّن أيضًا إمكانية اختبار إضافات Chrome. هذه اختبارات شاملة رفيعة المستوى تختبر وظائف موقع إلكتروني أو إضافة بعد تضمينها في المنتج النهائي. في هذا البرنامج التعليمي، سنوضّح كيفية كتابة اختبار أساسي لإحدى الإضافات من مستودع النماذج.

قبل البدء

استنسِخ مستودع chrome-extensions-samples أو نزِّله. سنستخدم العرض التوضيحي لواجهة برمجة التطبيقات الخاصة بالسجلّ في api-samples/history/showHistory كإضافة اختبارية.

عليك أيضًا تثبيت Node.JS، وهو وقت التشغيل الذي تم إنشاء Puppeteer عليه.

كتابة الاختبار

الخطوة 1: بدء مشروع Node.JS

علينا إعداد مشروع Node.JS أساسي. في مجلد جديد، أنشئ ملف package.json يتضمّن ما يلي:

package.json:

{
  "name": "puppeteer-demo",
  "version": "1.0"
}

على غرار ملف manifest.json الخاص بالإضافة، هذا الملف مطلوب من جميع مشاريع Node.

الخطوة 2: تثبيت Puppeteer وJest

نفِّذ الأمر npm install puppeteer jest لإضافة Puppeteer وJest كحزمتَين تابعتَين. ستتم إضافتها تلقائيًا إلى ملف package.json.

يمكن كتابة اختبارات مستقلة باستخدام Puppeteer، ولكننا سنستخدم Jest كأداة لتشغيل الاختبارات من أجل توفير بعض البنية الإضافية للرمز.

الخطوة 3: إنشاء نقطة دخول

أنشئ ملفًا جديدًا باسم index.test.js وأضِف الرمز التالي:

index.test.js:

const puppeteer = require('puppeteer');

const EXTENSION_PATH = '../../api-samples/history/showHistory';

let browser;
let worker;

beforeEach(async () => {
  // TODO: Launch the browser.
});

afterEach(async () => {
  // TODO: Close the browser.
});

الخطوة 4: تشغيل المتصفّح

عدِّل beforeEach وafterEach لتشغيل المتصفّح وإغلاقه. عند إجراء العديد من الاختبارات، ننصحك باستخدام المتصفّح نفسه. ومع ذلك، لا يُنصح بذلك بشكل عام لأنّه يقلّل من العزل بين الاختبارات وقد يتسبّب في أن يؤثّر أحد الاختبارات في نتيجة اختبار آخر.

index.test.js:

beforeEach(async () => {
  browser = await puppeteer.launch({
    headless: false,
    pipe: true,
    enableExtensions: [EXTENSION_PATH]
  });
});

afterEach(async () => {
  await browser.close();
  browser = undefined;
});

الخطوة 5: انتظار عامل خدمة الإضافة

علينا الانتظار إلى أن يبدأ عامل خدمة الإضافة لنتمكّن من استخدامه لاحقًا لفتح النافذة المنبثقة. عدِّل الدالة beforeEach باستخدام الرمز التالي:

beforeEach(async () => {
  browser = await puppeteer.launch({
    headless: false,
    pipe: true,
    enableExtensions: [EXTENSION_PATH]
  });

  const workerTarget = await browser.waitForTarget(
    // Assumes that there is only one service worker created by the extension
    // and its URL ends with service-worker.js.
    (target) =>
      target.type() === 'service_worker' &&
      target.url().endsWith('service-worker.js')
  );

  worker = await workerTarget.worker();
});

الخطوة 6: إضافة اسم مستعار

لتسهيل إجراء الاختبارات، أضِف اسمًا مستعارًا إلى ملف package.json:

package.json:

{
  "name": "puppeteer-demo",
  "version": "1.0",
  "dependencies": {
    "puppeteer": "^24.8.1"
  },
  "scripts": {
    "start": "jest ."
  }
}

سيؤدي ذلك إلى تشغيل جميع الملفات التي تنتهي بـ .test.js في الدليل الحالي.

الخطوة 7: فتح النافذة المنبثقة

أضِف اختبارًا أساسيًا. سنفتح أولاً صفحة جديدة ليكون هناك عنصر في سجلّ المتصفّح. بعد ذلك، سنفتح النافذة المنبثقة للاطّلاع على محتوى السجلّ. أضِف الرمز التالي:

index.test.js:

test('popup renders correctly', async () => {
  // Open a page to add a history item.
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Open the extension popup.
  await worker.evaluate('chrome.action.openPopup();');

  const popupTarget = await browser.waitForTarget(
    // Assumes that there is only one page with the URL ending with popup.html
    // and that is the popup created by the extension.
    (target) => target.type() === 'page' && target.url().endsWith('popup.html')
  );
});

الخطوة 8: تأكيد الحالة الحالية

تأكَّد من شيء ما، حتى يمكن أن تفشل اختباراتنا إذا لم تتصرف الإضافة على النحو المتوقع. نعلم أنّ النافذة المنبثقة يجب أن تعرض الصفحات التي تمت زيارتها مؤخرًا، لذا تحقّق من ظهور إحدى هذه الصفحات:

index.test.js:

test('popup renders correctly', async () => {
  // Open a page to add a history item.
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Open the extension popup.
  await worker.evaluate('chrome.action.openPopup();');

  const popupTarget = await browser.waitForTarget(
    // Assumes that there is only one page with the URL ending with popup.html
    // and that is the popup created by the extension.
    (target) => target.type() === 'page' && target.url().endsWith('popup.html')
  );

  const popup = await popupTarget.asPage();

  const list = await page.$('ul');
  const children = await list.$$('li');

  expect(children.length).toBe(1);
});

الخطوة 9: تنفيذ الاختبار

لإجراء الاختبار، استخدِم npm start. من المفترض أن تظهر لك نتائج تشير إلى أنّ الاختبار قد اجتاز بنجاح.

يمكنك الاطّلاع على المشروع الكامل في مستودع chrome-extensions-samples.

الخطوات التالية

بعد إتقان الأساسيات، جرِّب إنشاء مجموعة اختبارات للإضافة الخاصة بك. يحتوي مرجع واجهة برمجة التطبيقات الخاص بأداة Puppeteer على مزيد من المعلومات حول الإمكانات المتاحة، إذ تتوفّر العديد من الإمكانات التي لم يتم وصفها هنا.