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.jsoncypress.config.js / .ts
cypress/integrationcypress/e2e, файли *.cy.ts
testFilesspecPattern
cypress/plugins/index.jssetupNodeEvents у конфігу
cy.server(), cy.route()cy.intercept()
Cypress.Cookies.preserveOncecy.session()
Cypress DashboardCypress Cloud
Відео записується завждиЗ v13 вимкнене за замовчуванням

Будь-який із лівих термінів у твоїй відповіді сигналізує, що досвід закінчився до версії 10.

На співбесіді: З десятої версії конфіг — cypress.config, тести — у папці e2e, замість testFiles — specPattern, а плагіни переїхали в setupNodeEvents. Мережу перехоплюють через intercept замість старих server і route, а сесії зберігають через cy.session.