fix(e2e): replace false-passing assertions and hard-coded waits in test suite (#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]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
Romit
Romit
parent
a3baf493eb
commit
ecc5e66fd4
@@ -19,8 +19,8 @@ test.describe("Phone Location Auto-fill Feature", () => {
|
||||
// Verify custom phone fields start empty or country prefix (e.g., "+1")
|
||||
const v1 = await page.locator('[name="phone-1"]').inputValue();
|
||||
const v2 = await page.locator('[name="phone-2"]').inputValue();
|
||||
expect(v1 === "" || /^\+\d{1,3}$/.test(v1)).toBeTruthy();
|
||||
expect(v2 === "" || /^\+\d{1,3}$/.test(v2)).toBeTruthy();
|
||||
expect(v1 === "" || /^\+\d{1,3}$/.test(v1)).toBe(true);
|
||||
expect(v2 === "" || /^\+\d{1,3}$/.test(v2)).toBe(true);
|
||||
|
||||
// Select phone location and enter phone number
|
||||
const phoneNumber = "+14155551234";
|
||||
|
||||
@@ -105,7 +105,7 @@ test.describe("Event Types tests", () => {
|
||||
'[data-testid="event-types"] a[href^="/event-types/"] >> nth=0'
|
||||
);
|
||||
const href = await firstElement.getAttribute("href");
|
||||
expect(href).toBeTruthy();
|
||||
expect(href).not.toBeNull();
|
||||
const [eventTypeId] = new URL(WEBAPP_URL + href).pathname.split("/").reverse();
|
||||
const firstTitle = await page.locator(`[data-testid=event-type-title-${eventTypeId}]`).innerText();
|
||||
const firstFullSlug = await page.locator(`[data-testid=event-type-slug-${eventTypeId}]`).innerText();
|
||||
|
||||
@@ -18,7 +18,7 @@ test.describe("Limits Tab - Event Type", () => {
|
||||
await bookingPage.updateEventType();
|
||||
const eventTypePage = await bookingPage.previewEventType();
|
||||
|
||||
await eventTypePage.waitForTimeout(10000);
|
||||
await eventTypePage.getByTestId("time").first().waitFor({ state: "visible" });
|
||||
|
||||
const counter = await eventTypePage.getByTestId("time").count();
|
||||
await bookingPage.checkTimeSlotsCount(eventTypePage, counter);
|
||||
|
||||
@@ -40,8 +40,7 @@ export function createAppsFixture(page: Page) {
|
||||
await page.waitForURL(`apps/installation/event-types?slug=${app}`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator(`[data-testid="select-event-type-${eventTypeIds[0]}"]`).waitFor({ state: "visible" });
|
||||
for (const id of eventTypeIds) {
|
||||
await page.click(`[data-testid="select-event-type-${id}"]`);
|
||||
}
|
||||
@@ -88,8 +87,7 @@ export function createAppsFixture(page: Page) {
|
||||
await page.getByTestId("install-app-button").click();
|
||||
await page.waitForURL(`apps/installation/event-types?slug=${app.slug}`);
|
||||
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator(`[data-testid="select-event-type-${eventTypeIds[0]}"]`).waitFor({ state: "visible" });
|
||||
for (const id of eventTypeIds) {
|
||||
await page.click(`[data-testid="select-event-type-${id}"]`);
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ export function createWorkflowPageFixture(page: Page) {
|
||||
getWorkflowButton("delete-button"),
|
||||
]);
|
||||
|
||||
expect(editButton.isDisabled()).toBeTruthy();
|
||||
expect(deleteButton.isDisabled()).toBeTruthy();
|
||||
await expect(editButton).toBeDisabled();
|
||||
await expect(deleteButton).toBeDisabled();
|
||||
};
|
||||
|
||||
const assertWorkflowWasTriggered = async (emails: Fixtures["emails"], emailsToBeReceived: string[]) => {
|
||||
|
||||
@@ -14,8 +14,8 @@ test.describe("Login with api request", () => {
|
||||
const cookiesMap = new Map(contextCookies.map(({ name, value }) => [name, value]));
|
||||
|
||||
// The browser context will already contain all the cookies from the API response.
|
||||
expect(cookiesMap.has("next-auth.csrf-token")).toBeTruthy();
|
||||
expect(cookiesMap.has("next-auth.callback-url")).toBeTruthy();
|
||||
expect(cookiesMap.has("next-auth.session-token")).toBeTruthy();
|
||||
expect(cookiesMap.has("next-auth.csrf-token")).toBe(true);
|
||||
expect(cookiesMap.has("next-auth.callback-url")).toBe(true);
|
||||
expect(cookiesMap.has("next-auth.session-token")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -200,7 +200,7 @@ test.describe("Out of office", () => {
|
||||
const eventTypeLink = page.locator('[data-testid="event-type-link"]').first();
|
||||
await eventTypeLink.click();
|
||||
|
||||
await expect(page.getByTestId("away-emoji")).toBeTruthy();
|
||||
await expect(page.getByTestId("away-emoji").first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("User can create Entry for past", async ({ page, users }) => {
|
||||
@@ -338,7 +338,6 @@ test.describe("Out of office", () => {
|
||||
});
|
||||
|
||||
test("User cannot create infinite or overlapping reverse redirect OOOs", async ({ page, users }) => {
|
||||
const t = await localize("en");
|
||||
const teamMatesObj = [{ name: "member-1" }, { name: "member-2" }];
|
||||
const owner = await users.create(
|
||||
{ name: "owner" },
|
||||
@@ -367,7 +366,7 @@ test.describe("Out of office", () => {
|
||||
await goToOOOPage(page);
|
||||
await openOOODialog(page);
|
||||
await selectDateAndCreateOOO(page, "2", "5", owner.id, 400);
|
||||
await expect(page.locator(`text=${t("booking_redirect_infinite_not_allowed")}`)).toBeTruthy();
|
||||
await expect(page.getByTestId("toast-error")).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -410,7 +409,7 @@ test.describe("Out of office", () => {
|
||||
await page.getByTestId("ooofor_username_select").click();
|
||||
await page.getByTestId(`select-option-${member2User?.id}`).click();
|
||||
await selectDateAndCreateOOO(page, "1", "3", member1User?.id, 400, true);
|
||||
expect(page.locator(`text=${t("booking_redirect_infinite_not_allowed")}`)).toBeTruthy();
|
||||
await expect(page.getByTestId("toast-error")).toBeVisible();
|
||||
await page.locator(`text=${t("cancel")}`).click();
|
||||
});
|
||||
|
||||
@@ -428,7 +427,7 @@ test.describe("Out of office", () => {
|
||||
|
||||
await test.step("Delete OOO successfully", async () => {
|
||||
await page.getByTestId(`ooo-delete-${member3User?.username}`).click();
|
||||
expect(page.locator(`text=${t("success_deleted_entry_out_of_office")}`)).toBeTruthy();
|
||||
await expect(page.getByTestId("toast-success").last()).toBeVisible();
|
||||
});
|
||||
});
|
||||
test("Non-Admin has read-only access to team mate's OOO", async ({ page, users }) => {
|
||||
|
||||
@@ -123,15 +123,15 @@ test.describe("Payment app", () => {
|
||||
|
||||
await page.goto(`${user.username}/${paymentEvent?.slug}`);
|
||||
|
||||
// expect 200 sats to be displayed in page
|
||||
expect(await page.locator("text=350").first()).toBeTruthy();
|
||||
// expect 350 USD to be displayed in page
|
||||
await expect(page.locator("text=350").first()).toBeVisible();
|
||||
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
expect(await page.locator("text=350").first()).toBeTruthy();
|
||||
await expect(page.locator("text=350").first()).toBeVisible();
|
||||
|
||||
// go to /event-types and check if the price is 200 sats
|
||||
// go to /event-types and check if the price is 350 USD
|
||||
await page.goto(`event-types/`);
|
||||
expect(await page.locator("text=350").first()).toBeTruthy();
|
||||
await expect(page.locator("text=350").first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("Should be able to edit paypal price, currency", async ({ page, users }) => {
|
||||
@@ -170,15 +170,15 @@ test.describe("Payment app", () => {
|
||||
await page.goto(`${user.username}/${paymentEvent?.slug}`);
|
||||
|
||||
// expect 150 to be displayed in page
|
||||
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
|
||||
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
|
||||
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
// expect 150 to be displayed in page
|
||||
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
|
||||
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
|
||||
|
||||
// go to /event-types and check if the price is 150
|
||||
await page.goto(`event-types/`);
|
||||
expect(await page.locator("text=MX$150.00").first()).toBeTruthy();
|
||||
await expect(page.locator("text=MX$150.00").first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("Should display App is not setup already for alby", async ({ page, users }) => {
|
||||
@@ -203,12 +203,12 @@ test.describe("Payment app", () => {
|
||||
await page.locator("#event-type-form").getByRole("switch").click();
|
||||
|
||||
// expect text "This app has not been setup yet" to be displayed
|
||||
expect(await page.locator("text=This app has not been setup yet").first()).toBeTruthy();
|
||||
await expect(page.locator("text=This app has not been setup yet").first()).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Setup" }).click();
|
||||
|
||||
// Expect "Connect with Alby" to be displayed
|
||||
expect(await page.locator("text=Connect with Alby").first()).toBeTruthy();
|
||||
await expect(page).toHaveURL(/\/apps\/alby\/setup/);
|
||||
} finally {
|
||||
await cleanupAlbyApp();
|
||||
}
|
||||
@@ -233,12 +233,12 @@ test.describe("Payment app", () => {
|
||||
await page.locator("#event-type-form").getByRole("switch").click();
|
||||
|
||||
// expect text "This app has not been setup yet" to be displayed
|
||||
expect(await page.locator("text=This app has not been setup yet").first()).toBeTruthy();
|
||||
await expect(page.locator("text=This app has not been setup yet").first()).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Setup" }).click();
|
||||
|
||||
// Expect "Getting started with Paypal APP" to be displayed
|
||||
expect(await page.locator("text=Getting started with Paypal APP").first()).toBeTruthy();
|
||||
await expect(page.locator("text=Getting started with Paypal APP").first()).toBeVisible();
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -267,7 +267,7 @@ test.describe("Payment app", () => {
|
||||
|
||||
await page.locator("#event-type-form").getByRole("switch").click();
|
||||
// make sure Tracking ID is displayed
|
||||
expect(await page.locator("text=Tracking ID").first()).toBeTruthy();
|
||||
await expect(page.locator("text=Tracking ID").first()).toBeVisible();
|
||||
await page.getByLabel("Tracking ID").click();
|
||||
await page.getByLabel("Tracking ID").fill("demo");
|
||||
await page.getByTestId("update-eventtype").click();
|
||||
@@ -313,7 +313,9 @@ test.describe("Payment app", () => {
|
||||
await goToAppsTab(page, paymentEvent?.id);
|
||||
|
||||
await page.locator("[data-testid='paypal-app-switch']").click();
|
||||
await page.locator("[data-testid='stripe-app-switch']").isDisabled();
|
||||
// After enabling paypal, the paypal switch should be checked and stripe should be unchecked (mutual exclusivity)
|
||||
await expect(page.locator("[data-testid='paypal-app-switch']")).toBeChecked();
|
||||
await expect(page.locator("[data-testid='stripe-app-switch']")).not.toBeChecked();
|
||||
});
|
||||
|
||||
test("when more than one payment app is installed the price should be updated when changing settings", async ({
|
||||
|
||||
@@ -467,7 +467,7 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
|
||||
await page.goto(`/settings/teams/${subTeam.id}/members`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page.getByTestId("new-member-button")).toBeVisible();
|
||||
await page.getByTestId("new-member-button").click();
|
||||
const inviteLink = await getInviteLink(page);
|
||||
|
||||
@@ -546,9 +546,9 @@ test.describe("Email Signup Flow Test", async () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(createdUser).toBeTruthy();
|
||||
expect(createdUser).not.toBeNull();
|
||||
const membership = createdUser?.teams.find((m) => m.teamId === emailToken.teamId);
|
||||
expect(membership).toBeTruthy();
|
||||
expect(membership).not.toBeUndefined();
|
||||
expect(membership?.accepted).toBe(true);
|
||||
|
||||
await prisma.user.delete({ where: { id: createdUser!.id } });
|
||||
@@ -601,7 +601,7 @@ async function expectUserToBeAMemberOfTeam({
|
||||
}) {
|
||||
await page.goto(`/settings/teams/${teamId}/members`);
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
await page.waitForTimeout(1000);
|
||||
await expect(page.locator(`[data-testid="member-${username}"]`)).toBeVisible();
|
||||
expect(
|
||||
(
|
||||
await page
|
||||
|
||||
Reference in New Issue
Block a user