cy.session() is one of the most impactful commands for real-world Cypress suites, caching login state so most tests never need to repeat a full login. This lesson explains how it works and how to use it correctly.
What cy.session() Does
cy.session(id, setupFunction) runs the setup function (typically a login) only once per unique session id within a test run, caching cookies, local storage, and session storage afterward. On subsequent calls with the same id, Cypress restores that cached state instantly instead of re-running the setup.
The first test using this session id actually logs in; every subsequent test in the run restores the cached session almost instantly.
cy.session() Syntax
cy.session(id, setupFn)
cy.session(id, setupFn, {
validate() { /* optional: confirm the session is still valid */ },
cacheAcrossSpecs: true,
})
id can be a string or an array (like [email, password]), uniquely identifying this session.
validate() runs before reusing a cached session, and re-runs setup if it fails.
cacheAcrossSpecs: true extends caching beyond a single spec file, across the whole run.
cy.session() automatically clears cookies/storage before running the setup function.
cy.session() Cheat Sheet
Key behaviors and options to remember when using cy.session().
Aspect
Behavior
First call with a given id
Runs the full setup function
Later calls with the same id
Restores cached cookies/storage instantly
validate() option
Confirms cached session is still valid before reuse
cacheAcrossSpecs
Extends caching across multiple spec files
State restored
Cookies, localStorage, and sessionStorage
Validating a Cached Session Before Reuse
Providing a validate() function lets Cypress confirm a cached session is genuinely still usable, for example, that an auth token hasn't expired, before trusting it. If validation fails, Cypress automatically re-runs the setup function instead of proceeding with a stale session.
The common, recommended pattern combines cy.session() with beforeEach(), so every test starts fully authenticated without any repeated boilerplate, and without actually re-running the login setup for every single test.
Using a different session id unintentionally for what should be the same cached session, defeating the caching benefit.
Skipping validate() for suites with short-lived tokens, leading to confusing failures from a stale, expired session.
Assuming cy.session() persists across entirely separate Cypress runs, it does not, only within a single run.
Not calling cy.visit() after restoring a session, forgetting the browser still needs to load the target page.
Key Takeaways
cy.session() caches authentication state, running its setup function only once per unique id.
It dramatically speeds up suites where most tests simply require being logged in.
validate() confirms a cached session is still usable before reusing it.
Pairing cy.session() with beforeEach() is the standard, recommended pattern.
Pro Tip
Always pass a validate() function when your authentication uses short-lived tokens, without it, a suite can silently run many tests against an expired session, producing confusing failures far from the actual root cause (an old cached token).
You now understand cy.session() and how it speeds up authenticated testing. Next, dive into JWT Auth Testing specifically.