How to access the previous value of text in Cypress that you expect to change?

43 Views Asked by At

I'm in the process of upgrading Cypress from version 8 to version 13. In version 8, I was able to do something like this:

cy.getBySel('mealList-totalCalories').invoke('text').as('totalCals');

This accesses the original value of a value that will change later on once a new item is added to the meal list. Once the calorie value changes, I want to ensure the new value is equal to the previous value plus the caloric value of the item that was added. This used to work:

cy.get('@totalCals').then((totalCals) => {
  console.log(totalCals) // This used to equal the original value, 2020, now is 2300.
  const expected = parseInt(totalCals) + 280;
  cy.getBySel('mealList-totalCalories').should('have.text', expected);
});

It appears that previously Cypress was storing the original text value of totalCals, which I could later access. However, now the totalCals value is already equal to the previous value + 280, which makes me think Cypress is just running the previous query again to access the current value.

Is there a new way to store the text of an element in Cypress for later access?

3

There are 3 best solutions below

0
Joshua.J On BEST ANSWER

There's a switch to handle that. Please refer to as - options

The type of alias to store, which impacts how the value is retrieved later in the test. Valid values are query and static.

A query alias re-runs all queries leading up to the resulting value each time the alias is requested.

A static alias is retrieved once when the alias is stored, and will never change.

cy.getBySel('mealList-totalCalories').invoke('text').as('totalCals', {type:'static'})
1
berse2212 On

Yes, your assumption is correct that cypress re-runs queries to avoid stale elements: https://docs.cypress.io/guides/core-concepts/variables-and-aliases#Stale-Elements

However you can simply move the then expression upwards to the first command to capture the value yourself:

cy.getBySel('mealList-totalCalories').invoke('text').then(totalCals) => {
  console.log(totalCals) // This should be 2020 now

  //do the other stuff that somehow changes the totalCals

  const expected = parseInt(totalCals) + 280;
  cy.getBySel('mealList-totalCalories').should('have.text', expected);
});
0
agoff On

An alternative that avoids the nesting concerns you have would be to set the value as a Cypress environment variable. (That link focuses on Cypress environment variables between tests, but I think the concept holds true here as well).

cy.getBySel('mealList-totalCalories')
  .invoke('text')
  .then((totalCals) => {
    Cypress.env('totalCals', totalCals);
  });
... // more code here
cy.getBySel('mealList-totalCalories')
  .should('have.text', parseInt(Cypress.env('totalCals')) + 280);