Hey everyone! I wanted to share a small but impactful piece of work that is adding significant value to our automation tests with minimal effort. We’ve created a simple Cypress command that has contributed to nearly one-fourth of the total issues caught by our automation tests 🎉
The idea is straightforward: it checks that none of our pages are throwing API errors. If you’re new to Cypress, this is an easy and effective way to boost your testing without feeling overwhelmed.
How to set it up?
- Add a Custom Command in cypress/support/commands.js
Cypress.Commands.add("verifyApiStatus", (page, timeout, expectedStatusCodes) => {
// Intercept all API calls made to the specified endpoint
cy.intercept("/api/**").as(page);
// Navigate to the specified page (e.g., "/dashboard")
cy.visit(page);
// Wait for the specified duration to allow API calls to complete
// (e.g., 10000 or 15000 milliseconds)
cy.wait(timeout);
// Check each intercepted API response
cy.get(`@${page}.all`).each(interception => {
// Verify that the response exists and has a status code
if (interception.response && interception.response.statusCode) {
// Assert that the status code matches one of the expected values
expect(interception.response.statusCode).to.be.oneOf(expectedStatusCodes);
}
});
});
- Create a test file in pageload.cy.js
it("Verifies that the API for the dashboard and users page loads without errors", function () {
// Include the steps to log in
// Verify the API status for the dashboard and users pages,
// expecting status codes 200, 201 or 404
cy.verifyApiStatus("/dashboard", 10000, [200, 201, 404]);
cy.verifyApiStatus("/users", 10000, [200, 201, 404]);
});
Why Is This Useful? 🤔
This small command has made a big difference for us. If an API call returns a status code like 500, the test will fail, alerting you to potential issues immediately. If you’re just starting with Cypress, using this command can save you time and help ensure your app is stable. Simple, powerful, and effective! 💥
Editor’s note: three ways to harden it
Rojal’s command is a great starting point, and it’s worth knowing where it will bite you as the suite grows.
1. The fixed cy.wait(timeout) is the weak spot. A hardcoded 10-second wait is both too slow on a fast run and too short on a slow one — it’s the single most common source of flaky tests. Waiting on the alias instead makes the test wait exactly as long as it needs to:
cy.wait(`@${page}`, { timeout: 15000 });
That waits for the first matching call. When a page fires several, wait on the specific ones you care about rather than a wall-clock guess.
2. .each() over zero interceptions passes silently. If the route never matched — a typo in the pattern, a changed API prefix — the command asserts nothing and the test goes green. Assert that something was actually captured:
cy.get(`@${page}.all`).should("have.length.greaterThan", 0);
A test that can’t fail isn’t protecting anything, and this is the failure mode that quietly hollows out a suite over time.
3. Consider inverting the assertion. Listing every acceptable code ([200, 201, 404]) means each new endpoint needs its list maintained. Asserting that nothing returned a server error is often closer to what you actually mean, and needs no per-page configuration:
expect(interception.response.statusCode).to.be.lessThan(500);
Whichever way you go, the value of this command is real: a whole class of “the page looks fine but the data silently failed to load” bugs gets caught for about fifteen lines of code. If a run does go red and the message isn’t obvious, the Cypress error reference covers the ones that come up most.
👉🏻 By:Rojal Bati