DannyMoshe
DannyMoshe

Reputation: 6265

Storing an element's text in Cypress outside of a chainer method

How can I store the text value of a div once and use this throughout a cypress test?

Thus far I've managed to do this by nesting the bulk of my test's logic within the invocation of the then method, yet this doesn't seem elegant or ideal.

cy.get('div').then(($div) => {
    let storedVar = $div.text()
    // Bulk of dependent test logic gets nested here
})

I've tried to store the text outside of the then method as follows:

let storedVar = ''

cy.get('div').then($div => {storedVar=$div.text()})

But this doesn't work (since it's a promise, storedVar remains its initial value throughout the test).

Any alternatives to this nested solution?

Upvotes: 1

Views: 2275

Answers (2)

Muditha Perera
Muditha Perera

Reputation: 1252

In cypress to store the values, you need to use aliases Because of the asynchronous nature of cypress const value = cy.get('div').text() will not give you your expected output.

Cypress Values and Aliases

You need to use aliases to achieve what you need. but as you have mentioned in the question if you are going to use the aliases in the same test case that you are creating it you need to use .then. Because as I mentioned earlier cypress execution is asynchronous so if you use the alias like mentioned below, it will not give you the expected output.

it("test",function (){
cy.get('div').invoke('text').as('value')
//this is wrong
cy.log(this.value)
})

The correct way would be,

it("test",function (){
cy.get('div').invoke('text').as('value').then(() => {
cy.log(this.value)
})
})

And the second thing to keep in mind is when you use aliases when you write hooks (it) don't use arrow functions if you wish to use previously created aliases. so it("test",() => {}) will not work but it("test", function(){}) will work.

According to your question, you can use aliases like this,

Example:

//Lets create aliases in test01, test02 and test03
before("test01",() => {
cy.get('div').invoke('text').as('var1');
})

it("test02",() => {
cy.get('div').then($el => {
cy.wrap($el.text()).as('val2')
})
})

it("test03",() => {
cy.get('div').invoke('text').as('var3')
})

//let's create use those created aliases in another test
//remember - NO arrow functions to create hooks when using aliases
it("test04", function(){
const variable = this.var3
cy.log(this.var1)
cy.log(this.var2)
cy.log(variable)
//All the above commands will log the expected innerText values
})

Hope this is what you were looking for.

Upvotes: 1

Srinu Kodi
Srinu Kodi

Reputation: 512

Your code will not work as you are not doing the operation within chain. Cypress works in promise chain and that's how the architecture is.... You have to pass on values to chain and do the operation accordingly.

It will work like below.

return cy.get(`.locatorClassName`).then(ele => {
      return ele.text()
    }).then(eleValue => {
      cy.log(eleValue);
    });

Upvotes: 1

Related Questions