QA Interview Hub · База знань · Тести
Cypress
Пастки застарілих відповідей
що досі пишуть в інтернеті, і як правильно
Чи запускає Cypress тести паралельно і чи ретраїть упалі тести автоматично?
Обидва твердження хибні.
Паралельність: на одній машині Cypress виконує спеки послідовно — один процес, один браузер. Паралельно можна лише між кількома машинами: через Cypress Cloud (--record --parallel) або безкоштовно через матрицю CI і плагін на кшталт cypress-split.
Retries: за замовчуванням вимкнені. Їх треба явно ввімкнути в конфігу, зазвичай лише для CI.
// cypress.config.ts
export default defineConfig({
retries: { runMode: 2, openMode: 0 },
});
На співбесіді: Ні. На одній машині Cypress виконує спеки послідовно, паралельність буває тільки між кількома машинами — через Cloud або розбиття спеків у CI. А повторний запуск упалих тестів за замовчуванням вимкнений, я вмикаю його в конфігу для runMode, і кожен тест, що пройшов з повтору, розбираю окремо.
А в Playwright:У Playwright і те, і інше вбудоване: воркери паралелять тести на одній машині (за замовчуванням половина ядер), --shard ділить між машинами. Retries теж вимкнені за замовчуванням і задаються в конфігу (retries: process.env.CI ? 2 : 0), але трейс on-first-retry одразу показує, чому тест упав.
Як зберегти логін і cookies між тестами?
Cypress.Cookies.preserveOnce прибрали з Cypress 12, а ручне копіювання cookies — крихкий обхідний шлях. Сучасна відповідь — cy.session: він кешує cookies, localStorage і sessionStorage після логіну й відновлює їх у наступних тестах, а validate перевіряє, що сесія ще дійсна.
Детальніше — у питанні про cy.session у розділі «Стан, сесії, ізоляція».
На співбесіді: Сучасний спосіб — cy.session. Він один раз виконує логін, кешує cookies і сховища та відновлює їх у наступних тестах. Ручне копіювання cookies і старий preserveOnce — це підходи з версій до дванадцятої.
А в Playwright:Аналог — storageState: setup-проєкт логіниться і зберігає стан у JSON, інші проєкти підключають файл через dependencies.
Як зробити паузу (sleep) у Cypress?
Технічно cy.wait(ms) справді робить паузу, але правильна відповідь на співбесіді — пояснити, чому так робити не варто: фіксована пауза робить тест і повільним, і нестабільним.
Замість неї: асерт, який сам ретраїться (should('be.visible')), або очікування конкретного запиту через cy.intercept і cy.wait('@alias'). Виправдане використання cy.wait(ms) рідкісне — наприклад, перевірка debounce, де час і є вимогою.
На співбесіді: Формально — cy.wait з мілісекундами, але я так не роблю, бо це вгадане число: тест або чекає даремно, або падає. Я чекаю конкретний стан: асерт на елемент або завершення запиту через intercept з alias.
А в Playwright:У Playwright той самий антипатерн — page.waitForTimeout(). Замість нього web-first assertions і waitForResponse.
Як використовувати XPath у Cypress?
Нативної підтримки XPath немає, а офіційний плагін @cypress/xpath команда Cypress більше не підтримує. На старих проєктах його ще можна побачити, але радити його як рішення — ознака застарілих знань.
Задачі, для яких беруть XPath, закриваються вбудованими засобами: пошук за текстом — cy.contains, рух по дереву — .closest(), .parents(), .siblings(), .next(), семантичний пошук — Testing Library з cy.findByRole.
// XPath: //td[text()='Замовлення #1042']/parent::tr//button
cy.contains('td', 'Замовлення #1042').closest('tr').find('button').click();
На співбесіді: З коробки XPath у Cypress немає, а плагін для нього вже не підтримують. На практиці він і не потрібен: за текстом шукаю через contains, а від елемента до батька чи сусіда переходжу через closest, parents або siblings.
А в Playwright:Playwright підтримує XPath нативно (page.locator('xpath=...'), а рядок з // розпізнає сам), але рекомендує getByRole, getByText і getByTestId.
Як правильно встановлювати Cypress?
Локально в проєкт, як dev-залежність: npm install --save-dev cypress. Тоді версія зафіксована в package.json і lock-файлі, у всіх розробників і в CI вона однакова, а запуск іде через npx cypress.
Глобальна установка дає різні версії на різних машинах і ламає відтворюваність. Окремо зберігається лише бінарник Cypress — у системному кеші, і його перевіряють через npx cypress verify.
На співбесіді: Локально в проєкт як dev-залежність, щоб версія була зафіксована і однакова в усіх і в CI. Глобальна установка дає розбіжність версій між машинами.
А в Playwright:Те саме правило: npm i -D @playwright/test у проєкт, плюс npx playwright install для браузерів.
Елемент прихований і клік не проходить. Що робити?
Спершу зрозуміти, чому він прихований. Якщо його перекриває модалка, лоадер чи cookie-банер — тест виявив реальну проблему або сам має спершу закрити перешкоду. Якщо елемент з'являється після дії — треба дочекатися стану через should.
{ force: true } вимикає перевірки actionability, і тест може пройти там, де користувач клікнути не зміг би. Виправдано лише для свідомих випадків на кшталт прихованого нативного чекбокса під кастомним, і з коментарем.
На співбесіді: Спочатку з'ясовую причину: чи елемент перекритий, чи ще не з'явився, чи це баг. Force вимикає перевірки, і тест може стати зеленим там, де користувач застряг би, тому я використовую його лише в рідкісних обґрунтованих випадках і з коментарем.
Чим requestTimeout відрізняється від responseTimeout?
requestTimeout (5 с) — скільки cy.wait('@alias') чекає, поки застосунок відправить запит. Якщо за 5 секунд запит не пішов — помилка «No request ever occurred».
responseTimeout (30 с) — скільки чекати відповідь: на перехоплений запит у cy.wait і на cy.request.
Тобто це два різні етапи: «чи пішов запит» і «чи прийшла відповідь». Діагностика різна: перший таймаут зазвичай означає, що дія в UI не спрацювала або intercept зареєстровано після неї, другий — повільний бекенд.
На співбесіді: Це два етапи. requestTimeout — п'ять секунд на те, щоб запит узагалі відправився, і якщо він вичерпався, проблема зазвичай у тесті або UI. responseTimeout — тридцять секунд на відповідь сервера, і це вже про бекенд.
Як розпізнати застарілу відповідь про структуру Cypress?
| Застаріле (до v10) | Актуальне |
cypress.json | cypress.config.js / .ts |
cypress/integration | cypress/e2e, файли *.cy.ts |
testFiles | specPattern |
cypress/plugins/index.js | setupNodeEvents у конфігу |
cy.server(), cy.route() | cy.intercept() |
Cypress.Cookies.preserveOnce | cy.session() |
| Cypress Dashboard | Cypress Cloud |
| Відео записується завжди | З v13 вимкнене за замовчуванням |
Будь-який із лівих термінів у твоїй відповіді сигналізує, що досвід закінчився до версії 10.
На співбесіді: З десятої версії конфіг — cypress.config, тести — у папці e2e, замість testFiles — specPattern, а плагіни переїхали в setupNodeEvents. Мережу перехоплюють через intercept замість старих server і route, а сесії зберігають через cy.session.