Home Guide How to start with Cypress Debugging

How to start with Cypress Debugging

By Ganesh Hegde, Community Contributor -

Table of Contents

Cypress framework is a popular end-to-end automation tool favored by QAs for its many features. One of those features is its debuggability. The Cypress debugger provides readable error messages that help testers debug quickly. It even allows debugging using popular developer tools.

This article will discuss how testers can get started with debugging tests in Cypress. 

Why is debugging important?

Debugging is a core criterion when choosing an automation framework. For example, let’s say a tester has written ten lines of test script and it is throwing an error or tests are failing. They need to analyze why it is failing.

They can use the try and error method, but it is quite tedious. Testers may end up running scripts 100 times after modifying and analyzing the results.

However, a framework with robust debugging capabilities will let them fix issues much faster, often in minutes. Typically, the debug capability in any tool provides:

  • Readable error messages
  • The option to pause test execution
  • The option to modify or alter values of scripts during run time

Using debug capability, testers can quickly identify the problem and resolve it.

How to debug in Cypress

Cypress provides an easy way to debug test scripts. It offers powerful options such as:

  1. Using stack trace 
  2. Using debugger
  3. Using console logs
  4. Using .debug() command
  5. Using .pause() command

1. Debug Cypress tests using the stack trace

Let’s consider a simple test script:

describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/');

        cy.get('#logo').should('be.visible');

    })

    it('Click on Product Menu', () => {

        cy.get('#product-menu-toggle1').click();

    })

})

 

In the code above, the selector #product-menu-toggle1′ doesn’t exist in https://www.browserstack.com. So when the script runs, Cypress throws up a clear error message.

Testers can use the View stack trace option to view the detailed stack trace, and can even print the stack trace to the browser console as follows:

Timed out retrying after 4000ms: Expected to find element: #product-menu-toggle1, but never found it.  

Cypress Debugging Example

Cypress even provides the option to open the error-containing line in the IDE if one has configured the Cypress IDE / File Opener options beforehand.

How to configure Cypress IDE/File Opener Options in Cypress

With Cypress, one can choose to open files from a stack trace in their IDE directly. For example, if a tester sets the File Opener preference as Visual Studio Code IDE, then from stack track they can directly open the file causing the error, and cursor focus will be on the exact line with the error.

This is useful as testers don’t have to search and open files and lines with issues.

Setup a File Opener Preference in Cypress

  1. Navigate to Cypress main window.
  2. Click on Settings.
  3. Expand “File Opener Preference” Tab.
  4. Click on the desired IDE.

configure Cypress IDE/File Opener Options in Cypress

This example sets Visual Studio Code as the default IDE for Cypress. 

After setting up the preference, click on stack trace and it will take us to the concerned file or line.

For example, in the code above, cy.get(‘#product-menu-toggle1’).click(); is throwing an error. So the file causing the issue can be opened directly in the IDE from Cypress.

Configure Cypress IDE/File Opener

2. Debug Cypress Tests using the Debugger

Cypress provides options to use the native debugger keyword in tests. Just put the debugger keyword at the juncture in which test execution should pause.

 describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/');

        cy.get('#logo').should('be.visible');

    })

    it('Click on Sign In', () => {

        cy.get('a[title="Sign In"]').then(($selectedElement=> {

            debugger;

            $selectedElement.get(0).click()

        })

    })

})

In the above example the debugger is deployed in the second it().  When the test runs, it will pause as soon as it encounters the debugger keyword.

Debug Cypress Tests using the Debugger

At this point, testers can easily navigate to different tabs in developer tools like console, Elements, etc. to inspect or check what is happening at that part of the script.

Cypress Debugger

Note: The Debugger keyword should always be a chain with then(). Just using the debugger keyword directly without using then() may cause it to work incorrectly. For example, the code snippet below might not work as expected.

 

  //debugger might not work in expected way

    it('Click on Sign In', () => {

        cy.get('a[title="Sign In"]').click()

            debugger;
    })

 

Try Cypress Tests on Real Browsers

3. Debug Cypress Tests using console logs

With Cypress, testers can print logs on the browser console and the Cypress window console. They can even print the stack trace to the browser console.

There are two ways to use console logs in Cypress:

  1. cy.log() command
  2. console.log() by configuring cypress tasks

1. Using Cypress cy.log()

cy.log() is exclusively provided by Cypress. It helps print a message to the Cypress Command Log. It is quite useful to print a message or value after execution of a particular line of code.

Code Snippet

describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/');

        cy.get('#logo').should('be.visible');

        cy.log("Navigated to home page")

    })

})

In the above example, cy.log() is used to print the message Navigated to the home page after execution of above code, Cypress prints the message in the Cypress command log. One can also click on the log to print the message in the browser console.

Note: Cypress doesn’t print logs directly in the browser console. First, it prints on the Cypress window and from there one can print it on the console.

Debug using Cypress cy.log()

2. Using console.log() in Cypress

As seen earlier, cy.log() prints the message Cypress window first. Only when the user clicks on that will it print the message on the console. So, if executing tests on headless, testers will find console.log() very useful as they can see the printed message on the command line.

However, Cypress doesn’t directly support the use of console.log(). But it can be done as shown below.

console.log() helps print the message in the browser console. If users are leveraging headless mode, console.log() prints the message in the command line.

Follow the steps below to use console.log () in a Cypress script (the one used above):

  1. Navigate to the cypress/plugins folder.
  2. Open index.js file inside plugins folder. 
  3. Add a task to log messages as done below.
//index.js

module.exports = (onconfig=> {

  on('task', {

    log(message) {

      console.log(message)



      return null

    },

  })

}

   4. Now use the task log in the script.

//inside test script ex: first-test.js


describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/');

        cy.task("log","This is console log : Navigated to home page")

    })

})

Considering the example above, this script uses:


cy.task("log","Navigated to home page")

console.log() can be used with both headless mode (command-line) and headful mode tests. In the case of headless mode, the message will be printed in the command line. In headful mode the message will be printed in the Cypress command window.

Below is a snapshot of headless mode execution of Cypress with console.log()

Debug Using console.log() in Cypress

4. Debug Cypress with .debug() option

Cypress provides a powerful utility command to debug test scripts called .debug(). This command sets the debugger and logs what the previous command yields. .debug() can be chained with cy or off another command. It yields the same subject it was given from the previous command.

Note: One must have their Developer Tools open for .debug() to hit the breakpoint.

Code Snippet

describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/');

        cy.get("a[title='Sign In']").first().debug().click()

    })

})

The example above uses.debug()  in this line

cy.get("a[title='Sign In']").first().debug().click()

 

Considering this, .debug()  is placed after getting an element and before clicking on that element, so Cypress pauses execution after getting the element. Once the script hits debug point, it stops execution and testers can perform desired operations on developer tools to identify or resolve issues.

5. Cypress debug tests with .pause() option

The .pause() command stops cy commands from running and allows interaction with the application under test. Testers can then “resume” running all commands or choose to step through the “next” commands from the Command Log.

Difference between Cypress .pause() command and .debug() command

  • .pause() will stop test execution to inspect the web application, the DOM, the network, but .debug() will stop only when the developer tools are open.
  • The .pause() command does not provide any debugging information. .debug() provides debugging information when Cypress hits the .debug() command.
  • Using the .pause() command can stop the execution and continue step by step using the next option but .debug() doesn’t provide this function.


Code Snippet


describe('Verify Browser Stack Home Page', () => {

    it('Verify Browserstack logo is visible', () => {

        cy.visit('https://www.browserstack.com/').pause();

        cy.get("a[title='Sign In']").first().click()

    })

})

Consider the code snippet above.  The .pause() command is applied in the line:

cy.visit('https://www.browserstack.com/').pause();

So when Cypress navigates to the page it hits the .pause() command and stops execution. At this point, one can analyze the rendered DOM or perform desired activity using browser developer tools. Once the analysis is completed, they can just hit the Next button to see the next step or can hit the Resume button to continue execution.

Debug Cypress Tests with Visual Studio Code IDE

Debugging Cypress tests using Visual Studio Code was possible earlier but with the latest version of Cypress, there is no direct way to do so. Even with the latest version of Cypress, a workaround was possible using Debugger for Chrome – a Visual Studio Code Extension and cross-env npm package. However, the Debugger for Chrome Extension for Visual Studio Code is deprecated and the cross-env npm package has gone into maintenance mode.

So if testers try to configure Visual Studio Code and Cypress to debug tests, using an outdated package and extension might cause Cypress to behave unexpectedly. Hence, this is not a recommended option for debugging.  In short, there is no direct way to use Visual Studio Code for debugging Cypress tests. 

As this article depicts, there are multiple options of varying complexity that can be used to debug Cypress tests. Each method deserves a few rounds of execution before testers can find one (or more) suiting their skillset, resources and general convenience. 

Bear in mind that Cypress testing must be executed on real browsers for accurate results. Start running tests on 30+ versions of the latest browsers across Windows and macOS with BrowserStack. Use instant, hassle-free parallelization to get faster results without compromising on accuracy. Detect bugs before users do by testing software in real user conditions with BrowserStack.

Run Cypress Tests on Real Browsers

Tags
Cypress

Featured Articles

How to perform Cypress Test Automation

Getting Started with Cypress Installation for Test Automation

Beginner’s Guide To Software Application Testing

BrowserStack Logo Run Cypress Tests on 30+ Browser Versions Contact us Get Started Free