Comparison of 3 popular Cypress timekeeping methods
Written by
Grzegorz Wienconek
Published on
May 24, 2023
TL;DR
Accurate timekeeping is essential for measuring performance and validating time-based functionalities in web applications during testing. In Cypress, a popular end-to-end testing framework, developers have several options for capturing timestamps. This post provides an in-depth comparative review of three commonly used Cypress timekeeping methods: Date.now(), new Date(), and Performance.now().
Oops! Something went wrong while submitting the form.
Share
The site https://demoqa.com/ contains various challenges for people wanting to improve their skills in test automation.
As a part of monthly test automation workshops, we were challenged to develop tests in Cypress for a specific case under the https://demoqa.com/alerts address, which would test if, after clicking the second button from the top alert will appear after 5 seconds.
The most significant difference between solutions was in methods used to measure passing time. In this article, I will present those different approaches and describe how each method affected the results of the tests.
Part 1 – accessing alert
The major problem we encountered was accessing the alert that should appear after 5 seconds which is quite tricky when using Cypress.
After dealing with the problem of accessing the alert, the next thing was to test if it actually appeared after 5 seconds after clicking the button.
The primary approach to making this test was the same in all cases.
Make the 1st timestamp after clicking the button.
Make the 2nd timestamp after the alert window appears.
Subtract the value of the 1st timestamp from the 2nd to get the time passed after clicking the button.
Make an assertion that will check if the value from step 3 is bigger than 5 seconds/5000 milliseconds.
The main difference was in which method each person used to measure time. Below is a quick summary of them, including code examples and the time they measured.
cy.on('window:alert', (text) => { expect(text).to.contains('This alert appeared after 5 seconds'); const t1 = performance.now() const alertTime = ((t1 - t0)/1000) expect (alertTime).to.be.greaterThan(5) cy.log(`Alert appeared after ${alertTime} seconds.`); }) }) }) });
Results in seconds:
5.073599999994039
5.0685
5.07609999999404
5.091200000017881
5.091400000005961
Comparison of results
As we can see in the case of using Date.now() and new Date() results were quite similar, but they were never above 5 seconds. So if the assertion is strict and requires the results to be bigger than 5 seconds, tests would not pass. But when we look at the results when using performance.now(), they are always above 5 seconds. So, in this case, the assertion would be positive.
What causes such difference is the point in time to which each method relates. Both Date.now() and newDate() is relative to the Unix epoch (1970-01-01T00:00:00Z) and dependent on the system clock. On the other hand, Performance.now() is relative to page load and relies on monotonic time. Therefore it is not affected by time adjustments that the system clock may be target off.
In conclusion, performance.now() is better suited for monitoring the time in which a piece of code was executed, which in the case described in this article is the time passed since clicking the button to the time the alert appears on the screen. Another benefit is that Performance.now() makes timestamps with precision up to microseconds.