Extensive List of Cypress Interview QAns — Continued….

Table of contents
- Q: What is Cypress and why would you use it?
- A:
- Why Cypress :
- Q: What are the key advantages of Cypress over other testing tools?
- A:
- Q: How do you handle asynchronous operations in Cypress?
- A:
- Key Points:
- Caveats to respect:
- Q) How do you organize your Cypress tests?
- A)
- Conventions that keep tests readable:
- Reality check / caveats:
- Handy Snippet:
- Q) How do you mock API responses in Cypress?
- A)
- 💻 Using cy.intercept()
- What I actually do:
- Edge cases / caveats:
- Q) What are Cypress Custom Commands?
- When to Use Custom Commands
- Example
- Q: How do you debug failing Cypress tests?
- Triage checklist :
- Pro tips:
- Q) How do you configure Cypress for different environments?
- ⚙️ Using cypress.config.js and Environment Variables
- Approach:
- Professional guardrails:
- Q) What is the purpose of cypress.json vs cypress.config.js?
- Then vs Now (cheat sheet):
- Why it matters:
- Heads-up:
- Q) What’s the recommended approach for element selection in Cypress?
- Comparison of Selectors
- Q) How do you handle elements that are not immediately visible in Cypress?
- The Cypress Waiting Mechanism
- Q) How do you interact with iframes in Cypress?
- Method: The .contents() Workaround
- Disclaimer:

Q: What is Cypress and why would you use it?
A:
Cypress is a modern end-to-end (E2E) and component testing framework.
It operates directly within the browser’s event loop,
providing deep insights and control.
delivers auto-waiting,
time-travel debugging, and the
ability to stub network requests,
resulting in faster and more reliable tests compared to traditional WebDriver-based tools.
Why Cypress :
In-browser execution → no remote WebDriver hop.
Auto-wait & retries → fewer
sleep()
s.cy.intercept()
→ deterministic API stubs in CI.Time-travel snapshots, screenshots/videos out-of-box.
Component + E2E; Chrome/Edge/Firefox coverage.
Trade-offs:
Limited multi-tab/cross-origin;
not for native mobile;
WebKit/Safari limited.
Q: What are the key advantages of Cypress over other testing tools?
A:
Real-time browser preview and time-travel debugging
Automatic waiting (no need for explicit waits)
Network traffic control and stubbing
Screenshots and videos on failures
Easy setup with zero configuration
Consistent results across different environments:
Cypress runs inside the browser, so you get live preview, auto-waiting, and tight network control, which makes tests fast, debuggable, and stable.
Q: How do you handle asynchronous operations in Cypress?
A:
Cypress automatically handles async operations through its command queue.
Commands are automatically chained and waited for
Key Points:
- Automatic Command Chaining: Cypress enqueues commands and executes them sequentially, handling async behavior natively.
Built-In Retries: Automatically retries commands until conditions are met or timeouts occur, reducing flakiness.
No Manual Promises: Unlike traditional JavaScript, no need for .then() or async/await for most operations.
Waiting for Async Events: Implicitly waits for elements, network requests, or assertions to resolve.
Press enter or click to view image in full size
Custom Timeouts: Override default timeouts if needed for specific async operations.
Commands are Queued, not Executed Immediately: When a command like
cy.get()
is called, it doesn't immediately find the element. Instead, it's placed in a queue.Network sync:
cy.intercept()
+cy.wait('@alias')
aligns UI with XHR/fetch.Time control:
cy.clock()
/cy.tick()
for timers and debounce flows.
Caveats to respect:
Don’t mix Cypress commands with plain
await
—stay in-chain orcy.wrap(...)
.Commands don’t return assignable values; use aliases or
.then(...)
.Tune
defaultCommandTimeout
for slow endpoints.
Press enter or click to view image in full size
Q) How do you organize your Cypress tests?
A)
Group specs by feature/domain,
keep consistent names,
centralize helpers in
support/
, anduse fixtures for deterministic data.
Press enter or click to view image in full size
Conventions that keep tests readable:
Spec naming:
<feature>.<behavior>.cy.ts
(e.g.,login.happy-path.cy
.ts
).Selectors: stable
data-testid
attrs; avoid styling-driven CSS.Setup:
beforeEach
for commoncy.visit
/seed; keep tests independent.Network: fixtures +
cy.intercept()
for fast, deterministic CI.Reuse: move flows (e.g., login) into
support/commands.ts
.
Reality check / caveats:
Don’t over-nest folders — 2 levels is usually enough.
Avoid shared state across specs; prefer
cy.session()
for repeat logins.Keep fixtures small; generate data on demand if variety explodes.
Handy Snippet:
Press enter or click to view image in full size
Q) How do you mock API responses in Cypress?
A)
Mocking API responses in Cypress is a powerful way to test your application’s front end in isolation from the backend. This allows for faster, more reliable, and deterministic tests, as you can control the data and network conditions. The primary command for this is cy.intercept()
.
Use cy.intercept()
to match requests, stub the response, and wait on an alias for deterministic UI tests.
💻 Using cy.intercept()
The cy.intercept()
command lets you control network requests by intercepting them and responding with your own data. This means you can:
Stub a Response: Intercept a request and immediately send back a predetermined response, such as a fixture file.
Manipulate Requests: Modify requests as they are sent out.
Wait for Requests: Ensure a test doesn’t proceed until a specific network call has been made and completed. This is crucial for synchronizing tests with asynchronous API calls.
What I actually do:
Fixture stubs: serve stable JSON from
cypress/fixtures/
.Dynamic handlers: modify requests/responses in-code for edge cases.
Sync UI & network: Always
cy.wait('@alias')
before asserting.Failure/latency sims: force errors or add delays to exercise retries.
Stable matching: use globs/regex or route-matcher objects (method, path, query).
Press enter or click to view image in full size
Edge cases / caveats:
Don’t over-stub critical journeys — keep at least one end-to-end path real.
Match precisely (e.g.,
**/api/users*
) to avoid accidental intercepts.Update fixtures when API contracts change to prevent “green but wrong.”
Q) What are Cypress Custom Commands?
A)
Cypress custom commands are functions that you create to extend Cypress’s API (Cypress.Commands
).
They allow you to encapsulate a series of actions into a single, reusable command, making your tests more readable, concise, and maintainable
When to Use Custom Commands
You should use custom commands for any action that is repeated across multiple tests. This follows the Don’t Repeat Yourself (DRY) principle.
Common use cases include:
Authentication and Login: Instead of writing the login steps (
cy.visit()
,cy.get()
,cy.type()
) in every test file, you can create a singlecy.login()
command.Complex UI Interactions: For multi-step interactions like filling out a complex form or navigating a modal, a custom command simplifies the test and hides the implementation details.
Data Stubbing: Encapsulate the
cy.intercept()
logic for common API responses into a command likecy.stubApi()
.
Example
Here’s how you define and use a simple login
custom command.
- Define the Command in
cypress/support/commands.js
:
Press enter or click to view image in full size
2. Use the Command in a Test File:
Press enter or click to view image in full size
Q: How do you debug failing Cypress tests?
A)
Cypress provides powerful tools to debug failing tests efficiently,
Lean on time-travel + artifacts (screenshots/videos), interactive runner/devtools, and targeted pauses/logs to isolate the failure fast.
Triage checklist :
Time-travel in Runner: click each command to inspect DOM, props, and console at that moment.
.debug()
/cy.pause()
to halt where it breaks and poke around.Screenshots & videos: review CI artifacts; add
cy.screenshot()
at tricky points.Browser DevTools: run with
--headed
, open console/network, inspect app state.cy.log()
/ alias data: print payloads; log intercepted responses.Tighten selectors & waits: assert on visible/stable elements, not transient ones.
Pro tips:
Sync with network:
cy.intercept()
+cy.wait('@alias')
before UI assertions.Prefer data-testids; avoid brittle CSS/XPath.
Press enter or click to view image in full size
Q) How do you configure Cypress for different environments?
A)
Cypress is highly configurable to handle different environments like development, staging, and production
Cypress allows configuration for different environments using cypress.config.js
Use env-driven config (baseUrl + env
), optionally per-env config files, and CLI/CI overrides—no code changes between envs.
⚙️ Using cypress.config.js
and Environment Variables
The cypress.config.js
file is where you define all global settings for your project. To manage different environments, you can define configuration objects or use environment variables to dynamically change settings at runtime.
cypress.config.js
: This file is the central hub for all configuration. You can define global settings likebaseUrl
,viewportWidth
, andvideo
settings.Environment Variables: The best practice is to use environment variables to handle secrets and environment-specific settings. This keeps sensitive information out of your codebase. Cypress automatically loads environment variables prefixed with
CYPRESS_
and makes them available within your configuration and tests.
Approach:
Single config, env overrides: read from OS env (
CYPRESS_*
) andconfig.env
.Per-env files (optional): run with
--config-file cypress.config.staging.ts
.CLI flags:
--config baseUrl=...
and--env ENV=staging,username=ci-user
.Secrets: put in CI secrets or
cypress.env.json
(gitignored).In tests: always
Cypress.env('apiUrl')
; keepcy.visit('/')
relative tobaseUrl
.
Professional guardrails:
Don’t hardcode creds; prefer
CYPRESS_
OS vars →Cypress.env(...)
.Keep env logic in config, not scattered in specs.
Ensure one true E2E path points to real services in at least one pipeline.
Configuration File: Use cypress.config.js to define environment-specific settings like baseUrl or custom env variables.
Press enter or click to view image in full size
- Accessing Variables: Use Cypress.env() in tests to retrieve environment-specific values.
cy.visit(Cypress.env(‘baseUrl’));
Press enter or click to view image in full size
Q) What is the purpose of cypress.json vs cypress.config.js?
A)
cypress.config.js
is the modern configuration file for Cypress (version 10.0 and above), and it completely replaces the older cypress.json
file,
offering dynamic JavaScript-based configuration and improved TypeScript support,
while supporting separate setups for end-to-end (E2E) and component testing.
moving from a static JSON file to a dynamic JavaScript file.
- cypress.json (Legacy): Used in Cypress versions
- cypress.config.js (Modern): Introduced in v10, uses JavaScript for dynamic, programmatic configuration.
Press enter or click to view image in full size
- Separate Test Types: Configures E2E and component testing independently in one file.
- JavaScript-based Configuration: As a JavaScript file,
cypress.config.js
allows for dynamic and conditional logic within your configuration. You can use variables, environment checks (process.env
), and functions to customize settings, which was not possible with the staticcypress.json
.
Then vs Now (cheat sheet):
Old (
cypress.json
): static JSON; single test type.New (
cypress.config.js/ts
): JS/TS,defineConfig
,e2e
&component
blocks, programmatic tweaks.Plugins moved to
setupNodeEvents(on, config)
.Support files/paths live under the respective test-type key.
Why it matters:
TypeScript-friendly (autocomplete & types).
Dynamic env/overrides per CI/env without hacks.
One place for both E2E and Component test setup.
Heads-up:
cypress.json
is deprecated in v10+ projects.Many top-level keys now sit under
e2e
orcomponent
.
Press enter or click to view image in full size
Q) What’s the recommended approach for element selection in Cypress?
A)
The recommended approach for selecting elements in Cypress is to use data attributes (e.g., data-cy
, data-testid
). This method creates robust and stable tests that are not affected by avoiding fragile selectors like CSS classes or IDs or JavaScript changes, which are common during development.
Comparison of Selectors
Here’s a quick comparison demonstrating why data attributes are the best practice:
- Best Practice ✅: Use
data-cy
ordata-testid
. This selector is the most stable and intentional.
- Avoid ❌: Don’t rely on CSS classes (
.btn-primary
). These can easily change for styling reasons, causing your test to fail.
- Avoid ❌: Don’t rely on IDs (
#submit-button
) unless you're absolutely sure they're unique and will never change. IDs are often generated dynamically or reused.
Nice-to-have (ergonomic helper):
Press enter or click to view image in full size
Q) How do you handle elements that are not immediately visible in Cypress?
A)
Cypress is designed to handle elements that are not immediately visible by automatically waiting for them to become available and actionable. This built-in behavior is one of its core strengths.
When an element is initially hidden, you can use explicit assertions to verify its state and then perform actions once it becomes visible.
The Cypress Waiting Mechanism
- Automatic Retries: By default, Cypress will automatically retry
get
,contains
, and other commands for a short period (typically 4 seconds) until the element is found and is actionable. This eliminates the need for manualsleep()
commands, making tests more stable.
Cypress retries commands until elements meet conditions or timeout, no manual waits needed.
- Explicit Assertions: You can use
.should()
assertions to explicitly command Cypress to wait for a certain condition to be met before proceeding. This is the recommended approach for handling elements that appear after an animation or an asynchronous event.
Check if an element exists in the DOM, even if not visible, with .should(‘exist’).
.should(‘be.visible’) => to wait for elements to appear
or
.should(‘not.be.visible’) => for hidden ones.
Press enter or click to view image in full size
- Scroll into View: Use .scrollIntoView() for elements hidden off-screen.
Press enter or click to view image in full size
Playbook:
Assert the right thing:
\=> Appears later → should('be.visible')
\=> Present but hidden → should('exist').and('
not.be
.visible')
Sync first:
cy.intercept(...).as('req')
→cy.wait('@req')
before UI checks.Kill spinners/overlays: wait for
spinner
/backdrop
to not exist.Offscreen control:
.scrollIntoView()
before click.State gates: assert
not.be
.disabled
/have.attr
etc. before interacting.
Caveats & tips:
Avoid
click({ force: true })
—use it only after proving the element can’t become visible.If content is conditional, assert both paths: visible when expected,
not.exist
when not.For slow transitions, prefer app signals (aliases/overlays) over arbitrary
wait()
.
Press enter or click to view image in full size
Q) How do you interact with iframes in Cypress?
A)
Cypress has limited native iframe support, but you can interact with iframes using .then() to access their content or by leveraging plugins/custom commands for reliable interactions.
Interacting with an iframe in Cypress requires a workaround because iframes are treated as entirely separate documents. Cypress commands are designed to operate on the main application’s DOM, so you must first gain access to the iframe’s content before running your standard commands
Accessing iframe Content: Use .then() to extract the iframe’s DOM and interact with elements inside.
Press enter or click to view image in full size
Method: The .contents()
Workaround
The most common and effective method is to use a combination of .contents()
, .find()
, and cy.wrap()
.
Find the Iframe: Use a
cy.get()
command to select the iframe element itself.Access the Iframe’s Content: Use the
.then()
method to handle the result of thecy.get()
. Inside the.then()
callback, use.contents()
to access thedocument
of the iframe and.find('body')
to get its body element.Wrap the Body: Use
cy.wrap(body)
to create a new Cypress subject out of the iframe's body. This allows you to chain Cypress commands on the content of the iframe.
After wrapping the body, you can use any standard Cypress commands like cy.find()
, cy.get()
, or cy.click
()
to interact with elements inside the iframe.
Code Example
This snippet demonstrates the entire process of getting into an iframe and interacting with an element within it.
Press enter or click to view image in full size
- Plugins for Simplicity: Use cypress-iframe plugin to simplify iframe handling.
Press enter or click to view image in full size
- Custom Commands: Create reusable commands for frequent iframe interactions.
Press enter or click to view image in full size
or
Press enter or click to view image in full size
When origins differ (reality check):
You cannot poke into a cross-origin iframe’s DOM (SOP).
Test the iframe directly by visiting its URL (optionally with
cy.origin(...)
), or validate via network contracts/stubs.If possible, host the iframe under the same domain in test envs.
Pro tips:
Assert it’s ready:
.its('0.contentDocument.body').should('
not.be
.empty')
.Prefer
data-testid
inside the iframe content.Avoid hacks like
force: true
—fix visibility/overlay first.
Disclaimer:
Used it in my own learning. But Some ideas are also help from ChatGPT for this guide.
Happy Learning,
Suseela :)
Subscribe to my newsletter
Read articles from sheelu k directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
