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

    03 · Веб і мережі для AQA

    DevTools: вкладка Network і дебаг

    Зміст

    Кнопка натиснулась, а нічого не сталося. Форма «крутиться» вічно. Дані на сторінці старі, хоча в базі вже нові. Тест то зелений, то червоний без жодних змін у коді. У більшості таких випадків відповідь на «чому» лежить у вкладці Network інструментів розробника (DevTools). Це вікно між тим, що ви бачите в браузері, і тим, що насправді літає між клієнтом і сервером. Для AQA це не «інструмент розробника», а основний прилад діагностики: тут видно, який запит пішов, з якими заголовками, що повернув сервер, скільки це тривало і чому інколи не спрацювало.

    Далі скрізь орієнтуюся на Chrome DevTools як на найпоширеніший варіант. У Firefox і Safari логіка та сама, назви кнопок відрізняються.

    Відкрити панель: F12, або Cmd+Option+I (macOS) / Ctrl+Shift+I (Windows/Linux), далі вкладка Network.

    Що показує вкладка Network

    Кожен рядок у таблиці Network — це один мережевий запит, який зробила сторінка: завантаження самого HTML, зображень, скриптів, стилів, шрифтів, а також фонові звернення до API. DevTools записує мережу лише поки вони відкриті. Звідси перше правило: відкрийте DevTools перед тим, як відтворювати проблему, і бажано перезавантажте сторінку (Cmd/Ctrl+R), щоб побачити повний цикл із першого запиту.

    Ще один важливий вимикач поруч — Preserve log («зберігати журнал»). За замовчуванням список очищається на кожній навігації, тож редірект після логіну зітре все, що ви хотіли роздивитися. Увімкнений Preserve log зберігає запити крізь переходи між сторінками — це must-have для розслідування логінів, редіректів і багатокрокових форм.

    Чому це важливо саме для тестувальника? Те, що ви бачите очима, — це вже наслідок. Кнопка «Зберегти» могла відпрацювати ідеально на фронтенді, а помилка — у тому, що POST-запит повернув 422. Без Network ви бачите лише «не зберігається» і будуєте здогади. З Network ви бачите факт.

    Колонки таблиці

    За замовчуванням у таблиці кілька ключових колонок; їхній склад змінюється правою кнопкою по заголовку.

    КолонкаЩо показуєНавіщо AQA
    NameІм’я ресурсу / останній сегмент URLЗнайти потрібний запит
    StatusКод статусу HTTP-відповідіПерше, на що дивишся при збої
    TypeТип ресурсу (xhr, fetch, document, script, png…)Відфільтрувати «своє»
    InitiatorХто ініціював запит (рядок коду, інший запит, редірект)Зрозуміти, звідки взявся запит
    SizeОбсяг переданих даних / розмір ресурсуВиявити кеш і «важкі» відповіді
    TimeЗагальна тривалість запитуЗнайти повільні місця
    WaterfallЧасова діаграма фаз запитуПобачити, де саме гальмує

    Колонка Size показує два значення: скільки реально передано мережею (стиснуте тіло плюс заголовки) і повний, розпакований розмір ресурсу. Якщо там написано (from disk cache) або (from memory cache) — мережею не передавалося нічого, відповідь узята з кешу. До цього ще повернемось, це часте джерело плутанини в тестах.

    Фільтри за типом ресурсу

    Над таблицею — рядок кнопок-фільтрів за типом. Вони критично економлять час, бо на реальній сторінці сотні запитів, а вам потрібен один-два.

    ФільтрЩо лишаєТиповий випадок для AQA
    AllУсеЗагальний огляд
    Fetch/XHRВиклики до API (fetch() та XMLHttpRequest)Тут майже вся робота з бекендом
    DocГоловні HTML-документиПобачити редіректи, статус самої сторінки
    CSSТаблиці стилівСтилі не застосувались
    JSСкриптиСкрипт не завантажився / 404
    FontШрифти«Поплив» шрифт
    ImgЗображенняБитий src, повільні картинки
    WSВеб-сокети (WebSocket)Реалтайм: чати, живі оновлення

    Одна тонкість: у сучасному Chrome окремих кнопок XHR і Fetch немає — вони об’єднані в Fetch/XHR. Історично XHR (XMLHttpRequest) — старий спосіб асинхронних запитів, Fetch — сучасний через fetch(). Для діагностики різниця несуттєва: обидва — фонові звернення до сервера, і саме тут ви шукаєте виклики API.

    Поруч із кнопками є текстове поле фільтра. У ньому працюють і прості підрядки (users), і спеціальні оператори — наприклад status-code:500, method:POST, domain:api.example.com, а мінус на початку інвертує умову (-method:GET). Це швидший шлях до потрібного запиту, ніж прокручувати весь список.

    Заголовки запиту і відповіді

    Клацніть на будь-який запит — праворуч відкриється детальна панель із вкладками. Перша і найважливіша — Headers (заголовки). Заголовки (headers) — це метадані, які клієнт і сервер додають до повідомлення: хто, що, в якому форматі, з якою авторизацією.

    Панель Headers ділиться на блоки:

    • General — метод (GET/POST…), повний URL, код статусу, IP-адреса сервера (Remote Address).
    • Response Headers — що прислав сервер.
    • Request Headers — що надіслав браузер.

    Заголовки, які AQA зустрічає найчастіше:

    ЗаголовокНапрямЩо означає
    Content-TypeобидваФормат тіла: application/json, text/html
    AuthorizationзапитТокен доступу, напр. Bearer <token>
    CookieзапитКукі, які браузер відправляє серверу
    Set-CookieвідповідьКукі, які сервер просить зберегти
    Cache-ControlобидваПравила кешування (no-cache, max-age=3600)
    ETagвідповідь«Відбиток» версії ресурсу для перевірки кешу
    LocationвідповідьКуди редіректить (при 3xx)
    Access-Control-Allow-OriginвідповідьДозвіл CORS: кому можна читати відповідь

    Приклад типової пари запит-відповідь для логіну:

    POST /api/v1/login HTTP/1.1
    Host: app.example.com
    Content-Type: application/json
    Accept: application/json
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Set-Cookie: session=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
    Cache-Control: no-store

    Тут запит логіну не несе Authorization — токен ви якраз отримуєте у відповідь (у тілі або в Set-Cookie), а Bearer-заголовок з’явиться вже в наступних, авторизованих запитах.

    Для тестувальника заголовки — часто перше місце, де ховається баг. Немає Authorization у запиті → сервер повертає 401. Неправильний Content-Type → сервер не розуміє тіло і віддає 400/415. Відсутній Access-Control-Allow-Origin → запит заблокований політикою CORS (про це в кінці).

    Payload і тіло відповіді

    Вкладка Payload (у старіших версіях — частина Headers) показує, що саме браузер відправив у тілі запиту. Для POST/PUT/PATCH це найцінніше: тут видно фактичні дані, які пішли на сервер.

    {
      "email": "user@example.com",
      "password": "••••••",
      "remember": true
    }

    Часта помилка, яку ловлять саме тут: форма начебто заповнена правильно, але в payload летить порожнє поле або старе значення (стан не встиг оновитися). Це прямий доказ бага на фронтенді, а не на бекенді.

    Для GET-запитів окремого payload немає — параметри летять у самому URL (query string), і DevTools зручно розкладає їх у блоці Query String Parameters.

    Вкладка Response (поруч — Preview) показує тіло відповіді. Різниця між ними:

    • Response — сирий текст відповіді, як прийшов.
    • Preview — той самий вміст, але відрендерений: JSON — деревом, HTML — превʼю, картинка — зображенням.

    Саме тут ви звіряєте контракт: чи повернув сервер ті поля, що очікуються, у тому форматі й з тими значеннями. Це джерело правди для API-перевірок — DOM може показувати одне, а сервер віддавати інше.

    Статуси і кольори

    Код статусу HTTP (HTTP status code) — трицифрове число у відповіді, яке коротко каже, чим завершився запит. Перша цифра задає клас.

    КласЗначенняЧасті коди
    1xxІнформаційні101 (перехід на WebSocket)
    2xxУспіх200 OK, 201 Created, 204 No Content
    3xxПеренаправлення301, 302, 304 Not Modified, 307, 308
    4xxПомилка клієнта400, 401, 403, 404, 409, 422, 429
    5xxПомилка сервера500, 502, 503, 504

    Ключове для діагностики: 4xx — «винен» той, хто питав (не той запит, не ті дані, немає прав), 5xx — «винен» сервер (впав, таймаут бекенду, помилка коду). Це відразу ділить розслідування на дві гілки: 4xx веде до фронтенду й даних запиту, 5xx — до серверних логів.

    Кілька кодів, які постійно плутають:

    • 401 Unauthorized — насправді «не автентифікований»: немає або невалідний токен. За RFC 9110 такий статус доречний, коли запиту бракує валідних облікових даних, і відповідь має містити заголовок WWW-Authenticate.
    • 403 Forbidden — автентифікований, але немає прав на цю дію: сервер зрозумів запит і все одно відмовляє, і повторний логін тут не допоможе. Цінно для тестів рольового доступу.
    • 422 Unprocessable Content — тіло синтаксично коректне (інакше був би 400) і тип вмісту зрозумілий (інакше 415), але не проходить семантичну валідацію (наприклад, email уже зайнятий). У RFC 9110 це саме «Unprocessable Content»; історична назва з RFC 4918, яку досі часто вживають, — «Unprocessable Entity». У багатьох фреймворках (зокрема Rails) саме тут лежать повідомлення про помилки форм.
    • 304 Not Modified — не помилка: сервер підтвердив, що кеш актуальний (деталі нижче).

    Щодо кольорів: Chrome підсвічує червоним текстом невдалі й заблоковані запити — це найнадійніший візуальний сигнал: пробіг очима по списку, червоне — туди й дивишся.

    Нюанс. Колірна розмітка рядків у Network — деталь інтерфейсу, що змінюється між версіями браузера. Головний орієнтир — число в колонці Status, а не відтінок рядка.

    Waterfall: читаємо тайминг

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

    Клацнувши на запит і відкривши вкладку Timing, ви розкладаєте смужку на фази:

    ФазаЩо відбуваєтьсяПро що сигналить
    Queueing / StalledЗапит чекає у черзіБраузер обмежує к-сть одночасних з’єднань до хоста (для HTTP/1.1 — зазвичай 6)
    DNS LookupРезолвінг домену в IPПроблеми DNS
    Initial connectionВстановлення TCP-з’єднанняМережеві затримки
    SSLРукостискання TLSЧас на шифрування
    Waiting (TTFB)Очікування першого байта від сервераШвидкість бекенду
    Content DownloadЗавантаження тіла відповідіРозмір відповіді / канал

    Найважливіша для тестувальника фаза — TTFB (Time To First Byte), час очікування відповіді сервера. Великий TTFB означає, що гальмує бекенд, а не «інтернет» чи фронтенд. Якщо великий саме Content Download — відповідь надто важка або канал вузький.

    Queueing / Stalled

    DNS Lookup

    Initial connection

    SSL

    Waiting TTFB

    Content Download

    Queueing / Stalled

    DNS Lookup

    Initial connection

    SSL

    Waiting TTFB

    Content Download

    Дві вертикальні лінії на waterfall позначають ключові події завантаження сторінки: синя — DOMContentLoaded (HTML розібрано й побудовано DOM), червона — Load (завантажено всі підресурси сторінки). За наведенням DevTools показує точний час кожної події.

    Практичний зв’язок з автотестами: waterfall пояснює флак (flakiness). Тест «клікнув і одразу перевірив» падає, бо POST ще у фазі Waiting, а асерт уже виконався. Рішення — не «поспати рандомну секунду», а чекати на конкретну відповідь (у Playwright — waitForResponse), тобто прив’язати очікування (wait) до реальної події, яку ви бачите в Network.

    Кеш: живий запит проти кешованого

    Одне з питань, на яких «сипляться» і початківці, і тести: це справжня свіжа відповідь чи браузер підсунув старе з кешу?

    Ознаки, що відповідь із кешу (мережа не задіяна):

    • У колонці Size написано (from memory cache) або (from disk cache).
    • Статус 200, але фаза мережі в Timing практично нульова.

    Окремий випадок — статус 304 Not Modified. Це живий запит: браузер таки сходив на сервер із заголовком If-None-Match: <ETag> (або If-Modified-Since), а сервер відповів «нічого не змінилось, бери своє з кешу». Тобто мережа була, але тіло повторно не передавалось. Тому Size у 304 малий, а не «from cache».

    Що бачитеМережа?Тіло передано?
    200, Size = числотактак (живий, повний)
    200 (from disk/memory cache)ніні (з кешу)
    304 Not Modifiedтакні (кеш підтверджено)

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

    Disable cache

    У панелі Network є прапорець Disable cache. Коли він увімкнений (і DevTools відкриті), браузер ігнорує кеш і щоразу тягне ресурс наново — імітує «першого відвідувача». Це прибирає цілий клас хибних діагнозів на кшталт «чому старі дані».

    Важливий нюанс: Disable cache працює лише поки DevTools відкриті. Закрили панель — кеш знову в грі. Стабільні автотести на цей прапорець не покладаються: браузер запускають із чистим профілем/контекстом, тому в тестах проблема майже не виникає — вона більше про ручну діагностику.

    Кукі в запиті й відповіді

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

    Два напрями:

    • Сервер у відповіді надсилає Set-Cookie — «збережи це».
    • Браузер у наступних запитах шле Cookie — «ось що я зберіг».

    Це видно і в Headers, і в окремій вкладці Cookies обраного запиту (там кукі розкладені в таблицю з атрибутами).

    Атрибути куки, які має знати AQA:

    АтрибутЩо робитьЧому важливо для тестів
    Expires / Max-AgeТермін життяСесійна кука vs постійна
    Domain / PathОбласть діїЧому кука «не долітає» до потрібного запиту
    SecureПередається лише через HTTPSВиняток — localhost, який браузери вважають захищеним контекстом; на звичайному http:// (не localhost) не встановиться
    HttpOnlyНедоступна для JS (document.cookie)Її не прочитати зі скрипта — тільки з Network
    SameSiteПоведінка на крос-сайтових запитахЧаста причина «злетілої» сесії між доменами

    HttpOnly варто підкреслити: таку куку навмисно не видно з JavaScript (захист від крадіжки токена). Тому в автотесті ви не дістанете її через document.cookie — читайте через API браузера для роботи з кукі (у Playwright — context.cookies()) або дивіться в Network.

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

    Throttling: емуляція повільної мережі

    У панелі Network є випадаючий список профілів швидкості мережі (throttling). Він штучно ріже пропускну здатність і додає затримку, щоб відтворити поведінку на повільному з’єднанні, не виходячи з-за столу.

    Навіщо AQA:

    • Перевірити стани завантаження: чи є спінер, скелетон, чи не «моргає» порожній екран.
    • Зловити ганки, які на швидкому Wi-Fi не відтворюються (кнопка активна, поки запит іще летить → подвійне надсилання).
    • Профіль Offline — перевірити поведінку без мережі: чи є зрозуміле повідомлення, чи все «мовчки ламається».

    Можна створити власний профіль із конкретними значеннями завантаження, віддачі й затримки (latency).

    Набір готових пресетів змінювався між версіями Chrome: у поточних версіях це, зокрема, Fast 4G, Slow 4G і 3G (раніше були Fast 3G / Slow 3G). Тому для відтворюваних умов краще задавати власний профіль із фіксованими числами, а не покладатися на назву пресета.

    Прямий зв’язок із флаком: throttling — це чесний спосіб знайти race condition до того, як його знайде CI. Якщо тест падає на повільному профілі, він не «флакне на швидкому» — він просто ще не впав: очікування (wait) в ньому недостатньо прив’язані до подій.

    Вкладка Application → Storage

    Мережею дані приходять, але частина їх осідає в клієнтському сховищі. Це вкладка Application (у Firefox — Storage), розділ зліва.

    СховищеЩо зберігаєЖиве доки
    Local StorageРядки ключ-значенняПоки не видалять
    Session StorageТе саме, але на вкладкуПоки відкрита вкладка
    CookiesКукі доменуЗа Expires/Max-Age
    IndexedDBСтруктуровані дані, об’єктиПоки не видалять
    Cache StorageКеш Service Worker (офлайн, PWA)Керує Service Worker

    Для AQA це друге (після кукі) місце, де ховається стан. Токен доступу, вибрана мова, флаги фіч, «побачив онбординг» — усе це часто в Local Storage. Звідси два практичні наслідки:

    1. Діагностика. «Чому користувач після логіну бачить старий інтерфейс» — може, у Local Storage застряг старий флаг.
    2. Ізоляція тестів. Залишені між тестами localStorage чи IndexedDB — типова причина «тест проходить сам, але падає в наборі». Тому стан чистять між тестами; кнопка Clear site data в Application робить це вручну, а автотести стартують із чистого контексту.

    У розділі є оглядова сторінка Storage з квотою — скільки місця займає сайт і скільки доступно.

    Console: помилки поряд із мережею

    Вкладка Console — сусід Network, і ці двоє працюють у парі. Червоні рядки в консолі часто пояснюють те, що в Network виглядає як загадковий збій.

    Що читати AQA:

    • Uncaught TypeError / ReferenceError — упав JS. Дуже частий сценарій: fetch повернув не той формат, код спробував прочитати неіснуюче поле, і вся сторінка «застигла». У Network при цьому запит може бути зелений 200 — а баг у обробці відповіді.
    • CORS-помилки — саме тут з’являється розгорнутий текст, чому запит заблоковано (у Network ви побачите лише failed).
    • Mixed Content — сторінка на HTTPS тягне ресурс по HTTP, браузер блокує.
    • CSP (Content-Security-Policy) — політика безпеки заборонила завантажити скрипт/стиль/картинку.

    Зручний прийом: тримати Console і Network поруч. Побачили червоний запит у Network → зазирнули в Console по деталі причини. Часто відповідь одним рядком там і лежить.

    Для автотестів корисно слухати консоль програмно: збирати помилки консолі під час прогону й фейлити тест на несподіваних error-логах. Це ловить регресії, які візуально ще «наче працюють».

    Алгоритм діагностики «червоного» запиту

    Зібравши все докупи — ось послідовність, яка веде від «щось червоне / не працює» до причини. Ідемо згори вниз, зупиняємось на першому збігу.

    Крок 0. Відтворити при відкритих DevTools. Відкрити Network, за потреби увімкнути Preserve log (є редіректи) і Disable cache (підозра на кеш), відтворити дію. Знайти проблемний запит (фільтр Fetch/XHR + пошук за іменем).

    Крок 1. Подивитися на Status.

    • Число 4xx → помилка клієнта. Далі:
      • 401 → немає/невалідний токен. Перевірте Authorization у Request Headers і кукі сесії.
      • 403 → токен є, прав немає. Тестуєте роль — це очікувано; ні — питання до прав користувача.
      • 404 → неправильний URL/ендпоінт. Звірте General → Request URL.
      • 422/400 → погані дані. Відкрийте Payload і Response: там зазвичай список полів, що не пройшли валідацію.
      • 429 → уперлися в ліміт частоти (rate limit). Зачекайте / зменшіть навантаження.
    • Число 5xx → помилка сервера. Фронтенд ні до чого. Зафіксуйте запит (URL, тіло, час, x-request-id, якщо є) і йдіть до серверних логів/бекенд-команди. 502/503/504 часто означають, що бекенд лежить або не встиг відповісти.

    Крок 2. Статусу немає — написано (failed), (blocked), (pending). Значить, до логіки сервера навіть не дійшло. Дивимось у Console і колонку Status на деталь:

    ОзнакаПричинаКуди копати
    CORS error, у Console blocked by CORS policyСервер не дозволив крос-доменний запитResponse Headers на Access-Control-Allow-Origin; для складних запитів — попередній OPTIONS (preflight)
    net::ERR_BLOCKED_BY_CLIENTБлокує розширення (адблок)Вимкнути розширення / перевірити в режимі інкогніто
    blocked:csp / CSP у ConsoleПолітика безпеки сторінкиЗаголовок Content-Security-Policy
    Mixed ContentHTTPS-сторінка тягне HTTP-ресурсСхема URL ресурсу
    (pending) надовго / ERR_CONNECTION_* / таймаутНемає з’єднання, сервер недоступний, DNSTiming (де завис), доступність хоста

    Крок 3. Статус 200, але «не працює». Найпідступніший випадок — мережа ок, а результат ні. Тоді:

    • Відкрийте Response/Preview: можливо, сервер повернув 200 з тілом-помилкою ({"error": "..."}) або порожнім/не тим форматом.
    • Перевірте Console: імовірно, JS упав під час обробки відповіді.
    • Перевірте Size: якщо (from cache) — ви дивитесь на старі дані, а не на свіжу відповідь.

    4xx

    5xx

    failed / blocked / pending

    200, але не працює

    Знайти запит: Fetch/XHR + пошук за іменем

    Є код статусу?

    Помилка клієнта:
    Headers, Payload, Response

    Помилка сервера:
    зафіксувати запит, до бекенду

    До сервера не дійшло:
    дивитись Console

    Response / Console / Size from cache

    4xx

    5xx

    failed / blocked / pending

    200, але не працює

    Знайти запит: Fetch/XHR + пошук за іменем

    Є код статусу?

    Помилка клієнта:
    Headers, Payload, Response

    Помилка сервера:
    зафіксувати запит, до бекенду

    До сервера не дійшло:
    дивитись Console

    Response / Console / Size from cache

    Про CORS окремо, бо він лякає найбільше. CORS (Cross-Origin Resource Sharing) — механізм, що дозволяє сторінці з одного походження (origin) читати відповідь із іншого. Для «непростих» запитів (метод не GET/POST/HEAD, кастомні заголовки на кшталт Authorization, або Content-Type, відмінний від трьох простих — application/x-www-form-urlencoded, multipart/form-data, text/plain) браузер спершу шле preflight — окремий OPTIONS-запит — і питає сервер, чи можна. Якщо сервер не відповів потрібними Access-Control-Allow-* заголовками, браузер блокує відповідь. Для «простого» запиту (без preflight) він при цьому міг таки дійти до сервера й виконатись — тіло сформувалось, але браузер не дає його прочитати. Звідси характерна пастка: у логах сервера дія пройшла, а в браузері — «помилка». Це майже завжди питання конфігурації сервера/проксі, а не тесту.

    OPTIONS /api/v1/orders HTTP/1.1
    Origin: https://app.example.com
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: Authorization, Content-Type
    
    HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: https://app.example.com
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: Authorization, Content-Type

    Немає рядка Access-Control-Allow-Origin з вашим походженням у відповіді — браузер заблокує наступний POST, і ви побачите червоне.

    СерверБраузерСерверБраузерAccess-Control-Request-Method: POSTДозвіл є — шлемо запитOPTIONS /api/v1/orders (preflight)204, Access-Control-Allow-*POST /api/v1/orders200 OKСерверБраузерСерверБраузерAccess-Control-Request-Method: POSTДозвіл є — шлемо запитOPTIONS /api/v1/orders (preflight)204, Access-Control-Allow-*POST /api/v1/orders200 OK

    Мережа й автотести

    Усе вище — це не лише ручна діагностика. Кожна концепція має пряме продовження в автоматизації, і Network — це «джерело правди», проти якого звіряють поведінку тестів.

    • Очікування замість пауз. Побачили в Network, який запит завершує дію → у тесті чекайте саме на нього (waitForResponse за URL/статусом), а не на фіксовану паузу. Це прибирає найпоширеніший вид флаку.
    • Перехоплення мережі (network interception). Те, що в DevTools ви лише спостерігаєте, у тесті можна підмінити: віддати заздалегідь готову відповідь (мок), примусово повернути 500 (перевірити обробку помилок), затримати запит (перевірити спінер), заблокувати сторонні скрипти (стабільність). У Playwright це route/fulfill/abort.
    • Ізоляція стану. Кукі й Storage, які ви бачите в Application, — це те, що між тестами треба обнуляти. Свіжий контекст браузера на тест = немає «тест падає лише в наборі».
    • Асерти по контракту. Тіло відповіді з вкладки Response — еталон для перевірок: тест може перевіряти не тільки DOM, а й що API повернув потрібні поля з потрібними значеннями.
    • Кеш і детермінізм. Розуміння різниці 200 from cache / 304 / живий 200 рятує від хибних «баг збереження», коли насправді браузер віддав старе.

    Вкладка Network перетворює «щось не працює» на конкретне твердження — «запит POST /api/orders повернув 422, у тілі email already taken, Authorization присутній, кеш вимкнено». Саме такі формулювання відрізняють баг-репорт, який беруть у роботу відразу, від тікета, що повертається з питанням «а що конкретно сталося».