Context: I have an element with innerText in Page1 and another element with innerText on Page 2. And I need to compare these two values in Page 3. So I need to find a way to save these values in a variable globally so that they can be used later.
Things I tried:
Trial 1: Didn't work as page1value scope is limited to the cy.get()
cy.get('#selector').invoke('text').then(text => {
const page1value = text
})
Trial 2: Didn't work as whenever I try to print the value outside, it comes as undefined or the value with which it was initialized it with.
it('TC Name', () => {
let page1value,
cy.get('#selector').invoke('text').then(text => {
page1value = text
})
cy.log(page1value) //comes as undefined
})
Trial 3: Using .as() as well its coming as undefined.
let page1value;
cy.get('#selector').invoke('text').as('page1value');
cy.log(page1value) //comes as undefined
It would be great if someone could tell me where I am doing wrong.
Cypress commands are pushed (enqueued) into a queue (called the Command queue --- which is basically an array), and then executed serially (one after another), and asynchronously.
While your
cy.log()
will be executed asynchronously, too, after the previous command, the value you pass to it (page1value
) is passed/evaluated synchronously, at the time you push the command to the queue (which is evaluated at the time the callback passed toit()
is called --- at the beginning of the test).This is just regular JavaScript behavior, and has nothing to do with Cypress. All the commands
cy.*
are just methods (functions) on thecy
object, and they're called immediately. What is not called (executed) immediately, is the logic that each command does (e.g. query the DOM for the selector you supply tocy.get()
, log to Command log when you callcy.log('string')
, etc.).Thus, in your 2nd example:
page1value
.cy.get()
,cy.invoke
,cy.then()
.cy.log
, to which you passpage1value
(which at this time is stillundefined
).cy.then
command takes turn to execute, thepage1value
variable is assigned, but it's no longer used (read) anywhere for the rest of the test (recall that you've already read it when you passed it to thecy.log
command in the previous step).Thus, what you want to do instead, is:
In your 3rd example, if you alias something, you need to access that value using another command (remember, everything is asynchronous, so you can't access values that are set asynchronously, in a synchronous manner as you're doing), in this case
cy.get('@aliasName')
:Note that the above explanations are slightly inaccurate and inexhaustive (there are more things going on behind the scenes), for the sake of simplicity. But as an intro to how things work, they should do.
Anyway, you should definitely read Introduction to Cypress.
You may also take a look at my older answers that touch on related concepts: