I am trying to log something in the middle of a Cypress chain of calls:
function geAccountElement() {
return cy.get('div[ui-id=account]')
.then(thing => {
cy.log('Peek at thing: ' + thing);
return thing;
})
.contains(testAccountName)
.parents('div[ui-id=account-card]')
}
But I am getting this warning:
Command `contains` expects ["element", "cy"] as a previous subject, but "any" is passed from `then` command
How can I make this sort of chainable logging function work?
Update Saturday 23 March 2024, 06:20:04 PM
Turns out I was even more confused. I saw that warning in an IntelliJ tool tip but did not run the test. If I did, I would have seen:
cy.then() failed because you are mixing up async and sync code.
In your callback function you invoked 1 or more cy commands but then returned a synchronous value.
What I am trying to do is log the thing in between chained calls. I see I can do this:
cy.get('div[ui-id=account]')
.invoke('val')
.then(thing => {
cy.log('Peek at thing: ' + thing);
})
But that's a terminal operation.. meaning the rest of the test stops there. I wanted to try and get some logging happening between get
and the contains
.
On my test, the error about mixed async and sync code was fixed by wrapping the return value like this:
cy.visit('https://example.com');
cy.get('h1')
.then(thing => {
cy.log('Peek at thing: ' + thing) // this is an async command
// return thing // this line is the "sync" value complained about
return cy.wrap(thing) // wrapping makes it async
})
.contains('Example Domain')
Cypress is not overly smart about this error message, since the cy.log()
is just a side effect and has no bearing on the chain subject (i.e return thing
is acceptable without the cy.log).
You can instead swap in the synchronous Cypress.log()
call
cy.get('h1')
.then(thing => {
Cypress.log({
message: 'Peek at thing: ' + thing
})
return thing
})
.contains('Example Domain')
and make use of other properties for more informative log
cy.get('h1')
.then(thing => {
Cypress.log({
displayName: 'Peek at thing:',
message: thing
})
return thing
})
.contains('Example Domain')