Cypress
Cypress — відкритий раннер тестів для вебзастосунків, що виконує тест усередині браузера, у тій самій вкладці й event loop, що й застосунок. Сторінка починається з дванадцяти маршрутів зі сторінки «Наскрізне тестування» так, як магазин написав би їх на Cypress, — сім нативних, пʼять з обхідним шляхом і те одне, що спільне для всіх пʼяти, — далі вкладка й чотири компроміси, які Cypress називає постійними, черга команд, повторність у тому вигляді, в якому вона працює з Cypress 12, ізоляція й бік Node, паралельність за файлами специфікацій, чотири зміни під робочими наборами і де він не допомагає.
- Поточна версія
- 16.2 · жовтень 2026
- Тест виконується
- Усередині браузера
- Паралельність за
- Файлом специфікації, через Cloud
Дванадцять маршрутів магазину в Cypress на одному екрані — нативно чи в обхід
Питання, з яким команда приходить на цю сторінку, — чи пасує Cypress її продукту, і чесно відповісти на нього можна лише маршрут за маршрутом. Нижче — дванадцять маршрутів зі сторінки «Наскрізне тестування», той самий інтернет-магазин, — так, як магазин написав би їх на Cypress. Третя колонка каже, що потрібно Cypress для кожного; четверта дає вердикт. «Нативно» означає, що це робить звичайний APIApplication Programming Interface — контракт між програмамиПравила, за якими одна програма звертається до іншої: які запити можна надіслати, у якому вигляді й що прийде у відповідь. Для того, хто звертається, це контракт — усе, що за ним, лишається чорною скринькою, і саме тому другий бік можна переписати, не зламавши вас.Докладніше в статті →Усі терміни. «В обхід» означає, що це можна зробити — налаштуванням, окремим блоком чи експериментальним прапорцем — і з ціною, яку рядок називає. Наступні розділи посилаються на маршрути за номерами.
| # | Маршрут | У Cypress | Вердикт |
|---|---|---|---|
| 1 | Знайти «синій светр», відкрити SKU 30417, оплатити тестовою карткою | Поля картки — iframe платіжного провайдера на іншому домені. Cypress не автоматизує iframe з іншого домену, якщо не вимкнути вебзахист через chromeWebSecurity: false, — і лише в браузерах родини Chrome | В обхід · лише родина Chrome |
| 2 | Зареєструватися, підтвердити, увійти, перезавантажити — у Chromium і WebKit | WebKit працює лише з experimentalWebKitSupport і з установленою збіркою WebKit від Playwright, playwright-webkit | В обхід · експериментально |
| 3 | Скинути забутий пароль за посиланням із листа | cy.task() читає тестову скриньку в Node; cy.visit() відкриває посилання | Нативно |
| 4 | Застосувати SPRING10, змінити кількість, оплатити | Той самий iframe картки, що в маршруті 1; cy.request() читає списання з пісочниці | В обхід · лише родина Chrome |
| 5 | Оплатити з 3-D Secure: перехід на перевірку банку й назад | Iframe картки, а потім сторінка банку на іншому домені: її кроки йдуть усередині блока cy.origin(), який отримує значення лише через args | В обхід · двічі |
| 6 | Картку відхилено; оплатити ще раз | Iframe картки; cy.request() потім рахує замовлення | В обхід · лише родина Chrome |
| 7 | Спитати асистента замовлень «де моє замовлення» | Віджет чату — власна сторінка магазину. Відтворення моделі задане на сервері, як і з Playwright: cy.intercept() бачить лише те, що надсилає браузер | Нативно |
| 8 | Почати повернення на 30-й день; етикетка приходить листом | cy.clock() задає дату браузера; тестовий годинник сервера задають через cy.request() | Нативно |
| 9 | Склад підтверджує повернення; гроші повертаються | cy.request() надсилає вебхук складу з Node, де CORS не діє; cy.task() опитує скриньку | Нативно |
| 10 | Змінити адресу доставки до відвантаження | cy.request() читає тестовий ендпоінт складу | Нативно |
| 11 | Оформити замовлення як гість, потім створити акаунт | Ізоляція тестів очищає сторінку, cookie й обидва вебсховища перед кожним тестом — хоча не IndexedDB | Нативно |
| 12 | Агент підтримки повертає гроші за пошкоджений товар у бек-офісі | cy.session() один раз логінить агента й відновлює цю сесію для кожного тесту, що її просить | Нативно |
Команда може оминути iframeсторінка всередині сторінкиHTML-елемент, що вбудовує інший документ у сторінку, — платіжну форму, відео, вікно входу. Коли він з іншого домену, браузер відгороджує його від сторінки навколо, і тому інструмент тестування може як змогти, так і не змогти щось у нього ввести.Усі терміни, оплачуючи через API провайдера тестовим токеном замість введення картки. Тоді маршрут іде всюди — і перестає доводити шов, заради якого існує, — рядок 4 сторінки «Наскрізне тестування»: сума на екрані — це сума, яку просять списати провайдера. Така форма більшості рішень щодо Cypress. Інструмент пропонує шлях в обхід кожного краю, і кожен такий шлях трохи віддаляє тест від того, що робить клієнт.
Тест живе у вкладці — і чотири компроміси, які Cypress називає постійними
Більшість автоматизації браузера — дистанційне керування: тест — це програма деінде, що надсилає браузеру інструкції й читає відповіді. Cypress це перевертає. Ваш застосунок завантажується в iframe, тест завантажується поруч у тій самій вкладці, і обидва працюють на одному event loopодин потік, що виконує все по черзіЦикл в одному потоці, що бере з черги готову роботу — відповідь, яка прийшла, таймер, що спрацював, — і виконує її колбек, по одному за раз. Він дає одному потоку тримати тисячі очікувань одночасно й зупиняється для всіх, поки виконується будь-який один колбек.Докладніше в статті →Усі терміни JavaScript. Між тестом і сторінкою немає дроту, тож тест дістає до застосунку так, як міг би скрипт на самій сторінці. Усе поза браузером — файл, база даних, тестова скринька — іде через другий процес, Node.js, з яким тест говорить через cy.task().
Від Cypress 16, що вийшов 1 вересня 2026 року, одна частина цієї картини змінилася. У Chrome, Chromium та Edge Cypress тепер перехоплює трафік тестів у власній мережі браузера, а не пропускає його через свій проксі, тож застосунок тестують по HTTPHyperText Transfer Protocol — протокол вебуПротокол, яким спілкуються браузер і сервер: клієнт надсилає метод і адресу, сервер відповідає кодом стану й тілом. Між запитами він нічого не памʼятає — кожен запит стоїть сам по собі, тому все, що треба памʼятати, передається явно.Усі терміни/2 і HTTP/3 з його справжнім сертифікатом. Firefox, WebKit і Electron досі йдуть старим шляхом крізь проксі. Тож той самий cy.intercept() працює двома різними мережевими шляхами залежно від браузера, і кілька його поведінок між ними різняться.
Власна документація Cypress перелічує ціну життя у вкладці під заголовком «Trade-offs» і чотири з цих компромісів називає постійними. Їх варто прочитати її словами, бо це не проблеми конфігурації, які прибере наступна версія.
| Постійний компроміс | Що це означає | У магазині |
|---|---|---|
| «Cypress — не інструмент автоматизації загального призначення» | Його «солодка точка» — тестувати власний застосунок, а не індексувати чи обходити веб, тестувати продуктивність чи скриптувати чужі сайти | Пасує: кожен маршрут тестує магазин |
| «Команди Cypress виконуються всередині браузера» | Код тесту — JavaScript, що виконується в браузері; до бекенду дістаються через cy.task() і cy.request() | Скринька й склад ідуть через Node (3, 9, 10) |
| «Cypress не може керувати двома браузерами одночасно» | Один браузер за раз; документація радить підмінити інший бік, а для кількох вкладок — плагін @cypress/puppeteer | Маршрут 12 послідовний, тож пасує; живий чат між клієнтом і агентом — ні |
| «Кожен тест привʼязаний до одного супердомену» | Перехід на інший домен потребує блока cy.origin(), а з Cypress 14 піддомен теж рахується іншим доменом | Сторінка 3-D Secure банку (5) |
Та сама сторінка називає три «тимчасові», які Cypress сподівається розвʼязати: немає cy.hover(), немає підтримки нативних чи мобільних подій, а підтримка iframe «дещо обмежена» — фрейми з того самого домену можна запитувати, з іншого — ні. Останній із цих пунктів і вирішив чотири вердикти магазину.
Команди стають у чергу, а не виконуються — чому `await`, `try/catch` і `if` поводяться дивно
Наслідок, з яким стикаються першим: команди Cypress — не те, чим здаються. Документація каже прямо: команди нічого не роблять у момент виклику, а ставлять себе в чергу, щоб виконатися пізніше. Рядок, що просить елемент, не дістає його й не повертає. Він додає команду в чергу, яка починає виконуватися лише після того, як уся функція тесту завершилася. Тож значення не можна присвоїти з команди у змінну й використати наступним рядком: коли читається наступний рядок, ще нічого не виконалося.
Черга пояснює й налагодження, заради якого Cypress обирають. Оскільки раннер сам виконує кожну команду всередині сторінки, він тримає знімок сторінки для кожної команди, і Command Log дає навести на крок і побачити сторінку такою, якою вона була тієї миті. Команди йдуть одна за одною, ніколи паралельно, і документація називає це свідомим рішенням, а не технічним обмеженням: мета — тест, що поводиться однаково від запуску до запуску.
Повторність від Cypress 12: ланцюжок запитів повторюється з початку
Cypress не чекає на сторінку фіксований час. Він ділить команди на види й повторює ті, що лише читають. Запити — cy.get(), .find(), .contains(), .eq() тощо — звʼязуються з перевірками після них, і якщо перевірка падає, Cypress знову проганяє весь ланцюжок запитів із початку, типово до чотирьох секунд. Дії на кшталт .click() і .type() — не запити: вони чекають, доки елемент стане придатним для дії, повторюючи запити перед собою, поки чекають, і потім діють один раз.
Поради, написані до грудня 2022 року, і чимало тих, що досі їх копіюють, кажуть протилежне: що повторюється лише останній запит перед перевіркою, тож список, який перерендерюється, лишає тест із відʼєднаним елементом. Так було в Cypress до версії 11. Cypress 12 це змінив, і правило, що прийшло на заміну, має одну межу, яку варто засвоїти. Перевірка посередині ланцюжка, щойно пройде, фіксує субʼєкт; запити після неї повторюються від цього зафіксованого субʼєкта, а не з початку. Якщо сторінка перерендериться між двома перевірками, зафіксованого елемента вже немає — і тест падає.
| Що ви написали | Що повторюється | Що робити |
|---|---|---|
| Запити, потім перевірка | Увесь ланцюжок запитів, із початку | Нічого: на цю форму й розрахована модель |
| Запити, перевірка, ще запити, перевірка | До першої перевірки; після неї — лише від зафіксованого субʼєкта | Розділіть ланцюжок на перевірці або покладіть обидві в один .should(callback) |
Дія — .click(), .type() | Чекає на придатність до дії, повторюючи запити перед собою; потім діє один раз | Перевіряйте стан, що став наслідком дії, а не саму дію |
Значення, взяте в .then() і перевірене пізніше | Нічого: значення застигає в момент зчитування | Перевіряйте живий елемент |
cy.getCookie() і читання сховища | Від Cypress 16 це теж запити, і вони повторюються | Ланцюжте перевірку безпосередньо до них |
Ізоляція, сесії й бік Node
Від Cypress 12 ізоляція тестів увімкнена за замовчуванням. Перед кожним тестом Cypress відкриває about:blank і очищає , localStorage і sessionStorage на всіх доменах, тож маршрут не успадковує стан іншого. Різницю з Playwright варто знати точно. Playwright дає кожному тесту новий контекст браузера — цілий новий профіль. Cypress прибирає той самий браузер між тестами, і його документація каже, що лишається: IndexedDB та інші механізми сховища браузера не очищаються. Магазин, що тримав би гостьовий кошик в IndexedDB, мусив би сам очищати його перед маршрутом 11.
| Потреба | Команда | Виконується в | Що варто знати |
|---|---|---|---|
| Увійти раз і використовувати | cy.session() | Браузері | Кешує й відновлює cookie та обидва вебсховища під ідентифікатором; validate перевіряє, що відновлена сесія ще працює (маршрут 12) |
| Викликати API | cy.request() | Node, на боці Cypress | Не обмежений CORS чи політикою того самого джерела, тому може надіслати вебхук складу (маршрут 9) |
| Усе інше поза браузером | cy.task() | Node, у setupNodeEvents вашої конфігурації | Читання скриньки, засівання бази. cy.exec(), що запускав команди оболонки, у Cypress 16 видалили на його користь |
| Значення конфігурації | Cypress.expose() або cy.env() | Браузері або Node | Cypress 16 видалив Cypress.env() і зробив вибір явним: значення, відкрите браузеру, може прочитати застосунок під тестом і все, що він завантажує, тож секрет лишається в Node |
Доступ усередину застосунку заслуговує окремого застереження. Оскільки тест ділить сторінку, він може викликати функції застосунку, читати його стор чи стежити за методом. Це чудово для підготовки стану, до якого інакше вести шість кліків, і погано для перевірки поведінки: перевірка, написана по нутрощах, привʼязана до того, як збудовано фічу, тож рефакторинг, що нічого не змінює для клієнта, ламає набір. Готуйте зсередини; перевіряйте через те, що бачить людина.
Паралельно за файлами специфікацій, під керуванням Cypress Cloud
Cypress запускає один браузер за раз на машині, тож швидший набір означає більше машин. Його паралелізація — за файлами: машинам роздають цілі файли специфікацій, ніколи окремі тести. Роздає їх Cypress Cloud. Кожна машина запускає cypress run --record --parallel, Cloud оцінює тривалість кожної специфікації за попередніми запусками й дає кожній машині по одній, доки не скінчаться. Без Cloud команда все одно може розділити специфікації між машинами вручну, але такий поділ статичний і не вчиться.
У Cloud також налагоджують падіння в CI. Test Replay, що зʼявився в Cypress 13 у серпні 2023 року, записує DOM, мережеві запити й консоль кожного тесту в CI і дає розробнику пройти запуск у браузері пізніше; документація каже, що він доступний на всіх планах Cloud без доплати, у межах лімітів використання. Запис відео з того самого релізу вимкнено за замовчуванням. Обидва факти вказують в один бік: частини досвіду Cypress, що найбільше важать у CI, — балансування й відтворення — це хостований сервіс, і це вибір, який варто робити з розплющеними очима, а не деталь, яку виявляють згодом.
Чотири зміни під робочими наборами
Кожна з цих змін — датована, і опублікував її сам Cypress. Жодна не є дефектом. Кожна зрушила щось, на що набір встиг покластися, а третя колонка — те, що зробило цей зсув справою пообіддя, а не тижня.
| Зміна | Що вона виявила | Що захистило набір |
|---|---|---|
| Cypress 12, 6 грудня 2022: ізоляція тестів за замовчуванням; запити повторюються ланцюжком | Тести, що покладалися на сторінку чи cookie, лишені попереднім тестом, після оновлення впали, хоча в продукті нічого не змінилося. | Тести, незалежні з першого дня. testIsolation: false існує як шлях міграції — милиця, якій варто призначити дату прибирання. |
| Cypress 13, 2023: заблоковано сторонній модуль, що надсилав запуски в Sorry-Cypress і Currents; 7 листопада блокування поширюється на v12 | Проєкти, чиї паралельні запуски оркеструвалися цими сервісами, не могли оновитися й зберегти їх. Cypress виклав свої причини в окремому дописі: за його версією, ці сервіси користувалися його брендом і застосунком, витрати на який ніс Cypress. | Розуміння, що оркестрація паралельності — сервіс, який має власника, і запасний варіант, що не потребує нічийого дозволу: специфікації, розділені між машинами вручну. |
Cypress 14.4, 20 травня 2025: Chrome 137 припиняє підтримку --load-extension у брендовому Chrome | Плагін @cypress/puppeteer — задокументований спосіб тестувати кілька вкладок — зламався в режимі open і запусках із вікном у брендовому Chrome, як і launchOptions.extensions. Cypress порадив Electron, Chrome for Testing або Chromium; згодом Cypress 16 оголосив Electron застарілим як браузер для тестів. | Образи CI, що закріплюють збірку Chrome for Testing чи Chromium, а не той брендовий Chrome, який випадково є на машині: обхід «однієї вкладки» тримається на прапорці, яким володіє виробник браузера. |
Cypress 16, 1 вересня 2026: трафік перехоплюється в рідній мережі Chrome; cy.exec() і Cypress.env() видалено | Кілька поведінок cy.intercept() змінилися лише в браузерах родини Chrome — req.httpVersion більше не повідомляється, заголовків стиснення в перехоплених відповідях немає, — і кожен тест, що читав конфігурацію в браузері, мусив обрати між значенням, видимим браузеру, і значенням лише для Node. | Посібник із міграції, прочитаний до оновлення, і набір, прогнаний у тих браузерах, на які він розрахований, — бо той самий тест тепер іде двома мережевими шляхами залежно від браузера. |
Де він не допомагає і як порівнюється
Життя всередині вкладки — справжнє архітектурне зобовʼязання, і кожне обмеження нижче випливає з нього. Жодне не є скандалом; кожне варто знати до вибору, бо наступна версія його не прибере.
- Iframe з іншого домену — платіжну форму, вбудований вхід — не автоматизувати без вимкнення вебзахисту, а це працює лише в браузерах родини Chrome.
- Один браузер за раз, тож двох користувачів, що діють разом, — живий чат, агента, що бачить екран клієнта, — з одного боку підмінюють, а не тестують.
- WebKit експериментальний і приходить через збірку WebKit від Playwright; це теж не Safari.
- Паралельність — за файлами специфікацій між машинами, а добре її балансувати — це сервіс Cloud.
- Нативні діалоги, вибір файлів і все на рівні операційної системи лежать поза сторінкою, а отже, поза досяжністю.
cy.prompt(), у бета-версії, пише кроки зі звичайної англійської й позначає крок, що відновився, як «Self-healed». Вилікуваний крок — це змінений тест, і він заслуговує на рев’ю, як будь-яка інша зміна.
Cypress пасує краще, коли
- Тести пишуть і підтримують фронтенд-розробники, і щоденний досвід налагодження вирішує, чи робитимуть вони це далі.
- Компонентне тестування у справжньому браузері — велика частина плану, а не думка навздогін.
- Застосунок живе на одному домені, без платіжного iframe, другої вкладки й другого користувача в маршруті.
- У команди вже є робочий набір, і зміна інструмента коштує більше, ніж повертає.
Беріть Playwright, коли
- Шлях грошей проходить через iframe провайдера й має йти більш ніж в одному рушії.
- Маршрутові потрібні два користувачі водночас або він регулярно перетинає домени, вкладки чи вікна.
- Обмеженням є час набору, а дешева паралельність на одній машині змінює арифметику.
- Падіння в CI треба діагностувати з файлу, яким ви володієте, без хостованого сервісу.
Антипатерни, які варто назвати
- Чекати фіксовану кількість мілісекунд — саме цю звичку модель повторів і має зробити непотрібною.
- Логінитися через інтерфейс на початку кожного тесту — пʼять секунд на кейс, щоб довести те, що
cy.session()довів один раз. - Умовна логіка тесту за тим, що є на сторінці: виходить тест, який не може впасти, бо підлаштовується під усе.
- Підміняти кожен запит, аж поки набір не перестане тестувати будь-яку інтеграцію, і звітувати про це як про наскрізне покриття.
- Один файл специфікації на фічу, тож найдовша фіча задає нижню межу кожного запуску.
chromeWebSecurity: false, увімкнений для всього набору заради одного iframe, — і кожен маршрут тихо перестає йти у Firefox і WebKit.
Коли це застосовувати
Застосовуйте, коли
- Фронтенд-команди, що самі підтримуватимуть набір і щодня цінують зручність налагодження.
- Компонентне тестування у справжньому браузері — щоб зняти кейси з повільного наскрізного рівня.
- Вебзастосунки на одному домені, без платіжних iframe, других вкладок і двох користувачів в одному маршруті.
- Там, де підміна мережі на межі робить тестованими стани помилки й порожнечі, які інакше недосяжні.
Уникайте, коли
- Маршрути, що вводять дані в iframe третьої сторони й мають іти у Firefox чи WebKit.
- Сценарії, що законно перетинають вкладки, вікна чи кілька доменів: обхідних шляхів там більше, ніж тестів.
- Набори, де головним обмеженням є загальний час, а хостований сервіс балансування — не варіант.
- Перевірки, написані по нутрощах застосунку: вони привʼязують тест до того, як збудовано фічу.
Джерела й метод
На чому стоїть ця стаття
- 11 джерел
- Перевірено 19 жовтня 2026 р.
Інструмент — за його власною документацією
вердикти, компроміси, черга, повторність, ізоляція й паралельність у розділах 1–6- ДокументаціяTrade-offs in Cypress (відкривається в новій вкладці)Cypress
- ДокументаціяCross origin testing in Cypress (відкривається в новій вкладці)Cypress
- ДокументаціяIntroduction to Cypress (відкривається в новій вкладці)Cypress
- ДокументаціяRetry-ability in Cypress (відкривається в новій вкладці)Cypress
- ДокументаціяTest isolation in Cypress (відкривається в новій вкладці)Cypress
- Документаціяcy.origin() (відкривається в новій вкладці)Cypress
- Документаціяcy.session() (відкривається в новій вкладці)Cypress
- ДокументаціяParallelize tests in Cypress Cloud (відкривається в новій вкладці)Cypress
- ДокументаціяDebug failed and flaky tests with test replay in Cypress Cloud (відкривається в новій вкладці)Cypress
Зміни
чотири рядки розділу «Чотири зміни під робочими наборами»Дослідження з Claude. Пошук і звірку першоджерел зроблено з Claude (Anthropic). Відбір, текст і перевірку фактів — редакція Anatomy of IT Product.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.