diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index 447abd0442..692efdabeb 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -38,6 +38,7 @@ import { BrowserPlatformUtilsService } from "../../platform/services/platform-ut import { AutofillOverlayElement, AutofillOverlayPort, + MAX_SUB_FRAME_DEPTH, RedirectFocusDirection, } from "../enums/autofill-overlay.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; @@ -217,6 +218,25 @@ describe("OverlayBackground", () => { ); }); + it("triggers a destruction of the inline menu listeners if the max frame depth is exceeded ", async () => { + getFrameCounter = MAX_SUB_FRAME_DEPTH + 1; + const tab = createChromeTabMock({ id: tabId }); + sendMockExtensionMessage( + { command: "collectPageDetailsResponse", details: createAutofillPageDetailsMock() }, + mock({ + tab, + frameId: 1, + }), + ); + await flushPromises(); + + expect(tabsSendMessageSpy).toHaveBeenCalledWith( + tab, + { command: "destroyAutofillInlineMenuListeners" }, + { frameId: 1 }, + ); + }); + it("builds the offset values for a sub frame within the tab", async () => { sendMockExtensionMessage( { command: "collectPageDetailsResponse", details: createAutofillPageDetailsMock() }, diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index 3b95eac3bd..f4778c22a9 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -314,10 +314,14 @@ export class OverlayBackground implements OverlayBackgroundInterface { const subFrameData: SubFrameOffsetData = { url, top: 0, left: 0, parentFrameIds: [] }; let frameDetails = await BrowserApi.getFrameDetails({ tabId, frameId }); - while ( - (frameDetails && frameDetails.parentFrameId > -1) || - subFrameDepth > MAX_SUB_FRAME_DEPTH - ) { + while (frameDetails && frameDetails.parentFrameId > -1) { + subFrameDepth++; + if (subFrameDepth >= MAX_SUB_FRAME_DEPTH) { + subFrameOffsetsForTab.set(frameId, null); + this.triggerDestroyInlineMenuListeners(tab, frameId); + return; + } + const subFrameOffset: SubFrameOffsetData = await BrowserApi.tabSendMessage( tab, { @@ -346,13 +350,6 @@ export class OverlayBackground implements OverlayBackgroundInterface { tabId, frameId: frameDetails.parentFrameId, }); - subFrameDepth++; - } - - if (subFrameDepth > MAX_SUB_FRAME_DEPTH) { - subFrameOffsetsForTab.set(frameId, null); - this.triggerDestroyInlineMenuListeners(tab, frameId); - return; } subFrameOffsetsForTab.set(frameId, subFrameData); diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts index d8f40b27bc..996bb03f20 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts @@ -11,7 +11,7 @@ import { } from "../enums/autofill-overlay.enum"; import AutofillField from "../models/autofill-field"; import { createAutofillFieldMock } from "../spec/autofill-mocks"; -import { flushPromises, sendMockExtensionMessage } from "../spec/testing-utils"; +import { flushPromises, postWindowMessage, sendMockExtensionMessage } from "../spec/testing-utils"; import { ElementWithOpId, FillableFormFieldElement, FormFieldElement } from "../types"; import { AutoFillConstants } from "./autofill-constants"; @@ -1526,13 +1526,13 @@ describe("AutofillOverlayContentService", () => { parentFrameIds: [1, 2, 3], subFrameDepth: MAX_SUB_FRAME_DEPTH, }; - const event = mock(); - // @ts-expect-error - Need to mock the source to be the iframe content window - event.source = iframe.contentWindow; - event.data.subFrameData = subFrameData; sendExtensionMessageSpy.mockResolvedValue(4); - await autofillOverlayContentService["calculateSubFramePositioning"](event); + postWindowMessage( + { command: "calculateSubFramePositioning", subFrameData }, + "*", + iframe.contentWindow as any, + ); await flushPromises(); expect(globalThis.parent.postMessage).not.toHaveBeenCalled(); @@ -1553,13 +1553,12 @@ describe("AutofillOverlayContentService", () => { parentFrameIds: [1, 2, 3], subFrameDepth: 0, }; - const event = mock(); - // @ts-expect-error - Need to mock the source to be the iframe content window - event.source = iframe.contentWindow; - event.data.subFrameData = subFrameData; - sendExtensionMessageSpy.mockResolvedValue(4); - await autofillOverlayContentService["calculateSubFramePositioning"](event); + postWindowMessage( + { command: "calculateSubFramePositioning", subFrameData }, + "*", + iframe.contentWindow as any, + ); await flushPromises(); expect(globalThis.parent.postMessage).toHaveBeenCalledWith( @@ -1567,11 +1566,11 @@ describe("AutofillOverlayContentService", () => { command: "calculateSubFramePositioning", subFrameData: { frameId: 10, - left: 2, - parentFrameIds: [1, 2, 3, 4], - top: 2, + left: 20, + parentFrameIds: [1, 2, 3], + top: 20, url: "https://example.com/", - subFrameDepth: 1, + subFrameDepth: expect.any(Number), }, }, "*", @@ -1587,24 +1586,24 @@ describe("AutofillOverlayContentService", () => { left: 0, top: 0, parentFrameIds: [1, 2, 3], - subFrameDepth: 1, + subFrameDepth: expect.any(Number), }; - const event = mock(); - // @ts-expect-error - Need to mock the source to be the iframe content window - event.source = iframe.contentWindow; - event.data.subFrameData = subFrameData; - await autofillOverlayContentService["calculateSubFramePositioning"](event); + postWindowMessage( + { command: "calculateSubFramePositioning", subFrameData }, + "*", + iframe.contentWindow as any, + ); await flushPromises(); expect(sendExtensionMessageSpy).toHaveBeenCalledWith("updateSubFrameData", { subFrameData: { frameId: 10, - left: 2, - top: 2, + left: 168, + top: 168, url: "https://example.com/", - parentFrameIds: [1, 2, 3], - subFrameDepth: 2, + parentFrameIds: [1, 2, 3, 4], + subFrameDepth: expect.any(Number), }, }); });