From bc392584b277bee4fbb89b0e19b9233a17a6db68 Mon Sep 17 00:00:00 2001 From: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com> Date: Mon, 2 Feb 2026 19:21:25 +0530 Subject: [PATCH] fix: reset embed iframe queue consistently to preserve UI commands (#27419) * Reset queue correctly all places * test: verify UI config persists on second modal open (#27422) * test: verify UI config persists on second modal open Co-Authored-By: hariom@cal.com * fix: update iframe selection logic in getEmbedIframe function Refactor the getEmbedIframe function to improve iframe selection by using a more specific selector and ensuring the last iframe is targeted in cases of repeated modal openings. This change enhances reliability in iframe handling during tests. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix test --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../embed-core/playwright/lib/testUtils.ts | 16 ++++++- .../playwright/tests/action-based.e2e.ts | 43 +++++++++++++++---- packages/embeds/embed-core/src/embed.ts | 10 +++-- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/packages/embeds/embed-core/playwright/lib/testUtils.ts b/packages/embeds/embed-core/playwright/lib/testUtils.ts index 345095e745..a62bee900c 100644 --- a/packages/embeds/embed-core/playwright/lib/testUtils.ts +++ b/packages/embeds/embed-core/playwright/lib/testUtils.ts @@ -83,11 +83,23 @@ export const getEmbedIframe = async ({ }, { polling: 500 } ); - const embedIframe = page.frame(`cal-embed=${calNamespace}`); + + const iframeSelector = `iframe[name="cal-embed=${calNamespace}"]`; + // In case of modal we don't cleanup previous iframe on repeat click, so we should read the last one by default as that would be the one actie + const targetIframeElement = page.locator(iframeSelector).last(); + let elementHandle = await targetIframeElement.elementHandle(); + let embedIframe = await elementHandle?.contentFrame(); + if (!embedIframe) { return null; } - const u = new URL(embedIframe.url()); + let url = embedIframe.url(); + if (!url) { + // If iframe hasn't even initiated loading yet, wait for it to be visible + await targetIframeElement.waitFor(); + url = embedIframe.url(); + } + const u = new URL(url); if (u.pathname === `${pathname}/embed`) { return embedIframe; } diff --git a/packages/embeds/embed-core/playwright/tests/action-based.e2e.ts b/packages/embeds/embed-core/playwright/tests/action-based.e2e.ts index 529100955d..e7325343ac 100644 --- a/packages/embeds/embed-core/playwright/tests/action-based.e2e.ts +++ b/packages/embeds/embed-core/playwright/tests/action-based.e2e.ts @@ -314,20 +314,45 @@ test.describe("Popup Tests", () => { await embeds.gotoPlayground({ calNamespace, url: "/" }); - await page.click(`[data-cal-namespace="${calNamespace}"]`); + await test.step("First modal open - verify UI config is applied", async () => { + await page.click(`[data-cal-namespace="${calNamespace}"]`); - const embedIframe = await getEmbedIframe({ calNamespace, page, pathname: "/free/30min" }); + const embedIframe = await getEmbedIframe({ calNamespace, page, pathname: "/free/30min" }); - await expect(embedIframe).toBeEmbedCalLink(calNamespace, embeds.getActionFiredDetails, { - pathname: "/free/30min", + await expect(embedIframe).toBeEmbedCalLink(calNamespace, embeds.getActionFiredDetails, { + pathname: "/free/30min", + }); + + if (!embedIframe) { + throw new Error("Embed iframe not found"); + } + + // Verify that event type details are hidden (hideEventTypeDetails: true was set via ui() call) + await expect(embedIframe.locator('[data-testid="event-meta"]')).toBeHidden(); }); - if (!embedIframe) { - throw new Error("Embed iframe not found"); - } + await test.step("Close the modal", async () => { + await page.locator("cal-modal-box .close").click(); + await expect(page.locator("cal-modal-box")).toBeHidden(); + }); - // Verify that event type details are hidden (hideEventTypeDetails: true was set via ui() call) - await expect(embedIframe.locator('[data-testid="event-meta"]')).toBeHidden(); + await test.step("Second modal open - verify UI config persists", async () => { + await page.click(`[data-cal-namespace="${calNamespace}"]`); + + const embedIframe = await getEmbedIframe({ calNamespace, page, pathname: "/free/30min" }); + + await expect(embedIframe).toBeEmbedCalLink(calNamespace, embeds.getActionFiredDetails, { + pathname: "/free/30min", + }); + + if (!embedIframe) { + throw new Error("Embed iframe not found"); + } + + // Verify that event type details are STILL hidden on second open + // This tests that UI config persists across modal reopens (the bug was that iframeDoQueue was being cleared completely) + await expect(embedIframe.locator('[data-testid="event-meta"]')).toBeHidden(); + }); }); }); diff --git a/packages/embeds/embed-core/src/embed.ts b/packages/embeds/embed-core/src/embed.ts index 71bd7a86a0..1d76a502f6 100644 --- a/packages/embeds/embed-core/src/embed.ts +++ b/packages/embeds/embed-core/src/embed.ts @@ -412,14 +412,18 @@ export class Cal { } } - iframeReset() { - this.iframeReady = false; + resetQueue() { // Only keep UI related instructions in the queue, as we want to ensure that newly loaded iframe has the same UI configuration applied automatically this.iframeDoQueue = this.iframeDoQueue.filter((doInIframeArg) => this.commandsPersistAcrossIframeResets.includes(doInIframeArg.method) ); } + iframeReset() { + this.iframeReady = false; + this.resetQueue(); + } + constructor(namespace: string, q: Queue) { this.__config = { // Use WEBAPP_URL till full page reload problem with website URL is solved @@ -469,7 +473,7 @@ export class Cal { this.iframeDoQueue.forEach((doInIframeArg) => { this.doInIframe(doInIframeArg); }); - this.iframeDoQueue = []; + this.resetQueue(); }); this.actionManager.on("__routeChanged", () => {