Search code examples
javascriptnode.jscypress

In Cypress, how exactly do I use a returned value from a helper-function file within a test file?


I'm new to Cypress and have set up a bunch of helper functions on their own file. I want one of these functions to return a value, however I am getting stuck with how to do this within Cypress' synchronous structure.

I keep getting the error

CypressError: cy.then() failed because you are mixing up async and sync code.

I have tried to implement a similar fix as mentioned here Cypress returning Synchronous value within Async command? but to no avail.

My code is as such:

Helper function:

//helperFunction.js
module.exports.schemaChecker = () => {
    cy.get('script:contains("@context")').its('length').then((len) => {
        cy.task('log', 'Schemas: ' + len);
        if (len > 1) {
            return "fail";
        }
    })
}

Test file:

import { schemaChecker, } from '../../support/helperFunctions.js';
// other stuff...

Given('I am on X page', () => {
    cy.viewport(1480, 1000);
    cy.visit(pageUrl);

    schemaChecker().then((response) => {
        if (response == "fail") {
           // Do something
        };
    })
});

I've tried a few variations of this (eg: if (schemaChecker() == "fail") {}) but am just unsure how to make it work together and have not been able to find anything useful on Google.

Would anyone be able to point me in the right direction?


Solution

  • The error you are mixing up async and sync code is referring to the cy.task() call (which is async) and the return 'fail'; (which is sync).

    module.exports.schemaChecker = () => {
      return cy.get('script:contains("@context")').its('length').then((len) => {
    
        cy.task('log', 'Schemas: ' + len);  // <-- async
    
        if (len > 1) {
          return 'fail'                     // <-- sync
        }
      })
    }
    

    One way to fix is to make both steps async

    module.exports.schemaChecker = () => {
      return cy.get('script:contains("@context")').its('length').then((len) => {
    
        cy.task('log', 'Schemas: ' + len);  // <-- async
    
        if (len > 1) {
          return cy.wrap('fail')            // <-- also async
        }
      })
    }
    

    enter image description here


    Here's my test

    it('check the schema', () => {
      schemaChecker().then((response) => {
        if (response === 'fail') {
          Cypress.log({name: 'schema error', message: 'Woops it failed'})
        };
      })
    })
    

    and my app page with deliberate error condition

    <body>
      <script>
        const var1 = '@context'
      </script>
      <script>
        const var2 = '@context'
      </script>
    </body>