vyvchy
    Теми розділу

    07 · Інструменти автоматизації

    Візуальне тестування: скріншот-порівняння

    Зміст

    Функціональний носить очікування в собі: toHaveText('Оплачено') можна прочитати очима й зрозуміти, що саме перевіряється. Візуальний асерт натомість віддає очікування у PNG-файл, який ніхто не читає — і саме тому він одночасно найдешевший у написанні й найдорожчий у супроводі. Один рядок коду ловить те, чого не побачить звичайний функціональний асерт: зʼїхала верстка на 8 пікселів, кнопка стала того самого кольору, що фон, іконка зникла, хоч у DOM вона є. Той самий рядок коду через місяць червоніє на кожному прогоні, бо в CI інші шрифти.

    Главу можна пропустити при першому проході — повернетеся, коли візуальні тести реально зʼявляться у вашому проєкті. Але це єдине повне місце на сайті, де розібрано механізм: інші глави лінкують сюди. Читати варто не заради формулювань, а заради розуміння, чому «просто підняти поріг» майже ніколи не працює.

    Що таке візуальне тестування і чому це не «ще один асерт»

    (visual testing) — порівняння знімка інтерфейсу з раніше затвердженим (baseline screenshot). Механіка зводиться до трьох кроків: зняти, порівняти, показати різницю на рівні пікселів.

    Ключове слово в означенні — затвердженим. Технічно це асерт; організаційно — процес затвердження змін, і саме друга половина визначає, працює перевірка чи заважає. Причина в тому, що очікування живе не в коді, а у бінарному файлі: функціональний асерт ревʼюїться в за пʼять секунд, а змінений еталон у діфі виглядає просто як «змінився PNG».

    Друга особливість: візуальний асерт не знає слова «правильно». Він знає лише «так само, як раніше». Кнопка може бути на місці, того самого кольору й розміру — і не працювати. Тому візуальні перевірки не замінюють функціональні, а закривають інший клас дефектів: непередбачені візуальні відхилення, які функціональний асерт мовчки пропускає.

    Механіка порівняння: перший прогін, ретрай, pixelmatch

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

    Той самий механізм працює і в самому асерті: toHaveScreenshot чекає, доки два послідовні знімки сторінки дадуть однаковий результат, і лише тоді порівнює останній з еталоном. Це вбудований захист від зйомки посеред довантаження чи анімації. Візуальний асерт — звичайний ретрайний асерт із власним (за замовчуванням — таймаут асертів із конфігу); його можна скасувати сигналом, і скасування виглядає як таймаут. розібрана в главі «Playwright: перевірки і автоочікування».

    import { test, expect } from '@playwright/test';
    
    test('головна сторінка не змінилася візуально', async ({ page }) => {
      await page.goto('/');
      await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
      await expect(page).toHaveScreenshot('home.png');
    });

    Порівняння виконує бібліотека pixelmatch, а її опції задаються двома шляхами: у самому асерті або в конфізі — глобально чи на окремий проєкт. Формат зберігання за замовчуванням — PNG; WebP вмикається розширенням у назві еталона й теж без втрат.

    Ні

    Так

    Так

    Ні

    Візуальний асерт

    Еталон уже існує?

    Серія знімків,
    доки два послідовні не збіжаться

    Останній зберігається як еталон

    Серія знімків,
    доки два послідовні не збіжаться

    pixelmatch порівнює останній з еталоном

    У межах порогів?

    Асерт пройшов

    Асерт упав

    Ні

    Так

    Так

    Ні

    Візуальний асерт

    Еталон уже існує?

    Серія знімків,
    доки два послідовні не збіжаться

    Останній зберігається як еталон

    Серія знімків,
    доки два послідовні не збіжаться

    pixelmatch порівнює останній з еталоном

    У межах порогів?

    Асерт пройшов

    Асерт упав

    Три різні пороги, які всі називають одним словом

    «Ми поставили поріг 0.2» — фраза, яка нічого не означає, поки не сказано, поріг чого. Опцій три, і вони про різні речі.

    ОпціяЩо обмежуєДіапазон і дефолт
    thresholdсприйняту різницю кольору одного пікселя в просторі YIQвід 0 (строго) до 1 (вільно), за замовчуванням 0.2
    maxDiffPixelRatioчастку різних пікселів від їхньої загальної кількостівід 0 до 1, за замовчуванням не задана
    maxDiffPixelsабсолютну кількість різних пікселівчисло, за замовчуванням не задане

    Чому це важливо на практиці. threshold лікує лише «той самий піксель став трохи іншого відтінку» — типово це згладжування шрифту або субпіксельний рендеринг. Якщо блок зʼїхав на два пікселі, різними стають пікселі по всій його площі — для великого блоку з текстом це легко десятки тисяч, — і багато з них різні сильно: там, де була темна літера, тепер світлий фон. Тут threshold не той важіль: підняти його до значень, які сильну різницю кольору, означає майже перестати перевіряти колір узагалі. Потрібна інша опція: частка або абсолютна кількість.

    Дзеркальна пастка теж є. Дефолт «частка не задана» означає, що з коробки різниця не допускається зовсім: одного помітно іншого пікселя достатньо, щоб асерт упав. Тому візуальні тести на живому продукті починаються з підбору цих двох чисел — свідомого, з розумінням, який клас відхилень ви щойно дозволили пропускати.

    Динамічні зони: маска, стайлшит, анімації, час

    Будь-яка сторінка має ділянки, які змінюються самі: годинник, «оновлено 3 хвилини тому», аватарки з CDN, карусель, реклама. Їх треба або прибрати зі знімка, або зробити детермінованими.

    Маска. Найпоширеніший інструмент — і найчастіше не так зрозумілий. Замаскований елемент перекривається суцільним прямокутником (типово рожевим #FF00FF, колір налаштовується), який повністю накриває його bounding box. Це заливка у самому знімку, а не виріз із порівняння. Наслідок практичний: маска ховає вміст елемента, але не ховає розмір його рамки — якщо блок зі змінним текстом змінить висоту, залита область теж змінить висоту, і діф зʼявиться. Маска накладається й на невидимі елементи.

    Стайлшит на час знімка. Штатний спосіб ховати динаміку — власний CSS, який діє лише під час зйомки: сховати елемент, зробити невидимим, змінити властивість. Дві його важливі властивості: він проходить крізь Shadow DOM і діє на вкладені фрейми, тобто дістає туди, куди звичайний CSS сторінки не дістає.

    await expect(page).toHaveScreenshot('dashboard.png', {
      mask: [page.getByTestId('last-updated'), page.getByRole('img', { name: 'Аватар' })],
      stylePath: './tests/screenshot.css',
      maxDiffPixelRatio: 0.01,
    });

    Анімації вимкнені за замовчуванням — це один із найкорисніших дефолтів, про який мало хто знає. Опція глушить CSS-анімації, CSS-переходи й Web Animations, причому по-різному залежно від тривалості: скінченні перемотуються до кінця (тому подія transitionend таки спрацює), нескінченні скасовуються до початкового стану й програються після знімка. З цього переліку є важливий висновок: рух, зроблений іншим способом — наприклад, таймером, що щокадру править стилі, — у названий перелік не входить, тож і не глушиться.

    Текстова каретка теж ховається за замовчуванням — інакше блимання курсора в полі давало б різницю між двома знімками того самого стану.

    Час. Дата на екрані — це не візуальна проблема, а проблема детермінізму: маскувати її можна, але чесніше зафіксувати годинник сторінки. перевизначає Date, таймери, requestAnimationFrame і performance, а ставити її треба перед будь-якими іншими викликами, повʼязаними з часом, — інакше поведінка невизначена. Детально — у главі «Боротьба з флаком засобами інструмента».

    Чому еталони ламаються без жодної зміни коду

    Це головне джерело розчарування у візуальних тестах, і воно задокументоване, а не містичне. Рендеринг браузера залежить від ОС хоста, її версії, налаштувань, заліза, джерела живлення (батарея проти адаптера), headless-режиму та інших факторів. Припис доки з цього прямий: ганяти тести в тому самому середовищі, де згенеровано еталон.

    Окремо названо різницю між браузерами й платформами: знімки різняться через інший рендеринг, інші шрифти та інше — тому під кожну комбінацію потрібні окремі еталони. Саме тому в імені файлу еталона стоїть суфікс на кшталт chromium-darwin, а якщо в конфізі є проєкти, замість імені браузера туди йде імʼя проєкту. Набір еталонів множиться на матрицю конфігурацій. Кросбраузерність і адаптивність як явище розібрані в главі «Кросбраузерність і адаптивна верстка», а матриця проєктів — у главі «Playwright: фікстури, хуки і конфігурація».

    Далі накладається CI. Кожен прогін іде на свіжій, щойно розгорнутій віртуальній машині; браузери за замовчуванням запускаються в headless-режимі, а на Linux-агентах для headed потрібен встановлений Xvfb. Офіційний Docker- містить браузери й системні залежності браузерів — а шрифти якраз серед названих факторів різниці.

    Звідси класичний сценарій: еталон знято на macOS, тест ганяється в Linux- — і не проходить. Із дефолтним іменуванням падіння приходить навіть не діфом, а відсутнім еталоном: у файлі стоїть chromium-darwin, а прогін шукає файл своєї платформи. Справжній піксельний діф зʼявляється там, де платформа в імені збігається, а середовища — ні: свій Ubuntu проти образу CI з іншим набором шрифтів. Жоден із двох випадків не — це інше середовище рендерингу, і перезапуск його не змінить.

    ФакторЩо з ним робити
    ОС, версія, залізо, джерело живленнягенерувати еталони в тому самому середовищі, де прогін
    браузер і платформа (шрифти, рендеринг)окремий набір еталонів під кожну комбінацію
    проєкти в конфізіімʼя проєкту в назві файлу; шаблон шляху налаштовується окремо
    headless проти headedне змішувати: це різні умови рендерингу

    Практичний висновок один: еталони генерують у тому самому образі, у якому їх потім порівнюють. Локально це означає прогін оновлення знімків у контейнері, а не на своєму ноутбуці. Контейнеризація тестового середовища й CI-специфічні причини падінь — тема розділу про Git і CI/CD.

    Оновлення еталонів: процес, а не прапорець

    Технічно оновлення еталона — окремий прогону (--update-snapshots). Написати його — секунда, і саме тут візуальні тести найчастіше вмирають.

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

    Тому робоча схема виглядає так, і в ній важливі всі три умови:

    1. Діф дивиться людина. Не «тест впав», а «ось що змінилося на екрані» — і рішення «так, ми цього хотіли» або «ні, це баг».
    2. Оновлення еталона їде в тому самому пул-реквесті, що й зміна, яка його спричинила. Окремий «update snapshots» без коду поруч — це вже втрачений контекст.
    3. Прапорець не живе в CI-скрипті. Автоматичне оновлення еталонів на кожному прогоні перетворює перевірку на запис факту.

    Зовнішні сервіси: що вони додають до порівняння

    Файли-еталони в репозиторії — не єдина модель. Є клас зовнішніх сервісів візуального тестування, і механіку тут розберемо на Percy, чия довідка описує саме процес ревʼю еталонів.

    Сервіс робить чотири речі: знімає сторінки в наборі браузерів і на кількох адаптивних ширинах для десктопа й мобільних; порівнює нові знімки з раніше схваленими; показує різницю на рівні пікселів; веде схвалення через UI. Знімки при цьому збираються під час звичайного прогону тестів — окремого «візуального прогону» тут немає.

    Головна відмінність від файлів у репо — де живе еталон. Схвалені знімки переносяться в наступні гілки, а базовий білд для порівняння сервіс обирає сам. Схвалювати можна окремий знімок, групу або весь білд, і — якщо репозиторій підключено — результат стає статусом пул-реквесту або коміту. Дві деталі, які варто знати до впровадження:

    • для головної гілки дефолт — автосхвалення всіх змін, тобто без налаштування гілка-джерело істини приймає зміни сама;
    • достатньо одного знімка з позначкою «запит змін», щоб статус змінився в усього білду; позначка тримається, доки діф збігається з початковим, а щойно діф змінився — стан скидається в «не переглянуто».
    АспектЕталони у репозиторіїЗовнішній сервіс
    Де живе еталонPNG-файли в гілцісхвалений знімок у системі, переноситься між білдами
    Оновленняпрапорець прогонусхвалення в UI
    Ревʼю різницідіф бінарників у пул-реквестіокремий екран порівняння
    Матриця браузерів і ширинваша, з окремим набором файлів на комбінаціюна боці сервісу
    Гейтпадіння тестустатус пул-реквесту

    Немає

    Є

    Схвалено

    Запит змін

    Звичайний прогін тестів у CI

    Знімки їдуть у сервіс

    Є діф із базовим білдом?

    Білд без змін

    Ревʼю людиною в UI

    Знімок переноситься
    в наступні білди гілки

    Статус усього білду
    стає таким самим

    Статус пул-реквесту оновлено

    Немає

    Є

    Схвалено

    Запит змін

    Звичайний прогін тестів у CI

    Знімки їдуть у сервіс

    Є діф із базовим білдом?

    Білд без змін

    Ревʼю людиною в UI

    Знімок переноситься
    в наступні білди гілки

    Статус усього білду
    стає таким самим

    Статус пул-реквесту оновлено

    Що покривати візуально

    Питання «що покривати» тут вирішується не цінністю перевірки, а ціною супроводу: кожна нова комбінація браузер × платформа × проєкт — це ще один набір еталонів, який хтось мусить ревʼювати щоразу, коли інтерфейс змінюється. Тому візуальні перевірки — інструмент точковий, а не наскрізний.

    З механізму випливають робочі критерії:

    • Стабільні екрани й компоненти, а не флоу. Знімок наскрізного сценарію з десяти сторінок дасть десять еталонів, які ламаються разом; один знімок компонента дає локалізовану причину падіння.
    • Те, чого не бачить функціональний асерт. Верстка, відступи, кольори, стани компонентів (наведення, помилка, порожній стан), теми оформлення — там, де перевіряти текстом нічого.
    • Мінімум динаміки в кадрі. Кілька ділянок, які треба маскувати чи глушити стайлшитом, — сигнал звузити кадр до компонента або відмовитись від візуальної перевірки цього екрана.
    • Одна комбінація для старту. Матрицю браузерів і ширин розширюють після того, як одна комбінація стабільно зелена, а не одразу.

    І межа, яку варто проговорити вголос: візуальна перевірка не є перевіркою доступності, продуктивності чи логіки. Вона відповідає рівно на одне питання — «чи виглядає це так, як ми затвердили».

    Типові помилки

    • «Підняли threshold до 0.5, а діф усе одно є»threshold — про сприйняту різницю кольору одного пікселя, а не про кількість різних пікселів. Блок, що зʼїхав на два пікселі, дає стільки сильно різних пікселів, скільки в ньому вмісту; тут потрібні частка або абсолютне число.
    • «Замаскував таймер — зона більше не порівнюється» → маска це заливка рамки суцільним кольором у самому знімку, а не виріз із порівняння. Вміст сховано, розмір рамки — ні: змінилася висота блоку, змінилася й залита область.
    • «Знімок зняв кадр посеред анімації» → асерт чекає збігу двох послідовних знімків, а CSS-анімації, CSS-переходи й Web Animations вимкнені за замовчуванням. Якщо кадр усе одно проміжний, шукайте рух, зроблений не цими трьома способами: у названий перелік він не входить.
    • «Курсор блимає в полі — треба маскувати» → каретка ховається за замовчуванням; якщо ви бачите її в діфі, поведінку хтось змінив явно.
    • «Еталон із мого макбука не пройшов у CI — це флак, перезапустимо» → залежність рендерингу від ОС і шрифтів задокументована. Це не випадковість, а інше середовище, і перезапуск джоби на тому самому образі агента дасть той самий результат. Перше, що варто перевірити, — чи еталон під платформу CI взагалі існує: у назві файлу стоїть платформа, тож знімок із macOS у Linux навіть не буде з чим порівнювати.
    • «Оновив еталони, стало зелено — інцидент закритий» → якщо різницю ніхто не подивився, ви щойно затвердили як норму те, що приїхало. Через кілька ітерацій еталон описує випадковий стан, включно з реальною регресією.
    • «Візуальний тест перевірить, що сторінка працює» → він порівнює пікселі з попередньою затвердженою картинкою. Кнопка може бути ідеальною на вигляд і не надсилати запит.
    • «Підключили сервіс — тепер зміни не проскочать» → для головної гілки дефолт — автосхвалення. Без налаштування вона приймає зміни сама.

    Підсумок

    • Візуальне тестування — це асерт плюс процес затвердження. Очікування живе у файлі, а не в коді, тому без ревʼю діфа перевірка перетворюється на журнал того, що вже сталося.
    • Порогів три, і вони про різне. threshold — колір одного пікселя в YIQ (дефолт 0.2), частка різних пікселів і абсолютне їхнє число — окремі опції, за замовчуванням не задані.
    • Еталон привʼязаний до середовища. Браузер, платформа, шрифти, headless-режим, проєкт у конфізі — кожна комбінація має власний набір файлів, і генерувати їх треба там, де вони потім порівнюються.
    • Динаміку прибирають детермінізмом, а не порогом. Анімації й каретка вимкнені за замовчуванням, стайлшит ховає нестабільні елементи й проходить крізь Shadow DOM, час фіксують підміною годинника. Маска — заливка рамки, не виріз із порівняння.
    • Покривати варто точково. Стабільні екрани й компоненти з мінімумом динаміки, одна комбінація на старт; ціна теми — не написання асерту, а ревʼю еталонів на кожній зміні інтерфейсу.

    Можливі питання

    • «Що таке візуальне тестування і коли воно виправдане?» — інтервʼюер слухає, чи ви назвете обидві половини: порівняння з раніше затвердженим знімком і процес затвердження змін. Відповідь «це коли ми порівнюємо скріншоти» вважається половиною.
    • «Що означає threshold: 0.2 — перевірка на те, чи людина читала доку. Сильна відповідь: це допустима сприйнята різниця кольору одного пікселя в YIQ, а не частка різних пікселів — для неї є окремі опції, і вони за замовчуванням не задані.
    • «Скріншотний тест зелений локально й червоний у CI. Що робиш?» — оцінюють порядок розбору, а не здогад. Очікують: спершу перевірити, чи еталон знімався в тому самому середовищі (ОС, образ, шрифти, headless-режим), і лише потім говорити про пороги. «Перезапущу джобу» тут читається як нерозуміння механізму.
    • «Як покрити сторінку з годинником і каруселлю?» — хочуть почути набір інструментів, а не один: маска на динамічні зони, стайлшит на час знімка, вимкнені анімації, підміна часу для дати. Бонус — уточнення, що маска не виріз, а заливка.
    • «Як у вашій команді оновлюються еталони?» — найінформативніше питання теми, бо відповідь показує реальний процес. «Ганяємо з прапорцем оновлення, коли впало» — червоний прапорець; «діф ревʼюїть людина, оновлення їде в тому самому пул-реквесті» — те, що хочуть почути.
    • «Чим зовнішній сервіс кращий за PNG у репозиторії?» — чекають конкретики: еталон живе в процесі схвалення й переноситься між білдами гілки, схвалення стає статусом пул-реквесту, матриця браузерів і ширин — на боці сервісу. Плюс чесна ціна: залежність від зовнішньої системи й дефолтне автосхвалення головної гілки.

    Джерела

    Що таке візуальне тестування і чому це не «ще один асерт»

    • Playwright — Visual comparisons (test snapshots) — на першому прогоні генеруються референсні знімки, далі кожен прогін порівнюється з ними.
    • Percy (BrowserStack Docs) — Visual Testing with Percy — еталон це раніше схвалений знімок; сервіс підсвічує непередбачені візуальні відмінності на рівні пікселів і вимагає явного схвалення людиною.

    Механіка порівняння: перший прогін, ретрай, pixelmatch

    • Playwright — Visual comparisons (test snapshots) — генерація еталона на першому прогоні, серія знімків до збігу двох послідовних, порівняння через pixelmatch, опції в тесті й у конфізі (глобально або на проєкт), PNG за замовчуванням і WebP через розширення.
    • Playwright — API: PageAssertionstoHaveScreenshot чекає збігу двох послідовних знімків, має власний таймаут і скасовується сигналом (скасування виглядає як таймаут).

    Три різні пороги, які всі називають одним словом

    • Playwright — API: PageAssertionsthreshold як сприйнята різниця кольору одного пікселя в YIQ (01, дефолт 0.2), частка різних пікселів як окрема опція, не задана за замовчуванням, і абсолютне число різних пікселів поруч.
    • Playwright — Visual comparisons (test snapshots) — опції pixelmatch задаються в тесті або в конфізі, глобально чи на проєкт.

    Динамічні зони: маска, стайлшит, анімації, час

    • Playwright — API: PageAssertions — маска як перекриття bounding box суцільним кольором (#FF00FF за замовчуванням, налаштовний) і її дія на невидимі елементи; стайлшит на час знімка, що проходить крізь Shadow DOM і діє на вкладені фрейми; анімації вимкнені за замовчуванням із різним поводженням для скінченних і нескінченних; каретка ховається за замовчуванням.
    • Playwright — Visual comparisons (test snapshots) — власний стайлшит під час зйомки відфільтровує динамічні або нестабільні елементи й так підвищує детермінованість знімка.
    • Playwright — Clock — підміняються Date, таймери, requestAnimationFrame і performance; установка годинника мусить стояти перед іншими викликами, повʼязаними з часом, інакше поведінка невизначена.

    Чому еталони ламаються без жодної зміни коду

    • Playwright — Visual comparisons (test snapshots) — залежність рендерингу від ОС, версії, налаштувань, заліза, джерела живлення й headless-режиму; припис ганяти тести в тому самому середовищі, де знято еталон; різниця між браузерами й платформами через рендеринг і шрифти; суфікс chromium-darwin, імʼя проєкту в назві файлу й налаштовний шаблон шляху.
    • Playwright — Continuous Integration — браузери за замовчуванням у headless-режимі; headed на Linux-агентах вимагає Xvfb, який уже є в офіційному образі й GitHub Action.
    • GitHub Docs — Understanding GitHub Actions — кожен прогін воркфлоу іде на свіжій, щойно розгорнутій віртуальній машині.
    • Playwright — Docker — офіційний образ містить браузери й системні залежності браузерів (сам пакет Playwright у нього не входить і встановлюється окремо).

    Оновлення еталонів: процес, а не прапорець

    Зовнішні сервіси: що вони додають до порівняння

    • Percy (BrowserStack Docs) — Visual Testing with Percy — чотири кроки сервісу (знімки в наборі браузерів і на кількох адаптивних ширинах, порівняння з раніше схваленими, підсвітка різниці на рівні пікселів, схвалення через UI); перенесення схвалених знімків у наступні білди гілки й вибір базового білду сервісом; схвалення знімка, групи або білду як статус пул-реквесту; автосхвалення для головної гілки; один знімок із запитом змін міняє статус усього білду, а позначка тримається, доки діф збігається; знімки збираються під час звичайного прогону тестів.
    • Playwright — Visual comparisons (test snapshots) — модель «еталон як файл у репозиторії»: окремі набори під кожну комбінацію браузера й платформи, оновлення прапорцем прогону.

    Що покривати візуально

    • Playwright — Visual comparisons (test snapshots) — окремі набори еталонів під кожну комбінацію браузера, платформи й проєкту; стайлшит як спосіб відфільтрувати динамічні елементи.
    • Percy (BrowserStack Docs) — Visual Testing with Percy — знімки в наборі браузерів і на кількох адаптивних ширинах; перевірка ловить непередбачені візуальні відмінності, а схвалює їх людина.

    Типові помилки

    • Playwright — API: PageAssertionsthreshold як різниця кольору одного пікселя проти окремих опцій частки й абсолютного числа; маска як перекриття рамки; перелік вимкнених анімацій (CSS-анімації, CSS-переходи, Web Animations) і поводження зі скінченними й нескінченними; каретка ховається за замовчуванням; збіг двох послідовних знімків перед порівнянням.
    • Playwright — Visual comparisons (test snapshots) — залежність від ОС і шрифтів як причина різниці між середовищами; оновлення еталона прапорцем прогону.
    • Percy (BrowserStack Docs) — Visual Testing with Percy — автосхвалення для головної гілки за замовчуванням; схвалення людиною як умова того, що деплоїться лише навмисне.

    Підсумок

    • Playwright — Visual comparisons (test snapshots) — механіка еталонів, залежність від середовища, окремі набори на комбінацію, оновлення прапорцем прогону.
    • Playwright — API: PageAssertions — три пороги і їхні дефолти, маска, стайлшит, анімації й каретка за замовчуванням.
    • Playwright — Clock — перелік перевизначених глобалів часу й вимога ставити підміну годинника перед іншими викликами, повʼязаними з часом.
    • Percy (BrowserStack Docs) — Visual Testing with Percy — еталон як раніше схвалений знімок і схвалення людиною як частина процесу.

    Можливі питання

    • Playwright — Visual comparisons (test snapshots) — генерація й оновлення еталонів, залежність від середовища, окремі набори під комбінації.
    • Playwright — API: PageAssertions — означення threshold у YIQ і відмінність від опцій частки й абсолютного числа; маска, стайлшит, анімації, каретка.
    • Playwright — Clock — підміна часу як спосіб зробити дату на екрані детермінованою.
    • Percy (BrowserStack Docs) — Visual Testing with Percy — еталон у процесі схвалення, перенесення між білдами гілки, статус пул-реквесту, автосхвалення головної гілки.

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.