Santi R
Santi R

Reputation: 77

Stuck with Cypress - Login Redundancy

I'm currently grappling with a persistent issue and would appreciate some guidance. I am utilizing Cypress for conducting tests, and I'm trying to find a way to avoid repeated logins for each test case.

Below is my test file:

describe("Authenticated User Validations", () => {
    beforeEach(() => {
        cy.visit(baseUrl);
        cy.login(user, password);
    });

    it("Login and Verify URL", () => {
        cy.url().should('include', '/inventory.html');
    });

    it("Button Order from A-Z by Default", () => {
        cy.contains('A to Z').should('exist');
    });
});

Commands.js file

const baseUrl = Cypress.env("CYPRESS_BASE_URL");

Cypress.Commands.add('login', (user, password) => {
    cy.session([user, password], () => {
        cy.visit(baseUrl);
        cy.get('[data-test="username"]').type(user);
        cy.get('[data-test="password"]').type(password);
        cy.get('[data-test="login-button"]').click();
    });
});

I'm very confused about where to add the cy.visit , if in the command.js, or the beforeEach, or in test?

I can make it work without the session, but it types and login each time. I saw another solutions but it's not working for me

Thanks in advance

Upvotes: 1

Views: 330

Answers (1)

Paolo
Paolo

Reputation: 5461

cy.session(id, setup) is command that behaves differently each time it's called.

The parameter setup is only called on the first time it's called (in the first test of the spec).

The 2nd time it's called , the saved data is returned instead of running setup().

Here's a small example

const baseUrl = 'https://example.com'

Cypress.Commands.add('login', (user, password) => {
  cy.session([user, password], () => {
    console.log('in session setup')              // only appear once in the console
    cy.visit(baseUrl)
    cy.url().should('include', 'example.com')    // page is at baseUrl
    cy.setCookie('token', 'my-token-123')        // simulate a logon cookie
  })
})

it('test1', () => {
  cy.login('abc', '123')
  cy.url().should('include', 'about:blank')   // page is at the default blank URL
})

it('test2', () => {
  cy.login('abc', '123')
  cy.url().should('include', 'about:blank')   // page is at the default blank URL
})

The test runner shows created for test1 and restored for test2.

enter image description here


What about `cy.visit()`?

Inside both tests the URL is about:blank which is the Cypress default page if no cy.visit() is called.

So, each test must make it's own visit the the page you want to test.

This section of the docs Where to call cy.visit() gives the options

Intuitively it seems that you should call cy.visit() immediately after cy.session() in your login function or custom command, so it behaves (from the point of view of the subsequent test) exactly the same as a login function without cy.session().

However, if you want to test something on a different page, you will need to call cy.visit() at the beginning of that test...


The weird stuff

See Session caching

In order to reduce development time, when running Cypress in "open" mode, sessions will be cached for spec file re-runs.

So when you run the spec initially, you see the above log. Run it again and both tests are marked restored instead of test1: created, test2: restored.

You have to manually clear it for the second run with the Clear All Sessions link.

If you modify the test, the session should be cleared automatically but I'm not sure that always happens.

Upvotes: 4

Related Questions