diff --git a/apps/browser/src/autofill/content/autofill-init.spec.ts b/apps/browser/src/autofill/content/autofill-init.spec.ts index bc57d6014f7..65854c463eb 100644 --- a/apps/browser/src/autofill/content/autofill-init.spec.ts +++ b/apps/browser/src/autofill/content/autofill-init.spec.ts @@ -14,6 +14,7 @@ import AutofillInit from "./autofill-init"; describe("AutofillInit", () => { let autofillInit: AutofillInit; const autofillOverlayContentService = mock(); + const originalDocumentReadyState = document.readyState; beforeEach(() => { chrome.runtime.connect = jest.fn().mockReturnValue({ @@ -27,6 +28,10 @@ describe("AutofillInit", () => { afterEach(() => { jest.resetModules(); jest.clearAllMocks(); + Object.defineProperty(document, "readyState", { + value: originalDocumentReadyState, + writable: true, + }); }); describe("init", () => { @@ -37,6 +42,31 @@ describe("AutofillInit", () => { expect(autofillInit["setupExtensionMessageListeners"]).toHaveBeenCalled(); }); + + it("triggers a collection of page details if the document is in a `complete` ready state", () => { + jest.useFakeTimers(); + Object.defineProperty(document, "readyState", { value: "complete", writable: true }); + + autofillInit.init(); + jest.advanceTimersByTime(250); + + expect(chrome.runtime.sendMessage).toHaveBeenCalledWith( + { + command: "bgCollectPageDetails", + sender: "autofillInit", + }, + expect.any(Function), + ); + }); + + it("registers a window load listener to collect the page details if the document is not in a `complete` ready state", () => { + jest.spyOn(window, "addEventListener"); + Object.defineProperty(document, "readyState", { value: "loading", writable: true }); + + autofillInit.init(); + + expect(window.addEventListener).toHaveBeenCalledWith("load", expect.any(Function)); + }); }); describe("setupExtensionMessageListeners", () => { diff --git a/apps/browser/src/autofill/content/autofill-init.ts b/apps/browser/src/autofill/content/autofill-init.ts index f98aca06b01..e6f64683178 100644 --- a/apps/browser/src/autofill/content/autofill-init.ts +++ b/apps/browser/src/autofill/content/autofill-init.ts @@ -3,6 +3,7 @@ import { AutofillOverlayContentService } from "../services/abstractions/autofill import CollectAutofillContentService from "../services/collect-autofill-content.service"; import DomElementVisibilityService from "../services/dom-element-visibility.service"; import InsertAutofillContentService from "../services/insert-autofill-content.service"; +import { sendExtensionMessage } from "../utils"; import { AutofillExtensionMessage, @@ -56,6 +57,26 @@ class AutofillInit implements AutofillInitInterface { init() { this.setupExtensionMessageListeners(); this.autofillOverlayContentService?.init(); + this.collectPageDetailsOnLoad(); + } + + /** + * Triggers a collection of the page details from the + * background script, ensuring that autofill is ready + * to act on the page. + */ + private collectPageDetailsOnLoad() { + const sendCollectDetailsMessage = () => + setTimeout( + () => sendExtensionMessage("bgCollectPageDetails", { sender: "autofillInit" }), + 250, + ); + + if (document.readyState === "complete") { + sendCollectDetailsMessage(); + } + + window.addEventListener("load", sendCollectDetailsMessage); } /**