Resource library

Automation Interview

Cypress Interview Questions for 3 Years Experience

Practice Cypress interview questions for 3 years experience covering architecture, sessions, origin rules, GraphQL, CI, flake diagnosis, and model answers.

29 min read | 2,914 words

TL;DR

Three-year Cypress candidates should move beyond command definitions. Be ready to design a maintainable test slice, explain retries and subject lifecycles, control REST or GraphQL traffic, use `cy.session()` and `cy.origin()` correctly, isolate parallel tests, and diagnose CI failures from evidence.

Key Takeaways

  • At three years, connect Cypress mechanics to architecture, testability, CI feedback, and business risk.
  • Explain linked-query retryability, action boundaries, subject lifecycles, and why repeated side effects are dangerous.
  • Design intercepts as explicit scenario controls, while retaining unstubbed coverage for deployed integration.
  • Use cy.session for validated authentication state and cy.origin only for top-level secondary-origin interaction.
  • Make parallel tests independent across browser state, backend data, accounts, artifacts, and environment capacity.
  • Treat retries and quarantine as evidence-management tools with ownership, never as permanent flake fixes.
  • Prepare framework review and incident stories that show diagnosis, collaboration, and measured judgment.

Cypress interview questions 3 years experience candidates face are designed to separate routine script writing from independent engineering. You still need precise command, selector, assertion, and network knowledge, but the follow-up is usually architectural: how does the suite stay isolated, reviewable, fast enough, and useful in CI?

At this level, a good answer includes boundaries. You should know what a stubbed browser test proves, when cy.session() is safe, why cy.origin() is not an iframe command, how linked queries retry, and which data can collide during parallel execution. You should also be able to improve an existing framework without rebuilding it around a fashionable pattern.

Use this guide to practice mid-level design, coding, scenario diagnosis, and model answers. Replace illustrative endpoints and metrics with facts from your own work.

TL;DR

Capability Expected three-year evidence
Test design Chooses the smallest layer that protects the risk
Cypress internals Explains queue, subjects, query retrying, and action boundaries
Network strategy Controls REST or GraphQL scenarios without confusing stubs with integration
Authentication Caches approved setup with validated, correctly keyed sessions
Cross-origin flows Applies cy.origin() to top-level origin changes and serializable inputs
Parallel execution Isolates driver state, data, accounts, files, and run artifacts
CI ownership Triages failures, preserves evidence, and governs retries or quarantine
Collaboration Reviews testability, mentors through reasoning, and communicates release risk

1. What Cypress interview questions 3 years experience roles measure

A three-year Cypress engineer is often trusted to automate a feature from risk review through CI, review teammates' specs, and diagnose failures across the browser, application, data, and environment. The exact title varies, but the expected behavior is greater independence.

Interviewers may give an incomplete requirement and observe whether you ask technical questions: Which behavior is highest risk? Can data be created through an API? Is the response contract stable? Which browsers matter? What does a failure block? What evidence exists in CI? These questions are part of test design, not avoidance.

Expect a progression:

  • Explain an API accurately.
  • Apply it in code.
  • Diagnose a failure in that code.
  • Compare another design.
  • Discuss how the choice scales in CI.

For example, defining cy.intercept() is foundational. At three years, also explain when to stub, how to avoid overmatching, why the intercept must be registered before traffic, how GraphQL operations can share one URL, and which unstubbed check protects integration.

Prepare stories where your first hypothesis was wrong and evidence changed the diagnosis. This shows engineering judgment. A real root-cause narrative is more credible than claiming every flaky test was fixed by increasing waits.

2. Design a maintainable Cypress test slice

Start with risk, then choose layers. A high-value end-to-end test proves that a critical journey works across deployed components. Component tests cover UI states cheaply. API or contract tests cover combinations and service rules. Unit tests protect pure transformations.

Risk Strong starting coverage Cypress browser role
Form validation messages Component or unit tests One integrated happy and error path
Order creation across frontend and backend API plus focused end-to-end Prove browser wiring and user result
Large permission matrix Service or API tests Representative role journeys
Responsive navigation Component and selected browser viewports Critical viewport behavior
Third-party callback Contract and backend tests One supported sandbox integration
Data export formatting Service tests One download initiation and user feedback path

A maintainable spec states setup, action, and outcome without hiding the important state. Page or component helpers can centralize selectors and cohesive behavior, but a large inheritance hierarchy often hides too much.

const projectList = {
  row(name: string) {
    return cy.contains('[data-cy="project-row"]', name)
  },
  open(name: string) {
    this.row(name).find('a').click()
  },
}

it('opens an active project', () => {
  cy.visit('/projects')
  projectList.open('Apollo')
  cy.location('pathname').should('match', /\/projects\/[^/]+$/)
  cy.contains('h1', 'Apollo').should('be.visible')
})

This small object is not a universal page-object rule. It shows a cohesive vocabulary with fresh queries. Keep assertions in the test when they express the scenario, and keep data setup outside UI steps unless the UI creation flow is itself under test.

When comparing approaches, discuss failure readability, reuse, subject freshness, and team familiarity. Do not count abstraction layers as maturity.

3. Explain advanced retryability and subject lifecycle

Cypress queues commands. Queries link and retry from the top of their linked chain when an assertion fails. A state-changing non-query command runs once. The yielded subject can become invalid after the application re-renders.

Consider an inline-edit row:

cy.contains('[data-cy="project-row"]', 'Apollo')
  .find('button')
  .contains('Edit')
  .click()

cy.contains('[data-cy="project-row"]', 'Apollo')
  .find('[name="projectName"]')
  .clear()
  .type('Apollo 2')

cy.contains('[data-cy="project-row"]', 'Apollo 2')
  .should('have.attr', 'data-state', 'editing')

Fresh queries after the click and input actions reduce dependence on an element that a framework may replace. Chaining several actions can be fine on a stable element, but you should identify the re-render boundary rather than apply a ritual.

.should(callback) is retried, so keep it idempotent:

cy.get('[data-cy="progress"]').should(($progress) => {
  const value = Number($progress.attr('data-value'))
  expect(value).to.be.within(0, 100)
})

Do not click, create data, or mutate state inside that callback. .then() runs once and breaks linked query retrying before it, so a value transformation followed by a later assertion may not retry as a beginner expects. Put retry-dependent parsing inside .should(callback) or use a custom query only when justified.

Timeouts express how long a specific condition may take, not a quality strategy. Use local timeouts for documented slow operations and preserve the condition that failed. For deeper command design, review Cypress retryability through custom command patterns.

4. Control REST and GraphQL scenarios accurately

A good intercept is registered before traffic, matches the intended operation, and leads to a user-visible assertion. REST paths often identify operations directly. GraphQL commonly uses one endpoint, so inspect operationName.

cy.intercept('POST', '/graphql', (req) => {
  if (req.body.operationName === 'GetProjects') {
    req.alias = 'getProjects'
    req.reply({
      data: {
        projects: [
          { id: 'project-1', name: 'Apollo', status: 'ACTIVE' },
        ],
      },
    })
  }
})

cy.visit('/projects')

cy.wait('@getProjects').then(({ request, response }) => {
  expect(request.body.variables).to.deep.equal({ includeArchived: false })
  expect(response?.statusCode).to.equal(200)
})

cy.contains('[data-cy="project-row"]', 'Apollo')
  .should('contain.text', 'Active')

The GraphQL shape is illustrative and must match the application schema. In TypeScript projects, shared generated operation types can reduce fixture drift, but do not import production secrets or tightly couple tests to implementation-only objects.

Test a failure with the protocol your client handles. A GraphQL operation may return HTTP 200 with an errors array, while transport failures use another status. Follow the actual contract instead of assuming every error is 500.

Use request handlers carefully. Do not add a global intercept that silently changes all traffic. A spec should make scenario control visible. For dynamic responses, validate only the fields relevant to the test and avoid logging tokens or personal data.

A stubbed GraphQL test proves rendering and client behavior against that contract. Add contract checks and selected unstubbed journeys to detect schema or deployment mismatch. The Cypress cy.intercept example guide covers route handlers and failure simulation.

5. Use cy.session and cy.origin with correct boundaries

cy.session() caches and restores cookies, local storage, and session storage created by a setup callback. Key the session with every dimension that changes identity or browser state, and validate restored authentication.

type Role = 'viewer' | 'editor'

const loginAs = (role: Role) => {
  return cy.session(
    ['test-login', role],
    () => {
      cy.request({
        method: 'POST',
        url: '/api/test/session',
        body: { role },
      }).its('status').should('eq', 204)
    },
    {
      validate() {
        cy.request('/api/me').then((response) => {
          expect(response.status).to.equal(200)
          expect(response.body.role).to.equal(role)
        })
      },
    },
  )
}

beforeEach(() => {
  loginAs('editor')
  cy.visit('/projects')
})

The endpoint is an approved application test contract. It should be unavailable in production and use synthetic identities. Keep authentication setup separate from feature navigation so each test makes its route clear.

cy.origin() handles commands when the top-level page is on a secondary origin. Current Cypress requires it for cross-origin interaction, including origins that differ by subdomain. Values passed through args must be serializable because the callback is not a normal closure.

cy.contains('a', 'Open identity profile').click()

cy.origin(
  'https://identity.example.test',
  { args: { expectedName: 'Avery QA' } },
  ({ expectedName }) => {
    cy.contains('h1', 'Identity profile').should('be.visible')
    cy.get('[data-cy="display-name"]').should('have.text', expectedName)
  },
)

This is top-level navigation, not access to an embedded cross-origin iframe. See Cypress cy.origin cross-domain examples and Cypress cy.session examples for their separate contracts.

6. Make test data and parallel execution independent

Parallel-safe browser instances are only one part of isolation. Tests can still collide through accounts, records, file paths, feature flags, rate limits, emails, queues, and shared cleanup.

Create unique, traceable data:

const runId = Cypress.env('RUN_ID') ?? 'local'
const projectName = 'project-' + runId + '-' + Cypress._.random(1_000_000)

cy.request({
  method: 'POST',
  url: '/api/test/projects',
  body: { name: projectName },
}).then(({ body }) => {
  cy.visit('/projects/' + body.id)
})

cy.contains('h1', projectName).should('be.visible')

The helper endpoint and RUN_ID convention are application-specific. Randomness lowers collision probability but does not replace a unique server identifier. Prefer the returned ID for cleanup and correlation. If parallel workers can reuse the same run ID, add a spec or attempt dimension supplied by CI.

Cleanup should target only records created by the test. A broad "delete all projects" hook can erase another worker's data. Server-side expiration for synthetic records is a useful safety net.

Do not reuse one account for tests that mutate preferences, permissions, carts, or limits. Use role pools or per-test identities, and define ownership when pool capacity is exhausted. Validate that the environment can support the chosen concurrency. More workers can increase contention and slow every test.

Artifacts also collide. Include spec, test, browser, run, and attempt identifiers in custom filenames. Sanitize screenshots and logs because test environments can still contain sensitive data.

7. Balance component, end-to-end, and contract tests

At three years, explain not only how to mount a component but why the test belongs there. Component tests are strong for conditional rendering, validation, accessibility states, and event contracts. End-to-end tests are strong for deployed navigation, authentication, routing, and critical service integration.

Suppose a project form has 20 validation combinations. Cover pure schema rules at unit level, key visual and interaction states in component tests, API enforcement at service level, and a small browser journey proving creation. Duplicating all 20 in every layer raises cost without proportional confidence.

For component tests, control dependencies explicitly and avoid recreating a whole production application shell just to mount one button. For end-to-end tests, use real services when integration is the risk and stubs when a deterministic UI state is the risk. Label the intent in test names.

The phrase "testing pyramid" is less important than the reasoning: fast lower layers should cover many combinations, while fewer broad tests protect integration. Some systems need a different shape because risk and architecture differ. Present the portfolio you can defend, not a diagram learned by rote.

Know the project-specific mounting setup. cy.mount() is commonly registered in the component support file through the relevant adapter, but it is not an automatic universal command. See Cypress component testing examples.

8. Own CI feedback, retries, and flake diagnosis

A useful pipeline gives fast, trustworthy feedback. A common shape is a focused pull-request suite, broader regression after merge, and selected browser or environment coverage on a schedule. The exact split follows change risk and runtime constraints.

Retries preserve failed-attempt evidence and can identify intermittent behavior, but they do not convert an unstable test into a healthy one. Track first-attempt failures, final outcomes, ownership, and root-cause categories. Do not report only the final green result.

When a test fails only in CI, compare:

  • Browser and version.
  • Headless or headed run mode.
  • Viewport and locale.
  • Environment URLs and feature flags.
  • Test account and record collisions.
  • CPU, memory, and service capacity.
  • Proxy, DNS, CSP, and certificate behavior.
  • Artifact retention and missing diagnostics.

Quarantine is a temporary release-control decision. Record the covered risk, owner, reason, deadline, and alternative coverage. A permanent skipped test is an undocumented gap.

Improve failure output at the source. Name aliases by operation, label assertions, keep data IDs traceable, and capture safe request metadata. Avoid dumping whole page sources or authorization headers. A clean screenshot plus one correlation ID is often more useful than megabytes of logs.

In an interview, walk through one CI incident from detection to classification, fix, and prevention. Mention the product defect if automation revealed a real race.

9. Review framework code and improve testability

Review Cypress code on risk and failure behavior before style:

  1. Does the test protect a meaningful outcome?
  2. Can it run alone?
  3. Are selectors stable and owned?
  4. Are readiness conditions observable?
  5. Do stubs match a documented contract?
  6. Can actions be repeated accidentally?
  7. Are secrets and data safe?
  8. Will the failure identify the broken boundary?
  9. Is the abstraction smaller than the problem it solves?
  10. Does the chosen layer fit the risk?

Ask developers for testability that helps the product: stable accessible names, explicit loading and error states, deterministic API contracts, correlation IDs, safe data setup, and feature-flag visibility. Avoid adding attributes to every node without a locator strategy.

When mentoring, explain the failure mode behind a review comment. "Re-query after this click because the list replaces the row" teaches more than "split the chain." Distinguish blocking correctness from optional style.

Do not rebuild an existing framework just to apply page objects, BDD syntax, or custom commands everywhere. Make a focused change, measure its effect through failure clarity or maintenance, migrate gradually, and document the contract.

10. Cypress interview questions 3 years experience preparation plan

Prepare a repository slice that includes:

  • TypeScript configuration and environment validation.
  • API-based test-data creation.
  • Validated login caching with cy.session().
  • A REST or GraphQL intercept with success and failure states.
  • One component test and one unstubbed end-to-end journey.
  • Parallel-safe naming and targeted cleanup.
  • CI artifacts and a documented failure-triage flow.

Practice a 15-minute framework walkthrough. Trace one test from pipeline selection through configuration, data, authentication, browser action, request, assertion, artifact, and cleanup. Then answer what changes under parallel execution.

Prepare six stories: a root-caused flaky test, a product race, an API contract mismatch, a CI capacity issue, a code review improvement, and a disagreement about coverage. State evidence and team contribution. Use measured results only when you know the baseline and measurement.

For live coding, practice a GraphQL intercept, a retry-safe numeric assertion, unique data setup, and a session helper. After writing code, review it for origin boundaries, side effects, data exposure, and what the final assertion proves.

Interview Questions and Answers

Q: How do Cypress queries retry?

Linked queries rerun from the top of their chain when a connected assertion fails. They stop when the assertion passes or the timeout expires. Non-query actions execute once, so I separate state-changing actions from later fresh queries.

Q: Why can a long Cypress chain become unreliable?

An action in the middle can trigger a re-render and detach the current subject. Later commands may act on an obsolete element. I identify state transitions and start a fresh query after them.

Q: How do you test GraphQL calls with cy.intercept()?

I intercept the GraphQL endpoint, inspect req.body.operationName, alias or reply to the intended operation, and assert variables plus the UI outcome. The stub must match the real schema, and contract or unstubbed tests cover integration drift.

Q: What should be included in a cy.session() key?

Every value that changes the restored identity or relevant state, such as authentication method, user or role, tenant, and sometimes feature context. The validation callback proves that restored credentials are still usable.

Q: When is cy.origin() required?

It is used to interact with a top-level page on a different origin, including a different scheme, hostname, subdomain, or port. The callback receives serializable data through args; it is not an iframe switch.

Q: How do you make Cypress tests parallel-safe?

I isolate browser state, accounts, backend records, files, queues, flags, and artifact names. I create unique data, clean only owned records, and limit concurrency to environment capacity.

Q: How do you decide whether to stub an API?

I stub when deterministic frontend behavior is the target, especially rare error states. I keep an unstubbed path when deployed frontend-backend compatibility is the risk, and use service or contract tests for broad API behavior.

Q: How do you handle a flaky test that passes on retry?

I preserve the failed attempt, classify the cause, reproduce with the relevant environment, and fix the product, test, data, or infrastructure issue. Retry status is evidence, not resolution.

Q: What belongs in a page object or helper?

Stable selectors and cohesive interactions can belong there. Scenario assertions, unrelated pages, global state, and large orchestration usually should not. I favor small functions that issue fresh queries.

Q: What is your strategy for test data cleanup?

I track the exact identifiers created by a test and delete only those when cleanup is necessary. I also use server-side expiration for synthetic data. I never run broad destructive cleanup in a shared environment.

Q: How would you reduce a slow Cypress suite?

I measure setup, application, and command time, remove duplicate broad journeys, move combinations to lower layers, create data through APIs, cache validated login setup, and parallelize only within environment capacity. I verify that coverage and failure quality remain intact.

Q: What diagnostics should CI preserve?

The failed command and assertion, screenshot or video when useful, browser and environment configuration, safe request context, test data identifier, run and attempt ID, and relevant application correlation ID. Artifacts must not expose secrets or customer data.

Common Mistakes

  • Explaining syntax without stating what risk the test protects.
  • Putting clicks or server mutations inside a retrying .should() callback.
  • Continuing a chain through a known re-render boundary.
  • Stubbing every API and claiming full end-to-end coverage.
  • Matching all GraphQL operations with one unqualified response.
  • Keying every session as simply "login."
  • Using cy.origin() for an embedded cross-origin iframe.
  • Making only browser drivers independent while sharing accounts and records.
  • Running broad cleanup in a parallel environment.
  • Treating final-pass-after-retry as a healthy result.
  • Quarantining a test without owner, deadline, or replacement coverage.
  • Building a large base class that hides test intent.
  • Sharing secrets through Cypress.env() and browser logs.
  • Rewriting the framework without a measured migration reason.
  • Inventing performance or reliability improvements in interview stories.

Conclusion

Cypress interview questions 3 years experience roles require both technical precision and engineering judgment. Show how queue semantics, retryability, intercepts, sessions, origins, data, and CI choices combine into a trustworthy test system.

Prepare one framework slice you can trace end to end and several honest incident stories. If you can state what a test proves, diagnose its failure boundary, and improve the suite without hiding risk, you are demonstrating the independence expected at this level.

Interview Questions and Answers

How do linked Cypress queries retry?

When a connected assertion fails, Cypress reruns linked queries from the top of that query chain until the assertion passes or times out. State-changing commands do not rerun. I split chains at application transition points.

Why are long command chains risky?

An action can trigger a re-render that replaces the yielded element. Continuing with the old subject can cause detachment or misleading behavior. I start a fresh query after state transitions.

How do you intercept a GraphQL operation?

I match the GraphQL endpoint, inspect `req.body.operationName`, and alias or reply only to the intended operation. I assert relevant variables and the visible result, while contract or unstubbed tests protect schema integration.

How do you design a cy.session identifier?

I include every identity dimension that changes the restored state, such as auth method, user or role, and tenant. I add a fast validation request that proves the restored session still represents the intended identity.

When do you use cy.origin?

I use it for interaction after the top-level page moves to a different origin. I pass only serializable values through `args`. I do not use it as an iframe-switching mechanism.

How do you make tests safe for parallel execution?

I isolate accounts, records, flags, queues, files, and artifact names as well as browser state. Test data has unique identifiers, cleanup is targeted, and concurrency respects environment capacity.

When should an API response be stubbed?

I stub it when the target is deterministic client behavior or a rare error state. I retain unstubbed browser coverage when deployment integration matters and use contract or service tests for broad API rules.

What do you do when a retry passes?

I treat the earlier failure as evidence of instability. I preserve artifacts, classify the boundary, reproduce, fix the actual product, test, data, or infrastructure cause, and monitor the affected path.

What should a Cypress helper contain?

It can contain stable selectors and cohesive interactions with clear inputs and outputs. It should not hide unrelated workflows, shared mutable state, or scenario assertions that readers need to see.

How do you test same-origin and cross-origin iframes?

For same-origin content I wrap a non-empty `contentDocument.body`. For a cross-origin embed I test the owned configuration and callbacks through supported contracts because the browser blocks direct DOM access.

How do you clean test data?

I retain IDs for exactly the records a test creates and delete only those if cleanup is required. Synthetic data also expires server-side. Broad shared-environment deletion is unsafe.

How do you review force true in a click?

I identify the failed actionability condition and whether a real user can perform the action. I fix or wait for the blocking state. A forced action is accepted only for a narrow, documented product behavior.

How would you speed up a Cypress suite?

I measure where time is spent, remove duplicate end-to-end paths, move combinations lower, use API setup, cache validated authentication, and parallelize within capacity. I preserve critical coverage and diagnostics.

What failure evidence belongs in CI?

I keep the failing command, assertion, safe screenshot or video, browser and environment settings, request and correlation context, test-data ID, and run attempt. I redact secrets and personal data.

How do you handle ambiguous expected behavior?

I make the ambiguity explicit, gather current behavior and requirement evidence, and get a decision from the correct owner. I document the result and place coverage at the layer that best protects the clarified risk.

Frequently Asked Questions

What Cypress topics are expected at three years of experience?

Expect command internals, retryability, selectors, network stubbing, GraphQL or REST scenarios, sessions, cross-origin rules, test data, parallel execution, component testing, CI, and flake diagnosis. Interviewers often add architecture and review follow-ups.

How is a three-year Cypress interview different from a two-year interview?

The questions move from using APIs correctly to designing and maintaining a reliable test slice. You should discuss layer selection, testability, parallel isolation, CI evidence, and tradeoffs with greater independence.

Should I know cy.session for a three-year Cypress role?

Yes, understand its setup callback, session identifier, restored browser storage, validation, and test-isolation implications. Be able to explain how you prevent one role or tenant from receiving another session.

Do Cypress interviews ask GraphQL questions?

They can when the product uses GraphQL. Practice identifying an operation by `operationName`, controlling a documented response, validating variables, and explaining why contract or unstubbed tests are still required.

How should I prepare CI scenario questions?

Practice failures caused by data collisions, environment configuration, viewport, resource capacity, proxies, browsers, and stale artifacts. Describe the evidence, classification, focused fix, and verification.

Do I need to know component testing?

Know its purpose and project-specific setup even if your recent work is mostly end-to-end. Explain which UI risks become faster and more deterministic at component level and which journeys still require deployment integration.

What project should I present in a three-year interview?

Present a compact, real project or honest sample that includes typed configuration, data setup, authentication, network control, independent specs, CI, and failure artifacts. Depth of explanation matters more than the number of libraries.

Related Guides