Browse the Knowledge Hub101 resources
Question Bank
82 Cypress interview questions with answers
Eighty-two questions across the in browser architecture, selector strategy, the command queue and why Cypress commands are not promises, retry-ability, network stubbing with intercept, test data and state, custom commands, component testing, configuration, CI and parallelisation, debugging and the limitations worth naming before an interviewer does. Graded from fresher to lead, with the model answer, the follow-up to expect, and the trap that costs candidates the round.
All 82 questions, with model answers
Filter by level or topic, search the full text, and download the whole bank to revise offline.
Last updated
Experience level
Topic
Showing 82 of 82 questions
Q1FresherFundamentalsWhat is Cypress and what is it used for?
What is Cypress and what is it used for?
What they are assessing
Basic scope, and whether the candidate knows it is not a Selenium clone.
Model answer
Cypress is a JavaScript end to end testing framework that runs tests inside the browser alongside the application, rather than driving the browser from the outside over a wire protocol. It is used for end to end tests, integration tests and, since version 10, component tests. It ships as a complete package: runner, assertion library through Chai, mocking, stubbing and a time travelling debugger, so you are not assembling a stack from parts the way a Selenium project usually is.
Likely follow-up
What does running inside the browser let you do that WebDriver cannot?
Q2FresherFundamentalsWhich languages can you write Cypress tests in?
Which languages can you write Cypress tests in?
What they are assessing
Whether the candidate knows the constraint, and takes it seriously.
Model answer
JavaScript or TypeScript only. There is no Java, Python or C# binding, and there will not be one, because the tests execute in the browser rather than being sent to a driver. This is a genuine selection criterion rather than a detail: if the team has no JavaScript capability and the application is not a JavaScript front end, Cypress is a harder sell than Playwright, which has bindings for several languages.
Trap to avoid
Saying it supports many languages. It does not, and the interviewer is often asking precisely because they want to know whether you have evaluated tools rather than only used one.
Q3FresherFundamentalsWhat is the difference between cy.visit() and cy.request()?
What is the difference between cy.visit() and cy.request()?
What they are assessing
Whether the candidate separates UI navigation from HTTP calls.
Model answer
cy.visit() loads a page into the browser under test and makes the application available to subsequent commands. cy.request() makes an HTTP call directly from the Node process, outside the browser, and never renders anything. You use visit when the page is what you are testing, and request when you need to reach a state quickly: seeding data, logging in programmatically, or verifying an endpoint without a UI.
Likely follow-up
Why is cy.request() a good way to log in before a test?
Q4FresherFundamentalsWhat is the Cypress Test Runner, and what does time travel mean?
What is the Cypress Test Runner, and what does time travel mean?
What they are assessing
Familiarity with the day to day tooling.
Model answer
The Test Runner is the interactive application that executes specs in a real browser with the command log beside the page. Time travel means each command in that log holds a DOM snapshot from the moment it ran, so you can hover a step and see exactly what the page looked like at that point. It is the biggest day to day productivity feature, because most debugging is answering what the page actually looked like when this failed, without having to reproduce it.
Q5FresherFundamentalsWhat test runner and assertion library does Cypress use underneath?
What test runner and assertion library does Cypress use underneath?
What they are assessing
Whether the candidate knows what they are actually writing.
Model answer
Mocha provides the structure, so describe, context, it, before, beforeEach, after and afterEach are Mocha. Chai provides the assertions, extended with Chai-jQuery and Sinon-Chai, which is why you can assert have.class against a DOM element and have.been.calledWith against a stub. Knowing this matters because the Mocha and Chai documentation answers questions the Cypress documentation does not.
Likely follow-up
Which Mocha features does Cypress deliberately not support?
Q6Mid-levelFundamentalsWhat is the difference between e2e testing and component testing in Cypress?
What is the difference between e2e testing and component testing in Cypress?
What they are assessing
Understanding of the two modes added in version 10.
Model answer
End to end tests boot the real application, visit a URL and drive the whole stack as a user would. Component tests mount a single component in isolation in a real browser, with props and mocked dependencies supplied by the test, and no server involved. They share the same command API, the same runner and the same assertions, which is the point: you learn one API. The division of labour is that component tests cover rendering logic, props, states and edge cases cheaply, and end to end tests cover the journeys that matter, so you need far fewer of them.
Trap to avoid
Describing component testing as a replacement for end to end testing. It removes the need for a lot of low value end to end tests, not for the handful that prove the system works together.
Q7Mid-levelFundamentalsWhen would you not choose Cypress?
When would you not choose Cypress?
What they are assessing
Whether the candidate can argue against their own tool.
Model answer
Several cases. When you must test Safari on real iOS, or native mobile apps, because Cypress does not cover them. When the test genuinely requires multiple browser tabs or several independent browser sessions at once. When the team has no JavaScript capability. When you need broad cross browser coverage including WebKit as a first class target, where Playwright is stronger today. And when you need parallelisation across machines without standing up extra infrastructure, since orchestration is a paid feature of Cypress Cloud.
Likely follow-up
Which of those would you weigh most heavily on a new project?
Q8Mid-levelArchitectureHow does the Cypress architecture differ from Selenium WebDriver?
How does the Cypress architecture differ from Selenium WebDriver?
What they are assessing
The core architectural question, asked in almost every Cypress interview.
Model answer
Selenium runs outside the browser and sends commands to a browser driver over HTTP using the WebDriver protocol, so every instruction is a remote call and the test has no direct access to the application. Cypress executes inside the browser, in the same run loop as the application under test, with a Node process alongside it for anything needing the operating system. Because the test code and the application share a run loop, Cypress has synchronous access to the DOM, window, localStorage, the network layer and application internals.
Likely follow-up
What does that architecture make impossible?
Trap to avoid
Saying Cypress is faster because it has no network hop. It is often faster, but the real consequence is access and control, not latency.
Q9SeniorArchitectureWhat does the Cypress Node process do, and why is it separate?
What does the Cypress Node process do, and why is it separate?
What they are assessing
Whether the candidate understands the two halves of the system.
Model answer
The browser cannot touch the file system, spawn processes or intercept traffic at the network level, so anything of that kind runs in the Node process: reading and writing fixtures, screenshots and video, the proxy that lets Cypress see and modify traffic, and anything registered with cy.task or in setupNodeEvents. The two halves communicate over a WebSocket. This is why cy.task exists, and why spec files cannot simply require Node modules and expect them to work: the spec is bundled for the browser.
Likely follow-up
Give a concrete example of something you had to move into cy.task.
Q10SeniorArchitectureWhy did Cypress historically struggle with cross origin navigation, and how is it handled now?
Why did Cypress historically struggle with cross origin navigation, and how is it handled now?
What they are assessing
Depth on the most notorious Cypress constraint.
Model answer
Because Cypress runs in the browser, it is bound by the same origin policy. The application under test is loaded in an iframe, and a spec could not reach into an iframe on a different origin, so any flow navigating to another domain, typically a third party identity provider or payment page, broke the test. Cypress 9.6 introduced cy.origin, which runs a block of commands in the context of another origin, and it became stable in version 12. It works, with real constraints: variables do not cross the boundary automatically, so you pass them through the args option.
Trap to avoid
Saying cy.origin removed the limitation entirely. It made the common case workable. Multiple simultaneous origins and some redirect chains are still awkward, and the better answer is usually to avoid the third party page by logging in programmatically.
Q11SeniorArchitectureWhy can Cypress not control more than one browser tab?
Why can Cypress not control more than one browser tab?
What they are assessing
Whether the candidate can reason from the architecture to the limitation.
Model answer
Cypress runs inside the browser alongside the application, and its control extends to the window it is running in. A new tab is a separate browsing context Cypress has no handle on. The practical consequence is that any flow relying on target="_blank" needs rethinking. The standard approaches are to assert the anchor has the right href rather than following it, to remove the target attribute before clicking so navigation happens in the same tab, or to visit the destination URL directly. All three are legitimate, and an interviewer generally wants to hear that you test the intent rather than the mechanism.
Likely follow-up
How would you verify a link that opens a PDF in a new tab?
Q12SeniorArchitectureHow does Cypress handle the same origin policy within a single test?
How does Cypress handle the same origin policy within a single test?
What they are assessing
Precision about a rule candidates often state loosely.
Model answer
Within one test, Cypress requires that you stay on a single superdomain unless you explicitly use cy.origin. Navigating from one subdomain to another on the same superdomain is fine, because Cypress sets document.domain to the superdomain. Moving to an entirely different domain mid test is what triggers the cross origin error. The practical rule I apply is one origin per test where possible, and when a journey genuinely spans two, wrap the second in cy.origin rather than splitting the assertion across specs and losing the journey.
Q13LeadArchitectureA team wants to migrate a large Selenium suite to Cypress. What do you tell them?
A team wants to migrate a large Selenium suite to Cypress. What do you tell them?
What they are assessing
Judgement about migration, not enthusiasm for the new tool.
Model answer
First, that a direct port is the wrong model. The suites are structured differently, and translating Selenium page objects command for command produces Cypress code that fights the framework, typically by storing element references in variables and adding fixed waits. Second, I would ask what problem the migration solves. If the answer is flakiness, the cause is usually test design rather than the tool, and it will follow them across. Third, I would check the blockers early, because multi tab flows, Safari coverage and multi language teams can each kill the migration after significant investment. My usual recommendation is to run Cypress for new coverage, migrate the highest maintenance specs deliberately, and let the Selenium suite shrink rather than scheduling a cutover.
Likely follow-up
What would make you recommend against the migration outright?
Q14FresherSelectorsWhat is the recommended way to select elements in Cypress?
What is the recommended way to select elements in Cypress?
What they are assessing
Knowledge of the most repeated piece of Cypress guidance.
Model answer
A dedicated test attribute, conventionally data-cy or data-test, selected with cy.get and an attribute selector. The reason is decoupling: class names and ids change when styling or markup is refactored, and tag structure changes constantly, so tests tied to them break for reasons that have nothing to do with behaviour. A test attribute exists only for testing, so nobody removes it by accident, and its presence signals to developers that something depends on it.
Likely follow-up
How do you stop test attributes shipping to production, and should you?
Q15FresherSelectorsWhat is the difference between cy.get() and cy.contains()?
What is the difference between cy.get() and cy.contains()?
What they are assessing
Basic command knowledge.
Model answer
cy.get() selects by CSS selector or by alias. cy.contains() selects by visible text content, optionally scoped by a selector as a first argument. Both retry until they find something or time out. contains returns the first and deepest element containing the text, which surprises people, and it matches substrings by default, so Save also matches Save and close unless you pass an anchored regular expression.
Trap to avoid
Relying on cy.contains for everything. Text changes with copy edits and breaks under internationalisation, so it is reasonable for user facing assertions and poor for routine element selection.
Q16Mid-levelSelectorsHow does cy.get() differ from document.querySelector()?
How does cy.get() differ from document.querySelector()?
What they are assessing
Whether the candidate understands retry-ability at the selector level.
Model answer
querySelector runs once and returns null if the element is not there yet. cy.get retries the query repeatedly until the element exists or the timeout expires, and it yields a jQuery wrapped element rather than a raw node. That retry behaviour is why Cypress tests rarely need explicit waits for elements to appear. If you need the underlying DOM node, you unwrap it inside a then callback and take index zero.
Likely follow-up
If cy.get retries, why do people still get element not found failures?
Q17Mid-levelSelectorsHow do you select an element inside an iframe?
How do you select an element inside an iframe?
What they are assessing
Practical knowledge of a common gap.
Model answer
There is no first class command. The usual approach is to get the iframe element, read its contentDocument body through its, assert the body is not empty so you do not race the load, wrap it with cy.wrap, then use find within it. In practice most teams install cypress-iframe or write a custom command so this appears once rather than in every spec. If the iframe is on a different origin, the same origin policy applies and you cannot reach into it at all.
Trap to avoid
Forgetting the body may be empty on first access. Without a not.be.empty guard the test is flaky in a way that only appears under CI load.
Q18Mid-levelSelectorsWhat does .within() do?
What does .within() do?
What they are assessing
Scoping knowledge.
Model answer
It scopes all DOM commands inside its callback to the subject element, so you can target a field by name inside one form without matching the identical field in another. It is the clean answer to repeated elements on a page, such as the same input appearing in a billing and a shipping block. Commands that are not DOM based, such as cy.visit and cy.request, ignore the scope.
Q19SeniorSelectorsYour team cannot add data-cy attributes because the front end is a third party product. How do you build a reliable selector strategy?
Your team cannot add data-cy attributes because the front end is a third party product. How do you build a reliable selector strategy?
What they are assessing
Problem solving when the recommended answer is unavailable.
Model answer
I would build a layered strategy and centralise it. Prefer accessible attributes first, since role, aria-label and name are more stable than styling and are usually part of the contract. Where those are missing, use structural anchors that are semantically meaningful rather than positional, such as an input associated with its label, rather than nth-child. Put every selector in one module so a vendor redesign changes a file rather than a suite. And record which selectors are fragile, so the maintenance cost is visible when the vendor contract comes up for renewal.
Likely follow-up
How would you make the case to the vendor for test attributes?
Q20SeniorSelectorsWhat is a detached DOM element error and how do you fix it?
What is a detached DOM element error and how do you fix it?
What they are assessing
A failure every real Cypress user has hit.
Model answer
Cypress found the element, then the framework re-rendered and replaced that node before the next command ran, so the reference points at a node no longer in the document. It is most common in React and Vue applications where a state update rebuilds a list. The wrong fix is a fixed wait. The right fixes are to re-query rather than reuse a stored subject, to chain commands so each one re-runs the query, to assert a stable post-render condition before acting, and in stubborn cases to use should with a callback so the whole query retries as a unit.
Trap to avoid
Blaming Cypress. The error is a genuine race between test and application, and it often points at a real user facing instability where a control is clickable before the page has settled.
Q21Mid-levelCommands & chainingAre Cypress commands promises? Can you use async and await with them?
Are Cypress commands promises? Can you use async and await with them?
What they are assessing
The most important Cypress concept, and the most commonly misunderstood.
Model answer
No. Cypress commands are not promises, they are enqueued. Calling cy.get does not execute anything, it adds a command to a queue that Cypress runs after the test function has finished executing. They look promise-like because they are thenable, but they do not behave like promises: you cannot await them meaningfully and they have no catch. Using async and await alongside Cypress commands produces code that appears to work and then fails unpredictably, because you are mixing two execution models.
Likely follow-up
So how do you work with the value a command yields?
Trap to avoid
Assigning cy.get to a variable and using it later. That variable holds a Chainable, not an element, and every downstream line is wrong.
Q22Mid-levelCommands & chainingHow do you use the value a Cypress command yields?
How do you use the value a Cypress command yields?
What they are assessing
The practical consequence of the previous answer.
Model answer
With then, which receives the yielded subject as its argument. Anything you need to do with the value happens inside that callback, because outside it the command has not run yet. For reusing a value across commands, as creates an alias you retrieve with cy.get and an at sign prefix, which is cleaner than nesting then blocks several levels deep.
Likely follow-up
What is the difference between then and should with a callback?
Q23SeniorCommands & chainingWhat is the difference between .then() and .should() with a callback?
What is the difference between .then() and .should() with a callback?
What they are assessing
A distinction that separates people who have debugged flake from people who have not.
Model answer
The crucial difference is retry. A should callback is retried until it passes or the command times out, so any assertion inside it gets the benefit of retry-ability. A then callback runs exactly once. Assertions placed in then against a value that has not settled yet will fail intermittently, while the same assertions in should will wait. The rule I use is that should is for assertions and anything that needs to become true, and then is for taking a settled value and doing something with it, bearing in mind the callback must be free of side effects since it may run many times.
Trap to avoid
Putting a side effect such as a cy.request or a counter increment inside a should callback. Because it retries, the side effect happens repeatedly.
Q24Mid-levelCommands & chainingWhat does .as() do and when would you use it?
What does .as() do and when would you use it?
What they are assessing
Alias knowledge, which spans DOM, routes and fixtures.
Model answer
It assigns a name to the current subject so you can retrieve it later with cy.get and an at sign, or wait on it with cy.wait for network aliases. It works for three things: DOM elements, where it re-queries rather than reusing a stale reference, network intercepts, where it lets you wait for and inspect a specific call, and fixtures, where it exposes loaded data to the test. The re-query behaviour for DOM aliases matters, since it is why aliases avoid the detached element problem that storing an element in a variable creates.
Q25Mid-levelCommands & chainingWhat is the difference between parent, child and dual commands?
What is the difference between parent, child and dual commands?
What they are assessing
Whether the candidate understands the command grammar.
Model answer
Parent commands start a new chain and ignore any previous subject: cy.visit, cy.get, cy.request. Child commands must be chained off a subject and act on it: click, type, find, should. Dual commands do either, as cy.contains and cy.wait do. It matters because chaining a parent command off another command silently starts a new chain rather than scoping, which is a common cause of a test passing against the wrong element.
Likely follow-up
Why does cy.get() inside a .within() respect the scope if it is a parent command?
Q26SeniorCommands & chainingWhy does Cypress discourage conditional testing, and when is it legitimate?
Why does Cypress discourage conditional testing, and when is it legitimate?
What they are assessing
Understanding of a genuinely subtle topic.
Model answer
Because in most cases you cannot know the DOM has settled. Writing logic that dismisses a cookie banner if it is present asks Cypress to decide on a snapshot that may change a moment later, so the test passes or fails on timing rather than behaviour. The deeper objection is that a conditional usually means the test does not know what state the application is in, and a test that does not know its own preconditions is not a reliable signal. It is legitimate when the state is genuinely out of your control and already settled, for example branching on data you fetched yourself through cy.request. The better answer most of the time is to control the condition: seed the state, set the cookie, or stub the response so the branch does not exist.
Trap to avoid
Reaching for Cypress.$ to check existence without a wait. It gives a one-shot synchronous answer and reintroduces exactly the race the framework was protecting you from.
Q27SeniorCommands & chainingWhat does cy.wrap() do and when do you need it?
What does cy.wrap() do and when do you need it?
What they are assessing
Knowledge of the bridge between ordinary values and the command chain.
Model answer
It takes a plain value, a jQuery object or a promise and makes it the subject of a Cypress chain, so you can apply Cypress commands and assertions to it. You need it when a value arrives from outside the queue: a result from cy.task, an element obtained through Cypress.$, an object from an imported helper, or a promise from a third party client library. Wrapping a promise is also the supported way to make Cypress wait for genuinely asynchronous non-Cypress code, since the queue will not resolve it otherwise.
Q28SeniorCommands & chainingWhat is the difference between .each() and .then() on a list of elements?
What is the difference between .each() and .then() on a list of elements?
What they are assessing
Iteration patterns, which candidates routinely get wrong.
Model answer
then receives the whole jQuery collection once, so you iterate it yourself with plain JavaScript, and any Cypress commands you issue inside are queued rather than run per item in the way you might expect. each iterates the collection and runs its callback for each element, correctly serialising any Cypress commands issued inside it. If you need to run commands per element, use each. If you only need to read values from the collection, then is simpler. Either way, remember the collection is a snapshot, so a re-render mid loop gives you detached elements.
Likely follow-up
How would you assert that a table column is sorted ascending?
Q29FresherAssertionsWhat is the difference between implicit and explicit assertions?
What is the difference between implicit and explicit assertions?
What they are assessing
Basic assertion vocabulary.
Model answer
Implicit assertions are made with should or and, chained off a command, and they apply to the current subject: getting an element and asserting it is visible. Explicit assertions use expect or assert inside a then callback, where you have a value in hand and assert on it directly. The guidance is to prefer implicit assertions, because they retry, and to use explicit ones when you need to compute something before asserting.
Q30FresherAssertionsHow do you assert that an element is not present versus not visible?
How do you assert that an element is not present versus not visible?
What they are assessing
A distinction that causes real bugs to be missed.
Model answer
not.exist asserts the element is absent from the DOM entirely. not.be.visible asserts it is in the DOM but hidden, through display none, visibility hidden, zero size or a hidden ancestor. They are different outcomes and conflating them hides defects: a modal that is removed and a modal that is merely transparent behave differently for keyboard users and screen readers. Pick the one that matches the behaviour you actually want.
Trap to avoid
Using not.be.visible when the element does not exist. The assertion fails, because Cypress cannot evaluate visibility of something that is not there.
Q31Mid-levelAssertionsHow do you chain multiple assertions on the same element?
How do you chain multiple assertions on the same element?
What they are assessing
Fluency with the assertion API.
Model answer
With and, which is an alias for should that keeps the same subject: assert an element is visible, and has a class, and contains text. Each link retries as part of the same command. Chaining is better than separate get calls for the same element both because it reads better and because it re-queries less. If assertions diverge onto child elements, within or find is clearer than a long chain.
Q32Mid-levelAssertionsHow would you assert on text that is split across child elements?
How would you assert on text that is split across child elements?
What they are assessing
A common practical problem.
Model answer
contain checks the combined text content of the element and its descendants, so asserting the parent contains the full string usually works even when the markup splits it across spans. When whitespace is the issue, read the text in a then callback, normalise it by collapsing whitespace, then assert on the normalised value with expect. The second approach is more code but far more stable against formatting changes.
Trap to avoid
Using have.text, which asserts the exact full text of the element including whitespace from the markup, and so breaks on a line break a developer added for readability.
Q33Mid-levelAssertionsWhat is the difference between have.value, have.text and contain?
What is the difference between have.value, have.text and contain?
What they are assessing
Precision.
Model answer
have.value reads the value property, so it is for form controls: inputs, selects and textareas. have.text asserts the exact text content of the element. contain asserts the text content includes the given substring, and is the more forgiving of the two. The common error is asserting have.text on an input, which fails, because an input has no text content.
Q34SeniorAssertionsHow do you assert something does not happen, for example that a request was never made?
How do you assert something does not happen, for example that a request was never made?
What they are assessing
Negative assertion, which is genuinely hard.
Model answer
Carefully, because you cannot prove absence by waiting a moment. For network calls I intercept and alias the route, then use cy.get on the alias with should and null to assert it has not been called, after driving the application to the point where the call would have fired. The important part is establishing a positive synchronisation point first: do the thing, wait for an observable consequence that definitely means the application has finished, and only then assert the absence. Asserting a negative without that anchor is a test that passes because it checked too early.
Likely follow-up
What is the weakness of that approach even when done properly?
Q35SeniorAssertionsWhat is a soft assertion, and does Cypress support them?
What is a soft assertion, and does Cypress support them?
What they are assessing
Knowledge of a genuine gap and how teams work around it.
Model answer
A soft assertion records a failure but lets the test continue, so one run reports several problems. Cypress does not support them natively: the first failed assertion fails the test. Workarounds exist, collecting results in an array and asserting at the end, or using a plugin, but I would question the requirement first. Needing several independent assertions in one test usually means the test is doing several jobs, and splitting it gives clearer failures without any workaround. The genuine case is a page-wide check such as validating many fields on a form.
Q36Mid-levelRetry & waitingExplain retry-ability in Cypress.
Explain retry-ability in Cypress.
What they are assessing
The concept that most flake traces back to.
Model answer
Most Cypress queries and all assertions retry automatically until they pass or the command times out, defaulting to four seconds. That is why you do not write explicit waits for elements to appear. The critical detail is that only the last query before an assertion is retried, together with the assertion. If you chain get, then find, then an assertion, Cypress retries the find and the assertion but will not go back and re-run the get. Understanding this explains most of the cases where a test behaves as if retry is not working.
Likely follow-up
Given that, how would you restructure a chain so the whole query retries?
Q37Mid-levelRetry & waitingWhy is cy.wait() with a fixed number of milliseconds considered an anti-pattern?
Why is cy.wait() with a fixed number of milliseconds considered an anti-pattern?
What they are assessing
A question almost guaranteed to be asked.
Model answer
Because it couples the test to a duration rather than to a condition. The number is always wrong: too small and the test is flaky when CI is loaded, too large and every run pays the cost whether needed or not. A suite full of fixed waits is both slow and still flaky, which is the worst combination. The alternatives are waiting on an aliased network call, or asserting on the state that proves the application is ready. Both wait exactly as long as necessary and no longer.
Trap to avoid
Saying it is always wrong. There are narrow cases, such as a CSS animation with no observable completion event, where a short fixed wait is the pragmatic answer. Saying so reads as experience rather than dogma.
Q38Mid-levelRetry & waitingHow does cy.wait() on an alias differ from cy.wait() on a number?
How does cy.wait() on an alias differ from cy.wait() on a number?
What they are assessing
The preferred waiting mechanism.
Model answer
Waiting on an alias from cy.intercept waits for that specific HTTP call to complete and then yields the interception object, giving you access to the request and response so you can assert on status, body or headers. It waits only as long as the call takes. Waiting on a number pauses for that duration regardless of what the application is doing. The alias form is both faster and more meaningful, because the test states what it is waiting for.
Q39SeniorRetry & waitingWhich commands do not retry, and why does that matter?
Which commands do not retry, and why does that matter?
What they are assessing
Precision about where the safety net ends.
Model answer
Action commands do not retry: click, type, select, check and similar. They wait for actionability, meaning the element must be visible, not disabled, not covered and not animating, but once those conditions are met they fire once. then does not retry either. Nor do commands with side effects such as cy.request or cy.task. It matters because any assertion you want to be resilient must sit in a retrying command, and because a click that fires into a transitional state will not try again on your behalf.
Likely follow-up
What are the actionability checks Cypress performs before a click?
Q40SeniorRetry & waitingWhat does Cypress check before performing a click, and what is force: true doing?
What does Cypress check before performing a click, and what is force: true doing?
What they are assessing
Actionability, and whether the candidate abuses the escape hatch.
Model answer
Cypress checks that the element is not hidden, not disabled, not detached, not covered by another element at the click coordinates, and that it has stopped animating. It scrolls it into view, then fires the event. Passing force true skips every one of those checks and dispatches the event directly. It is occasionally necessary, for instance when a custom control uses an invisible input, but reaching for it to fix a failure usually suppresses a real finding: if a user could not click that element, the test should not either.
Trap to avoid
Using force true to get past a covering overlay. The overlay is the bug, and forcing the click means production ships with an element users cannot reach.
Q41SeniorRetry & waitingA test fails only in CI, never locally. How do you approach it?
A test fails only in CI, never locally. How do you approach it?
What they are assessing
Debugging method under the most common real condition.
Model answer
First I gather evidence rather than guess: the video and screenshots from the failing run, and the command log in the Cypress Cloud output if available. Then I look for the usual causes in order. Timing, because CI is slower and surfaces races a fast machine hides. Viewport, since CI runs headless at the configured size and an element may be off screen or behind a sticky header. Test data, where a shared environment has state another run left behind. Ordering, where the test only passes because a previous test left the application in a convenient state. And environment differences such as feature flags or seeded accounts. I try to reproduce by running headless locally at the CI viewport with the CI configuration before changing anything.
Likely follow-up
How would you confirm the cause is ordering rather than timing?
Q42LeadRetry & waitingYour suite has a 12 percent flake rate. How do you bring it down?
Your suite has a 12 percent flake rate. How do you bring it down?
What they are assessing
Systematic thinking rather than a list of tips.
Model answer
I would make it measurable before making it better. Record every failure with its spec, the command that failed and the run, so I can rank by frequency rather than by whoever complained most recently. Almost always a small number of specs produce most of the noise, so the first pass is targeted rather than general. Then I categorise causes: fixed waits, shared state between tests, unstubbed third party calls, real application races and genuine defects. Each has a different fix, and the last category is the one worth protecting, because teams under flake pressure start deleting tests that are actually correct. I would also quarantine the worst offenders out of the blocking pipeline immediately, so the team regains trust in the signal while the work happens, with a deadline on the quarantine so it does not become permanent.
Likely follow-up
How do you stop quarantine becoming a graveyard?
Q43Mid-levelNetwork & interceptWhat is cy.intercept() and what replaced it?
What is cy.intercept() and what replaced it?
What they are assessing
Current API knowledge.
Model answer
cy.intercept is the command for observing and modifying network traffic. It replaced cy.route and cy.server, which were removed in Cypress 12. The improvement is substantial: intercept handles fetch as well as XHR, which route could not, and it can match on method, URL, headers and body, modify requests on the way out as well as responses on the way back, and delay or throttle a response to simulate slow networks.
Likely follow-up
Why was the inability to intercept fetch such a problem?
Q44Mid-levelNetwork & interceptWhat is the difference between stubbing and spying with cy.intercept()?
What is the difference between stubbing and spying with cy.intercept()?
What they are assessing
A distinction that drives test design.
Model answer
Spying means intercepting without supplying a response, so the real call goes to the server and you observe it, usually to alias it and wait on it or assert on the request payload. Stubbing means supplying a response, so the call never reaches the server and the application receives exactly what you specified. Spying gives integration confidence and depends on the backend being up and the data being right. Stubbing gives determinism and speed and lets you produce states the real backend will not easily give you, such as a 500 or an empty list.
Q45SeniorNetwork & interceptWhen should you stub network calls, and when should you not?
When should you stub network calls, and when should you not?
What they are assessing
Judgement about the central trade-off in end to end testing.
Model answer
Stub when the call is not what you are testing and determinism matters more than integration: third party services, error and edge states, slow endpoints, and setup traffic on the way to the thing under test. Do not stub the call that is the point of the test. If you stub everything, you have a very fast suite that proves the front end renders fixtures correctly and would not notice the API changing its contract. My usual shape is a small number of fully integrated journeys that stub nothing, and a larger number of stubbed tests covering states and errors, with contract tests covering the API shape so the stubs cannot silently drift from reality.
Trap to avoid
Not having an answer for stub drift. Stubbed responses are a copy of a contract, and without something enforcing that contract the suite goes green while production breaks.
Q46SeniorNetwork & interceptHow do you test how the UI handles a server error or a slow response?
How do you test how the UI handles a server error or a slow response?
What they are assessing
Practical use of intercept beyond the happy path.
Model answer
For an error, intercept the route and reply with the status code and body the server would return, then assert the application shows the right message, keeps the user data they entered, and offers a way to retry. For slowness, intercept with a delay, then assert the loading state appears and that controls are disabled so the user cannot double submit. For a network failure rather than an error status, use forceNetworkError. These states are where most real defects live and where production incidents originate, and they are nearly impossible to trigger reliably without stubbing.
Likely follow-up
How would you test a request that times out entirely?
Q47SeniorNetwork & interceptHow do you wait for a specific call among several to the same endpoint?
How do you wait for a specific call among several to the same endpoint?
What they are assessing
A real problem on busy applications.
Model answer
Match more narrowly so the intercept only captures the call you care about: add the method, a query parameter, or a body matcher rather than matching the path alone. If that is not possible, cy.wait on the same alias repeatedly yields each matching call in order, so you can wait twice and assert on the second. You can also supply a routeHandler function and inspect the request before deciding to reply. What I avoid is waiting on a bare path and hoping the right call arrives first, which is a race dressed up as an assertion.
Q48SeniorNetwork & interceptHow do you assert on the body of a request the application sent?
How do you assert on the body of a request the application sent?
What they are assessing
Request-side verification, which many candidates have never done.
Model answer
Intercept and alias the route without stubbing, drive the UI, then wait on the alias and inspect the yielded interception object, whose request property holds the body, headers and URL. This is how you prove that the form actually sent the fields the backend expects, including the ones that are not visible on screen, such as a tracking identifier or a correlation header. It is one of the highest value assertions available, because a UI can look entirely correct while sending the wrong payload.
Q49FresherTest dataWhat is a fixture and how do you use one?
What is a fixture and how do you use one?
What they are assessing
Basic data handling.
Model answer
A fixture is a static file, usually JSON, held in the fixtures folder and loaded with cy.fixture. It is used to supply stubbed responses to cy.intercept, or to feed input data to a test. Loading it with an alias makes the data available across the test. Fixtures keep data out of the spec, so the same payload is reused rather than copied and the test reads as behaviour rather than as a wall of JSON.
Q50Mid-levelTest dataHow do you handle test data that must be unique per run?
How do you handle test data that must be unique per run?
What they are assessing
A problem every shared environment creates.
Model answer
Generate it rather than hardcode it. A timestamp or a short random suffix on an email or a reference keeps runs from colliding, and a faker style library makes the data realistic. The more important half is cleanup: either the test removes what it created through an API call in an after hook, or the environment is reset on a schedule, or the data is namespaced so it can be purged in bulk. Creating unique data without a cleanup story means the database grows until something unrelated starts failing.
Likely follow-up
Why is cleanup in an after hook not completely reliable?
Q51Mid-levelTest dataHow do you seed application state before a test?
How do you seed application state before a test?
What they are assessing
Whether the candidate drives setup through the UI.
Model answer
Through the API with cy.request, or through a task that talks to the database or a seeding endpoint. The principle is that you only drive the UI for the thing you are testing, and reach every precondition the fastest reliable way. A test about checkout should not spend forty seconds registering, confirming an email and adding items through the interface, because every one of those steps is an opportunity to fail for a reason unrelated to checkout, and the registration flow already has its own test.
Trap to avoid
Seeding through the UI because it is more realistic. It makes the test slower and more fragile, and it does not improve the signal, since the setup path is covered by its own test.
Q52SeniorTest dataHow do you handle authentication across a suite?
How do you handle authentication across a suite?
What they are assessing
A decision that affects every spec.
Model answer
Log in programmatically, not through the form, for every test except the one testing login itself. The modern answer is cy.session, which runs the login steps once, caches the resulting cookies, localStorage and sessionStorage, and restores them for subsequent tests, validating the session is still good before reusing it. Before cy.session this meant a cy.request to the auth endpoint and writing the token into storage by hand. Either way the saving is large: a suite of two hundred specs each spending eight seconds on a login form is nearly half an hour of nothing.
Likely follow-up
What does the validate option on cy.session do, and why would you use it?
Q53SeniorTest dataHow would you test a flow that needs an email, such as a password reset?
How would you test a flow that needs an email, such as a password reset?
What they are assessing
A gap Cypress does not cover natively.
Model answer
Not by opening a real inbox in the browser. The options are a mail catching service with an API such as Mailosaur or MailHog, which the test queries over cy.request to read the message and extract the link, or a backend test endpoint that returns the most recent token for an address, which is faster and usually acceptable in a non-production environment. The second needs care so it never exists in production. In either case the test retrieves the link by API and then visits it, so Cypress never has to drive a mail client.
Q54FresherHooks & stateWhat hooks are available and in what order do they run?
What hooks are available and in what order do they run?
What they are assessing
Mocha basics as they apply in Cypress.
Model answer
before runs once before all tests in its block, beforeEach runs before each test, afterEach after each test, and after once when the block finishes. With nested describe blocks the outer before hooks run before the inner ones, and the after hooks unwind in the opposite order. Most setup belongs in beforeEach, because setup in before leaks state from one test into the next.
Q55Mid-levelHooks & stateWhy is putting setup in before() rather than beforeEach() usually a mistake?
Why is putting setup in before() rather than beforeEach() usually a mistake?
What they are assessing
Test independence.
Model answer
Because whatever before established is shared by every test in the block, and the first test that modifies it changes the starting conditions for the rest. The suite then passes only in one order, and a failure in test two can be caused by test one. Cypress compounds this: since version 12 test isolation is enabled by default for end to end tests, so cookies, localStorage and the page are cleared between tests, which can leave state created in before only partially intact and produce confusing failures.
Trap to avoid
Using before for speed. The time saved is real but small, and the cost is a suite whose failures cannot be read.
Q56Mid-levelHooks & stateWhat is test isolation in Cypress 12 and what changed?
What is test isolation in Cypress 12 and what changed?
What they are assessing
Awareness of a significant behavioural change.
Model answer
From version 12, each test in an end to end spec starts in a clean browser context by default: cookies, localStorage and sessionStorage are cleared and the page is reset between tests. Before that, state carried over, and many suites quietly depended on it, which is why upgrading broke tests that had been passing for years. You can disable it per suite with testIsolation false, which is sometimes the pragmatic answer for a long journey split across tests, but it is a deliberate trade and should be rare.
Likely follow-up
Why would a long journey split across tests be a design smell anyway?
Q57SeniorHooks & stateShould tests be independent, and how do you handle a genuinely long journey?
Should tests be independent, and how do you handle a genuinely long journey?
What they are assessing
Whether the candidate holds the principle without being rigid.
Model answer
Yes, independent by default, because dependent tests cannot be run in isolation, cannot be parallelised, and produce failures that point at the wrong place. For a genuinely long journey the answer is usually not to split it across dependent tests but to keep it as one test and make it fast by seeding everything up to the point of interest through the API. If the journey truly must be staged, I would make each stage set up its own preconditions programmatically, so each is still independently runnable even though they read as a sequence.
Q58SeniorHooks & stateWhat is cy.session() and what problem does it solve?
What is cy.session() and what problem does it solve?
What they are assessing
Knowledge of the most useful recent addition.
Model answer
It caches and restores the browser state produced by a set of login steps, keyed by an identifier you supply. The first test to request a session runs the setup; subsequent tests restore the cached cookies and storage instead, which is near instant. An optional validate callback runs before reuse, so an expired session is detected and re-created rather than producing a confusing failure deep in the test. It solved the problem that test isolation made worse, where clearing state between tests meant logging in again every time.
Likely follow-up
What should the session key include when tests use different user roles?
Q59Mid-levelCustom commandsHow do you create a custom command and where do they live?
How do you create a custom command and where do they live?
What they are assessing
Basic extensibility.
Model answer
With Cypress.Commands.add, giving a name and a function, declared in the support commands file so it is loaded for every spec. It can be a parent command or, with prevSubject set, a child command that receives whatever was chained into it. In TypeScript you also declare the signature in the Cypress namespace so the editor knows about it, which is worth doing because an undeclared custom command gives no autocomplete and no type checking at the call site.
Q60SeniorCustom commandsWhen should something be a custom command rather than a plain function?
When should something be a custom command rather than a plain function?
What they are assessing
Design judgement, where many teams over-apply the feature.
Model answer
Make it a custom command when it needs to participate in the command queue, when it should appear in the command log for debugging, or when it genuinely reads better chained off a subject. Use a plain imported function for everything else, including most page object methods and any pure helper. Custom commands are globally available, which sounds convenient and becomes a problem: a support file with sixty commands is a global namespace nobody can navigate, and plain functions give better type inference and are easier to find.
Trap to avoid
Turning every page action into a custom command. It bloats the global namespace and makes the origin of a command hard to trace.
Q61SeniorCustom commandsHow do you overwrite an existing Cypress command, and when is that justified?
How do you overwrite an existing Cypress command, and when is that justified?
What they are assessing
Knowledge of a powerful and dangerous feature.
Model answer
With Cypress.Commands.overwrite, which receives the original command as its first argument so you can call through to it. Legitimate uses are narrow: adding a default header to every cy.visit, logging every cy.request for debugging, or applying a consistent screenshot setting. It is dangerous because anyone reading a spec sees a standard command behaving in a non standard way with nothing at the call site to indicate it. If I use it, I document it clearly, because a surprising override is one of the hardest things to debug in an unfamiliar suite.
Q62SeniorCustom commandsDo you use the Page Object Model with Cypress?
Do you use the Page Object Model with Cypress?
What they are assessing
Whether the candidate has a reasoned position rather than a habit.
Model answer
Sometimes, but not in the Selenium form. Cypress itself argues against it, and the objection has merit: page objects in Selenium exist largely to manage element references and waits, and Cypress removes both problems through retry-ability and re-querying. What survives is the valuable part, namely centralising selectors and naming meaningful user actions. So I tend to use a selectors module plus task functions such as one that submits a login, rather than classes with element getters. The genuine problem with classic page objects here is that they encourage storing elements, which is the precise pattern that produces detached element errors.
Likely follow-up
What would change your mind on a given project?
Q63Mid-levelComponent testingHow does Cypress component testing work?
How does Cypress component testing work?
What they are assessing
Understanding of the mode rather than just its existence.
Model answer
The component is mounted directly into a real browser with cy.mount, with no application server and no routing, using a dev server from your own project configuration so the component builds exactly as it does in the application. You pass props and mock dependencies from the test, then use the same commands and assertions as end to end tests. The distinguishing feature against a jsdom based runner is that it is a real browser, so layout, CSS, real events and visibility assertions all behave as they do in production.
Likely follow-up
What can you test in a browser that jsdom cannot give you?
Q64SeniorComponent testingWhen would you choose component tests over end to end tests?
When would you choose component tests over end to end tests?
What they are assessing
Testing strategy.
Model answer
For anything where the component is the unit of risk: rendering branches, prop combinations, validation states, error and empty states, and edge cases in presentation. They run in a fraction of the time, fail with a precise location, and need no backend, so they are the right place for breadth. End to end tests should be reserved for proving the pieces work together across the real stack, which is a smaller set of journeys than most teams write. The practical shape is wide component coverage and a thin, deliberate end to end layer.
Q65SeniorComponent testingWhat are the limitations of Cypress component testing?
What are the limitations of Cypress component testing?
What they are assessing
Balance.
Model answer
It is slower per test than a jsdom runner such as Jest or Vitest, because each test runs in a real browser, so for a large number of pure logic tests it is the wrong tool. Framework support, while good for React, Vue, Angular and Svelte, lags behind for less common setups, and unusual build configurations can be awkward to wire up. It also does not replace unit tests for non-component code. And since it mocks the dependencies, it shares the standard isolation weakness: everything passes while the integration is broken.
Q66Mid-levelConfigurationWhat is cypress.config.js and what goes in it?
What is cypress.config.js and what goes in it?
What they are assessing
Current configuration knowledge, which changed at version 10.
Model answer
It is the configuration file that replaced cypress.json in version 10. It exports an object with separate e2e and component sections, each holding settings such as baseUrl, specPattern, viewport dimensions, timeouts, retries, and a setupNodeEvents function where you register plugins and tasks. The move to a JavaScript file was specifically so configuration could be computed, for instance reading environment variables, which a JSON file could not do.
Q67Mid-levelConfigurationHow do you manage environment specific configuration and secrets?
How do you manage environment specific configuration and secrets?
What they are assessing
Practical setup across environments.
Model answer
Environment values go through Cypress environment variables, read in tests with Cypress.env, and can be supplied by a cypress.env.json file that is not committed, by CYPRESS_ prefixed operating system variables, or on the command line. baseUrl is usually overridden per environment so the same specs run anywhere. Secrets never go in the repository or in cypress.config: they come from the CI secret store as environment variables at run time. I also avoid putting credentials in fixtures, which is a common accident because fixtures feel like data rather than code.
Trap to avoid
Committing cypress.env.json. It is the standard way credentials end up in a repository, and the file name does not look alarming in a diff.
Q68Mid-levelConfigurationWhat is the difference between defaultCommandTimeout, pageLoadTimeout and requestTimeout?
What is the difference between defaultCommandTimeout, pageLoadTimeout and requestTimeout?
What they are assessing
Whether the candidate knows which knob to turn.
Model answer
defaultCommandTimeout, four seconds by default, governs how long most commands and assertions retry. pageLoadTimeout, sixty seconds, is how long cy.visit and page transitions may take. requestTimeout, five seconds, is how long cy.wait on a route waits for the request to begin, with responseTimeout covering the response. Raising defaultCommandTimeout globally to mask a slow page is a common mistake: it slows every failure in the suite, so a failing run takes far longer to report. Overriding the timeout on the single command that needs it is better.
Q69SeniorConfigurationWhat are test retries in Cypress and what is your position on them?
What are test retries in Cypress and what is your position on them?
What they are assessing
A question where the easy answer is the wrong one.
Model answer
Configured retries re-run a failing test a set number of times before reporting failure, and can be set separately for runMode and openMode. They are useful as a stabiliser so a single flaky test does not block a pipeline. My position is that they are a painkiller, not a cure: a retried test still failed, and if nobody looks at the retry data the suite silently degrades until the retries stop being enough. So I enable them in CI, usually two attempts, and treat the count of tests that only passed on retry as a metric to drive down rather than a problem that has been solved.
Trap to avoid
Presenting retries as the fix for flakiness. Interviewers asking this are usually checking whether you distinguish suppressing a symptom from fixing a cause.
Q70Mid-levelCI & parallelHow do you run Cypress in CI?
How do you run Cypress in CI?
What they are assessing
Basic pipeline knowledge.
Model answer
With cypress run, which executes headlessly and records video and screenshots on failure. In practice that means installing dependencies with a cached Cypress binary, starting the application, waiting until it actually responds rather than sleeping, then running the specs and publishing artefacts. Most teams use the official Docker images or the official CI actions, because they already contain the system libraries the browsers need, which is otherwise a recurring source of setup failures.
Likely follow-up
Why does waiting for the server to respond matter more than it sounds?
Q71SeniorCI & parallelHow does parallelisation work in Cypress?
How does parallelisation work in Cypress?
What they are assessing
Knowledge of a genuine commercial constraint.
Model answer
Cypress parallelises at the spec file level, not within a spec, across multiple CI machines. Doing it with the built in support requires a recording key and Cypress Cloud, which orchestrates the balancing by assigning each machine the next spec as it becomes free, weighting by past duration. Without Cloud you can split specs across machines manually or use an open source orchestrator such as sorry-cypress. Because the split is per spec, one very long spec sets the floor on total duration, so balancing spec sizes matters as much as adding machines.
Trap to avoid
Saying Cypress parallelises tests. It parallelises spec files, and a single spec containing forty tests still runs serially on one machine.
Q72SeniorCI & parallelYour suite takes 50 minutes in CI. How do you make it faster?
Your suite takes 50 minutes in CI. How do you make it faster?
What they are assessing
Optimisation thinking in the right order.
Model answer
I would measure first, because the distribution is usually uneven and a few specs dominate. Then, roughly in order of return: remove fixed waits, which are almost always present and are pure dead time. Replace UI login with cy.session. Seed state through the API rather than driving the interface to reach preconditions. Stub third party calls that are slow and not under test. Then split long specs so parallelisation can balance them, and add machines. I would also question coverage: suites of this length usually contain many end to end tests that should be component tests, and moving them is a larger win than any amount of tuning.
Likely follow-up
Which of those would you expect to give the biggest single saving?
Q73LeadCI & parallelShould the full Cypress suite run on every pull request?
Should the full Cypress suite run on every pull request?
What they are assessing
Pipeline design judgement.
Model answer
Usually not, once the suite is beyond a few minutes. The useful shape is a fast subset on every pull request, covering critical journeys and anything touching the changed area, with the full suite on merge to the main branch and on a schedule. The reasoning is that pull request feedback has to be fast enough that people wait for it, and a thirty minute gate gets ignored or bypassed. I would pair that with a rule that a failure in the full post-merge run is treated as a blocking issue rather than something to look at later, because otherwise the subset becomes the only suite anyone trusts.
Q74Mid-levelDebuggingHow do you debug a failing Cypress test?
How do you debug a failing Cypress test?
What they are assessing
Practical method.
Model answer
In the interactive runner, the command log with time travel usually answers it directly: hover the failing command and see the DOM as it was. Beyond that, cy.pause stops execution so you can step, .debug inserts a breakpoint with the subject available in the console, and cy.log writes to the command log. In headless runs the video and screenshots are the primary evidence. The habit that matters most is reading the failure message properly before changing anything, since Cypress error messages are unusually specific about what it was looking for and how long it waited.
Q75Mid-levelDebuggingWhat is the difference between cy.log(), console.log() and .debug()?
What is the difference between cy.log(), console.log() and .debug()?
What they are assessing
Tooling detail.
Model answer
cy.log writes a message into the Cypress command log, in queue order, so it appears in the right place in the sequence and survives into the run artefacts. console.log writes to the browser console and executes immediately when the test function runs, which means it fires before any queued command, so its output is usually in a misleading order. .debug is chained off a command, pauses with a debugger statement and exposes the current subject in the console for inspection.
Trap to avoid
Using console.log to trace command order. Because commands are queued, the output order does not reflect execution order, which sends people down the wrong path.
Q76SeniorDebuggingA test passes in the interactive runner but fails headless. What are the likely causes?
A test passes in the interactive runner but fails headless. What are the likely causes?
What they are assessing
A specific and very common failure pattern.
Model answer
Viewport is the first suspect, since headless uses the configured size and an element may be outside it or under a sticky header. Speed is the second: the interactive runner is slower, which accidentally hides races that headless exposes. Animations and transitions behave differently without a visible compositor. Browser differences matter if headless runs Electron while you develop in Chrome. And the interactive runner may be benefiting from state left behind by earlier manual runs. I reproduce by running headless locally with the same browser and viewport before investigating further.
Q77SeniorDebuggingHow do you handle uncaught application exceptions failing your tests?
How do you handle uncaught application exceptions failing your tests?
What they are assessing
Knowledge of a specific behaviour, and the judgement around suppressing it.
Model answer
By default an uncaught exception in the application fails the test, which is correct, because it usually is a defect. You can suppress it by returning false from an uncaught exception handler, either globally in the support file or for one spec. The judgement is that global suppression is almost always wrong: it hides real front end errors from everyone. If a known third party script throws harmlessly, I narrow the handler to that specific message and leave a comment explaining why, so the exception the application itself throws still fails the run.
Trap to avoid
Adding a blanket suppression in the support file to get a pipeline green. It removes an entire class of defect detection permanently, and nobody remembers it is there.
Q78Mid-levelLimitationsWhat are the main limitations of Cypress?
What are the main limitations of Cypress?
What they are assessing
Honesty, and whether the candidate has hit the edges.
Model answer
JavaScript and TypeScript only. No multi tab control and no multiple simultaneous browser instances. Same origin constraints, eased but not removed by cy.origin. No native mobile application support. No Safari support, with WebKit still experimental rather than production ready. Parallel orchestration gated behind a paid service unless you run an alternative. And no native support for file download verification or operating system dialogs, which need workarounds. None of these makes it a bad tool, but each one has ended a Cypress evaluation somewhere.
Likely follow-up
Which of these has actually blocked you on a project?
Q79SeniorLimitationsHow do you test file upload and download in Cypress?
How do you test file upload and download in Cypress?
What they are assessing
Two things that are harder than candidates expect.
Model answer
Upload is straightforward since version 9.3: selectFile accepts a path or a fixture and attaches it to the input, handling drag and drop targets too. Download is the awkward one, because the browser writes the file to disk and Cypress commands run in the browser. The approach is to configure a known downloads folder, trigger the download, then verify from the Node side with cy.task reading the file system, or use cy.readFile which polls until it appears. For contents, parse in a task, since a PDF or spreadsheet cannot be meaningfully asserted on as a string.
Q80SeniorLimitationsHow does Cypress compare with Playwright today?
How does Cypress compare with Playwright today?
What they are assessing
Current market awareness without tribalism.
Model answer
Playwright is stronger on browser coverage with first class WebKit, on multi tab, multi origin and multi context scenarios, on language support beyond JavaScript, and on free parallelisation built into the runner. Cypress is stronger on the interactive developer experience, where time travel and the command log are still better than anything else, on its component testing story, and on approachability for teams new to automation. The honest summary is that Playwright has closed most of the gap that made Cypress compelling in 2019 and opened some of its own, which is why it is the more common default on new projects, while Cypress remains a perfectly good choice for a JavaScript team testing a web application in Chromium.
Trap to avoid
Dismissing either tool. An interviewer asking this is testing whether you choose tools on evidence or on allegiance.
Q81LeadLimitationsHow do you decide between Cypress and Playwright for a new project?
How do you decide between Cypress and Playwright for a new project?
What they are assessing
A structured decision rather than a preference.
Model answer
I would work through the constraints that eliminate options before weighing preferences. Does the browser matrix require Safari or WebKit, and does the team write a language other than JavaScript? Those two eliminate Cypress outright when the answer is yes. Then the journeys: anything needing multiple tabs, several origins or concurrent sessions points to Playwright. Then the team: existing Cypress skill is a real asset and switching has a cost that is often underestimated. Then budget, for parallelisation. If nothing has eliminated either by that point, I would lean Playwright on a greenfield project for the broader coverage and free parallelism, and stay with Cypress where the team already knows it, because tool choice matters less than the discipline of the suite.
Likely follow-up
How would you present that recommendation to a sceptical engineering manager?
Q82LeadLimitationsWhat makes a Cypress suite survive three years rather than being abandoned?
What makes a Cypress suite survive three years rather than being abandoned?
What they are assessing
A considered view of long term maintenance.
Model answer
Four things, in my experience. A selector strategy the application team is committed to, because without test attributes the suite erodes with every redesign. Test independence, so specs can be run, parallelised and deleted individually rather than as a sequence nobody dares touch. Ruthlessness about scope, keeping end to end coverage to the journeys that genuinely need the whole stack and pushing everything else down to component and unit level, because suites die of runtime before they die of complexity. And treating flake as a defect with an owner rather than background noise, since the moment a team stops trusting a red build, the suite has stopped doing its job whether or not it still runs.
What Cypress interviews actually separate on
Listing the commands takes ten minutes. These four areas decide the outcome, and every one of them comes from maintaining a suite rather than finishing a tutorial.
Commands are not promises
Assigning cy.get to a variable, or reaching for async and await, is the single clearest signal that someone has written Cypress without understanding it.
Retry-ability, and its edges
Knowing commands retry is table stakes. Knowing only the last query retries, and that then never does, is what explains most flake.
Stubbing with a reason
Stub everything and you prove the front end renders fixtures. Expect to defend where you draw the line and how stubs are kept honest.
Naming the limitations
No multi tab, no Safari, no language beyond JavaScript. Candidates who volunteer these read as engineers who have evaluated tools, not just used one.
Written by engineers who maintain Cypress suites
This bank was written and reviewed by QAble automation engineers who build and rescue Cypress suites on client projects, including the ones that went wrong: specs held together with fixed waits, support files carrying sixty global custom commands, and a blanket uncaught exception handler added years ago to get one pipeline green that quietly disabled front end error detection for everyone since.
Answers are pitched at the level marked on each question, and several argue against Cypress where that is the honest answer, including when to choose Playwright instead and when a Selenium migration is not worth running. If you think an answer here is wrong, we would genuinely like to hear it.
Tell us what we got wrongCypress suite slow or flaky?
QAble builds and rescues Cypress suites, including removing fixed waits, moving setup off the UI and splitting end to end coverage down to component level where it belongs.
Automation testing servicesMore question banks
View allUFT interview questions
Question bank82 UFT One questions across the object repository and identification, Smart Identification, descriptive programming, checkpoints, actions, recovery scenarios and framework design.Test manager interview questions
Question bank82 questions at organisational level: QA strategy, operating model, budgets and cost of quality, resourcing, vendor selection, tooling, metrics, governance and transformation.Test lead interview questions
Question bank82 questions at team and delivery level: planning and estimation, allocation, risk-based strategy, triage, reporting, stakeholder management, mentoring and the difficult conversations.SQL for testers interview questions
Question bank82 questions on query skill for QA roles: joins and the anti-join pattern, aggregation, the NOT IN null trap, set operations for reconciliation, window functions and safe data modification.Mobile testing interview questions
Question bank82 questions across device strategy, platform differences, upgrade paths, interrupts and the app lifecycle, network conditions, performance, mobile security and staged release.REST Assured interview questions
Question bank82 questions across the Java DSL, GPath body assertions, schema validation, serialisation with POJOs, authentication, reusable specifications, filters and parallel execution thread safety.BDD interview questions
Question bank82 questions on the practice rather than the tooling: discovery, formulation and automation, example mapping, declarative scenario design, living documentation and the anti-patterns.JUnit interview questions
Question bank82 JUnit 5 questions across the three module architecture, annotations and lifecycle, assertThrows and assertAll, parameterized tests, the extension model, Mockito and migration from JUnit 4.Banking domain testing interview questions
Question bank82 domain questions across the general ledger and double entry, payments and reversals, cards, lending and interest, KYC and AML, the batch and end of day cycle and reconciliation.Agile testing interview questions
Question bank82 questions across testing inside the sprint, the agile testing quadrants, user stories and acceptance criteria, definition of done, automation, regression strategy and the anti-patterns.Maven interview questions
Question bank82 questions for automation roles across the POM and lifecycle, dependency scopes and transitive conflicts, Surefire and Failsafe, profiles, multi module builds and CI.LoadRunner interview questions
Question bank82 questions across VuGen scripting and the action sections, correlation and parameterisation, transactions and pacing, Controller scenario design, Analysis and LoadRunner Enterprise.Salesforce testing interview questions
Question bank82 questions across the order of execution, governor limits and bulkification, the layered sharing model, sandboxes and refresh, Flow, Lightning locators and seasonal release regression.Functional testing interview questions
Question bank82 questions across test levels and types, equivalence partitioning and boundary analysis, decision tables, risk based prioritisation, exploratory testing and the automation boundary.Performance testing interview questions
Question bank82 tool agnostic questions across workload modelling, percentiles and results analysis, correlation and pacing, bottleneck diagnosis, monitoring, scalability and reporting.Robot Framework interview questions
Question bank82 questions across keyword design and abstraction, variables and scope, SeleniumLibrary and the Browser library, custom Python libraries, tags, templates and parallel execution with Pabot.Jira interview questions
Question bank82 questions for QA roles across workflows and transitions, JQL, the defect lifecycle, boards and sprints, test management add-ons, reporting and permissions.Software testing interview questions
Question bank82 questions for freshers through to lead, across fundamentals, the testing lifecycle, test design technique, defect management, agile practice and strategy.JMeter interview questions
Question bank82 questions across test plan elements, correlation, timers and pacing, distributed execution, results analysis and troubleshooting.ETL testing interview questions
Question bank82 questions across warehouse modelling, slowly changing dimensions, source to target validation, incremental loads and the SQL that verifies them.TestNG interview questions
Question bank82 questions across annotations and execution order, data providers and factories, groups, dependencies, parallel execution, listeners and the suite XML.Tosca interview questions
Question bank82 questions across modules and scanning, TestCase Design, reusable blocks, buffers and expressions, distributed execution and risk based testing.Postman interview questions
Question bank82 questions across variable scopes and precedence, scripting and chaining, assertions and schema validation, authentication, data driven runs and Newman in CI.Cucumber interview questions
Question bank82 questions across BDD practice, Gherkin, step definitions and expressions, hooks, tags, data tables, shared state, parallel runs and the anti-patterns.Database testing interview questions
Question bank82 questions across schema and constraints, verification SQL, data integrity, transactions and isolation, indexes, migrations, security and NoSQL.Appium interview questions
Question bank82 questions across architecture, capabilities, locator strategies, drivers, gestures, hybrid contexts, parallel execution and troubleshooting.Manual testing interview questions
Question bank65 questions across fundamentals, test design, defect management, agile, scenarios and lead-level strategy, with model answers and follow-ups.Selenium interview questions
Question bank50 questions across WebDriver architecture, locators, waits and flakiness, interactions, framework design, Grid and CI, with model answers and follow-ups.Playwright interview questions
Question bank34 questions across architecture, locators, auto-waiting, assertions, fixtures, network mocking, tracing and parallelism.API testing interview questions
Question bank42 questions across HTTP semantics, schema validation, authentication, API security, tooling, contract testing and performance.Automation testing interview questions
Question bank30 tool-agnostic questions on what to automate, framework design, flakiness, CI/CD, test data, metrics and ROI.SDET interview questions
Question bank30 questions across coding, data structures, framework and system design, CI/CD, testability and quality strategy.Preparing for interviews, or need a suite the team actually trusts?
QAble builds test automation with ISTQB-certified engineers, in Cypress where it fits and elsewhere where it does not. Start with a free QA audit of your suite.