Call cy.log in a chain of calls

30 Views Asked by At

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.

1

There are 1 best solutions below

1
K.Kassianides On BEST ANSWER

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')

enter image description here

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')

enter image description here