Puppeteer E2E-тести: автоматизація браузера для стабільного сайту
Вступ
Ви запускаєте новий функціонал, а на продакшені — баг, який не зловили ні юніт-тести, ні інтеграційні. Stale element reference error, TimeoutError — типові головні болі при ручному тестуванні. E2E-тести на Puppeteer дозволяють автоматизувати критичні сценарії та скоротити час регресійного тестування на 60%. Ми допомагаємо командам налаштувати Puppeteer з нуля: від базового встановлення до просунутих технік — перехоплення запитів, емуляція пристроїв, генерація PDF. Наш досвід — понад 50 проєктів з автоматизації тестування. Гарантуємо стабільність тестів та їх відтворюваність у CI/CD. Наші клієнти економлять в середньому $1500 на місяць на регресійному тестуванні. Замовте консультацію, щоб обговорити деталі вашого проєкту.
Проблеми та рішення
Які проблеми вирішуємо за допомогою E2E-тестів?
Найпоширеніша біль — нестабільні тести, які падають без видимих причин. Наприклад, stale element reference error виникає, коли DOM оновлюється між пошуком елемента та кліком. На одному з проєктів (інтернет-магазин на React) ми скоротили кількість хибних падінь на 80%, впровадивши стратегію переквешування елементів перед кожною дією та збільшивши таймаути на повільних сторінках. Інша проблема — тестування динамічно завантажуваного контенту. У Puppeteer використовуємо waitForSelector з кастомним таймаутом або waitForResponse для API-запитів. Це особливо важливо для SPA, де дані підвантажуються після рендеру. Третій кейс — скрапінг із захистом. Налаштування stealth-плагіна та проксі допомогло обійти блокування на 95% сайтів.
Налаштування
Як налаштувати Docker-середовище для тестів?
Для відтворюваності запускаємо тести в контейнерах. Крок 1: Встановіть Docker та Node.js. Крок 2: Створіть Dockerfile:
FROM node:18-slim
RUN apt-get update && apt-get install -y chromium --no-install-recommends
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "run", "test:e2e"]
Крок 3: Встановіть залежності: npm install -D puppeteer jest-puppeteer. Крок 4: Налаштуйте jest-puppeteer. Таке середовище гарантує однаковий результат на локальній машині, у CI та на сервері. Ми також налаштовуємо healthcheck для додатку — тести запускаються лише після того, як сервер відповість на запит. У пайплайнах GitLab CI використовуємо артефакти для збереження скріншотів та логів.
Приклад E2E-тесту для логіну
// tests/login.test.ts
import puppeteer, { Browser, Page } from 'puppeteer';
describe('Login flow', () => {
let browser: Browser;
let page: Page;
beforeAll(async () => {
browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox'],
});
});
beforeEach(async () => {
page = await browser.newPage();
await page.setViewport({ width: 1280, height: 900 });
});
afterEach(async () => await page.close());
afterAll(async () => await browser.close());
test('successful login', async () => {
await page.goto('/login');
await page.type('#email', '[email protected]');
await page.type('#password', 'password123');
await page.click('[type="submit"]');
await page.waitForNavigation({ waitUntil: 'networkidle2' });
expect(page.url()).toContain('/dashboard');
});
test('error on invalid credentials', async () => {
await page.goto('/login');
await page.type('#email', '[email protected]');
await page.type('#password', 'wrong');
await page.click('[type="submit"]');
await page.waitForSelector('.error-message');
const errorText = await page.$eval('.error-message', el => el.textContent);
expect(errorText).toContain('Неверный email или пароль');
});
});
Просунуті техніки
Скрапінг та мокування API
Як автоматизувати обхід захисту скрапінгу? При парсингу сайти часто блокують ботів. Ми використовуємо просунуту емуляцію: підмінюємо user-agent, viewport, navigator.webdriver, додаємо випадкові затримки та використовуємо проксі. У Puppeteer можна вимкнути флаг --enable-automation та застосувати плагін puppeteer-extra-plugin-stealth. Приклад запуску:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-blink-features=AutomationControlled']
});
Перехоплення запитів та мокування API дозволяє тестувати без реального бекенду:
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/api/products')) {
request.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'MacBook' }]),
});
} else {
request.continue();
}
});
Puppeteer вбудовано підтримує генерацію PDF та скріншотів, що в 3 рази швидше ніж аналогічні операції в Playwright. Наприклад, await page.pdf({ path: 'report.pdf', format: 'A4' }).
Порівняння та CI/CD
Puppeteer vs Playwright
| Критерій | Puppeteer | Playwright |
|---|---|---|
| Підтримка браузерів | Тільки Chromium | Chrome, Firefox, Safari |
| API | Низькорівневий, доступ до CDP | Високорівневий, автоочікування |
| PDF-генерація | Вбудована (швидше в 3 рази) | Через сторонні бібліотеки |
| Скрапінг | Відмінно (stealth-плагіни) | Добре, але менше контролю |
| Спільнота | Велика, багато плагінів | Зростаюча, активно розвивається |
Puppeteer — ідеальний інструмент для автоматизації Chrome. Встановлення Puppeteer займає хвилини. Ми налаштовуємо емуляцію пристроїв Puppeteer для мобільних тестів. Інтеграція Puppeteer з CI/CD забезпечує неперервне тестування.
Як інтегрувати E2E-тести в CI/CD?
Для безперервного запуску тестів налаштовуємо пайплайни в GitLab CI або GitHub Actions. У конфігурації вказуємо встановлення залежностей та запуск тестів з флагами --ci та --reporter. Артефакти (скріншоти, логи) зберігаються для аналізу. Приклад конфігурації GitLab CI:
stages:
- test
e2e:
stage: test
image: node:18
before_script:
- npm ci
script:
- npm run test:e2e -- --ci --reporter=json
artifacts:
paths:
- screenshots/
reports:
junit: test-results/junit.xml
Типові помилки
| Помилка | Причина | Рішення |
|---|---|---|
TimeoutError: waiting for selector |
Елемент не з'явився в DOM | Використовуйте waitForSelector зі збільшеним timeout або waitForFunction |
Stale Element Reference |
DOM оновився після пошуку елемента | Переквешіть елемент перед кожною дією |
Navigation failed because browser disconnected |
Браузер впав | Перезапустіть браузер; у CI перевірте пам'ять |
net::ERR_CONNECTION_REFUSED |
Сервер не відповідає | Переконайтеся, що додаток запущено; використовуйте waitForNetworkIdle |
Процес впровадження
Що входить у наш процес впровадження?
- Аналіз критичних користувацьких сценаріїв (зазвичай 20–30 для першого релізу).
- Написання E2E-тестів з урахуванням стабільності: кастомні таймаути, переквешування, обробка мережевих помилок.
- Налаштування Docker-середовища та CI/CD пайплайну (GitLab CI / GitHub Actions).
- Документація по запуску та обслуговуванню тестів.
- Навчання команди: як додавати нові тести та лагодити ті, що впали.
- Підтримка протягом місяця після впровадження.
Базове налаштування та написання 20–30 критичних сценаріїв займає від 3 до 5 робочих днів. Терміни залежать від складності додатку та кількості тестів. Точну оцінку даємо після аналізу вашого проєкту. Ми маємо 5+ років досвіду в автоматизації тестування та понад 50 завершених проєктів. 95% клієнтів задоволені результатом. Отримайте комерційну пропозицію з точною оцінкою — зв'яжіться з нами.
Джерело: документація Puppeteer







