javascriptcypresscypress-origin

Reduce callback nesting in cypress


I've read that in Cypress I should not use await and that it is not needed because you can remove nesting through chaining. Here I have a cy.fixure nested in cy.origin nested in cy.session, is there a way to flatten this?

  cy.session([], () => {
    cy.visit("")
    cy.origin("https://my-address.com", () => {
      cy.fixture("user").then((user) => {
        cy.get("#username").type(user.username)
        cy.get("#password").type(user.password)
      })

      cy.get("button[type='submit']").click()
      cy.url().should("equal", "/login-success")
    })
  })

Edit
This is not a question regarding regular javascript, it's Cypress specific and normal async / await won't work here.


Solution

  • Not really (any way to flatten). As you said, async/await does not work with Cypress commands since they aren't promises.

    Well, you can put promises in place and await them, but it's clumsy and actually more code.

    But cy.session() and cy.origin() are funky commands that only work because of the callback - or more accurately require the callback to function.

    cy.session() only fires it's callback on the first call, there-after it caches the session data and returns them on the 2nd call instead of re-calling the callback.

    cy.origin() uses the callback to make an isolated sandbox for code running against the other (specified) origin, and it's not even a callback in the Javascript sense, since it cannot use closure to variables in the outside scope.

    Which links in to the fixture() part. Normally you can import or require a fixture

    const user = require('cypress/fixtures/user.json')
    

    but with cy.origin that doesn't help you since the fixture in imported in the outer scope and cannot be seen inside the cy.origin sandbox.


    For a promise-creating plugin see cypress-promise, but it won't work with session and origin for reasons stated.

    import promisify from 'cypress-promise'
     
    it('should run tests with async/await', async () => {
      const foo = await promisify(cy.wrap('foo'))
      const bar = await promisify(cy.wrap('bar'))
     
      expect(foo).to.equal('foo')
      expect(bar).to.equal('bar')
    })