ebanster
ebanster

Reputation: 1086

Passing a variable's value from a test to the next one in Cypress

Is it possible to pass a variable from one it test to the next it test ? The following using cy.wrap does not work:

it('test1', () => {
 const var1 = 'test'
 cy.wrap(var1).as('var1Alias')
})
it('test2', () => {
 cy.get('@var1Alias').then(var1Alias => {
    // do stuff with the var1Alias
  })
})

I've checked old stackoverflow questions similar to mine such as this: Use variables across multiple 'it' statements to track change in Cypress and the difference is that the variable is declared globally outside the tests (it). Hence, you can always replace the variable.

My specific issue is that the dependency on the variable's value from the previous test. I know Cypress best practice suggests that tests shouldn't be sequential but this is a common scenario in my opinion to properly categorise tests in a readable manner.

For context, my first test is calling a POST endpoint then the response body will be passed as a query parameter for my GET endpoint in the succeeding test.

Current workarounds (while I am still looking for a better option):

Upvotes: 4

Views: 9008

Answers (3)

lambs
lambs

Reputation: 52

A bit late to respond but could help others, the way I done it was to use cy.write and created a json fixture file with the data in it

eg first test would have this line of code in:

cy.writeFile('cypress/fixtures/data.json', { Title: title, Desc: desc });

the second test would use this fixture file

cy.fixture('data.json').then(dataExtract=> {
      cy.get('#input').type(dataExtract.Title)

Upvotes: 0

Kyle Burriss
Kyle Burriss

Reputation: 751

Although this is not suggested by the Cypress team, we can't assume a one-size-fits-all approach. Following Paul's instructions, you could add Getter and Setter Tasks to the Plugins/Index.js file, like such:

on('task', {
   setVar1(val) {
     return (storeVariable= val);
   },
   getVar1(){
     return storeVariable;
   }
})

(Please note that Paul suggests you place the above within the "Support" index,js, this is wrong. Place it within the "plugins" index.js; furthermore, place it within the "module.exports" function.) Now you can add cy.task('setVar1 ', var1); to your first Test, and then the following within your second Test:

cy.task('getVar1').then((var1) => {
  //do stuff with var1 here
});

Upvotes: 2

Yurii Ya
Yurii Ya

Reputation: 159

If your it() tests share the same domain, you should use traditional function declaration "function() {do smth}" so you can use this. context, just right after the describe() define let variable with no value. After that in .then() inside your test "it()" you can redefine variable value like this.str = value; This value will be saved and can be passed to other it();

Example:

describe('test', function() {
  let str;
  it('take value from input', () => {
    cy.visit('/');

    cy.contains('Forms').click();
    cy.contains('Form Layouts').click();
    cy.contains('nb-card', 'Using the Grid').find('[data-cy="imputEmail1"]').type('[email protected]').invoke('val').then((value) => {
      this.str = value;
    });
  });

  it('put value', () => {
    cy.visit('/');
    cy.log(this.str);
  });
});

Upvotes: 3

Related Questions