Anandhi K
3 min readAug 20, 2022

Login using Cypress Session()

This article is about how to login into app before every test using cy.session API command.

Usually in Test Automation, we may repeat running the login scenario before each test which will eat up our test execution time. To avoid this problem, Cypress has a ‘session’ command.

Using this command, can login into app only once and the session details will be stored and used for further login. This command will Cache and restore cookies, localStorage, and sessionStorage in order to reduce test setup times.

The session API is currently experimental, and can be enabled by setting the experimentalSessionAndOrigin option to true in the Cypress config.

Enabling this flag does the following:

  • It adds the cy.session() and cy.origin() commands, and Cypress.session API.
  • It adds the following new behaviors (that will be the default in a future major update of Cypress) at the beginning of each test:

The page is cleared (by setting it to about:blank).

All active session data (cookies, localStorage and sessionStorage) across all domains are cleared.

Sample application url is:

https://react-redux.realworld.io/

This application is about Creating and Editing articles and before any of these scenarios user must have login into app.

Now we are going to create test scripts to automate the below scenarios,

1. Login and Create an article

2. Login and View the list of articles.

Configuration in cypress.json :

Since, Login is the common action we create it as custom command in support/commands.js file as below,

//Caching session when login via page visitCypress.Commands.add('LoginWithPageSession', (uName, pwd) => {cy.visit('/')cy.contains('Sign in').click()cy.get("input[placeholder = 'Email']").type(uName)cy.get("input[placeholder = 'Password']").type(pwd)cy.get("button[type='submit']").click()cy.get('ul.nav.navbar-nav.pull-xs-right > li:nth-child(2)').should('contain', 'New Post')})

And call this command in test as,

describe('Login with headless auth', () => {beforeEach(() => {const uName = 'aaaaaaaa@xyz.com'const pwd = 'bbbbbbb'cy.LoginWithPageSession(uName, pwd)})it('Create an article', () => {cy.contains('New Post').click()cy.get("input[placeholder ='Article Title']").type('Cypress hooks114')cy.get('input[placeholder="What\'s this article about?"]').type('About how cyprees hooks works')cy.get('textarea[placeholder="Write your article (in markdown)"]').type('Hooks are used to set some prerequisites')cy.get("input[placeholder='Enter tags']").type('#cypresshooks')cy.contains('Publish Article').click()cy.contains('Edit Article').should('be.visible')})it('View Global Feed', () => {cy.get('ul.nav.nav-pills.outline-active > li:nth-child(2)').click()})})

Here, we call custom command inside beforeEach.

cy.LoginWithPageSession(uName, pwd)

This will perform login action before each test which may slow down E2E test execution. So instead, we want to perform login action only once and maintain the same session for remaining test. Now, we are going to use cy.session command by,

//Caching session when login via page visitCypress.Commands.add('LoginWithPageSession', (uName, pwd) => {cy.session([uName, pwd], () => {cy.visit('/')cy.contains('Sign in').click()cy.get("input[placeholder = 'Email']").type(uName)cy.get("input[placeholder = 'Password']").type(pwd)cy.get("button[type='submit']").click()cy.get('ul.nav.navbar-nav.pull-xs-right > li:nth-child(2)').should('contain', 'New Post')})})

If we run, both the test will fail

Because the page is cleared at the beginning of each test, cy.visit() must be explicitly called at the beginning of each test.

Our test script will be,

it('Create an article', () => {cy.visit('/')cy.contains('New Post').click()cy.get("input[placeholder ='Article Title']").type('Cypress hooks114')cy.get('input[placeholder="What\'s this article about?"]').type('About how cyprees hooks works')cy.get('textarea[placeholder="Write your article (in markdown)"]').type('Hooks are used to set some prerequisites')cy.get("input[placeholder='Enter tags']").type('#cypresshooks')cy.contains('Publish Article').click()cy.contains('Edit Article').should('be.visible')})it('View Global Feed', () => {cy.visit('/')cy.get('ul.nav.nav-pills.outline-active > li:nth-child(2)').click()})

Note: This app will accept only unique ‘Article Title’, so during every run update accordingly.

Switching sessions inside tests :

Because cy.session() clears the page and all active session data before running setup, you can use it to easily switch between sessions without first needing to log the previous user out. This allows tests to more accurately represent real-world scenarios and helps keep test run times short.

Now let we create one more user and if we want to view the list of articles of two different users, then our code will be modified to,

it('View Global Feed of CorpTraining', () => {cy.visit('/')cy.get('ul.nav.nav-pills.outline-active > li:nth-child(2)').click()//To view the articles of other usercy.LoginWithPageSession('xxxxx@xyz.com', 'yyyyyyy')cy.visit('/')cy.get('ul.nav.nav-pills.outline-active > li:nth-child(2)').click()})

Reference:

session | Cypress Documentation

Conclusion:

The cy.session command is helpful in reducing test setup times by maintaining cookies, localstorage and sessionStorage.

Anandhi K

DevOps Test Automation Consultant, Trainer and Blogger in Cypress, Selenium, Cucumber, Playwright & CI/CD Tools.