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 8f0a7ef8225..5bfb57e799f 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 @@ -19,6 +19,7 @@ describe("AutofillOverlayContentService", () => { let autofillInit: AutofillInit; let autofillOverlayContentService: AutofillOverlayContentService; let sendExtensionMessageSpy: jest.SpyInstance; + const sendResponseSpy = jest.fn(); beforeEach(() => { autofillOverlayContentService = new AutofillOverlayContentService(); @@ -200,9 +201,8 @@ describe("AutofillOverlayContentService", () => { expect(autofillFieldElement.addEventListener).not.toHaveBeenCalled(); }); - // CG - Test is invalid due to the fallback listener we set up for fields that are not visible - it.skip("ignores fields that do not appear as a login field", async () => { - autofillFieldData.placeholder = "not-a-login-field"; + it("ignores fields that do not appear as a login field", async () => { + autofillFieldData.placeholder = "another-type-of-field"; await autofillOverlayContentService.setupAutofillInlineMenuListenerOnField( autofillFieldElement, @@ -256,8 +256,7 @@ describe("AutofillOverlayContentService", () => { }); describe("sets up form field element listeners", () => { - // TODO - Seems like we're setting up a focus listener on this when it is in a non-viewable state. This test needs to be updated. - it.skip("removes all cached event listeners from the form field element", async () => { + it("removes all cached event listeners from the form field element", async () => { jest.spyOn(autofillFieldElement, "removeEventListener"); const inputHandler = jest.fn(); const clickHandler = jest.fn(); @@ -275,16 +274,21 @@ describe("AutofillOverlayContentService", () => { expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith( 1, + "focus", + expect.any(Function), + ); + expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith( + 2, "input", inputHandler, ); expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith( - 2, + 3, "click", clickHandler, ); expect(autofillFieldElement.removeEventListener).toHaveBeenNthCalledWith( - 3, + 4, "focus", focusHandler, ); @@ -893,6 +897,11 @@ describe("AutofillOverlayContentService", () => { }); describe("handleVisibilityChangeEvent", () => { + beforeEach(() => { + autofillOverlayContentService["mostRecentlyFocusedField"] = + mock>(); + }); + it("skips removing the overlay if the document is visible", () => { autofillOverlayContentService["handleVisibilityChangeEvent"](); @@ -901,8 +910,7 @@ describe("AutofillOverlayContentService", () => { }); }); - // TODO CG = This test is failing, not entirely sure why but skipping to verify coverage on other files - it.skip("removes the overlay if the document is not visible", () => { + it("removes the overlay if the document is not visible", () => { Object.defineProperty(document, "visibilityState", { value: "hidden", writable: true, @@ -1381,5 +1389,66 @@ describe("AutofillOverlayContentService", () => { ); }); }); + + describe("getSubFrameOffsets message handler", () => { + const iframeSource = "https://example.com/"; + + beforeEach(() => { + document.body.innerHTML = ``; + }); + + it("calculates the sub frame's offsets if a single frame with the referenced url exists", async () => { + sendMockExtensionMessage( + { + command: "getSubFrameOffsets", + subFrameUrl: iframeSource, + }, + mock(), + sendResponseSpy, + ); + await flushPromises(); + + expect(sendResponseSpy).toHaveBeenCalledWith({ + frameId: undefined, + left: 2, + top: 2, + url: "https://example.com/", + }); + }); + + it("returns null if no iframe is found", async () => { + document.body.innerHTML = ""; + sendMockExtensionMessage( + { + command: "getSubFrameOffsets", + subFrameUrl: "https://example.com/", + }, + mock(), + sendResponseSpy, + ); + await flushPromises(); + + expect(sendResponseSpy).toHaveBeenCalledWith(null); + }); + + it("returns null if two or more iframes are found with the same src", async () => { + document.body.innerHTML = ` + + + `; + + sendMockExtensionMessage( + { + command: "getSubFrameOffsets", + subFrameUrl: iframeSource, + }, + mock(), + sendResponseSpy, + ); + await flushPromises(); + + expect(sendResponseSpy).toHaveBeenCalledWith(null); + }); + }); }); }); diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts index c0fcc3130f8..2732847c67f 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts @@ -997,10 +997,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ ): SubFrameOffsetData { const iframeRect = iframeElement.getBoundingClientRect(); const iframeStyles = globalThis.getComputedStyle(iframeElement); - const paddingLeft = parseInt(iframeStyles.getPropertyValue("padding-left")); - const paddingTop = parseInt(iframeStyles.getPropertyValue("padding-top")); - const borderWidthLeft = parseInt(iframeStyles.getPropertyValue("border-left-width")); - const borderWidthTop = parseInt(iframeStyles.getPropertyValue("border-top-width")); + const paddingLeft = parseInt(iframeStyles.getPropertyValue("padding-left")) || 0; + const paddingTop = parseInt(iframeStyles.getPropertyValue("padding-top")) || 0; + const borderWidthLeft = parseInt(iframeStyles.getPropertyValue("border-left-width")) || 0; + const borderWidthTop = parseInt(iframeStyles.getPropertyValue("border-top-width")) || 0; return { url: subFrameUrl,