---
title: "Authenticate Faster in Tests with the cy.session Command"
url: "https://www.cypress.io/blog/authenticate-faster-in-tests-cy-session-command"
description: "The cy.session command makes Cypress authentication in tests faster than ever. Learn how this Cypress command can speed up your test executions."
---

# Authenticate Faster in Tests with the cy.session Command

August 4, 2021

By The Cypress Team

![How to perform authentication testing with Cypress.](https://storage.ghost.io/c/12/89/12899ca1-4786-4eea-b7e1-9c5268baa48a/content/images/2021/08/Authenticate-faster-in-tests-with-the-cy.session-command.png)

Cypress helped you reduce the time it takes to log in before each of your tests with the introduction of the experimental `[cy.session()](https://docs.cypress.io/api/commands/session?ref=cypress-io.ghost.io)` command with [Cypress 8.2.0](https://docs.cypress.io/guides/references/changelog?ref=cypress-io.ghost.io#8-2-0).

To view the latest updates, including our fix for the issue with the cy.session command in Cypress 12.1.0, view our [changelog](https://docs.cypress.io/guides/references/changelog?ref=cypress-io.ghost.io).

## A Brief Refresher on Logging in

When testing an application that requires authentication, it's common to create a `cy.login()` [custom command](https://docs.cypress.io/api/cypress-api/custom-commands?ref=cypress-io.ghost.io) or `login` helper function to log in to your app:

```JavaScript
Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login')
  cy.get('[data-test=username]').type(username)
  cy.get('[data-test=password]').type(password)
  cy.get('#login').click()
  cy.url().should('contain', '/login-successful')
})
```

In order to ensure your tests can access the app, you need to call `cy.login()` to log in before each test. Often, this is done in a `beforeEach` hook:

```JavaScript
describe('User account page', () => {
	
  beforeEach(() => {
    cy.login('user1', 'p4ssw0rd123')
  })
	
  it('should actually be accessible', () => {
    cy.visit('/account')
  })

  it('should have the correct page title', () => {
    cy.visit('/account')
    cy.title().should('eq', 'Account Details for User 1')
  })
  
})
```

While logging in during each test that requires being logged-in is a best practice, the process of logging in can be slow, which people sometimes attempt to work around by logging in just once per spec file in a `before` hook, or by using the [`Cypress.Cookies` API](https://docs.cypress.io/api/cypress-api/cookies?ref=cypress-io.ghost.io) to persist cookies across tests. However, [having tests rely on the state of previous tests](https://docs.cypress.io/guides/references/best-practices?ref=cypress-io.ghost.io#Having-tests-rely-on-the-state-of-previous-tests) is not a best practice, and should be avoided.

## Caching Sessions When Logging in

The new `cy.session()` command solves this problem by caching and restoring cookies, `localStorage` and `sessionStorage` after a successful login. The steps that your login code takes to create the session will only be performed once when it's called the first time in any given spec file. Subsequent calls will restore the session from cache.

You can easily update your `cy.login()` custom command or `login` helper function to use `cy.session()`, like so:

```JavaScript
Cypress.Commands.add('login', (username, password) => {
  cy.session([username, password], () => {
    cy.visit('/login')
    cy.get('[data-test=username]').type(username)
    cy.get('[data-test=password]').type(password)
    cy.get('#login').click()
    cy.url().should('contain', '/login-successful')
  })
})
```

Note that, in order to ensure sessions are created consistently, Cypress clears the page after `cy.session()` is called, so `cy.visit()` will always need to be called explicitly afterwards.

Fortunately, explicitly calling `cy.visit()` makes your tests more readable. And because `cy.session()` caches session data, your tests won't need to rely on external services and UI interaction nearly as much, so they'll run faster.

## Switching Users in Tests

When you run `cy.session()`, it automatically clears the active session before running your login code, so that in addition to speeding up the process of logging in, switching between users in a single test will be faster, because you no longer need to log out explicitly before logging in a different user.

```JavaScript
it('should transfer money between users', () => {
  cy.login('user', 's3cr3t')
  cy.visit('/account')
  cy.get('#amount').type('100.00')
  cy.get('#send-money').click()

  // you don't need to log out here!
  
  cy.login('other-user', 'p4ssw0rd')
  cy.visit('/account')
  cy.get('#balance').should('eq', '100.00')
})
```

Because users no longer need to be logged out, and because the active session is getting completely cleared and restored, switching between users in a test can behave more like multiple users using different browsers, rather than multiple users taking turns in the same browser, which allows your tests to more closely resemble real-world usage.

Of course, you can continue to log out any time you need to, as `cy.session()` will automatically detect invalid sessions, using a `validate` function that you define.

## Using the Session Command

Once you've upgraded to [Cypress 8.2.0](https://docs.cypress.io/guides/references/changelog?ref=cypress-io.ghost.io#8-2-0), you can start using this feature by setting the `experimentalSessionSupport` [configuration option](https://docs.cypress.io/guides/references/configuration?ref=cypress-io.ghost.io) to `true`.

Be sure to check out the `[cy.session()](https://docs.cypress.io/api/commands/session?ref=cypress-io.ghost.io)` docs for more details, the [changelog](https://docs.cypress.io/guides/references/changelog?ref=cypress-io.ghost.io#8-2-0) for a full list of fixes, and the [migration guide](https://docs.cypress.io/guides/references/migration-guide?ref=cypress-io.ghost.io) to assist with your upgrade.

## One More Thing — Avoiding CORS Errors

It’s not a problem that comes up frequently, but if you get a CORS error when you run your tests, it might be caused by the absence of authentication. The security measure kicks in if the cross-origin request is not authenticated — all the more reason to ensure the right steps are in place to authenticate faster and more accurately. You can learn more about CORS and how it interacts with Cypress [here](https://docs.cypress.io/guides/guides/cross-origin-testing?ref=cypress-io.ghost.io).

## We'd like to hear from you!

The Cypress team has been working hard to deliver this improved experience. We're excited to bring these new APIs to Cypress users, and as always, we're eager to hear your feedback.

You can submit an [issue](https://github.com/cypress-io/cypress/issues?ref=cypress-io.ghost.io) on Github or chat with us on our [Discord](https://discord.gg/Cd4CdSx?ref=cypress-io.ghost.io). Especially while this feature is experimental, issue submissions are critical. If you’d like to stay up to date with all things Cypress, [subscribe to our newsletter](https://www.cypress.io/subscribe?ref=cypress-io.ghost.io).

Thanks for your support, and happy testing!

\-Cypress Team