Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice of pass states between tests in Cypress

Tags:

cypress

I want to pass/share data between each test. What is the best way to implement it in Cypress?

For example:

 it('test 1'), () => {
   cy.wrap('one').as('a')
   const state1 = 'stat1'
 })

 it('test 2'), () => {
   cy.wrap('two').as('b')
 })

 it('test 2'), () => {
   //I want to access this.a and this.b

   //Also I want to access state1

 })
like image 683
Jake He Avatar asked Aug 28 '18 05:08

Jake He


People also ask

Does Cypress clear cookies between tests?

Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear a specific cookie inside a single test.

What does cypress do between tests?

Cypress Automation Offers Fast Test Execution The framework automatically waits for things like DOM loading, animation, elements, and more. Furthermore, the framework also runs subsequent tests automatically after the first one is executed. This eliminates downtime and the need to manually trigger the next test.

What is the best way to wait and test the page in Cypress?

You can wait for basically anything by passing a callback function into . should() command. It will use the built in retry logic and wait for the function to pass. For example, you can wait until all of the elements on page have the proper text.


1 Answers

I can see the answer worked for author, but in case anyone needs to share data between different test files, the solution is to use cy task method and store data in Node environment, e.g. in my case I needed to store user data:

// cypress/plugins/index.ts
export default (on, config) => {
  on('task', {
    setUserData: (userData: UserDataType) => {
      global.userData = userData;
      return null;
    },
    getUserData: () => {
      return global.userData;
    },
  });
};

then in test case we can do:

// cypress/integration/login.spec.ts
describe('Login', () => {
  it('should work', () => {
    cy.visit('/login-page');
    cy.intercept('api/login-endpoint').as('postLogin');
    // login interactions
    cy.wait('@postLogin').then((interception) => {
      // intercept user data and store it in global variable
      cy.task('setUserData', JSON.parse(interception.response.body));
    });
    // ... further assertions
  });
});

later we can retrieve this data easily:

// cypress/integration/otherTest.spec.ts
describe('Other test', () => {
  it('uses user data', () => {
    cy.task('getUserData').then((userData: UserDataType) => {
      console.log(userData);
      // voila! Stored data between two .spec files
    });
  });
});

You'll also need to extend Node TS types for this, but this answer is long enough already.

Yes, I know it is not a great way of writing tests at all, as it makes them depend on each other, but sometimes a long interaction flow in application makes it necessary.

like image 91
Emzaw Avatar answered Oct 03 '22 07:10

Emzaw