Background scripts

Фоновые скрипты (Background scripts) в контексте автоматизации браузера с Puppeteer представляют собой код, который выполняется не в основном потоке страницы, а в отдельном контексте браузера. Это позволяет осуществлять мониторинг, обработку событий и сбор данных, не влияя на визуальный рендер страницы. Такие скрипты особенно полезны при тестировании веб-приложений с асинхронными процессами или тяжелыми вычислениями.


Запуск фоновых скриптов через page.evaluateOnNewDocument

Метод page.evaluateOnNewDocument позволяет внедрять код, который будет выполняться до загрузки любой страницы, что обеспечивает возможность перехвата и модификации глобальных объектов, до того как JavaScript страницы начнет работу.

const puppeteer = require(&

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.evaluateOnNewDocument(() => {
    window._customLogger = function(message) {
      console.log("LOG:", message);
    };
  });

  await page.goto('https://example.com');
  await page.evaluate(() => {
    _customLogger("Страница загружена");
  });

  await browser.close();
})();

Ключевые моменты:

  • Фоновый скрипт выполняется перед всеми скриптами страницы.
  • Можно создавать глобальные объекты и функции для использования в основной логике теста.
  • Используется для перехвата сетевых запросов, изменения поведения стандартных API и внедрения вспомогательных утилит.

Использование сервис-воркеров и фоновых задач

Puppeteer позволяет работать с сервис-воркерами через контекст страницы. Для фоновых процессов, которые работают независимо от визуальной части страницы, важно учитывать:

  • browserContext.overridePermissions() — дает доступ к API, требующим разрешений.
  • page.waitForTarget() — позволяет отслеживать создание новых воркеров или окон.

Пример отслеживания сервис-воркера:

const browser = await puppeteer.launch();
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();

page.on('workercreated', worker => {
  console.log('Создан сервис-воркер:', worker.url());
});

await page.goto('https://example.com');

Особенности:

  • Событие workercreated срабатывает при старте любого воркера на странице.
  • Доступ к воркеру можно получить через worker.executionContext().
  • Позволяет тестировать фоновые задачи, не блокируя основную страницу.

Внедрение скриптов в фоновые процессы

Для полноценного тестирования фоновых задач важно запускать скрипты, которые работают параллельно с основным потоком. Puppeteer предоставляет несколько подходов:

  1. Через воркеры страницы:
const worker = await page.evaluateHandle(() => {
  return new Worker(URL.createObjectURL(new Blob([
    `self.onmess age = e => self.postMessage(e.data * 2);`
  ], { type: 'text/javascript' })));
});

// Отправка и получение сообщений
await worker.evaluate(w => w.postMessage(10));
  1. Через контекст браузера:
const context = await browser.createIncognitoBrowserContext();
const bgPage = await context.newPage();

await bgPage.evaluate(() => {
  setInterval(() => console.log('Фоновая проверка'), 1000);
});

Эти методы позволяют не зависеть от рендеринга страницы и тестировать поведение фоновых процессов в реальном времени.


Логирование и мониторинг фоновых скриптов

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

page.on('console', msg => {
  if (msg.type() === 'debug') {
    console.debug('DEBUG LOG:', msg.text());
  } else {
    console.log('LOG:', msg.text());
  }
});

Рекомендации:

  • Использовать разные уровни логов (debug, info, error) для разделения фоновой и основной информации.
  • При тестировании асинхронных задач подключать обработчики событий page.on(‘response’) и page.on(‘requestfailed’).
  • Хранить логи в отдельной структуре для последующего анализа.

Работа с асинхронными фоновыми процессами

Фоновые скрипты часто выполняют асинхронные операции: опрос API, обработку WebSocket-сообщений, таймеры. Для корректного тестирования этих процессов необходимо:

  • Ждать завершения фоновых задач с помощью Promise или page.waitForFunction().
  • Избегать гонок между основной страницей и фоновыми вычислениями.

Пример ожидания фона:

await page.evaluate(() => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('Фоновая задача завершена');
      resolve(true);
    }, 2000);
  });
});

Ограничения и особенности

  • Фоновые скрипты не имеют прямого доступа к DOM, если они выполняются в отдельном воркере.
  • Ограничение ресурсов браузера может замедлить выполнение фоновых задач при большом количестве воркеров.
  • Необходимо контролировать время жизни воркеров, чтобы избежать утечек памяти.

Фоновые скрипты в Puppeteer обеспечивают мощный инструмент для тестирования и мониторинга скрытых процессов веб-приложения, позволяя создавать надежные сценарии, которые проверяют асинхронное поведение и взаимодействие с внешними сервисами без вмешательства в визуальную часть страницы.