Тестирование расширений

Puppeteer — это библиотека для управления браузером Chromium через высокоуровневый API. Она позволяет автоматизировать действия пользователя, проверять интерфейсы и проводить нагрузочное тестирование. В контексте расширений браузера Puppeteer становится мощным инструментом для имитации взаимодействия с расширениями, проверки их поведения и интеграции с веб-страницами.

Подготовка окружения

Для тестирования расширений необходимо запускать Chromium с указанием пути к расширению. В Puppeteer это реализуется через аргумент –disable-extensions-except и –load-extension.

Пример настройки:

const puppeteer = require(&

(async () => {
    const pathToExtension = '/path/to/extension';
    const browser = await puppeteer.launch({
        headless: false, // Расширения работают только в не-headless режиме
        args: [
            `--disable-extensions-except=${pathToExtension}`,
            `--load-extension=${pathToExtension}`
        ]
    });

    const page = await browser.newPage();
    await page.goto('https://example.com');

    // Дополнительные действия по взаимодействию с расширением
})();

Ключевой момент: расширения не загружаются в headless-режиме, поэтому тесты должны выполняться с видимым интерфейсом браузера.

Взаимодействие с интерфейсом расширения

Расширения могут иметь разные элементы: всплывающие окна (popup), фоновые страницы (background), контент-скрипты (content scripts). Puppeteer позволяет взаимодействовать с ними напрямую через селекторы или используя контекст страницы.

Popup:

const targets = await browser.targets();
const extensionTarget = targets.find(t => t.type() === 'background_page');
const backgroundPage = await extensionTarget.page();

// Взаимодействие с popup через page.evaluate
await backgroundPage.evaluate(() => {
    document.querySelector('#toggleButton').click();
});

Content scripts:

Контент-скрипты внедряются в веб-страницу. Их можно тестировать напрямую через объект page:

await page.evaluate(() => {
    const element = document.querySelector('#contentButton');
    element.click();
});

Мониторинг фоновых процессов

Расширения часто выполняют задачи в фоновом режиме, такие как обработка событий или работа с API. Для тестирования таких процессов Puppeteer предоставляет доступ к background pages.

Пример проверки фонового состояния:

const backgroundTarget = browser.targets().find(target => target.type() === 'background_page');
const backgroundPage = await backgroundTarget.page();

const result = await backgroundPage.evaluate(() => {
    return window.extensionState; // глобальное состояние расширения
});
console.log('Состояние расширения:', result);

Тестирование сообщений и событий

Механизм обмена сообщениями (chrome.runtime.sendMessage и chrome.runtime.onMessage) можно проверить с помощью Puppeteer, используя page.evaluate для имитации отправки сообщений и отслеживания ответов.

const response = await backgroundPage.evaluate(() => {
    return new Promise(resolve => {
        chrome.runtime.sendMessage({ action: 'getData' }, (reply) => {
            resolve(reply);
        });
    });
});
console.log('Ответ расширения:', response);

Особенность: тестирование сообщений важно для проверки взаимодействия между content scripts, popup и background scripts.

Проверка манипуляций с DOM

Расширения часто модифицируют DOM веб-страниц. Puppeteer позволяет проверять эти изменения и их последовательность.

await page.evaluate(() => {
    const newElement = document.querySelector('.new-element');
    return newElement ? newElement.textContent : null;
});

Можно комбинировать ожидания (page.waitForSelector) с проверкой значений:

await page.waitForSelector('.new-element');
const content = await page.$eval('.new-element', el => el.textContent);
console.log('Содержимое элемента:', content);

Работа с настройками расширений

Для некоторых расширений важно проверить сохранение и изменение настроек. Puppeteer позволяет взаимодействовать с chrome.storage через контекст background страницы:

await backgroundPage.evaluate(() => {
    chrome.storage.local.set({ theme: 'dark' });
});

const theme = await backgroundPage.evaluate(() => {
    return new Promise(resolve => {
        chrome.storage.local.get('theme', (data) => {
            resolve(data.theme);
        });
    });
});
console.log('Тема расширения:', theme);

Советы по организации тестов

  • Изоляция: каждый тест должен запускаться с чистым профилем браузера, чтобы исключить влияние предыдущих состояний.
  • Ожидания: для асинхронных процессов использовать waitForFunction или waitForSelector, чтобы тесты не прерывались преждевременно.
  • Логирование: важно сохранять логи background page и ошибок контент-скриптов для анализа.
  • Многократное тестирование: автоматическая перезагрузка страницы и повторное взаимодействие с расширением позволяет проверить стабильность.

Отладка тестов

Puppeteer предоставляет встроенные инструменты отладки:

  • headless: false + devtools: true для открытия DevTools.
  • page.screenshot() и page.pdf() для визуальной проверки.
  • console и page.on(‘console’) для отслеживания сообщений.
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
await page.screenshot({ path: 'popup.png' });

Эти подходы позволяют выявлять ошибки, связанные с DOM, асинхронными событиями или внутренними процессами расширения, до того как они проявятся в реальном использовании.

Тестирование расширений в CI/CD

Для интеграции с системами автоматизации тестирования используется запуск Puppeteer в контейнерах с предустановленным Chromium. Важно:

  • Установить нужные версии Chromium и Puppeteer.
  • Использовать не-headless режим с виртуальным дисплеем (например, Xvfb) для CI-сред.
  • Сохранять результаты тестов и скриншоты для анализа ошибок.

Это позволяет интегрировать тестирование расширений в процесс разработки, проверяя совместимость, корректность работы и стабильность функционала при изменениях кода.