1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 17:23:37 +00:00

[PM-5189] Adjusting AutofillOverlayIframeService jest tests

This commit is contained in:
Cesar Gonzalez
2024-04-08 16:06:38 -05:00
parent 3f710c5e82
commit 27483cf486
7 changed files with 90 additions and 44 deletions

View File

@@ -135,7 +135,7 @@ type OverlayButtonPortMessageHandlers = {
forceCloseAutofillOverlay: ({ port }: PortConnectionParam) => void; forceCloseAutofillOverlay: ({ port }: PortConnectionParam) => void;
overlayPageBlurred: () => void; overlayPageBlurred: () => void;
redirectOverlayFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void; redirectOverlayFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void;
getPageColorScheme: () => void; updateOverlayPageColorScheme: () => void;
}; };
type OverlayListPortMessageHandlers = { type OverlayListPortMessageHandlers = {

View File

@@ -97,7 +97,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
this.closeOverlay(port.sender, { forceCloseOverlay: true }), this.closeOverlay(port.sender, { forceCloseOverlay: true }),
overlayPageBlurred: () => this.checkOverlayListFocused(), overlayPageBlurred: () => this.checkOverlayListFocused(),
redirectOverlayFocusOut: ({ message, port }) => this.redirectOverlayFocusOut(message, port), redirectOverlayFocusOut: ({ message, port }) => this.redirectOverlayFocusOut(message, port),
getPageColorScheme: () => this.updateButtonPageColorScheme(), updateOverlayPageColorScheme: () => this.updateButtonPageColorScheme(),
}; };
private readonly overlayListPortMessageHandlers: OverlayListPortMessageHandlers = { private readonly overlayListPortMessageHandlers: OverlayListPortMessageHandlers = {
checkAutofillOverlayButtonFocused: () => this.checkOverlayButtonFocused(), checkAutofillOverlayButtonFocused: () => this.checkOverlayButtonFocused(),
@@ -886,7 +886,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
private updateButtonPageColorScheme() { private updateButtonPageColorScheme() {
this.overlayButtonPort?.postMessage({ this.overlayButtonPort?.postMessage({
command: "getPageColorScheme", command: "updateOverlayPageColorScheme",
}); });
} }

View File

@@ -18,7 +18,7 @@ type BackgroundPortMessageHandlers = {
initAutofillOverlayList: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; initAutofillOverlayList: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
updateIframePosition: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; updateIframePosition: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
updateOverlayHidden: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; updateOverlayHidden: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
getPageColorScheme: () => void; updateOverlayPageColorScheme: () => void;
}; };
interface AutofillOverlayIframeService { interface AutofillOverlayIframeService {

View File

@@ -60,7 +60,7 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService.initOverlayIframe({}, "title"); autofillOverlayIframeService.initOverlayIframe({}, "title");
expect(autofillOverlayIframeService["shadow"].appendChild).toBeCalledWith( expect(autofillOverlayIframeService["shadow"].appendChild).toHaveBeenCalledWith(
autofillOverlayIframeService["iframe"], autofillOverlayIframeService["iframe"],
); );
}); });
@@ -71,7 +71,9 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService.initOverlayIframe({}, "title", ariaAlert); autofillOverlayIframeService.initOverlayIframe({}, "title", ariaAlert);
expect(autofillOverlayIframeService["createAriaAlertElement"]).toBeCalledWith(ariaAlert); expect(autofillOverlayIframeService["createAriaAlertElement"]).toHaveBeenCalledWith(
ariaAlert,
);
expect(autofillOverlayIframeService["ariaAlertElement"]).toMatchSnapshot(); expect(autofillOverlayIframeService["ariaAlertElement"]).toMatchSnapshot();
}); });
@@ -86,9 +88,9 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD)); autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD));
portSpy = autofillOverlayIframeService["port"]; portSpy = autofillOverlayIframeService["port"];
expect(chrome.runtime.connect).toBeCalledWith({ name: AutofillOverlayPort.Button }); expect(chrome.runtime.connect).toHaveBeenCalledWith({ name: AutofillOverlayPort.Button });
expect(portSpy.onDisconnect.addListener).toBeCalledWith(handlePortDisconnectSpy); expect(portSpy.onDisconnect.addListener).toHaveBeenCalledWith(handlePortDisconnectSpy);
expect(portSpy.onMessage.addListener).toBeCalledWith(handlePortMessageSpy); expect(portSpy.onMessage.addListener).toHaveBeenCalledWith(handlePortMessageSpy);
}); });
it("skips announcing the aria alert if the aria alert element is not populated", () => { it("skips announcing the aria alert if the aria alert element is not populated", () => {
@@ -97,7 +99,7 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD)); autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD));
expect(globalThis.setTimeout).not.toBeCalled(); expect(globalThis.setTimeout).not.toHaveBeenCalled();
}); });
it("announces the aria alert if the aria alert element is populated", () => { it("announces the aria alert if the aria alert element is populated", () => {
@@ -108,10 +110,12 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD)); autofillOverlayIframeService["iframe"].dispatchEvent(new Event(EVENTS.LOAD));
expect(globalThis.setTimeout).toBeCalled(); expect(globalThis.setTimeout).toHaveBeenCalled();
jest.advanceTimersByTime(2000); jest.advanceTimersByTime(2000);
expect(shadowAppendSpy).toBeCalledWith(autofillOverlayIframeService["ariaAlertElement"]); expect(shadowAppendSpy).toHaveBeenCalledWith(
autofillOverlayIframeService["ariaAlertElement"],
);
}); });
}); });
}); });
@@ -149,19 +153,19 @@ describe("AutofillOverlayIframeService", () => {
it("removes the port's onMessage listener", () => { it("removes the port's onMessage listener", () => {
triggerPortOnDisconnectEvent(portSpy); triggerPortOnDisconnectEvent(portSpy);
expect(portSpy.onMessage.removeListener).toBeCalledWith(handlePortMessageSpy); expect(portSpy.onMessage.removeListener).toHaveBeenCalledWith(handlePortMessageSpy);
}); });
it("removes the port's onDisconnect listener", () => { it("removes the port's onDisconnect listener", () => {
triggerPortOnDisconnectEvent(portSpy); triggerPortOnDisconnectEvent(portSpy);
expect(portSpy.onDisconnect.removeListener).toBeCalledWith(handlePortDisconnectSpy); expect(portSpy.onDisconnect.removeListener).toHaveBeenCalledWith(handlePortDisconnectSpy);
}); });
it("disconnects the port", () => { it("disconnects the port", () => {
triggerPortOnDisconnectEvent(portSpy); triggerPortOnDisconnectEvent(portSpy);
expect(portSpy.disconnect).toBeCalled(); expect(portSpy.disconnect).toHaveBeenCalled();
expect(autofillOverlayIframeService["port"]).toBeNull(); expect(autofillOverlayIframeService["port"]).toBeNull();
}); });
}); });
@@ -171,7 +175,9 @@ describe("AutofillOverlayIframeService", () => {
portSpy.name = "wrong-port-name"; portSpy.name = "wrong-port-name";
sendPortMessage(portSpy, {}); sendPortMessage(portSpy, {});
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).not.toBeCalled(); expect(
autofillOverlayIframeService["iframe"].contentWindow.postMessage,
).not.toHaveBeenCalled();
}); });
it("passes on the message to the iframe if the message is not registered with the message handlers", () => { it("passes on the message to the iframe if the message is not registered with the message handlers", () => {
@@ -179,10 +185,9 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith( expect(
message, autofillOverlayIframeService["iframe"].contentWindow.postMessage,
"*", ).toHaveBeenCalledWith(message, "*");
);
}); });
it("handles port messages that are registered with the message handlers and does not pass the message on to the iframe", () => { it("handles port messages that are registered with the message handlers and does not pass the message on to the iframe", () => {
@@ -190,7 +195,9 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, { command: "updateIframePosition" }); sendPortMessage(portSpy, { command: "updateIframePosition" });
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).not.toBeCalled(); expect(
autofillOverlayIframeService["iframe"].contentWindow.postMessage,
).not.toHaveBeenCalled();
}); });
describe("initializing the overlay list", () => { describe("initializing the overlay list", () => {
@@ -211,11 +218,10 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(updateElementStylesSpy).not.toBeCalled(); expect(updateElementStylesSpy).not.toHaveBeenCalled();
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith( expect(
message, autofillOverlayIframeService["iframe"].contentWindow.postMessage,
"*", ).toHaveBeenCalledWith(message, "*");
);
}); });
it("sets a light theme based on the user's system preferences", () => { it("sets a light theme based on the user's system preferences", () => {
@@ -228,7 +234,9 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)"); expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)");
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith( expect(
autofillOverlayIframeService["iframe"].contentWindow.postMessage,
).toHaveBeenCalledWith(
{ {
command: "initAutofillOverlayList", command: "initAutofillOverlayList",
theme: ThemeType.Light, theme: ThemeType.Light,
@@ -247,7 +255,9 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)"); expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)");
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith( expect(
autofillOverlayIframeService["iframe"].contentWindow.postMessage,
).toHaveBeenCalledWith(
{ {
command: "initAutofillOverlayList", command: "initAutofillOverlayList",
theme: ThemeType.Dark, theme: ThemeType.Dark,
@@ -264,9 +274,12 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(updateElementStylesSpy).toBeCalledWith(autofillOverlayIframeService["iframe"], { expect(updateElementStylesSpy).toHaveBeenCalledWith(
borderColor: "#4c525f", autofillOverlayIframeService["iframe"],
}); {
borderColor: "#4c525f",
},
);
}); });
it("updates the border to match the `nord` theme", () => { it("updates the border to match the `nord` theme", () => {
@@ -277,9 +290,12 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(updateElementStylesSpy).toBeCalledWith(autofillOverlayIframeService["iframe"], { expect(updateElementStylesSpy).toHaveBeenCalledWith(
borderColor: "#2E3440", autofillOverlayIframeService["iframe"],
}); {
borderColor: "#2E3440",
},
);
}); });
it("updates the border to match the `solarizedDark` theme", () => { it("updates the border to match the `solarizedDark` theme", () => {
@@ -290,9 +306,12 @@ describe("AutofillOverlayIframeService", () => {
sendPortMessage(portSpy, message); sendPortMessage(portSpy, message);
expect(updateElementStylesSpy).toBeCalledWith(autofillOverlayIframeService["iframe"], { expect(updateElementStylesSpy).toHaveBeenCalledWith(
borderColor: "#073642", autofillOverlayIframeService["iframe"],
}); {
borderColor: "#073642",
},
);
}); });
}); });
@@ -310,7 +329,7 @@ describe("AutofillOverlayIframeService", () => {
styles: { top: 100, left: 100 }, styles: { top: 100, left: 100 },
}); });
expect(autofillOverlayIframeService["updateElementStyles"]).not.toBeCalled(); expect(autofillOverlayIframeService["updateElementStyles"]).not.toHaveBeenCalled();
}); });
it("updates the iframe position if the document has focus", () => { it("updates the iframe position if the document has focus", () => {
@@ -349,7 +368,9 @@ describe("AutofillOverlayIframeService", () => {
}); });
jest.advanceTimersByTime(2000); jest.advanceTimersByTime(2000);
expect(shadowAppendSpy).toBeCalledWith(autofillOverlayIframeService["ariaAlertElement"]); expect(shadowAppendSpy).toHaveBeenCalledWith(
autofillOverlayIframeService["ariaAlertElement"],
);
}); });
}); });
@@ -361,6 +382,22 @@ describe("AutofillOverlayIframeService", () => {
expect(autofillOverlayIframeService["iframe"].style.display).toBe("none"); expect(autofillOverlayIframeService["iframe"].style.display).toBe("none");
}); });
it("updates the button based on the web page's color scheme", () => {
sendPortMessage(portSpy, {
command: "updateOverlayPageColorScheme",
});
expect(
autofillOverlayIframeService["iframe"].contentWindow.postMessage,
).toHaveBeenCalledWith(
{
command: "updateOverlayPageColorScheme",
colorScheme: "normal",
},
"*",
);
});
}); });
}); });
@@ -384,7 +421,7 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].style.visibility = "hidden"; autofillOverlayIframeService["iframe"].style.visibility = "hidden";
await flushPromises(); await flushPromises();
expect(autofillOverlayIframeService["updateElementStyles"]).not.toBeCalled(); expect(autofillOverlayIframeService["updateElementStyles"]).not.toHaveBeenCalled();
}); });
it("reverts any styles changes made directly to the iframe", async () => { it("reverts any styles changes made directly to the iframe", async () => {
@@ -403,7 +440,9 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].src = "http://malicious-site.com"; autofillOverlayIframeService["iframe"].src = "http://malicious-site.com";
await flushPromises(); await flushPromises();
expect(sendExtensionMessageSpy).toBeCalledWith("closeAutofillOverlay", { forceClose: true }); expect(sendExtensionMessageSpy).toHaveBeenCalledWith("closeAutofillOverlay", {
forceClose: true,
});
}); });
it("force closes the autofill overlay if excessive mutations are being triggered", async () => { it("force closes the autofill overlay if excessive mutations are being triggered", async () => {
@@ -413,7 +452,9 @@ describe("AutofillOverlayIframeService", () => {
autofillOverlayIframeService["iframe"].src = "http://malicious-site.com"; autofillOverlayIframeService["iframe"].src = "http://malicious-site.com";
await flushPromises(); await flushPromises();
expect(sendExtensionMessageSpy).toBeCalledWith("closeAutofillOverlay", { forceClose: true }); expect(sendExtensionMessageSpy).toHaveBeenCalledWith("closeAutofillOverlay", {
forceClose: true,
});
}); });
it("resets the excessive mutations and foreign mutation counters", async () => { it("resets the excessive mutations and foreign mutation counters", async () => {

View File

@@ -45,7 +45,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
initAutofillOverlayList: ({ message }) => this.initAutofillOverlayList(message), initAutofillOverlayList: ({ message }) => this.initAutofillOverlayList(message),
updateIframePosition: ({ message }) => this.updateIframePosition(message.styles), updateIframePosition: ({ message }) => this.updateIframePosition(message.styles),
updateOverlayHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles), updateOverlayHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
getPageColorScheme: () => this.updateOverlayPageColorScheme(), updateOverlayPageColorScheme: () => this.updateOverlayPageColorScheme(),
}; };
constructor( constructor(
@@ -304,6 +304,10 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
} }
}; };
/**
* Triggers a forced closure of the autofill overlay. This is used when the
* mutation observer is triggered excessively.
*/
private forceCloseAutofillOverlay() { private forceCloseAutofillOverlay() {
void this.sendExtensionMessage("closeAutofillOverlay", { forceClose: true }); void this.sendExtensionMessage("closeAutofillOverlay", { forceClose: true });
} }

View File

@@ -71,7 +71,7 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
this.getTranslation("toggleBitwardenVaultOverlay"), this.getTranslation("toggleBitwardenVaultOverlay"),
); );
this.buttonElement.addEventListener(EVENTS.CLICK, this.handleButtonElementClick); this.buttonElement.addEventListener(EVENTS.CLICK, this.handleButtonElementClick);
this.postMessageToConnector({ command: "getPageColorScheme" }); this.postMessageToConnector({ command: "updateOverlayPageColorScheme" });
this.updateAuthStatus(authStatus); this.updateAuthStatus(authStatus);

View File

@@ -126,6 +126,7 @@ const offscreen = {
const webNavigation = { const webNavigation = {
getFrame: jest.fn(), getFrame: jest.fn(),
getAllFrames: jest.fn(),
}; };
// set chrome // set chrome