I recently installed Cypress 10 on a personal project and I was implementing a dummy test to ensure everything works. I decided to go a bit "the extra" mile on the example and I am wondering why the following assertions fail. The scenario is the following: the user types into a search box, and a list of cultural events is displayed. The user clicks an anchor on the first one; This causes the page to go from / to /events/:event_id (most of these things are still hard-coded hence the usage of .first when finding items (instead of looking for a specific listitem)... Now, the problem arises with the expectations that come after that.
If I add a cy.wait expression, the assertions work; If I do not use cy.wait nor cypress-testing-library#within, the assertions work... If I do not use cy.wait and use within, the assertions fail regardless of having or not having timeouts spread all over the code. Note that, I am confident by verification, that the assertions are supposed to be within a main HTML element. I have the browser element-inspect open right next to me, as well as the Next code that renders the <AppLayout> and sticks the content within the main element.
I would like to know the alternatives to cy.wait since this is not a very reliable way of waiting for elements to render. Also, if someone can explain the reasoning behind these failings, it would be great.
describe("dummy spec", () => {
it("passes", () => {
const testEvent = "networking for introverts";
const testEventRegExp = new RegExp(testEvent, "i");
cy.visit("/");
cy.findByRole("banner").within(() => {
cy.findByRole("searchbox", { name: /search events/i }).type(`${testEvent}{enter}`);
});
cy.findByRole("main").within(() => {
cy.findAllByRole("listitem")
.first()
.within(() => {
cy.findByRole("link", { name: testEventRegExp }).click();
});
});
cy.location("pathname").should("eq", "/events/e2");
// Waiting the tinniest bit and the expectations below pass as expected
// cy.wait(25);
cy.findByRole("main").within(() => {
cy.findByRole("heading", { name: testEventRegExp })
// Assertion fails regardless of specified timeout amount
.should("be.visible", { timeout: 1000 })
.contains(testEvent, {
matchCase: false
});
cy.findByTestId("event-summary").should("be.visible");
cy.findByTestId("event-description").should("be.visible");
});
});
});
First thing I would say is 25 ms is nothing compared to the overall test duration (about 1/12 the time of a blink).
Don't be concerned about the principle of
cy.wait()if it's what makes the test work, but burn-test to make sure you have the right duration.Since you have a Next app which has React as base framework, and if you use functional components (hooks) you may be able to use
cy.wait(0).Javascript is single-threaded, meaning any code running in the test will hog the thread until blocked by, say a network call or a
setTimeout().Using
wait(0)blocks the test momentarily and allows the React hooks to complete.This also fits with your observation that adding timeout does not work.
However
timeout: 1000is going the wrong way - normal timeout is4000so you want to try10000.