Cypress.io and CI Parallelization: cy.intercept Stub Resolution Race Conditions
0 reputation · 28 Dec 2022, 02:37 UTC
0 reputation · 28 Dec 2022, 02:37 UTC
When executing tests across parallel containers using cypress run --parallel, the timing between network stub registration and the actual request dispatch can become nondeterministic. This behavior often manifests as intermittent 404 errors in the logs that do not provide a clear trace of why the intercept failed to catch the request.
The goal is to ensure that cy.intercept consistently resolves before the application triggers the network call, regardless of the container's resource allocation or the parallelization overhead. Current configurations for video and screenshot artifacts help correlate the failure with the visual state, but they do not resolve the underlying timing discrepancy between the stub and the request.
cy.intercept is active across all parallel instances before the first page load?35275 reputation · 28 Dec 2022, 13:19 UTC
No — Cypress does not guarantee that cy.intercept is active before the first page load in each parallel container. Each container in cypress run --parallel runs an independent Cypress runner with its own command queue, and intercepts are registered as queued commands, not synchronously at spec load. If your application fires a request during cy.visit() before the intercept command has been processed, the request goes to the real backend and you get exactly the symptom you describe: an intermittent 404 with no useful trace.
Confirmed behavior: intercepts are per-runner and per-test. Nothing is shared across parallel containers, and registration happens in command-queue order as the test executes. An intercept declared after cy.visit() — or in a support file path that runs too late — cannot catch requests the app makes at boot.
Likely explanation for your flakes: under parallel CI, container CPU contention slows command-queue processing, widening the window between page load and stub activation. That's why the same spec passes sequentially and fails only under load.
Register the intercept before any navigation, in a beforeEach that precedes cy.visit():
beforeEach(() => {
cy.intercept('GET', '/api/config', { fixture: 'config.json' }).as('getConfig');
cy.visit('/');
cy.wait('@getConfig'); // deterministic barrier before interacting
});The cy.wait('@alias') converts a timing assumption into an assertion: if the stub didn't catch the request, the wait times out loudly instead of producing a silent 404 downstream.
cypress run --spec path/to/spec.cy.js. If the 404 disappears, it's a race, not a missing backend route.cy.wait('@alias') immediately after the triggering action. A timeout here proves the request bypassed the stub.Don't rely on video/screenshots for this diagnosis — they capture state after the failure. If flakes persist after reordering, check whether the app fires requests from a service worker or before the Cypress-controlled page context, which intercepts cannot see. One detail that would change this recommendation: whether the 404'd request originates from the initial HTML load rather than XHR/fetch — cy.intercept only handles the latter.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.