В Puppeteer каждая страница (Page) создается через
экземпляр браузера и представляет собой отдельный контекст для
взаимодействия с веб-контентом. Правильное управление страницами
критично для оптимизации тестирования и снижения нагрузки на ресурсы,
особенно при запуске множества сценариев или в рамках параллельного
тестирования.
Стандартное создание страницы выглядит так:
const browser = await puppeteer.launch(); const page = await
browser.newPage(); await page.goto(&
При каждом вызове browser.newPage() создается новая
вкладка, что увеличивает потребление памяти и время запуска. В больших
тестовых наборах часто возникает необходимость переиспользовать
страницы, чтобы минимизировать накладные расходы.
Преимущества переиспользования страниц
-
Снижение времени запуска тестов. Создание новой
страницы требует инициализации контекста, загрузки ресурсов и скриптов.
Переиспользование существующей страницы позволяет сразу работать с
контентом.
-
Снижение потребления памяти. Каждая новая вкладка
занимает отдельный объект памяти, включая ресурсы браузера.
-
Сохранение состояния. Переиспользуемая страница может
хранить состояние сессии, cookies и localStorage, что удобно для
последовательных сценариев тестирования.
Реализация переиспользования страниц
На практике переиспользование можно реализовать несколькими способами:
-
Глобальная страница для тестового набора
let page;
beforeAll(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
afterAll(async () => {
await browser.close();
});
test('Проверка заголовка', async () => {
await page.goto('https://example.com');
const title = await page.title();
expect(title).toBe('Example Domain');
});
test('Проверка ссылки', async () => {
await page.goto('https://example.com');
const link = await page.$('a');
const href = await page.evaluate(el => el.href, link);
expect(href).toBe('https://www.iana.org/domains/example');
});
В этом примере одна страница используется для всех
тестов, что позволяет избежать повторного создания вкладок.
-
Пул страниц для параллельных тестов
При необходимости одновременного запуска нескольких тестов лучше создать
пул страниц и распределять их между тестовыми сценариями.
const pages = [];
const MAX_PAGES = 3;
beforeAll(async () => {
browser = await puppeteer.launch();
for (let i = 0; i < MAX_PAGES; i++) {
pages.push(await browser.newPage());
}
});
afterAll(async () => {
await browser.close();
});
async function getAvailablePage() {
return pages.shift(); // взять страницу из пула
}
async function releasePage(page) {
pages.push(page); // вернуть страницу в пул
}
Такой подход позволяет контролировать количество одновременно
используемых вкладок, сохраняя баланс между производительностью
и ресурсами.
Очистка состояния страницы
При повторном использовании важно сбрасывать состояние
страницы, чтобы тесты не влияли друг на друга:
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});
const client = await page.target().createCDPSession();
await client.send('Network.clearBrowserCookies');
Это гарантирует, что cookies и данные сессии не сохранятся между
тестами, что важно для изоляции сценариев.
Навигация и переиспользование
Страницу можно переиспользовать для перехода между различными URL без
закрытия вкладки:
await page.goto('https://example.com');
await page.waitForSelector('h1');
await page.goto('https://example.com/about');
await page.waitForSelector('h2');
Метод page.goto() автоматически очищает предыдущий контент
и выполняет загрузку нового, что позволяет использовать один объект
страницы для последовательных тестов.
Подводные камни
-
Неожиданное сохранение состояния. Если не очищать
cookies, localStorage или sessionStorage, тесты могут давать ложные
результаты.
-
Ошибки навигации. Переиспользуемая страница может
оставаться в «зависшем» состоянии после ошибки в предыдущем тесте.
Рекомендуется предусматривать механизм восстановления.
-
Проблемы с асинхронностью. При параллельной работе с
одной страницей необходимо синхронизировать доступ, иначе промисы могут
конфликтовать.
Советы по оптимизации
-
Использовать одну страницу на тестовый поток при
последовательных тестах.
-
Для параллельных сценариев — пул страниц фиксированного
размера, чтобы избежать перегрузки браузера.
-
Перед переиспользованием страницы очищать состояние,
чтобы тесты оставались независимыми.
-
Отслеживать ошибки навигации через
page.on(‘error’,
handler) и page.on(‘pageerror’, handler).
Переиспользование страниц в Puppeteer позволяет значительно повысить
эффективность тестирования, снизить нагрузку на ресурсы и ускорить
выполнение сценариев, при этом сохраняя контроль над состоянием и
стабильностью тестов.