Reputation: 8384
I have the following code:
function getValues(date)
{
let totalValue=-10;
cy.visit('http://localhost/page1');
cy.get(".total").then((span)=>
{
console.log("Values: "+span.text())
totalValue=span.text()
}
)
//.then(()=> totalValue);
return totalValue;
}
I would like to get the value of the element so I use this:
it('Testing values',()=>
{
var totalValues=getValues(startDate)
console.log("Total values: "+ totalValues)
}
Unfortunately, it never waits for the variable to be set.
Either I get this -10
(when I use the return
) or undefined
(when I use then
) as results and the order is incorrect:
Total values: -10
Values: 2.5
How could I force the execution to wait until the correct value is set?
Upvotes: 0
Views: 589
Reputation: 4405
You can use an alias to store the value, but as already mentioned you have to access with .then()
in the test
function getValues(date) {
let totalValue = -10;
cy.visit('http://localhost/page1');
cy.get(".total")
.then((span) => {
totalValue = span.text()
cy.wrap(totalValue).as('totalValues') // set alias value,
// must be inside .then()
})
}
it('Testing values', () => {
getValues(startDate)
cy.get('@totalValues').then(totalValues => {
console.log("Total values: "+ totalValues)
})
})
Exception to using .then()
You can use before()
block in conjunction with alias to avoid using .then()
, but it's a specific pattern.
function getValues(date) {
let totalValue = -10;
cy.visit('http://localhost/page1');
cy.get(".total")
.then((span) => {
totalValue = span.text()
// will put totalValue on the "this" scope
cy.wrap(totalValue).as('totalValues')
})
}
before(() => {
getValues(startDate) // calling in before hook resolves all asynchronous calls
})
it('Testing values', function() { // must use a function() format
// your value is a property of "this"
console.log("Total values: " + this.totalValues)
})
Upvotes: 3
Reputation: 2555
The mixture of async(cypress) and sync code is the reason for the wrong order of logging.
In the scope of what you shared, here is what you can use to have the logging in the correct order. I'm not sure where the startDate
or where else you plan on using or the html you'll use the getValues()
function.
Here is the spec file.
<div class="total">2.5</div>
function getValues(date) {
let totalValue = -10
return cy
.get(".total")
.invoke("text")
.then((value) => cy.log("Value: " + value))
}
getValues().then((totalValues) => {
cy.log("Total values: " + totalValues)
})
Upvotes: 0
Reputation: 31974
With a plain JS function, return the last internal command and use .then()
on the return value.
function getValues(date) {
cy.visit('http://localhost/page1');
return cy.get(".total").then((span) => span.text())
}
it('Testing values', () => {
getValues(startDate).then(totalValues => {
console.log("Total values: "+ totalValues)
})
})
Or create a custom command
Cypress.Commands.add('getValues', (date) => {
cy.visit('http://localhost/page1');
cy.get(".total").then((span) => span.text()) // does not need an explicit return
})
it('Testing values', () => {
cy.getValues(startDate).then(totalValues => {
console.log("Total values: "+ totalValues)
})
})
If you want var totalValues = ...
in the test, there's no way to do it. You always need a .then()
because the value is obtained asynchronously.
Upvotes: 2