Handle Cypress uncaught exceptions from test failures, app errors, or unexpected status codes to ensure reliable, smooth, and uninterrupted test execution.
OVERVIEW
Cypress is a powerful tool for automating web application testing, but the uncaught exceptions in Cypress can disrupt your tests and prevent them from completing successfully. Proper exception handling is crucial to ensure accurate test results.
By handling the Cypress uncaught exception in various test cases, you can address errors that occur during test execution, validate command outputs, and ensure more reliable tests. Without proper exception handling, the root cause of errors may be hard to identify. With proper handling, errors will be logged, helping you resolve the issue efficiently.
Exception handling is the process of managing runtime errors during program execution. In Cypress, exceptions can cause tests to fail abruptly and provide unclear error messages, leading to unreliable test results.
To handle exceptions effectively, Cypress provides methods like the fail and uncaught:exception events or options like failOnStatusCode: false. Proper exception handling ensures smoother test execution and more reliable results in your Cypress e2e tests .
Exception handling is important because it allows a program to recover from errors and continue running instead of crashing. Cypress test automation helps identify and isolate issues quickly and prevents tests from failing due to external factors like network or server errors.
For example, if a Cypress test fails due to an unavailable element, handling the exception allows the test to retry or continue, improving the robustness of the test suite. Additionally, logging custom error messages provides better clarity for the entire team.
Note : Run Cypress test scripts across 50+ browsers and operating systems. Try LambdaTest Now!
In Cypress, exceptions can occur due to various reasons, some of which are mentioned below:
To handle these, you can use cy.on or Cypress.on:
Therefore, if you want to register a global listener that applies to all tests, you should use the Cypress.on method. However, if you only want to register an event listener for a specific test, you should use the cy.on method.
Subscribe to LambdaTest YouTube Channel to get more tutorials on Cypress automation and more.
By default, Cypress throws an exception if the server responds with a status code other than 200 or 303. This helps ensure that tests fail when the application returns error status codes, such as 400 (Bad Request) or 500 (Internal Server Error).
However, in some test scenarios, you may expect a status code other than 200 or 303, and you might not want the test to fail immediately. In these cases, you can handle this Cypress uncaught exception caused by an unexpected status code by using the failOnStatusCode: false option in your test.
For example, let's say you open a URL that returns a 404 status code. This demonstrates how Cypress handles unexpected status codes and how you can manage these situations within your tests to prevent the test from failing due to an uncaught exception.
Test Scenario:
URL to Test: LambdaTest eCommerce Playground (This URL returns a 404 status code.) |
Code Implementation:
describe("Cypress Exception Handling", () => {
it("Fail on status code", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login/1");
});
});
Code Walkthrough:
Result:
When running this code, Cypress will throw an error because the server responds with a status code of 404 (Not Found). To prevent this error and continue execution, you can modify the code.
Modified Code with failOnStatusCode: false:
describe("Cypress Exception Handling", () => {
it("Fail on status code", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login/1", {
failOnStatusCode: false
});
});
});
Execution:
Run npx cypress open on the terminal.
As shown in the screenshot below, the test case has not failed this time.
You can handle this Cypress uncaught exception caused by an unexpected status code when making an API call as well.
Below is the sample test case to pass failOnStatusCode:false in the API test.
describe("Cypress Exception Handling", () => {
it("Fail on status code by calling api", () => {
cy.request(
{url:"https://ecommerce-playground.lambdatest.io/index.php?route=account/login/1",
failOnStatusCode: false, })
}) })
To prevent Cypress from failing the test when an unexpected status code is returned, add the { failOnStatusCode: false } option to the cy.visit() command.
Result:
For demonstration purposes, we will be running all tests on a cloud-based platform like LambdaTest because it offers significant advantages in terms of scalability, flexibility, and cross-browser testing.
By leveraging the cloud, we can run tests across a wide range of browsers, devices, and OS combinations without needing to maintain and manage test infrastructure. This ensures faster execution, better coverage, and efficient resource management, especially for parallel test execution.
LambdaTest is an AI-powered test execution platform that allows you to run manual and automated tests over a Cypress cloud of over 3000+ real web browsers online.
This platform integrates with popular automation frameworks like Cypress, allowing us to run tests on the cloud. With LambdaTest, you can scale Cypress testing efforts, run tests across multiple virtual machines, and save time through parallel execution, all while benefiting from cross-browser testing. This approach improves the overall efficiency and reliability of your testing process.
To run the test on the cloud, follow the steps below:
Step 1: Install LambdaTest CLI
Navigate to your Cypress project, open the terminal, and install the LambdaTest CLI using the command:
npm install lambdatest-cypress-cli
Ensure you download the latest version of lambdatest-cypress-cli to access its newest features. You can verify and use the latest version from the official GitHub repository.
Step 2:Set up the config
After installing the LambdaTest CLI, set up the configuration by running the command: lambdatest-cypress-cli
This command will create a file named lambdatest-config.json in your project.
The next step is to configure this file to run test cases on different browsers using LambdaTest. For Cypress version 10 and above, use the following code to set up lambdatest-config.json.
{
"lambdatest_auth": {
"username": "user.name",
"access_key": "<access_key>"
},
"browsers": [
{
"browser": "Chrome",
"platform": "Windows 10",
"versions": ["latest-1"]
},
{
"browser": "Firefox",
"platform": "Windows 10",
"versions": ["latest-1"]
}
],
"run_settings": {
"config_file": "cypress.config.js",
"reporter_config_file": "base_reporter_config.json",
"build_name": "Exception Handling",
"parallels": 1,
"specs": "./cypress/e2e/HomePage/cypressException.cy.js",
"ignore_files": "",
"network": false,
"headless": false,
"npm_dependencies": {
"cypress": "13.5.0"
}
}
}
For complete guidance on getting started with the LambdaTest Cypress CLI and a full list of supported commands, refer to the official support documentation on the List of LambdaTest Cypress CLI Commands .
To better understand how Cypress works and validate the configuration, let’s execute the same test scenario mentioned in the previous section.
Test Scenario:
Open URL: LambdaTest eCommerce Playground using cy.visit(). |
The code remains the same as provided in the unexpected status codes section. All you need to do is execute the Cypress test case on the cloud platform using the following command:
<npx lambdatest-cypress run>
Once the command executes successfully and the test cases are completed, you will receive a link to the LambdaTest Dashboard. This link directs you to the Web Automation Dashboard, where you can review the test execution details.
Now, you are ready to execute other methods for handling the Cypress uncaught exception, whether caused by test failures or application errors, as explained below.
In Cypress UI testing , if a command fails, the test fails. To prevent a test case from failing due to a Cypress uncaught exception caused by the test failures, you can register a listener and ignore the error for the failing test.
Let's explore a test scenario to better understand how you can handle the Cypress uncaught exception caused by test failures.
Test Scenario:
|
Below is the code implemented for the above test scenario:
Code Implementation:
describe("Display Error on wrong credentials", () => {
it("displays an error message when the password is incorrect", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com");
cy.get('[id="input-password"]').type("Cypress1234!!");
cy.get('[value="Login"]').click();
cy.get(".error-message").should("be.visible");
});
});
Code Walkthrough:
Execution:
Run npx cypress open on the terminal. It throws an error on the page, as shown below:
In the above case, the test fails because it attempts to access an element that does not exist. In Cypress, a fail event is emitted whenever any test fails, including when a Cypress uncaught exception occurs.
You can handle these exceptions in two ways:
If you are using an older version of Cypress and wish to migrate to Cypress 10, you can follow this tutorial on Cypress 10 migration .
To fix the issue caused by test failure in individual spec files, you can either debug the application code or update your test code. One way to handle errors in individual spec files is by adding the following code to handle the Cypress uncaught exception:
Global Exception Handler:
Cypress.on("fail", (err, runnable) => {
cy.log(err.message);
return false;
});
Code Walkthrough:
Note: The above code is a global method for handling any Cypress uncaught exception and will apply to all subsequent tests, covering both test failures and application errors.
This is useful if you want to handle the error in a specific way and do not want Cypress to log the error as part of the test results. To achieve this, you need to make a few modifications to the code shown below:
Code Implementation:
describe("Display Error on wrong credentials", () => {
it("Test Failure when trying to find incorrect locator - error message", () => {
cy.on("fail", (err, runnable) => {
cy.log(err.message);
return false;
});
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get("input[name=email]").type("test@example.com");
cy.get("input[name=password]").type("incorrectpassword");
cy.get('[value="Login"]').click();
cy.get(".error-message").should("be.visible");
});
});
In the above test script, the exception is handled by using the command cy.on('fail') and then opening the URL with cy.visit(), inputting values into the text box, and verifying the result.
Result:
You will observe that it will not fail, and the failed assertion will be ignored, as shown in the screenshot below.
To handle the Cypress uncaught exception across all tests within a spec file, add Cypress.on('fail') at the top of the spec file before any it blocks.
Code Implementation (2 tests in the spec file):
describe("Cypress Exception Handling", () => {
Cypress.on("fail", (err, runnable) => {
cy.log(err.message);
return false;
});
it("Test Failure when trying to find incorrect locator - error message", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com");
cy.get('[id="input-password"]').type("Cypress1234!!");
cy.get('[value="Login"]').click();
cy.get(".error-message").should("be.visible");
});
it("Test Failure when trying to find incorrect locator - password", () => { cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com");
cy.get('[id="input-password1"]').type("Cypress1234!!");
});
});
Code Walkthrough:
Below is the code walkthrough for the above code implementation:
This suite includes two tests with Cypress uncaught exception handling set up globally using Cypress.on("fail"). This ensures that if a test fails, Cypress logs the error message and prevents the test from being marked as failed.
Test Case 1: Test Failure when trying to find incorrect locator - error message
it("Test Failure when trying to find incorrect locator - error message", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com");
cy.get('[id="input-password"]').type("Cypress1234!!");
cy.get('[value="Login"]').click();
cy.get(".error-message").should("be.visible");
});
Test Case 2: Test Failure when trying to find incorrect locator - password
it("Test Failure when trying to find incorrect locator - password", () => {
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com");
cy.get('[id="input-password1"]').type("Cypress1234!!");
});
To summarize the overall behavior, you can say that:
Result:
If you run the above test case, you can see the test case will not fail, but it will still show the error message.
Since the locator does not exist, this will result in a failure, which will trigger the global exception handler. The handler ensures that all test failures are logged for debugging, but the tests continue executing regardless of the failures, which is useful in debugging scenarios but should be avoided in production tests where failures need to be addressed.
Cypress uncaught exceptions also occur when the application code throws an exception that is not properly handled within the test code. These exceptions can arise due to various reasons, such as:
If left unhandled, these Cypress uncaught exceptions can cause tests to fail unexpectedly, leading to unclear error messages and making it difficult to identify the root cause of the failure. When Cypress uncaught exception occurs, the program may halt and display an error message or stack trace indicating where the exception occurred.
To prevent the Cypress uncaught exception, ensure your test code is accurate and properly handles any exceptions thrown by the application.
Let’s explore how to handle Cypress uncaught exceptions in real-time scenarios.
Test Scenario:
|
Below is the code implementation for the above test scenario:
Code Implementation:
describe("Cypress Exception Handling", () => {
it("Uncaught Exception - Due to application error", () => {
cy.visit("index.html")
cy.get("button#error").click()
cy.wait(1000); }) })
When you run the above test case, it fails because the page throws an uncaught exception.
To prevent your test case from failing due to a Cypress uncaught exception, you can use the cy.on or Cypress.on command to listen for the uncaught:exception event and handle it accordingly.
This event is triggered whenever the Cypress uncaught exception occurs within the command chain. To resolve the issue, debug the application code or update your test case by adding the code below to handle errors.
Below is an example of how to handle the Cypress uncaught exception for a single test:
cy.on("uncaught:exception", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
console.log("error", e.message);
return false;
});
Code Walkthrough:
Below is the code walkthrough for the above code implementation:
This is useful if you want to handle the error in a custom way and prevent Cypress from logging it in the test results.
Code Implementation:
describe("Cypress Exception Handling", () => {
it.("Uncaught Exception - Due to application error", () => {
cy.on("uncaught:exception", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
return false;
});
cy.visit("index.html");
cy.get("button#error").click();
cy.wait(1000);
});
});
Execution:
In the example above, you learned how to handle the Cypress uncaught exception when a test fails due to an application error. However, there may be situations where you want to ignore a specific error while still failing the test for other exceptions.
To achieve this, you can define the expected error message. This allows your test to bypass failures caused by the defined error but still fail for any other Cypress uncaught exception. You can implement this by adding an if condition in the uncaught exception handler.
Code Implementation:
describe("Cypress Exception Handling", () => {
it("Uncaught Exception - Due to application error", () => {
cy.on("uncaught:exception", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
if (e.message.includes("Things went bad")) {
return false;
}
});
cy.visit("index.html");
cy.get("button#error").click();
cy.wait(1000);
});
});
Now, if your application throws any error other than "Things went bad," the test case will fail, as we have handled the uncaught exception only for that specific message.
Let’s consider a negative scenario where we need to handle exceptions that occur when the error message is Service Downtime.
describe("Cypress Exception Handling", () => {
it("Uncaught Exception - Due to application error", () => {
cy.on("uncaught:exception", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
if (e.message.includes("“Service Downtime”")) {
return false;
}
});
cy.visit("index.html");
cy.get("button#error").click();
cy.wait(1000);
});
});
In this case, the test case would fail as the exception is not handled in the code.
Adding a customized message helps to handle known exceptions, but if any other error occurs, your test case should fail.
Code Implementation:
Cypress.on("uncaught:exception", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
if (e.message.includes("Things went bad")) {
return false;
}
});
Code Walkthrough:
In the above code, you can use Cypress.on("uncaught:exception") to listen for uncaught exceptions during test execution. This event handler is triggered whenever an uncaught exception occurs in the application code.
The event handler receives two arguments:
The event handler works as follows:
This approach allows you to selectively handle specific exceptions while letting other errors cause the test to fail as expected. It enables you to customize how exceptions are managed in your tests and provides more targeted error messages, making it easier to debug any issues that arise.
Result:
Now, re-run the test script, and you will observe that the test execution will not fail.
In the final section of this tutorial on Cypress uncaught exceptions, you learned how to handle uncaught exceptions for a single spec file. But what if you want to handle exceptions globally across all test/spec files?
To do this, you need to add the exception handling code in support/e2e.js (Cypress version 10 and above). This file is loaded before any test files are evaluated, allowing you to apply the code globally for all test/spec files.
To handle exceptions across all test/spec files, you need to add the code in support/e2e.js (Cypress version 10 and above) since it is loaded before any test files are evaluated.
Code Implementation:
describe("Cypress Exception Handling", () => {
it("Test Failure when trying to find incorrect locator- error Message
", () =>
{
cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login" )
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com")
cy.get('[id="input-password"]').type("Cypress1234!!")
cy.get('[value="Login"]').click()
cy.get(".error-message").should("be.visible")
})
it("Test Failure when trying to find incorrect locator - Password
", () =>
{cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login" )
cy.get('[id="input-email"]').type("lambdatest.Cypress@disposable.com")
cy.get('[id="input-password1"]').type("Cypress1234!!")
})
Code Walkthrough:
Below is the code walkthrough for the above code implementation:
This implementation involves adding global exception handling to all test/spec files in Cypress, specifically by placing the handler in the support/e2e.js file for Cypress version 10 and above.
The handler will be executed before any test files, ensuring it affects the entire test suite. The tests in the spec file are designed to check the behavior of the application under certain conditions.
The tests are intended to simulate failures and trigger the exception handler.
This test is expected to pass if the error message is visible.
Result:
Now, if you execute the above test case, the result will still be the same as shown below:
The above example explains how to handle errors if my test case fails due to any Cypress error.
To handle specific errors while allowing others to fail, you can customize the global exception handling in Cypress.
The goal is to ignore failures for certain errors (e.g., a timeout error for a missing element) while letting other errors cause a test failure. This can be done by adding a condition inside the global Cypress.on("fail") event handler.
Sample Code for Custom Exception Handling:
Cypress.on("fail", (e, runnable) => {
console.log("error", e);
console.log("runnable", runnable);
console.log("message", e.message);
if (
e.name === "AssertionError" &&
!e.message.includes("Timed out retrying after 4000ms: Expected to find element: '.error-message', but never found it.")
) {
throw e;
}
});
Code Walkthrough:
Below is the code walkthrough for the above code implementation:
Result:
Let’s run the test case and see the results:
So, in the above screenshot, it is visible that the 1st case is getting passed, whereas the second case failed because of the customized error message in Cypress.on(‘fail’), which was defined for only one error.
Uncaught exception handling in Cypress is a crucial aspect of testing with Cypress. It enables you to manage and recover from errors that may occur during test execution, ensuring your tests run smoothly and provide accurate results.
By proactively handling exceptions, you can identify and address errors, validate command outputs, and maintain the reliability of your tests. This approach helps create more robust and reliable test suites while gracefully managing unexpected issues that may arise during test execution.
On this page
Example:
cy.on('uncaught:exception', (err, runnable) => {
if (err.message.includes('Unexpected token')) {
console.log('Application Error: Unexpected token');
return false;
}
return true;
});
Example:
cy.get('#id').should('be.visible').click()
This approach leverages Cypress's built-in retry-ability and waits up to the default timeout ( i.e., 4000ms) for the element to become visible. module.exports = {
defaultCommandTimeout: 10000 // 10 seconds
}
cy.get('.slow-loading-element', { timeout: 10000 })
cy.get('body').then(($body) => {
if ($body.find('.#locator).length) {
cy.get('#locator').click()
} })
})
Did you find this page helpful?
Try LambdaTest Now !!
Get 100 minutes of automation test minutes FREE!!