Робочий процес із Playwright

Стабільне візуальне тестування Playwright у CI

Коротка відповідь

Playwright порівнює поточний знімок браузера зі збереженим базовим зображенням через `toHaveScreenshot()`. Для стабільного тесту треба зафіксувати проєкт браузера, розмір вікна, мову, часовий пояс і дані, а потім дочекатися видимого готового стану. CI має зберігати очікуване й поточне зображення, різницю та звіт для перевірки.

Перевірила команда RenderLogОновлено
Деталі запуску RenderLog із базовим знімком, поточним результатом, різницею і діями перевірки

Візуальну перевірку легко додати п'ятьма рядками коду, але вже за тиждень вона може почати випадково падати. Причина рідко ховається в самому порівнянні. Сторінку зняли з іншим шрифтом, живою ціною, випадковим кадром анімації, новим станом cookie або іншою збіркою браузера. Playwright робить ці приховані змінні помітними, але команда має взяти їх під контроль.

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

Зафіксуйте стан браузера до створення першого зразка

Використовуйте названі проєкти Playwright, а не поточний браузер розробника. Встановіть розмір вікна через профіль пристрою або точні розміри, задайте мову, часовий пояс і тему. У CI встановлюйте браузер і шрифти з тієї самої зафіксованої конфігурації, у якій погоджували базовий знімок. Зображення, створене на macOS, не повинно мовчки ставати зразком для Linux із відмінним рендерингом шрифтів.

Визначте місце для базових файлів. Зберігання в репозиторії робить зміни видимими в запиті на об'єднання і добре працює для помірного набору. Окреме сховище може бути зручнішим для великої матриці, але потребує версій і правил доступу. У будь-якому випадку тест має отримувати точний зразок для свого браузера й стану, а не останній файл із випадковою назвою.

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

Зробіть готовність видимою на самій сторінці

Стан `networkidle` не гарантує, що сторінка готова. Таймер може змінити DOM після завершення запитів, а шрифт може замінитися вже після першого малювання. Чекайте на заголовок, повний набір карток або спеціальний стан застосунку, який побачив би користувач. Тестова ознака готовності має означати завершений рендеринг, а не лише те, що JavaScript змонтував компонент.

Уникайте фіксованих пауз. Дві секунди марнуються, коли сторінка готова за 200 мілісекунд, і не рятують, коли CI потребує 2,2 секунди. Твердження Playwright повторюють перевірку до появи стану і пояснюють, чого саме не вистачає. Візуальне порівняння повинно запускатися після них, щоб відсутня картка спершу повідомлялася як відсутня картка, а не як незрозуміла різниця всієї сторінки.

  • Чекайте на заголовок, стабільний набір карток або ознаку готовності.
  • Перевірте критичний текст чи стан перед створенням знімка.
  • Вимкніть анімації через Playwright і тестові налаштування продукту.
  • Вважайте перевищення часу помилкою запуску, а не зміною зображення.

Керуйте даними, не вирізаючи поведінку, яку перевіряєте

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

Практичне правило просте: стабілізуйте вхідні дані поза межами рішення і збережіть реальними ті, що є частиною рішення. Зафіксуйте цю межу в назві тесту та короткому поясненні. Людина, яка бачить `pricing.png`, повинна розуміти, чи файл підтверджує виробничу ціну, верстку з тестовими даними або лише рендеринг статичного маршруту.

  • Підміняйте зовнішні дані лише тоді, коли не перевіряєте їхнє значення.
  • Називайте фікстури так, щоб було видно межі доказу.
  • Вузько маскуйте сторонні віджети замість великих ділянок.
  • Явно задавайте стан входу та згоди з cookie.

Встановлюйте поріг після перегляду справжніх невдач

Почніть зі строгого порівняння Playwright на зафіксованому середовищі. Запустіть незмінену сторінку кілька разів. Якщо результат нестабільний, огляньте різницю до зміни `maxDiffPixels` або `maxDiffPixelRatio`. Контури шрифтів означають проблему середовища, курсор чи перехід означає нестабільний стан, а великий рухомий блок вказує на живі дані або потребу в окремому тесті компонента.

Допуск має бути найменшим, що прибирає відому дрібну варіацію. Зміни порога варто перевіряти разом із кодом і пояснювати прикладом, який їх спричинив. Частка, безпечна для довгої сторінки, може повністю приховати помилку розміром із кнопку. Для критичного компонента краще додати окремий знімок, зберігши повну сторінку як ширший контекст.

  • Повторіть незмінений тест кілька разів до вибору допуску.
  • Усуньте відтворювані причини до прийняття піксельного шуму.
  • Перевіряйте зміни порога так само уважно, як виробничий код.
  • Для малих ризикових компонентів використовуйте точні знімки елементів.

Зберігайте всі результати невдачі, навіть коли CI зупиняє зміну

Якщо CI не зберіг поточне, очікуване зображення і різницю, людині доведеться відтворювати запуск локально. Завантажуйте звіт Playwright і каталог `test-results` після успіху та невдачі. Строк зберігання має бути довшим за звичайний час перевірки зміни. Додавайте назву проєкту й тесту до шляху, щоб не переплутати мобільний і настільний результати.

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

  • Завантажуйте HTML-звіт і вихідні зображення після невдачі.
  • Називайте файли за тестом і проєктом браузера.
  • Зберігайте їх достатньо довго для звичайного циклу перевірки.
  • Оновлюйте базові знімки окремо від змін продукту.

Передавайте публічну сторінку туди, де її справді переглядають

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

У такому випадку залиште компонентні й критичні перевірки в Playwright, а готову публічну адресу запускайте в RenderLog за розкладом або через API після випуску. Там власник бачить базове й поточне зображення, різницю, історію та може погодити зміну. Не переносіть один і той самий тест двічі: визначте, яка поверхня блокує код, а яка підтверджує стан опублікованої сторінки.

  • Playwright має блокувати зміни, що належать розробникам.
  • RenderLog може підтверджувати стан уже опублікованої сторінки.
  • Призначте людину, яка переглядає кожен тип результату.
  • Не дублюйте однаковий знімок без різних рішень після невдачі.

Як розібрати невдалий візуальний тест Playwright

Починайте не з оновлення знімка, а з форми різниці та стану запуску. Ця коротка таблиця допомагає відокремити середовище, сторінку й очікувану зміну.

ОзнакаЙмовірна причинаЩо перевіритиНаступна дія
Контури текстуШрифт або браузерВерсію образу, браузера і шрифтівВирівняти середовище до зміни порога
Зміщений великий блокДані, стан або версткаAPI, ширину вікна і готовністьВиправити стан або дослідити регресію
Порожня сторінкаПомилка запускуВідповідь сторінки, журнали і часВиправити запуск, не оновлювати зразок
Відома зміна макетаОчікувана змінаЗапит, дизайн і сусідні ділянкиПогодити точний новий базовий стан

Базове налаштування Playwright для знімків і результатів CI

Приклади показують порівняння, проєкт браузера, перевірку тарифів і збереження результатів. Замініть селектори й дані на справжній стан вашого продукту, а поріг обирайте лише після повторних запусків у тому самому CI.

playwright.config.ts

import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./tests/visual",
  expect: {
    toHaveScreenshot: {
      animations: "disabled",
      caret: "hide",
      maxDiffPixelRatio: 0.001
    }
  },
  use: {
    locale: "en-US",
    timezoneId: "UTC",
    colorScheme: "light"
  },
  projects: [
    { name: "desktop-chromium", use: { ...devices["Desktop Chrome"] } },
    { name: "mobile-chromium", use: { ...devices["Pixel 7"] } }
  ]
});

tests/visual/pricing.spec.ts

import { test, expect } from "@playwright/test";

test("pricing page", async ({ page }) => {
  await page.route("**/api/prices", async route => {
    await route.fulfill({ json: { plan: "Pro", price: 49 } });
  });
  await page.goto("https://example.com/pricing", { waitUntil: "networkidle" });
  await page.getByRole("heading", { name: "Pricing" }).waitFor();
  await expect(page).toHaveScreenshot("pricing.png", {
    fullPage: true,
    mask: [page.getByTestId("live-chat-launcher")]
  });
});

CI artifact handoff

npx playwright test --project=desktop-chromium
# Upload test-results/ and playwright-report/ even when the job fails.
# Send the public page to RenderLog when review must continue outside the repository.

Офіційна документація для реалізації

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

Далі за робочим процесом

Додайте один післявипускний знімок до наявного тесту

Залиште перевірку компонента в Playwright. Після розгортання запустіть збережену перевірку публічної сторінки в RenderLog і дайте продуктовому власнику переглядати зміни там, де видно всю історію.

Створити перевірку RenderLog