diff --git a/apps/browser/src/autofill/overlay/abstractions/autofill-overlay-list.ts b/apps/browser/src/autofill/overlay/abstractions/autofill-overlay-list.ts index c5bb6698f7..e7f4e544df 100644 --- a/apps/browser/src/autofill/overlay/abstractions/autofill-overlay-list.ts +++ b/apps/browser/src/autofill/overlay/abstractions/autofill-overlay-list.ts @@ -14,7 +14,6 @@ type InitAutofillOverlayListMessage = OverlayListMessage & { theme: string; translations: Record; ciphers?: OverlayCipherData[]; - messageConnectorUrl: string; portKey: string; }; diff --git a/apps/browser/src/autofill/overlay/pages/button/autofill-overlay-button.ts b/apps/browser/src/autofill/overlay/pages/button/autofill-overlay-button.ts index 802ab51d21..8f56f1267f 100644 --- a/apps/browser/src/autofill/overlay/pages/button/autofill-overlay-button.ts +++ b/apps/browser/src/autofill/overlay/pages/button/autofill-overlay-button.ts @@ -46,7 +46,6 @@ class AutofillOverlayButton extends AutofillOverlayPageElement { * @param authStatus - The authentication status of the user * @param styleSheetUrl - The URL of the stylesheet to apply to the page * @param translations - The translations to apply to the page - * @param messageConnectorUrl - The URL of the message connector to use * @param portKey - Background generated key that allows the port to communicate with the background */ private async initAutofillOverlayButton({ diff --git a/apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.spec.ts b/apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.spec.ts index e5e4ebb3e5..41a9d3a510 100644 --- a/apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.spec.ts +++ b/apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.spec.ts @@ -101,7 +101,7 @@ describe("AutofillOverlayList", () => { const originalListOfElements = autofillOverlayList["overlayListContainer"].querySelectorAll(".cipher-container"); - autofillOverlayList["handleCiphersListScrollEvent"](); + window.dispatchEvent(new Event("scroll")); jest.runAllTimers(); const updatedListOfElements = @@ -119,11 +119,11 @@ describe("AutofillOverlayList", () => { "handleDebouncedScrollEvent", ); - autofillOverlayList["handleCiphersListScrollEvent"](); + window.dispatchEvent(new Event("scroll")); jest.advanceTimersByTime(100); - autofillOverlayList["handleCiphersListScrollEvent"](); + window.dispatchEvent(new Event("scroll")); jest.advanceTimersByTime(100); - autofillOverlayList["handleCiphersListScrollEvent"](); + window.dispatchEvent(new Event("scroll")); jest.advanceTimersByTime(400); expect(handleDebouncedScrollEventSpy).toHaveBeenCalledTimes(1); @@ -377,6 +377,60 @@ describe("AutofillOverlayList", () => { expect((firstCipherItem as HTMLElement).focus).toBeCalled(); }); }); + + describe("blur event", () => { + it("posts a message to the parent window indicating that the overlay has lost focus", () => { + postWindowMessage(createInitAutofillOverlayListMessageMock({ portKey })); + + globalThis.dispatchEvent(new Event("blur")); + + expect(globalThis.parent.postMessage).toHaveBeenCalledWith( + { command: "overlayPageBlurred", portKey }, + "*", + ); + }); + }); + + describe("keydown event", () => { + beforeEach(() => { + postWindowMessage(createInitAutofillOverlayListMessageMock({ portKey })); + }); + + it("skips redirecting keyboard focus when a KeyDown event triggers and the key is not a `Tab` or `Escape` key", () => { + globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "test" })); + + expect(globalThis.parent.postMessage).not.toHaveBeenCalled(); + }); + + it("redirects the overlay focus out to the previous element on KeyDown of the `Tab+Shift` keys", () => { + globalThis.document.dispatchEvent( + new KeyboardEvent("keydown", { code: "Tab", shiftKey: true }), + ); + + expect(globalThis.parent.postMessage).toHaveBeenCalledWith( + { command: "redirectOverlayFocusOut", direction: "previous", portKey }, + "*", + ); + }); + + it("redirects the overlay focus out to the next element on KeyDown of the `Tab` key", () => { + globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "Tab" })); + + expect(globalThis.parent.postMessage).toHaveBeenCalledWith( + { command: "redirectOverlayFocusOut", direction: "next", portKey }, + "*", + ); + }); + + it("redirects the overlay focus out to the current element on KeyDown of the `Escape` key", () => { + globalThis.document.dispatchEvent(new KeyboardEvent("keydown", { code: "Escape" })); + + expect(globalThis.parent.postMessage).toHaveBeenCalledWith( + { command: "redirectOverlayFocusOut", direction: "current", portKey }, + "*", + ); + }); + }); }); describe("handleResizeObserver", () => { diff --git a/apps/browser/src/autofill/spec/autofill-mocks.ts b/apps/browser/src/autofill/spec/autofill-mocks.ts index a5b2c7b406..e79723529a 100644 --- a/apps/browser/src/autofill/spec/autofill-mocks.ts +++ b/apps/browser/src/autofill/spec/autofill-mocks.ts @@ -204,7 +204,6 @@ function createInitAutofillOverlayListMessageMock( styleSheetUrl: "https://jest-testing-website.com", theme: ThemeType.Light, authStatus: AuthenticationStatus.Unlocked, - messageConnectorUrl: "https://jest-testing-website.com/message-connector", portKey: "portKey", ciphers: [ createAutofillOverlayCipherDataMock(1, {