How to start with Cypress Debugging? (Top 5 Methods)
By Ganesh Hegde, Community Contributor - February 10, 2023
Cypress testing 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 through Cypress logs, Cypress log elements, and finally Visual Studio Code IDE.
- Why is debugging important?
- How to debug in Cypress
- 1. Debug Cypress tests using the stack trace
- 2. Debug Cypress Tests using the Debugger
- 3. Debug Cypress Tests using console logs
- 4. Debug Cypress with .debug() option
- 5. Cypress debug tests with .pause() option
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 pretty tedious. Testers may run 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
Once you’ve finished installing Cypress, it is easy to debug test scripts. It offers powerful options such as:
- Using stack trace
- Using debugger
- Using console logs
- Using .debug() command
- 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 even allows the option to open the error-containing line in the IDE if one configured the Cypress IDE / File Opener options beforehand.
How to configure Cypress IDE/File Opener Options in Cypress
With Cypress, one can directly open files from a stack trace in their IDE. For example, suppose a tester sets the File Opener preference as Visual Studio Code IDE, then from stack track. In that case, they can directly open the file causing the error, and the 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
- Navigate to Cypress’s main window.
- Click on Settings.
- Expand the “File Opener Preference” Tab.
- Click on the desired IDE.
This example sets Visual Studio Code as the default IDE for Cypress.
After setting up the preference, click on stack trace, which will take us to the concerned file or line.
For example, in the code above, cy.get(‘#product-menu-toggle1’).click(); throws an error. So the file causing the issue can be opened directly in the IDE from Cypress.
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.
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.
Note: The Debugger keyword should always be a chain with then(). 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; })
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:
- cy.log() command
- 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.
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 leverage 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):
- Navigate to the cypress/plugins folder.
- Open index.js file inside plugins folder.
- Add a task to log messages as done below.
//index.js module.exports = (on, config) => { 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 the headless mode execution of Cypress with console.log()
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 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.
Bonus Read: How to Run Safari Test on Cypress
This article depicts that multiple options of varying complexity 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.
- Remember 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.