Open In App

Cypress - Debugging

Last Updated : 21 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Cypress is an open-source website testing tool that is used to automate tests for JavaScript web applications. It is designed for end-to-end testing and can be used for unit and integration tests. It is fast, reliable, and can run directly in the browser in real-time. It's built to work with any front-end framework or website, including React, Angular, and Vue. In this article, we will learn about Debugging in Cypress.

Why is debugging important?

Debugging is an important part of software engineering because it helps to identify and fix errors & Bugs in software before they become problematic. Debugging can help to improve system quality, reduce downtime, increase user satisfaction and more. It helps pinpoint where and why a test is failing. It uncovers hidden issues that can be addressed to improve the overall quality of the code.

Debug Cypress tests using the stack trace

Cypress automatically captures stack traces when a test fails. It provides detailed information about where the error occurred. The stack trace shows the sequence of function calls that led to the error.

Example: You can put the below code later in a given example in this article to view the error stack.

JavaScript
it('fails to log in with incorrect credentials', function() {
    cy.get('#username').type('incorrectUser');
    cy.get('#password').type('wrongPassword');
    cy.get('#loginButton').click();

    // This will fail and produce a stack trace
    cy.get('#welcomeMessage').should('be.visible'); 
});


error-stack
error-stack

Debug Cypress Tests using the Debugger

debugger keyword is a JavaScript feature that pauses code execution. It allowing you to inspect the current state in your browser's Developer Tools. You can Insert debugger at the point where you want to pause execution. When Cypress hits this line, the test will pause and you can use the Developer Tools to inspect variables, DOM elements and more.

make sure to open inspect window then only this debugger will be pause.

JavaScript
it("checks login button behavior", function() {
    cy.get("#username").type("correctUser");
    cy.get("#password").type("correctPass");

    // Execution will pause here
    debugger;
    cy.get("#loginButton").click();
});

Debug Cypress Tests using console logs

Using console.log() statements in your Cypress tests can help you track the flow of the test and inspect the values of variables at different stages. You can Insert console.log() at various points in your test to output the values of variables or messages to the console and review the output in the browser’s Developer Tools console.

JavaScript
it('logs input values', function() {
  cy.get('#username').type('correctUser').then(($input) => {
    console.log('Username:', $input.val());
  });
  cy.get('#password').type('correctPass').then(($input) => {
    console.log('Password:', $input.val());
  });
  cy.get('#loginButton').click();
});

Debug Cypress with .debug() option

Cypress provides a .debug() command. It acts like a built-in debugger that pauses the test and prints the current subject to the console. It is particularly useful for inspecting elements or variables at a specific point in the test. You can chain a .debug() after a Cypress command to inspect the element or value it yields.

JavaScript
it('inspects login button', function() {
  cy.get('#loginButton').debug().click(); // Inspect the login button before clicking
});

Cypress debug tests with .pause() option

.pause() command in Cypress halts test execution at the point where it is called. It allows you to manually interact with the application and inspect the state before continuing. You can insert .pause() at the point where you want the test to stop. The test will remain paused until you manually resume it.

JavaScript
it('pauses before submitting the form', function() {
  cy.get('#username').type('correctUser');
  cy.get('#password').type('correctPass');
  cy.pause(); // Execution will pause here
  cy.get('#loginButton').click();
});

Difference Between Cypress .pause() Command and .debug() Command

.pause()

.debug()

It Stops the entire test execution and allows manual interaction.

It prints the current subject to the console for inspection.

In this, Test execution is halted until manually resumed by the user.

In this, Test execution continues after printing the subject.

It allows full manual interaction with the application before resuming.

It is limited to inspecting the current subject; no interaction.

It is ideal for debugging complex flows where manual intervention is required.

It is best for quick inspections without needing manual interaction.

Debug Cypress Tests with Visual Studio Code IDE

Visual Studio Code provides a debugging support for Cypress tests. It allows you to set breakpoints, inspect variables and control the flow of test execution directly from the IDE. To use, first set up Cypress with VS Code using the npx cypress open command. then place breakpoints in your test code where you want execution to pause and sse the built-in debugger in VS Code to inspect the application’s state and control the test flow.

Cypress Installation

Before we begin make sure node.js in installed in your system.

Open the Windows Command Prompt, Powershell or a similar command line tool, and type

“node -v”

Step 1: Create a Project Folder and move to it by using following command.

mkdir cypress 
cd cypress

Step 2: Initialize a project and Install Cypress.

npm init -y 
npm install cypress –save-dev

Step 3: After Creating a Project, Run this command to start cypress.

npx cypress open

Step 4: Testing type, Configuration and creating a spec.

  • Choose a E2E Testing or Component Testing, then after quick configuration choose browser.
  • After that create a new spec then click on your spec name to open your spec in any IDE.

Step 5: Testing HTML File.

  • Create a HTML File and open it with any live server extension.
  • copy that live server file serve link, for later use.

Example of .debug() and .pause() option

The below example demonstrate the using of .debug() and .pause option.

HTML
<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Login Form</title>
</head>
<body>
  <h1>Login</h1>
  <form id="loginForm">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username">
    <br><br>
    <label for="password">Password:</label>
    <input type="password" id="password" name="password">
    <br><br>
    <button type="button" id="loginButton" disabled>Login</button>
  </form>
  <p id="errorMessage" style="display: none; color: red;">Invalid credentials</p>
  <p id="welcomeMessage" style="display: none;">Welcome, <span id="user"></span>!</p>

  <script>
    document.getElementById('username').addEventListener('input', enableButton);
    document.getElementById('password').addEventListener('input', enableButton);

    function enableButton() {
      const username = document.getElementById('username').value;
      const password = document.getElementById('password').value;
      document.getElementById('loginButton').disabled = !(username && password);
    }

    document.getElementById('loginButton').addEventListener('click', () => {
      const username = document.getElementById('username').value;
      const password = document.getElementById('password').value;
      if (username === 'correctUser' && password === 'correctPass') {
        document.getElementById('welcomeMessage').style.display = 'block';
        document.getElementById('user').textContent = username;
        document.getElementById('errorMessage').style.display = 'none';
      } else {
        document.getElementById('errorMessage').style.display = 'block';
        document.getElementById('welcomeMessage').style.display = 'none';
      }
    });
  </script>
</body>
</html>
JavaScript
describe("Login Form Functionality", function() {
    beforeEach(function() {
        // Visiting the testing website
        cy.visit("http://127.0.0.1:5500/index.html");

        // Loading Fixture Data
        cy.fixture("loginData.json")
            .then((data) => { this.data = data; });

        // Verify the presence and visibility of the login
        // form elements
        cy.get("#username")
            .should("exist")
            .and("be.visible");
        cy.get("#password")
            .should("exist")
            .and("be.visible");
        cy.get("#loginButton")
            .should("exist")
            .and("be.visible");

        // Verify that the login button is initially
        // disabled
        cy.get("#loginButton").should("be.disabled");
    });

    it("incorrect form data", function() {
        // Enter an incorrect username and password
        cy.get("#username")
            .type(this.data.incorrectUsername);
        cy.get("#password")
            .type(this.data.incorrectPassword);

        // Pause to inspect the state before clicking the
        // login button
        cy.pause();

        cy.get("#loginButton").should("be.enabled").click();

        // Debug the error message element before making
        // assertions
        cy.get("#errorMessage")
            .debug()
            .should("exist")
            .and("be.visible")
            .and("contain", "Invalid credentials");
    });

    it("correct form data", function() {
        // Enter a correct username and password
        cy.get("#username")
            .clear()
            .type(this.data.correctUsername);
        cy.get("#password")
            .clear()
            .type(this.data.correctPassword);

        // Adding a breakpoint for inspection
        cy.get("#loginButton").should("be.enabled").click();

        // Logging before verifying the welcome message
        cy.log(
            "Checking if the welcome message is displayed with the correct username");
        cy.get("#welcomeMessage")
            .should("exist")
            .and("be.visible")
            .and("contain",
                 `Welcome, ${this.data.correctUsername}`)
            .debug();

        // Logging before verifying the absence of the error
        // message
        cy.log(
            "Ensuring the error message is not visible after a correct login");
        cy.get("#errorMessage").should("not.be.visible");
    });
});

Output

Conclusion

In conclusion, Cypress is a end-to-end automated testing tool that enables efficient and reliable testing of web applications. Cypress provides a .debug and .pause command which can be used to debug the application. Cypress commands are easy-to-write that make it an ideal choice for automating the testing of dropdowns and other web components.


Next Article

Similar Reads