Skip to content

Commit ecc5e66

Browse files
voidmatchaclauderomitg2
authored
fix(e2e): replace false-passing assertions and hard-coded waits in test suite (calcom#28486)
* fix(e2e): replace always-passing assertions and hard-coded waits - Replace toBeTruthy() on Locator objects with toBeVisible() (always-passing) - Replace toBeTruthy() on boolean expressions with toBe(true) for clarity - Replace hardcoded waitForTimeout() with element-based waits (waitFor/toBeVisible) - Fix strict mode violation: getByTestId("away-emoji").first() - Fix error assertion: infinite redirect error shown as toast → getByTestId("toast-error") - Fix isDisabled() no-op → await expect().toBeDisabled() in workflows fixture - Fix alby setup: add waitForURL(), remove unverifiable "Connect with Alby" assertion - Fix stripe/paypal: replace no-op isDisabled() with toBeChecked() on paypal switch Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(e2e): fix stale comment in stripe price test Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(e2e): address cubic review feedback on assertion patterns - workflows.ts: replace non-retrying isDisabled() snapshot with toBeDisabled() - out-of-office.e2e.ts: add .first() for away-emoji strict mode, use toast-error testid, remove unused const t - payment-apps.e2e.ts: replace always-passing toBeTruthy() with toHaveURL() assertion * fix --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]> Co-authored-by: Romit <[email protected]> Co-authored-by: Romit <[email protected]>
1 parent a3baf49 commit ecc5e66

9 files changed

Lines changed: 35 additions & 36 deletions

File tree

apps/web/playwright/booking-phone-autofill.e2e.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ test.describe("Phone Location Auto-fill Feature", () => {
1919
// Verify custom phone fields start empty or country prefix (e.g., "+1")
2020
const v1 = await page.locator('[name="phone-1"]').inputValue();
2121
const v2 = await page.locator('[name="phone-2"]').inputValue();
22-
expect(v1 === "" || /^\+\d{1,3}$/.test(v1)).toBeTruthy();
23-
expect(v2 === "" || /^\+\d{1,3}$/.test(v2)).toBeTruthy();
22+
expect(v1 === "" || /^\+\d{1,3}$/.test(v1)).toBe(true);
23+
expect(v2 === "" || /^\+\d{1,3}$/.test(v2)).toBe(true);
2424

2525
// Select phone location and enter phone number
2626
const phoneNumber = "+14155551234";

apps/web/playwright/event-types.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ test.describe("Event Types tests", () => {
105105
'[data-testid="event-types"] a[href^="/event-types/"] >> nth=0'
106106
);
107107
const href = await firstElement.getAttribute("href");
108-
expect(href).toBeTruthy();
108+
expect(href).not.toBeNull();
109109
const [eventTypeId] = new URL(WEBAPP_URL + href).pathname.split("/").reverse();
110110
const firstTitle = await page.locator(`[data-testid=event-type-title-${eventTypeId}]`).innerText();
111111
const firstFullSlug = await page.locator(`[data-testid=event-type-slug-${eventTypeId}]`).innerText();

apps/web/playwright/eventType/limit-tab.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test.describe("Limits Tab - Event Type", () => {
1818
await bookingPage.updateEventType();
1919
const eventTypePage = await bookingPage.previewEventType();
2020

21-
await eventTypePage.waitForTimeout(10000);
21+
await eventTypePage.getByTestId("time").first().waitFor({ state: "visible" });
2222

2323
const counter = await eventTypePage.getByTestId("time").count();
2424
await bookingPage.checkTimeSlotsCount(eventTypePage, counter);

apps/web/playwright/fixtures/apps.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ export function createAppsFixture(page: Page) {
4040
await page.waitForURL(`apps/installation/event-types?slug=${app}`);
4141
}
4242

43-
// eslint-disable-next-line playwright/no-wait-for-timeout
44-
await page.waitForTimeout(1000);
43+
await page.locator(`[data-testid="select-event-type-${eventTypeIds[0]}"]`).waitFor({ state: "visible" });
4544
for (const id of eventTypeIds) {
4645
await page.click(`[data-testid="select-event-type-${id}"]`);
4746
}
@@ -88,8 +87,7 @@ export function createAppsFixture(page: Page) {
8887
await page.getByTestId("install-app-button").click();
8988
await page.waitForURL(`apps/installation/event-types?slug=${app.slug}`);
9089

91-
// eslint-disable-next-line playwright/no-wait-for-timeout
92-
await page.waitForTimeout(1000);
90+
await page.locator(`[data-testid="select-event-type-${eventTypeIds[0]}"]`).waitFor({ state: "visible" });
9391
for (const id of eventTypeIds) {
9492
await page.click(`[data-testid="select-event-type-${id}"]`);
9593
}

apps/web/playwright/fixtures/workflows.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ export function createWorkflowPageFixture(page: Page) {
127127
getWorkflowButton("delete-button"),
128128
]);
129129

130-
expect(editButton.isDisabled()).toBeTruthy();
131-
expect(deleteButton.isDisabled()).toBeTruthy();
130+
await expect(editButton).toBeDisabled();
131+
await expect(deleteButton).toBeDisabled();
132132
};
133133

134134
const assertWorkflowWasTriggered = async (emails: Fixtures["emails"], emailsToBeReceived: string[]) => {

apps/web/playwright/login.api.e2e.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ test.describe("Login with api request", () => {
1414
const cookiesMap = new Map(contextCookies.map(({ name, value }) => [name, value]));
1515

1616
// The browser context will already contain all the cookies from the API response.
17-
expect(cookiesMap.has("next-auth.csrf-token")).toBeTruthy();
18-
expect(cookiesMap.has("next-auth.callback-url")).toBeTruthy();
19-
expect(cookiesMap.has("next-auth.session-token")).toBeTruthy();
17+
expect(cookiesMap.has("next-auth.csrf-token")).toBe(true);
18+
expect(cookiesMap.has("next-auth.callback-url")).toBe(true);
19+
expect(cookiesMap.has("next-auth.session-token")).toBe(true);
2020
});
2121
});

apps/web/playwright/out-of-office.e2e.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ test.describe("Out of office", () => {
200200
const eventTypeLink = page.locator('[data-testid="event-type-link"]').first();
201201
await eventTypeLink.click();
202202

203-
await expect(page.getByTestId("away-emoji")).toBeTruthy();
203+
await expect(page.getByTestId("away-emoji").first()).toBeVisible();
204204
});
205205

206206
test("User can create Entry for past", async ({ page, users }) => {
@@ -338,7 +338,6 @@ test.describe("Out of office", () => {
338338
});
339339

340340
test("User cannot create infinite or overlapping reverse redirect OOOs", async ({ page, users }) => {
341-
const t = await localize("en");
342341
const teamMatesObj = [{ name: "member-1" }, { name: "member-2" }];
343342
const owner = await users.create(
344343
{ name: "owner" },
@@ -367,7 +366,7 @@ test.describe("Out of office", () => {
367366
await goToOOOPage(page);
368367
await openOOODialog(page);
369368
await selectDateAndCreateOOO(page, "2", "5", owner.id, 400);
370-
await expect(page.locator(`text=${t("booking_redirect_infinite_not_allowed")}`)).toBeTruthy();
369+
await expect(page.getByTestId("toast-error")).toBeVisible();
371370
});
372371
});
373372

@@ -410,7 +409,7 @@ test.describe("Out of office", () => {
410409
await page.getByTestId("ooofor_username_select").click();
411410
await page.getByTestId(`select-option-${member2User?.id}`).click();
412411
await selectDateAndCreateOOO(page, "1", "3", member1User?.id, 400, true);
413-
expect(page.locator(`text=${t("booking_redirect_infinite_not_allowed")}`)).toBeTruthy();
412+
await expect(page.getByTestId("toast-error")).toBeVisible();
414413
await page.locator(`text=${t("cancel")}`).click();
415414
});
416415

@@ -428,7 +427,7 @@ test.describe("Out of office", () => {
428427

429428
await test.step("Delete OOO successfully", async () => {
430429
await page.getByTestId(`ooo-delete-${member3User?.username}`).click();
431-
expect(page.locator(`text=${t("success_deleted_entry_out_of_office")}`)).toBeTruthy();
430+
await expect(page.getByTestId("toast-success").last()).toBeVisible();
432431
});
433432
});
434433
test("Non-Admin has read-only access to team mate's OOO", async ({ page, users }) => {

apps/web/playwright/payment-apps.e2e.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ test.describe("Payment app", () => {
123123

124124
await page.goto(`${user.username}/${paymentEvent?.slug}`);
125125

126-
// expect 200 sats to be displayed in page
127-
expect(await page.locator("text=350").first()).toBeTruthy();
126+
// expect 350 USD to be displayed in page
127+
await expect(page.locator("text=350").first()).toBeVisible();
128128

129129
await selectFirstAvailableTimeSlotNextMonth(page);
130-
expect(await page.locator("text=350").first()).toBeTruthy();
130+
await expect(page.locator("text=350").first()).toBeVisible();
131131

132-
// go to /event-types and check if the price is 200 sats
132+
// go to /event-types and check if the price is 350 USD
133133
await page.goto(`event-types/`);
134-
expect(await page.locator("text=350").first()).toBeTruthy();
134+
await expect(page.locator("text=350").first()).toBeVisible();
135135
});
136136

137137
test("Should be able to edit paypal price, currency", async ({ page, users }) => {
@@ -170,15 +170,15 @@ test.describe("Payment app", () => {
170170
await page.goto(`${user.username}/${paymentEvent?.slug}`);
171171

172172
// expect 150 to be displayed in page
173-
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
173+
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
174174

175175
await selectFirstAvailableTimeSlotNextMonth(page);
176176
// expect 150 to be displayed in page
177-
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
177+
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
178178

179179
// go to /event-types and check if the price is 150
180180
await page.goto(`event-types/`);
181-
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
181+
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
182182
});
183183

184184
test("Should display App is not setup already for alby", async ({ page, users }) => {
@@ -203,12 +203,12 @@ test.describe("Payment app", () => {
203203
await page.locator("#event-type-form").getByRole("switch").click();
204204

205205
// expect text "This app has not been setup yet" to be displayed
206-
expect(await page.locator("text=This app has not been setup yet").first()).toBeTruthy();
206+
await expect(page.locator("text=This app has not been setup yet").first()).toBeVisible();
207207

208208
await page.getByRole("button", { name: "Setup" }).click();
209209

210210
// Expect "Connect with Alby" to be displayed
211-
expect(await page.locator("text=Connect with Alby").first()).toBeTruthy();
211+
await expect(page).toHaveURL(/\/apps\/alby\/setup/);
212212
} finally {
213213
await cleanupAlbyApp();
214214
}
@@ -233,12 +233,12 @@ test.describe("Payment app", () => {
233233
await page.locator("#event-type-form").getByRole("switch").click();
234234

235235
// expect text "This app has not been setup yet" to be displayed
236-
expect(await page.locator("text=This app has not been setup yet").first()).toBeTruthy();
236+
await expect(page.locator("text=This app has not been setup yet").first()).toBeVisible();
237237

238238
await page.getByRole("button", { name: "Setup" }).click();
239239

240240
// Expect "Getting started with Paypal APP" to be displayed
241-
expect(await page.locator("text=Getting started with Paypal APP").first()).toBeTruthy();
241+
await expect(page.locator("text=Getting started with Paypal APP").first()).toBeVisible();
242242
});
243243

244244
/**
@@ -267,7 +267,7 @@ test.describe("Payment app", () => {
267267

268268
await page.locator("#event-type-form").getByRole("switch").click();
269269
// make sure Tracking ID is displayed
270-
expect(await page.locator("text=Tracking ID").first()).toBeTruthy();
270+
await expect(page.locator("text=Tracking ID").first()).toBeVisible();
271271
await page.getByLabel("Tracking ID").click();
272272
await page.getByLabel("Tracking ID").fill("demo");
273273
await page.getByTestId("update-eventtype").click();
@@ -313,7 +313,9 @@ test.describe("Payment app", () => {
313313
await goToAppsTab(page, paymentEvent?.id);
314314

315315
await page.locator("[data-testid='paypal-app-switch']").click();
316-
await page.locator("[data-testid='stripe-app-switch']").isDisabled();
316+
// After enabling paypal, the paypal switch should be checked and stripe should be unchecked (mutual exclusivity)
317+
await expect(page.locator("[data-testid='paypal-app-switch']")).toBeChecked();
318+
await expect(page.locator("[data-testid='stripe-app-switch']")).not.toBeChecked();
317319
});
318320

319321
test("when more than one payment app is installed the price should be updated when changing settings", async ({

apps/web/playwright/signup.e2e.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ test.describe("Email Signup Flow Test", async () => {
467467

468468
await page.goto(`/settings/teams/${subTeam.id}/members`);
469469
await page.waitForLoadState("domcontentloaded");
470-
await page.waitForTimeout(500);
470+
await expect(page.getByTestId("new-member-button")).toBeVisible();
471471
await page.getByTestId("new-member-button").click();
472472
const inviteLink = await getInviteLink(page);
473473

@@ -546,9 +546,9 @@ test.describe("Email Signup Flow Test", async () => {
546546
},
547547
});
548548

549-
expect(createdUser).toBeTruthy();
549+
expect(createdUser).not.toBeNull();
550550
const membership = createdUser?.teams.find((m) => m.teamId === emailToken.teamId);
551-
expect(membership).toBeTruthy();
551+
expect(membership).not.toBeUndefined();
552552
expect(membership?.accepted).toBe(true);
553553

554554
await prisma.user.delete({ where: { id: createdUser!.id } });
@@ -601,7 +601,7 @@ async function expectUserToBeAMemberOfTeam({
601601
}) {
602602
await page.goto(`/settings/teams/${teamId}/members`);
603603
await page.waitForLoadState("domcontentloaded");
604-
await page.waitForTimeout(1000);
604+
await expect(page.locator(`[data-testid="member-${username}"]`)).toBeVisible();
605605
expect(
606606
(
607607
await page

0 commit comments

Comments
 (0)