diff --git a/apps/web/playwright/filter-helpers.ts b/apps/web/playwright/filter-helpers.ts index 1c899692ca..3d73a613b0 100644 --- a/apps/web/playwright/filter-helpers.ts +++ b/apps/web/playwright/filter-helpers.ts @@ -114,7 +114,7 @@ export async function createFilterSegment( * Select a segment from the dropdown */ export async function selectSegment(page: Page, segmentName: string) { - await page.getByTestId("filter-segment-select").click(); + await page.getByTestId("filter-segment-select").first().click(); await page .locator('[data-testid="filter-segment-select-content"] [role="menuitem"]') @@ -126,7 +126,7 @@ export async function selectSegment(page: Page, segmentName: string) { * Open submenu of a certain segment */ export async function openSegmentSubmenu(page: Page, segmentName: string) { - await page.getByTestId("filter-segment-select").click(); + await page.getByTestId("filter-segment-select").first().click(); await page .locator('[data-testid="filter-segment-select-content"] [role="menuitem"]') @@ -183,7 +183,7 @@ export function locateSelectedSegmentName(page: Page, expectedName: string) { * Check if a system segment is visible in the dropdown */ export async function expectSystemSegmentVisible(page: Page, segmentName: string) { - await page.getByTestId("filter-segment-select").click(); + await page.getByTestId("filter-segment-select").first().click(); await expect( page.locator('[data-testid="filter-segment-select-content"]').getByText("Default") ).toBeVisible(); @@ -240,7 +240,7 @@ export async function renameSegment(page: Page, originalName: string, newName: s * Check if a segment group (like "Default" or "Personal") is visible */ export async function expectSegmentGroupVisible(page: Page, groupName: string) { - await page.getByTestId("filter-segment-select").click(); + await page.getByTestId("filter-segment-select").first().click(); await expect( page.locator('[data-testid="filter-segment-select-content"]').getByText(groupName) ).toBeVisible(); diff --git a/apps/web/playwright/fixtures/embeds.ts b/apps/web/playwright/fixtures/embeds.ts index f480b42879..0452c4afb7 100644 --- a/apps/web/playwright/fixtures/embeds.ts +++ b/apps/web/playwright/fixtures/embeds.ts @@ -17,6 +17,46 @@ export const createEmbedsFixture = (page: Page) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore window.eventsFiredStoreForPlaywright = window.eventsFiredStoreForPlaywright || {}; + + // Add a postMessage listener immediately to capture __iframeReady events + // This avoids the race condition where the event fires before Cal.ns[namespace] is ready + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + if (!window.postMessageListenerAdded) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + window.postMessageListenerAdded = true; + window.addEventListener("message", (event) => { + // Filter for Cal.com embed messages + if ( + event.data && + typeof event.data === "object" && + event.data.originator === "CAL" && + event.data.type + ) { + const { type, namespace, data } = event.data; + console.log("PlaywrightTest postMessage:", `Received ${type} for namespace ${namespace}`); + + // Set iframeReady when we receive __iframeReady event for our namespace + if (type === "__iframeReady" && namespace === calNamespace) { + console.log("PlaywrightTest postMessage:", "Setting window.iframeReady = true"); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + window.iframeReady = true; + } + + // Store the event in our event store + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + const store = window.eventsFiredStoreForPlaywright; + if (store) { + const eventStore = (store[`${type}-${namespace}`] = store[`${type}-${namespace}`] || []); + eventStore.push({ type, namespace, fullType: `CAL:${namespace}:${type}`, data }); + } + } + }); + } + document.addEventListener("DOMContentLoaded", function tryAddingListener() { if (parent !== window) { // Firefox seems to execute this snippet for iframe as well. Avoid that. It must be executed only for parent frame. diff --git a/apps/web/playwright/system-segments.e2e.ts b/apps/web/playwright/system-segments.e2e.ts index c74914a230..11ac507727 100644 --- a/apps/web/playwright/system-segments.e2e.ts +++ b/apps/web/playwright/system-segments.e2e.ts @@ -46,7 +46,7 @@ test.describe("System Segments", () => { await navigateToBookings(page); - await page.getByTestId("filter-segment-select").click(); + await page.getByTestId("filter-segment-select").first().click(); await page .locator('[data-testid="filter-segment-select-content"] [role="menuitem"]') .filter({ hasText: "My Bookings" }) diff --git a/apps/web/playwright/team/team-invitation.e2e.ts b/apps/web/playwright/team/team-invitation.e2e.ts index fb934709eb..dd958496c1 100644 --- a/apps/web/playwright/team/team-invitation.e2e.ts +++ b/apps/web/playwright/team/team-invitation.e2e.ts @@ -33,7 +33,10 @@ test.describe("Team", () => { await page.waitForTimeout(500); // Add a small delay to ensure UI is fully loaded await page.getByTestId("new-member-button").click(); await page.locator('input[name="inviteUser"]').fill(invitedUserEmail); - await page.getByText(t("send_invite")).click(); + const submitPromise = page.waitForResponse("/api/trpc/teams/inviteMember?batch=1"); + await page.getByTestId("invite-new-member-button").click(); + const response = await submitPromise; + expect(response.status()).toBe(200); const inviteLink = await expectInvitationEmailToBeReceived( page, emails, @@ -119,7 +122,10 @@ test.describe("Team", () => { await page.waitForTimeout(500); // Add a small delay to ensure UI is fully loaded await page.getByTestId("new-member-button").click(); await page.locator('input[name="inviteUser"]').fill(invitedUserEmail); - await page.getByText(t("send_invite")).click(); + const submitPromise = page.waitForResponse("/api/trpc/teams/inviteMember?batch=1"); + await page.getByTestId("invite-new-member-button").click(); + const response = await submitPromise; + expect(response.status()).toBe(200); await expectInvitationEmailToBeReceived( page, emails, @@ -167,13 +173,17 @@ test.describe("Team", () => { await page.waitForTimeout(500); // Add a small delay to ensure UI is fully loaded await page.getByTestId("new-member-button").click(); await page.locator('input[name="inviteUser"]').fill(invitedMember.email); - await page.getByText(t("send_invite")).click(); + const submitPromise = page.waitForResponse("/api/trpc/teams/inviteMember?batch=1"); + await page.getByTestId("invite-new-member-button").click(); + const response = await submitPromise; + expect(response.status()).toBe(200); await invitedMember.apiLogin(); await page.goto(`/teams`); - await page.getByTestId(`accept-invitation-${team.id}`).click(); - const response = await page.waitForResponse("/api/trpc/teams/acceptOrLeave?batch=1"); - expect(response.status()).toBe(200); + const response2Promise = page.waitForResponse("/api/trpc/teams/acceptOrLeave?batch=1"); + await page.getByTestId(`accept-invitation-${team.id}`).first().click(); + const response2 = await response2Promise; + expect(response2.status()).toBe(200); await page.goto(`/event-types`); //ensure managed event-type is created for the invited member @@ -211,7 +221,10 @@ test.describe("Team", () => { await page.waitForTimeout(500); await page.getByTestId("new-member-button").click(); await page.locator('input[name="inviteUser"]').fill(invitedUser.email); - await page.getByText(t("send_invite")).click(); + const submitPromise = page.waitForResponse("/api/trpc/teams/inviteMember?batch=1"); + await page.getByTestId("invite-new-member-button").click(); + const response = await submitPromise; + expect(response.status()).toBe(200); inviteLink = await expectInvitationEmailToBeReceived( page, @@ -275,7 +288,10 @@ test.describe("Team", () => { await page.waitForTimeout(500); await page.getByTestId("new-member-button").click(); await page.locator('input[name="inviteUser"]').fill(invitedUser.email); - await page.getByText(t("send_invite")).click(); + const submitPromise = page.waitForResponse("/api/trpc/teams/inviteMember?batch=1"); + await page.getByTestId("invite-new-member-button").click(); + const response = await submitPromise; + expect(response.status()).toBe(200); inviteLink = await expectInvitationEmailToBeReceived( page,