DEV Community

Cover image for Failing a Test on console.error in Cypress
Ben Tyler
Ben Tyler

Posted on • Updated on • Originally published at lostcreekdesigns.co

Failing a Test on console.error in Cypress

This post originally ran on my personal website.

We recently switched over to Cypress for our end to end testing at my job. We were previously using a combination of Mocha and Puppeteer that made our tests so flakey to the point we just turned them off. This flake has totally disappeared and all things considered it was a relatively easy process to port all of our tests. If you have not had a chance to use Cypress I highly recommend checking it out.

As part of this process of porting tests over, I realized that Cypress was not failing our tests on console.error statements. There are two easy workarounds for this though: 1) add a small bit of logic to the cypress/support/index.js file or 2) the cypress-fail-on-console-error package. Both options are totally valid. We ended up opting for option 1 because it worked for us and meant we didn't have to add another dev dependency to our project.

Method 1 - Update commands.js

The first method is to add the following logic to cypress/support/index.js. This solution was adapted from Ryan Yost's post, Advanced Cypress Tips.

// /cypres/support/index.js
Cypress.on("window:before:load", win => {
  cy.stub(win.console, "error").callsFake(msg => {
    // log out to the terminal
    cy.now("task", "error", msg)
    // log to Command Log and fail the test
    throw new Error(msg)
  })
})
Enter fullscreen mode Exit fullscreen mode

Here is a walk through of what is going on.

  • we use Cypress.on() to listen for the window:before:load event to hook into and modify the window before any of our app's code runs
  • we stub out the console.error method and attach callsFake so that we can ensure our desired logic gets run
  • cy.now() is a bit of a hack here that Ryan Jost discusses in his blog post but it allows us to ensure the error gets logged out to the terminal. More info on cy.now() can be found here
  • and lastly we intercept the contents of the console.error and throw them as a proper error.

Method 2 - Use the cypress-fail-on-console-error package

This method is pretty straightforward as well and has some additional configuration options that you can read about in the project repo.

Install the package

# npm
npm install cypress-fail-on-console-error --save-dev

# yarn
yarn add cypress-fail-on-console-error -D
Enter fullscreen mode Exit fullscreen mode

Then make a small tweak to cypress/support/index.js.

// /cypress/support/index.js
import failOnConsoleError from "cypress-fail-on-console-error"

failOnConsoleError()
Enter fullscreen mode Exit fullscreen mode

That's it!

If you have any questions or comments please reach out below! If you found this post useful, please retweet or share! You also can sign up for updates for whenever I release a new post.

Top comments (1)

Collapse
 
karfau profile image
Christian Bewernitz

I just wanted to mention that you can also very easily enable it for a single test by using the onBeforeLoad option on cy.visit.

In my case I had to rethrow the error with a setTimeout to not interrupt rendering that was currently going on.

  function failOnConsoleError(win: Cypress.AUTWindow) {
    win.console.error = (...args) => {
      // since this is happening in the scope of the application
      // rethrowing directly would cause more error messages
      // we just delay it a bit, cypress will still log it as an uncaught error
      // and causes the test to fail
      setTimeout(() => {
        throw new Error(args.join(', '))
      }, 0);
    }
  }
Enter fullscreen mode Exit fullscreen mode