Puppeteer E2E-тести: автоматизація браузера для стабільного сайту

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Puppeteer E2E-тести: автоматизація браузера для стабільного сайту
Середній
~5 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    956
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    947

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

Чому юніт-тести важливі, але не панацея?

Баг, знайдений юніт-тестом, коштує хвилини виправлення. Той самий баг у продакшені — години інциденту, компенсації та втрата довіри. На проекті інтернет-магазину помилка в розрахунку знижки пройшла ручне тестування, потрапила в прод і за 4 години обробила 37 замовлень за нульовою ціною. Автотест на граничні випадки розрахунку зловив би її при першому ж push. Оцініть свій проект — ми проведемо аудит поточного покриття і дамо рекомендації.

Jest — стандарт для JavaScript/TypeScript, але юніт-тести виправдані тільки там, де є ізольована логіка: функції трансформації, валідатори, бізнес-правила, утиліти. Тестувати React-компоненти через Jest + Testing Library правильно для поведінкових тестів: «кнопка з'являється після завантаження», «форма показує помилку при порожньому email». Снепшот-тести (toMatchSnapshot) — пастка: вони ламаються при будь-якій зміні верстки і стають шумом, який розробники оновлюють не дивлячись. Покриття коду (code coverage) — погана метрика якості: 80% coverage можна отримати тестами, які нічого не перевіряють. Coverage показує, що код виконався, а не те, що він працює правильно.

Критерій Jest Vitest
Швидкість для великих проектів Середня (Babel-трансформація) В 10–20 разів швидше (ES modules)
Інтеграція з Vite Через плагін Нативна
Монорепозиторії Вимагає конфігурації З коробки

Vitest як альтернатива Jest для Vite-проектів: в 10–20 разів швидше завдяки нативним ES modules без трансформації через Babel. Для монорепозиторіїв з тисячами тестів різниця у швидкості відчутна. Детальніше про юніт-тестування.

Як налаштувати E2E тести, які не будуть flaky?

Playwright обійшов Cypress за ключовими параметрами: нативна підтримка multi-tab, multi-origin, iframe; паралельне виконання на рівні тестів; WebKit, Firefox, Chromium з коробки; немає iframe для додатку — тести працюють в реальному браузері.

Playwright codegen записує дії та генерує тест — хороша точка старту, але згенерований код потрібно рефакторити. Локатори за text content крихкі: getByRole('button', { name: 'Оформить заказ' }) — стійкіше, ніж locator('.btn-primary').

Page Object Model — стандарт організації E2E тестів. Кожна сторінка — окремий клас з методами замість прямих локаторів. Коли кнопка переїхала з хедера в сайдбар — міняємо в одному місці, не шукаємо по всіх тестах.

Як уникнути flaky тестів? Типова проблема — flaky tests. Причини: race condition між запитом і рендером, анімації без очікування, залежність від зовнішніх API. Рішення: `page.waitForResponse()` замість `page.waitForTimeout()`, мокування зовнішніх API через `page.route()`.
// Погано
await page.click('#submit');
await page.waitForTimeout(2000);
await expect(page.locator('.success')).toBeVisible();

// Добре
await page.click('#submit');
await page.waitForResponse(resp =>
  resp.url().includes('/api/orders') && resp.status() === 201
);
await expect(page.getByRole('alert', { name: /заказ создан/i })).toBeVisible();

Наші інженери гарантують стабільність тестів у CI. Документація Playwright — основний інструмент на проектах з мільйонами користувачів.

Навантажувальне тестування з k6

k6 — інструмент для навантажувального тестування з JavaScript API. Сценарії пишуться як код, версіонуються в git, запускаються в CI. Три основних сценарії:

  • Spike test — різке зростання навантаження: 0 → 1000 користувачів за 30 секунд. Імітує запуск рекламної кампанії. Показує здатність системи реагувати на піки.
  • Soak test — стабільне навантаження на 2–4 години. Виявляє memory leaks, connection pool exhaustion, деградацію продуктивності.
  • Stress test — навантаження вище розрахункової (150–200% від очікуваного піку). Показує точку відмови та graceful degradation.

Порогові значення:

thresholds: {
  http_req_duration: ['p95<500', 'p99<1000'],
  http_req_failed: ['rate<0.01'],
}

p95 < 500ms означає: 95% запитів відповідають швидше півсекунди. Якщо поріг не виконується — k6 завершується з кодом помилки, CI-пайплайн падає.

На одному проекті інтернет-магазину ми виявили деградацію API на 4-й годині тесту: p95 зріс з 200ms до 2s через витік з'єднань. Після оптимізації клієнт заощадив значну суму на інцидентах та зайвих ресурсах. Отримайте аналогічний аудит вашого проекту — замовте навантажувальне тестування.

Як Core Web Vitals впливають на ранжування?

Google використовує Core Web Vitals у ранжуванні. Lighthouse CLI в CI-пайплайні: при кожному деплої перевіряємо, що LCP < 2.5s, CLS < 0.1, INP < 200ms. Детальніше про веб-продуктивність. Реальні проблеми, які Lighthouse знаходить:

  • Hero image без атрибутів width/height: CLS 0.35 при завантаженні.
  • JavaScript-бандл 2.1MB синхронно блокує парсинг: INP 450ms.
  • Шрифти без font-display: swap: невидимий текст до завантаження шрифту (FOIT).
  • Неоптимізований hero image 4MB: LCP 8.2s.

Lighthouse CI (lhci) зберігає історію метрик і надсилає коментар до PR з деградацією. За даними Google, 53% користувачів залишають сайт при завантаженні довше 3 секунд — наші тести запобігають таким втратам.

Піраміда тестування в проекті

Рівень Інструмент Кількість Швидкість
Юніт Vitest/Jest Багато (тисячі) <5 хв
Інтеграція Vitest + supertest Середня 5–15 хв
E2E Playwright Мало (happy path) 10–30 хв
Навантаження k6 За розкладом 30–60 хв
Продуктивність Lighthouse CI При кожному деплої 5 хв

Що входить в роботу?

  • Аудит поточного покриття та визначення критичних user flows.
  • Написання unit-тестів для ключової бізнес-логіки, інтеграційних тестів для API, E2E для сценаріїв користувача.
  • Налаштування паралельного виконання в CI (sharded workers для Playwright).
  • Навантажувальне тестування зі звітом та рекомендаціями.
  • Документація за тест-кейсами, навчання вашої команди роботі з тестами.
  • Гарантійна підтримка 1 місяць після впровадження.

Процес роботи

  1. Аналітика — аудит поточного тестування, виявлення слабких місць, визначення пріоритетів.
  2. Проектування — вибір інструментів, написання тест-плану, узгодження.
  3. Реалізація — написання тестів, інтеграція в CI.
  4. Тестування — прогін всіх рівнів, аналіз результатів, виправлення помилок.
  5. Деплой — запуск в прод, моніторинг метрик, навчання команди.

Терміни

Налаштування повного тест-пайплайна (Jest + Playwright + k6 + Lighthouse CI) з нуля: 2–4 тижні. Покриття E2E-тестами існуючого проекту (20–30 сценаріїв): 3–6 тижнів. Навантажувальне тестування зі звітом та рекомендаціями: 1–2 тижні. Вартість розраховується індивідуально після аудиту.

Готові обговорити ваш проект? Залиште заявку — ми проведемо аудит поточного тестування безкоштовно і запропонуємо план з економією до 60% часу на інциденти. Отримайте консультацію з тестування веб-додатків — напишіть нам.