fix: add timeout: 0 to E2E assertions that check for absence of elements (#26353)

This fixes hanging E2E tests where assertions like toHaveCount(0) and
not.toBeVisible() would wait for the full timeout (10s in CI, 120s locally)
before failing, instead of failing immediately.

These assertions are 'state check' assertions that verify an element is
already absent or hidden, rather than waiting for it to become so.
Adding { timeout: 0 } makes them fail immediately if the condition is not met.

Files updated:
- locale.e2e.ts: 16 instances of toHaveCount(0)
- booking-seats.e2e.ts: 8 instances of toHaveCount(0)
- organization-redirection.e2e.ts: 3 instances of toHaveCount(0)
- organization-creation-flows.e2e.ts: 5 instances of not.toBeVisible()
- insights-charts.e2e.ts: 1 instance of toHaveCount(0)
- bookings-list.e2e.ts: 1 instance of toHaveCount(0)
- availability.e2e.ts: 1 instance of toHaveCount(0)
- managed-event-types.e2e.ts: 1 instance of toHaveCount(0)
- team-invitation.e2e.ts: 1 instance of toHaveCount(0)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Keith Williams
2025-12-31 14:58:20 -03:00
committed by GitHub
co-authored by Devin AI
parent 4563194fcf
commit 486817a688
9 changed files with 34 additions and 34 deletions
+1 -1
View File
@@ -124,7 +124,7 @@ test.describe("Availability", () => {
await submitAndWaitForResponse(page, "/api/trpc/availability/schedule.delete?batch=1", {
action: () => page.locator('[data-testid="delete-schedule"]').click(),
});
await expect(page.locator('[data-testid="schedules"] > li').nth(1)).toHaveCount(0);
await expect(page.locator('[data-testid="schedules"] > li').nth(1)).toHaveCount(0, { timeout: 0 });
});
await test.step("Cannot delete the last schedule", async () => {
await page.locator('[data-testid="schedules"] > li').nth(0).getByTestId("schedule-more").click();
+8 -8
View File
@@ -64,14 +64,14 @@ test.describe("Booking with Seats", () => {
await test.step("Attendee #2 shouldn't be able to cancel booking using only booking/uid", async () => {
await page.goto(`/booking/${booking.uid}`);
await expect(page.locator("[text=Cancel]")).toHaveCount(0);
await expect(page.locator("[text=Cancel]")).toHaveCount(0, { timeout: 0 });
});
await test.step("Attendee #2 shouldn't be able to cancel booking using randomString for seatReferenceUId", async () => {
await page.goto(`/booking/${booking.uid}?seatReferenceUid=${randomString(10)}`);
// expect cancel button to don't be in the page
await expect(page.locator("[text=Cancel]")).toHaveCount(0);
await expect(page.locator("[text=Cancel]")).toHaveCount(0, { timeout: 0 });
});
});
@@ -82,7 +82,7 @@ test.describe("Booking with Seats", () => {
{ name: "John Third", email: "third+seats@cal.com", timeZone: "Europe/Berlin" },
]);
await page.goto(`/booking/${booking.uid}?cancel=true`);
await expect(page.locator("[text=Cancel]")).toHaveCount(0);
await expect(page.locator("[text=Cancel]")).toHaveCount(0, { timeout: 0 });
// expect login text to be in the page, not data-testid
await expect(page.locator("text=Login")).toHaveCount(1);
@@ -99,7 +99,7 @@ test.describe("Booking with Seats", () => {
await page.goto(`/booking/${booking.uid}?cancel=true`);
// expect login button to don't be in the page
await expect(page.locator("text=Login")).toHaveCount(0);
await expect(page.locator("text=Login")).toHaveCount(0, { timeout: 0 });
// fill reason for cancellation
await page.fill('[data-testid="cancel_reason"]', "Double booked!");
@@ -183,7 +183,7 @@ test.describe("Reschedule for booking with seats", () => {
await page.locator('[data-testid="day"][data-disabled="false"]').nth(1).click();
// Validate that the number of seats its 10
await expect(page.locator("text=9 / 10 Seats available")).toHaveCount(0);
await expect(page.locator("text=9 / 10 Seats available")).toHaveCount(0, { timeout: 0 });
});
test("Should cancel with seats but event should be still accessible and with one less attendee/seat", async ({
@@ -325,7 +325,7 @@ test.describe("Reschedule for booking with seats", () => {
// No attendees should be displayed only the one that it's cancelling
const notFoundSecondAttendee = await page.locator('p[data-testid="attendee-email-second+seats@cal.com"]');
await expect(notFoundSecondAttendee).toHaveCount(0);
await expect(notFoundSecondAttendee).toHaveCount(0, { timeout: 0 });
const foundFirstAttendee = await page.locator('p[data-testid="attendee-email-first+seats@cal.com"]');
await expect(foundFirstAttendee).toHaveCount(1);
@@ -365,7 +365,7 @@ test.describe("Reschedule for booking with seats", () => {
const getBooking = await booking.self();
await page.goto(`/booking/${booking.uid}`);
await expect(page.locator('[data-testid="reschedule"]')).toHaveCount(0);
await expect(page.locator('[data-testid="reschedule"]')).toHaveCount(0, { timeout: 0 });
// expect login text to be in the page, not data-testid
await expect(page.locator("text=Login")).toHaveCount(1);
@@ -382,7 +382,7 @@ test.describe("Reschedule for booking with seats", () => {
await page.goto(`/booking/${booking.uid}`);
// expect login button to don't be in the page
await expect(page.locator("text=Login")).toHaveCount(0);
await expect(page.locator("text=Login")).toHaveCount(0, { timeout: 0 });
// reschedule-link click
await page.locator('[data-testid="reschedule-link"]').click();
+1 -1
View File
@@ -455,7 +455,7 @@ test.describe("Bookings", () => {
.click();
await bookingsGetResponse2;
await expect(page.locator('[data-testid="booking-item"]')).toHaveCount(0);
await expect(page.locator('[data-testid="booking-item"]')).toHaveCount(0, { timeout: 0 });
});
test.describe("Filter Dropdown Item Search", () => {
+1 -1
View File
@@ -282,7 +282,7 @@ test.describe("Insights > Charts Loading", () => {
// Verify no charts are in error state
const errorCharts = page.locator('[data-testid="chart-card"][data-loading-state="error"]');
await expect(errorCharts).toHaveCount(0);
await expect(errorCharts).toHaveCount(0, { timeout: 0 });
});
});
});
+13 -13
View File
@@ -239,7 +239,7 @@ test.describe("authorized user sees correct translations (de)", async () => {
{
const locator = page.getByText("Event Types", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -258,7 +258,7 @@ test.describe("authorized user sees correct translations (de)", async () => {
{
const locator = page.getByText("No upcoming bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -277,7 +277,7 @@ test.describe("authorized user sees correct translations (de)", async () => {
{
const locator = page.getByText("No upcoming bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
});
@@ -311,7 +311,7 @@ test.describe("authorized user sees correct translations (pt-br)", async () => {
{
const locator = page.getByText("Event Types", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -330,7 +330,7 @@ test.describe("authorized user sees correct translations (pt-br)", async () => {
{
const locator = page.getByText("Bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -349,7 +349,7 @@ test.describe("authorized user sees correct translations (pt-br)", async () => {
{
const locator = page.getByText("Bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
});
@@ -383,7 +383,7 @@ test.describe("authorized user sees correct translations (ar)", async () => {
{
const locator = page.getByText("Event Types", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -402,7 +402,7 @@ test.describe("authorized user sees correct translations (ar)", async () => {
{
const locator = page.getByText("Bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -421,7 +421,7 @@ test.describe("authorized user sees correct translations (ar)", async () => {
{
const locator = page.getByText("Bookings", { exact: true });
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
});
@@ -463,7 +463,7 @@ test.describe("authorized user sees changed translations (de->ar)", async () =>
{
const locator = page.getByText("Allgemein", { exact: true }); // "general"
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -482,7 +482,7 @@ test.describe("authorized user sees changed translations (de->ar)", async () =>
{
const locator = page.getByText("Allgemein", { exact: true }); // "general"
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
});
@@ -522,7 +522,7 @@ test.describe("authorized user sees changed translations (de->pt-BR) [locale1]",
{
const locator = page.getByText("Allgemein", { exact: true }); // "general"
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
@@ -541,7 +541,7 @@ test.describe("authorized user sees changed translations (de->pt-BR) [locale1]",
{
const locator = page.getByText("Allgemein", { exact: true }); // "general"
await expect(locator).toHaveCount(0);
await expect(locator).toHaveCount(0, { timeout: 0 });
}
});
});
@@ -129,7 +129,7 @@ test.describe("Managed Event Types", () => {
// Proceed to unlock and check that it got unlocked
titleLockIndicator.click();
await expect(titleLockIndicator.locator("[data-state='checked']")).toHaveCount(0);
await expect(titleLockIndicator.locator("[data-state='checked']")).toHaveCount(0, { timeout: 0 });
await expect(titleLockIndicator.locator("[data-state='unchecked']")).toHaveCount(1);
// Save changes
@@ -242,8 +242,8 @@ test.describe("Organization Creation Flows - Comprehensive Suite", () => {
// Verify billing fields are NOT visible to regular users
if (IS_TEAM_BILLING_ENABLED) {
await expect(page.locator("input[name=seats]")).not.toBeVisible();
await expect(page.locator("input[name=pricePerSeat]")).not.toBeVisible();
await expect(page.locator("input[name=seats]")).not.toBeVisible({ timeout: 0 });
await expect(page.locator("input[name=pricePerSeat]")).not.toBeVisible({ timeout: 0 });
// Verify "Upgrade to Organizations" UI is shown
await expect(page.getByText(/upgrade to organizations/i)).toBeVisible();
@@ -439,9 +439,9 @@ test.describe("Organization Creation Flows - Comprehensive Suite", () => {
await page.goto("/settings/organizations/new");
// Should NOT see admin billing fields
await expect(page.locator("input[name=seats]")).not.toBeVisible();
await expect(page.locator("input[name=pricePerSeat]")).not.toBeVisible();
await expect(page.locator("#billingPeriod")).not.toBeVisible();
await expect(page.locator("input[name=seats]")).not.toBeVisible({ timeout: 0 });
await expect(page.locator("input[name=pricePerSeat]")).not.toBeVisible({ timeout: 0 });
await expect(page.locator("#billingPeriod")).not.toBeVisible({ timeout: 0 });
// Should see upgrade/pricing UI
await expect(page.getByText(/upgrade to organizations/i)).toBeVisible();
@@ -57,7 +57,7 @@ test.describe("Unpublished Organization Redirection", () => {
await expect(page.getByTestId("empty-screen")).toBeVisible();
// Ensure that the team name is not displayed.
await expect(page.getByTestId("team-name")).toHaveCount(0);
await expect(page.getByTestId("team-name")).toHaveCount(0, { timeout: 0 });
});
});
@@ -101,8 +101,8 @@ test.describe("Unpublished Organization Redirection", () => {
await expect(page.getByTestId("empty-screen")).toBeVisible();
// Ensure user profile elements are not visible.
await expect(page.locator('[data-testid="name-title"]')).toHaveCount(0);
await expect(page.locator('[data-testid="event-types"]')).toHaveCount(0);
await expect(page.locator('[data-testid="name-title"]')).toHaveCount(0, { timeout: 0 });
await expect(page.locator('[data-testid="event-types"]')).toHaveCount(0, { timeout: 0 });
});
});
@@ -74,7 +74,7 @@ test.describe("Team", () => {
await page.goto(`/settings/teams/${team.id}/settings`);
await expect(
page.locator(`[data-testid="email-${invitedUserEmail.replace("@", "")}-pending"]`)
).toHaveCount(0);
).toHaveCount(0, { timeout: 0 });
});
await test.step("To the team by invite link", async () => {