Debugging with Cypress vs. Playwright

August 2, 2024

•

By Farah Shalwani

When it comes to end-to-end testing, developers often face the challenging task of debugging failing tests. Two of the most popular tools in this space are Cypress and Playwright. Both offer powerful features, including time travel debugging capabilities. However, Cypress excels in creating a more intuitive and developer-friendly experience that enhances productivity and efficiency. In this blog post, we'll explore the differences in debugging between Cypress and Playwright and highlight why Cypress's approach to time travel debugging, combined with Test Replay in Cypress Cloud, gives it a significant edge. With these tools, debugging becomes almost enjoyable.

Debugging with Cypress

Cypress provides an intuitive and developer-friendly debugging experience, leveraging features like its built-in debugger in the open-source app and the innovative Test Replay for CI. These features culminate in what is known as time travel debugging. This technique allows developers to navigate backward and forward through their test runs, inspecting the state of their application at each step. This ease of use is a game-changer, making it significantly simpler to identify and fix issues.  Cypress achieves this feat with the following functionalities:

Interactive Test Runner

Cypress's interactive test runner enhances the debugging process. As tests run, Cypress captures snapshots of the DOM at each step and logs every action. This allows developers to hover over each command in the Command Log to see a snapshot of the application at that point. The interactive test runner is started with the command: npx cypress open. Hovering over any command will show the state of the application at that time, including where Cypress is clicking and the state of the DOM before and after each network request.

Built-In Debugger

Cypress's debugger is integrated seamlessly into the app. Developers can use cy.debug() to pause the test at any point, inspect the current state of the application, and step through code execution. This makes it easy to pinpoint where things go wrong. It’s worth noting that the browser's Developer Tools need to be open for cy.debug() to work. However, this feature is particularly advantageous because it does not impact headless test runs. This means that while cy.debug() can be used effectively during interactive sessions with the Developer Tools open, it has no effect on automated test runs that execute without a visible browser interface, ensuring that debugging does not interfere with continuous integration processes.

Detailed Command Log

The Command Log provides a comprehensive view of every command executed during the test. Developers can click on any command to see detailed information, including the state of the application before and after each action. This level of detail is invaluable for understanding the sequence of events that led to a test failure. Developers can trace through the test case, examining each step in detail to pinpoint the exact step that triggers the failure. If even this extensive information isn’t enough, cy.log() allows developers to add additional details. Unlike console.log(), cy.log() prints information directly into the Cypress Command Log. This ensures that all relevant information is consolidated in a single log, making debugging more efficient.

Video and screenshot recordings

While Cypress excels at debugging during test execution, it also provides tools for debugging without running tests. By leveraging the multitude of videos and screenshots that Cypress generates, developers can effectively document and diagnose issues. These small-sized files are ideal for attaching to bug tickets. Moreover, there's nothing more frustrating than having a reported bug closed with a "cannot reproduce" label. Cypress helps eliminate this issue by providing clear, visual evidence to support debugging efforts.

Debugging with Test Replay in Cypress Cloud

When tests are run in Continuous Integration (CI) environments, debugging can become more challenging due to the lack of an interactive interface or visual feedback. Cypress addresses this with its Test Replay feature, available in Cypress Cloud.

Test Replay allows developers to replay test runs directly from Cypress Cloud. This feature lets you step through each command and observe the application's state, similar to the interactive test runner. Unlike static video captures, which are limited by frame rates and often miss crucial details such as console logs, network requests, and out-of-frame or scrollable DOM content, Test Replay offers a comprehensive view of the entire test run.

With Test Replay, you don’t need to reproduce issues locally, saving time and effort. Additionally, you can share Test Replay links with team members to enhance collaboration and streamline the debugging process. This feature goes beyond static artifacts by enabling direct interaction with a recreated state of the application. Developers can inspect the DOM at the exact point of failure, examine network events, console logs, and JavaScript errors, gaining a deeper understanding of failed or flaky tests.

By providing real-time code debugging and the ability to examine the application's state at any point during the test run, Test Replay significantly improves the stability and reliability of your CI pipeline. It ensures that critical details are captured, making it easier to diagnose and resolve issues that only occur in CI environments, and preventing the frustration of having bugs closed with a "cannot reproduce" label.

Debugging with Playwright

While Cypress offers a robust and integrated debugging experience, Playwright also provides various debugging tools, albeit with different features and limitations. Playwright's debugging capabilities include tools like the Playwright Inspector, console logs, tracing, video recording, and the Trace Viewer. However, these tools have their own quirks and may not offer the same level of convenience or depth as Cypress. For instance, Playwright relies heavily on manual logging and specific commands to enable debugging features, such as PWDEBUG=1 node my_script.js for the Inspector and DEBUG=pw:api node my_script.js for verbose logging.

While Playwright’s UI Mode offers a comprehensive interactive debugging environment with features like timeline views, DOM inspection, and test filtering, Cypress provides a more streamlined and developer-friendly experience through its intuitive time travel debugging, deep integration across local and CI environments, minimal configuration requirements, and built-in tools that reduce the need for additional plugins or complex setups, ultimately enhancing the overall debugging process.

Let's explore each of these Playwright debugging tools in more detail to understand their functionalities and limitations.

Playwright Inspector

Playwright offers an Inspector tool that lets developers pause tests and inspect the current state of the application. However, it lacks the seamless integration and automatic state capture that Cypress offers. Additionally, enabling the Inspector requires a specific command: PWDEBUG=1 node my_script.js.

Console Logs and Tracing

Playwright relies heavily on console logs and tracing for debugging. Developers must manually add logging statements to their tests, which can be time-consuming and less intuitive compared to Cypress's automatic test state capture. Tracing in Playwright must be enabled and stopped with specific lines of code. For example, to start and stop tracing, use the following code:

await page.tracing.start({ screenshots: true, snapshots: true });
await page.goto('https://example.com');
await page.tracing.stop({ path: 'trace.zip' });

Additionally, verbose logging can be enabled by adding DEBUG=pw:api node my_script.js to your command.

Video Recording 

While both Cypress and Playwright offer video recordings of test runs, there are notable differences in their implementation and utility. Cypress’s video recordings provide a detailed visual playback of the entire test, capturing every interaction with the application and synchronized with console logs, network requests, and other key elements of the test run. This integrated approach allows developers to see exactly what happened at each step of the test and easily correlate actions with test results.

In contrast, Playwright’s video recordings are more limited in scope. They capture a visual sequence of the test run but do not include detailed contextual information such as console logs or network requests. This can make it harder to diagnose issues, as developers must rely solely on the video footage without the added context that Cypress provides. Additionally, Playwright’s recordings are not integrated with other debugging features, such as network monitoring or DOM snapshots, which are available through its Trace Viewer but require separate handling. This separation can add complexity to the debugging process and make it more challenging to resolve issues effectively.

Trace Viewer

Another debugging tool available in Playwright is the Trace Viewer. This feature provides a detailed overview of test runs by recording various aspects of the test execution. By configuring Playwright to enable tracing, you can capture comprehensive data, including every action performed, network calls, screenshots, and DOM snapshots throughout the test. This information is compiled into a zip file, which can be accessed and examined to diagnose issues after the test has completed.

{
  "use": {
    "trace": "on-first-retry"
  }
}

While the Trace Viewer offers a more detailed analysis compared to video recordings, it still has some limitations. Videos capture only a sequence of frames, making it challenging to correlate specific actions with the application's state comprehensively. In contrast, the Trace Viewer provides a more in-depth view by including network requests and screenshots, but it requires manual handling of zip files and may need additional setup for accessing and interpreting the recorded data.

Why Cypress is Better for Debugging

Intuitive Time Travel Debugging

Cypress’s time travel debugging is a standout feature that drastically simplifies the process of diagnosing and fixing test failures. By allowing developers to view the application's state at every step of the test, Cypress offers a clear and detailed picture of what happened during test execution. This capability is complemented by an interactive command log that provides real-time visibility into each action performed during the test run, integrating directly into the core experience. This combination of features significantly reduces the time and effort needed to pinpoint issues, as developers can easily navigate through the test steps and see exactly how the application’s state evolved over time.

Seamless Integration

Cypress's debugging tools are seamlessly integrated into both the open-source app and Cypress Cloud, providing a consistent and unified debugging experience. Whether tests are run locally on a developer’s machine or within a Continuous Integration (CI) environment, the debugging process remains cohesive and streamlined. This integration ensures that developers benefit from the same level of detailed insight and interactive features, regardless of where the tests are executed.    

Developer-Friendly

Cypress is built with developers in mind, focusing on reducing the complexity and overhead associated with testing. From the moment you install Cypress, it provides a rich set of tools and features out of the box, requiring minimal configuration to get started. The Cypress Test Runner offers an interactive interface where you can watch your tests execute in real-time, providing immediate feedback and insights into your application's behavior. Cypress automatically handles common pain points like waiting for elements to load, ensuring tests are more reliable and reducing the need for brittle manual waits or timeouts. Additionally, Cypress's clear and detailed error messages make it easier for developers to understand what went wrong and how to fix it, streamlining the debugging process.

Built-in Debugging Capabilities

Cypress incorporates robust debugging capabilities directly into its core framework, making advanced debugging accessible out of the box. In contrast, Playwright requires additional plugins and specific configurations to achieve a similar level of user-friendly debugging. While Playwright offers debugging features, they are not as inherently integrated or streamlined as those in Cypress. This means that developers using Playwright may need to spend extra time setting up and configuring their debugging environment to achieve comparable functionality, which can add complexity to the debugging process.

Conclusion

While both Cypress and Playwright offer robust end-to-end testing capabilities, Cypress distinguishes itself in the area of debugging. Its time travel debugging, seamlessly integrated tools, and emphasis on developer experience make it the superior choice for diagnosing and resolving test failures. With Cypress, developers can spend less time troubleshooting and more time focused on building and enhancing high-quality applications.

The combination of the powerful Cypress Test Runner and Test Replay ensures that most issues can be efficiently debugged and resolved. This ease of use allows developers and test engineers to concentrate on what truly matters: developing and delivering high-quality software.