skip to content

In a Cypress spec, how long does a value set with `Cypress.config()` last?

level: middleimportance: should knowfreq 50%

answer

  1. It never touches the config file
  2. A fresh browser starts each spec
  3. Scope is the current spec file
  4. Runs synchronously, outside the command queue
  5. Some keys are refused during a test

basics

~20 s

For the rest of the current spec file, and no longer. Cypress exits the browser between specs, so the change never reaches another spec, and it is never written back to the configuration file on disk.

solid answer

~40 s

`Cypress.config(name, value)` changes the resolved configuration for the **remainder of the current spec file** and nothing more. Cypress exits the browser between specs, so the next spec starts from the file-resolved values again, and the config file itself is never modified. It executes synchronously, unlike `cy.*` commands, which are enqueued — so a call written between two commands takes effect before either runs; chain it inside `.then()` if it must land mid-test. Not every key is writable: read-only options are refused by name, `testIsolation` can only be overridden in a `describe` config object, and as of Cypress 16 `viewportWidth`, `viewportHeight` and `blockHosts` **throw** when set this way during test execution, because doing so used to affect the next test rather than the current one. Use `cy.viewport()` or a suite/test config object instead.

code

javascript · 11 lines
javascript
describe('tenant settings', () => {
  it('waits out a slow tenant search re-index', () => {
    Cypress.config('defaultCommandTimeout', 20000)
    cy.visit('/tenants/acme/settings')
    cy.get('[data-test=index-status]').should('contain', 'Ready')
  })

  it('still resolves 20000: the change is scoped to this spec file', () => {
    cy.wrap(Cypress.config('defaultCommandTimeout')).should('equal', 20000)
  })
})

go deeper

for a junior

Recall that Cypress.config() reads and writes settings from inside a spec, and that a write is temporary. Being able to read a value back is the part you are likely to be asked for.

for a middle

Explain the scope precisely — rest of the spec file, because each spec gets a fresh browser — and contrast it with a describe/it config object, which is narrower and self-restoring.

for a senior

An interviewer expects you to know which keys are refused and why, including that Cypress 16 turned the viewport and blockHosts cases into hard errors rather than a change that silently hit the next test.

for a principal

Own the boundary: run-time configuration changes are invisible to anyone reading the config file, so decide when a suite may use them at all versus pushing the value into the file or a per-suite override.

## What the call does, and for how long `Cypress.config()` is the run-time door onto the configuration Cypress already resolved. Called with no argument it returns the whole flat object; with a name it reads one value; with a name and a value, or an object, it **sets** values. The scope of a set is exactly one thing: **the remainder of the current spec file**. It is not written back to `cypress.config.js`, it does not reach other specs, and it does not survive the run. The reason is structural rather than a policy choice — Cypress runs each spec in isolation and exits the browser between specs, so nothing set in the browser can outlive the spec that set it. ```javascript // cypress/e2e/tenants/settings.cy.ts it('waits out a slow tenant re-index', () => { Cypress.config('defaultCommandTimeout', 20000) cy.visit('/tenants/acme/settings') }) it('still sees 20000', () => { // the previous test's change is still in force for this spec file }) ``` ## Three declaration sites at test time, and their reach | Site | Reach | Restored when | |---|---|---| | Config file (root or testing-type block) | the whole run | never — it is the baseline | | `describe`/`context`/`it` config object | that suite or test | the suite or test ends | | `Cypress.config(name, value)` | rest of the spec file | the spec file ends | The suite- and test-level override is the second argument to the Mocha function: `describe('tenant settings', { defaultCommandTimeout: 20000 }, () => { ... })`. It is narrower than `Cypress.config()` and self-restoring, which usually makes it the better tool when only one block of tests needs the different value. ## It is synchronous, and that trips people up `Cypress.config()` executes the moment JavaScript reaches it. `cy.*` commands do not — they are enqueued and run later. So a call written between two commands takes effect **before either of them runs**, not between them. When the change must land mid-test, chain it: ```javascript cy.get('[data-test=tenant-row]').click().then(() => { Cypress.config('defaultCommandTimeout', 20000) }) ``` ## Reading, as opposed to writing Half of what `Cypress.config()` is good for is the read. Called with no argument it hands back the whole resolved configuration as a flat object — the `e2e` and `component` keys are already gone, so `Cypress.config('defaultCommandTimeout')` returns the number the run actually settled on, whatever combination of defaults, config file, block and command line produced it. That makes it the cheapest way to answer "which value is this suite really using?" from inside a spec, and it is worth reaching for before anyone starts editing the config file on a hunch. ## What Cypress refuses to set Not every key is writable at test time, and the refusals are graded: - **Read-only keys** can never be overridden — the error says so by name. Most of the run-shaped settings (folders, video, reporter, `specPattern`) are here. - **Suite-level only.** `testIsolation` can be overridden in a `describe` config object and nowhere else — not per test, not via `Cypress.config()`. - **Suite-or-test only.** As of **Cypress 16**, `viewportWidth`, `viewportHeight` and `blockHosts` **throw** when set with `Cypress.config()` during test execution. Before 16 the call was accepted and quietly affected the *next* test rather than the current one, which is precisely why it now errors. Use `cy.viewport()` to change the viewport during a test, or set the values in a `describe`, `context` or `it` config object. - Everything else — the timeouts, `retries`, `scrollBehavior`, `keystrokeDelay`, `waitForAnimations`, `screenshotOnRunFailure` — is settable at any of the three sites. ## When to reach for it For a multi-tenant admin console, the honest use is a spec-wide, spec-specific adjustment: one spec drives a tenant migration screen whose operations take twenty seconds, and the run-wide `defaultCommandTimeout` should not be raised for everyone to accommodate it. Setting it once at the top of that spec file is clearer than repeating a `timeout` option on ten commands, and safer than raising the global default. What it is not is a configuration mechanism. It cannot make a value persist, it cannot be read by another spec, and it is invisible to anyone reading the config file. Chai's `expect` will happily assert on `Cypress.config('...')` inside a spec if you want to prove which value is in force; nothing outside the spec can observe the change. Two habits keep it honest. Set it **once, near the top of the spec file** rather than sprinkled through tests, so a reader can see the spec's baseline in one place — a call buried in the fourth test silently changes every test after it. And prefer the `describe` override when the wider blast radius is not wanted: it is restored automatically when the suite ends, whereas a `Cypress.config()` call leaves the value in force for everything that follows in the file, including tests someone adds later without reading the top.

  • Why can `Cypress.config()` appear to have no effect mid-test?
    Because it runs synchronously the moment JavaScript reaches it, while `cy.*` commands are only enqueued at that point. A call written between two commands executes before either of them, so it looks like it applied too early. Put it inside a `.then()` callback when it has to take effect between two specific commands.
  • How do you change the viewport during a Cypress 16 test?
    Use `cy.viewport()`, or declare `viewportWidth`/`viewportHeight` in the config object of a `describe`, `context` or `it`. As of Cypress 16, `Cypress.config('viewportWidth', ...)` throws during test execution, because setting it that way used to affect the following test rather than the current one and was not reflected in Test Replay.

saying these in an interview costs you the question

  • Thinks Cypress.config() edits the configuration file
  • Expects the change to carry into the next spec
  • Believes it queues like a cy command
  • Says any configuration key can be set at run time
  • Uses Cypress.config() to resize the viewport mid-test