From 1c4a2e4753bfe9dd88c4564af03a513999a4a90c Mon Sep 17 00:00:00 2001 From: KW Date: Tue, 12 Sep 2023 00:55:49 +0200 Subject: [PATCH] [UnitTests] Popup window not close after some time --- src/navigators/PopupWindow.test.ts | 56 +++++++++++++++++++++++++----- src/navigators/PopupWindow.ts | 2 +- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/navigators/PopupWindow.test.ts b/src/navigators/PopupWindow.test.ts index f010d3b00..361577c6c 100644 --- a/src/navigators/PopupWindow.test.ts +++ b/src/navigators/PopupWindow.test.ts @@ -1,11 +1,20 @@ import { mocked } from "jest-mock"; import { PopupWindow } from "./PopupWindow"; +import { Log } from "../utils"; function firstSuccessfulResult(fn: () => T): T { expect(fn).toHaveReturned(); return mocked(fn).mock.results[0].value as T; } +function definePopupWindowClosedProperty(closed: boolean) { + const popupFromWindowOpen = firstSuccessfulResult(window.open); + Object.defineProperty(popupFromWindowOpen, "closed", { + enumerable: true, + value: closed, + }); +} + describe("PopupWindow", () => { beforeEach(() => { Object.defineProperty(window, "location", { @@ -115,11 +124,7 @@ describe("PopupWindow", () => { const popupWindow = new PopupWindow({}); const promise = popupWindow.navigate({ url: "http://sts/authorize?x=y", state: "someid" }); - const popupFromWindowOpen = firstSuccessfulResult(window.open); - Object.defineProperty(popupFromWindowOpen, "closed", { - enumerable: true, - value: true, - }); + definePopupWindowClosedProperty(true); jest.runOnlyPendingTimers(); await expect(promise).rejects.toThrow("Popup closed by user"); @@ -145,7 +150,7 @@ describe("PopupWindow", () => { }, window.location.origin); }); - it("should close the window after closePopupWindowAfter is greater than 0", async () => { + it("should run setTimeout when closePopupWindowAfterInSeconds is greater than 0", async () => { jest.spyOn(global, "setTimeout"); new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: 1 } }); @@ -155,7 +160,7 @@ describe("PopupWindow", () => { jest.runAllTimers(); }); - it("shouldnt close the window after closePopupWindowAfter is equal to 0", async () => { + it("shouldn't run setTimeout when closePopupWindowAfterInSeconds is equal to 0", async () => { jest.spyOn(global, "setTimeout"); new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: 0 } }); @@ -165,7 +170,7 @@ describe("PopupWindow", () => { jest.runAllTimers(); }); - it("shouldnt close the window after closePopupWindowAfter is less than 0", async () => { + it("shouldn't run setTimeout when closePopupWindowAfterInSeconds is less than 0", async () => { jest.spyOn(global, "setTimeout"); new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: -120 } }); @@ -174,4 +179,39 @@ describe("PopupWindow", () => { expect(setTimeout).toHaveBeenCalledTimes(0); jest.runAllTimers(); }); + + it("should invoke close popup window when closePopupWindowAfterInSeconds is greater than 0 and window is open", async () => { + const popupWindow = new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: 1 } }); + definePopupWindowClosedProperty(false); + const closeWindowSpy = jest.spyOn(popupWindow, "close"); + + jest.runOnlyPendingTimers(); + + expect(closeWindowSpy).toHaveBeenCalledTimes(1); + jest.runAllTimers(); + }); + + it("shouldn't invoke close popup window when closePopupWindowAfterInSeconds is greater than 0 and window is not open", async () => { + const popupWindow = new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: 1 } }); + definePopupWindowClosedProperty(true); + const closeWindowSpy = jest.spyOn(popupWindow, "close"); + + jest.runOnlyPendingTimers(); + + expect(closeWindowSpy).not.toBeCalled(); + jest.runAllTimers(); + }); + + it("should show error when closePopupWindowAfterInSeconds is greater than 0 and window is not open", async () => { + Log.setLevel(Log.DEBUG); + const popupWindow = new PopupWindow({ popupWindowFeatures: { closePopupWindowAfterInSeconds: 1 } }); + const consoleDebugSpy = jest.spyOn(console, "debug"); + const promise = popupWindow.navigate({ url: "http://sts/authorize?x=y", state: "someid" }); + + jest.runOnlyPendingTimers(); + + await expect(promise).rejects.toThrow("Popup blocked by user"); + expect(consoleDebugSpy).toHaveBeenCalled(); + jest.runAllTimers(); + }); }); diff --git a/src/navigators/PopupWindow.ts b/src/navigators/PopupWindow.ts index 38b08d6bb..9624537a7 100644 --- a/src/navigators/PopupWindow.ts +++ b/src/navigators/PopupWindow.ts @@ -33,7 +33,7 @@ export class PopupWindow extends AbstractChildWindow { const centeredPopup = PopupUtils.center({ ...DefaultPopupWindowFeatures, ...popupWindowFeatures }); this._window = window.open(undefined, popupWindowTarget, PopupUtils.serialize(centeredPopup)); if (popupWindowFeatures.closePopupWindowAfterInSeconds && popupWindowFeatures.closePopupWindowAfterInSeconds > 0) { - setTimeout(() => { + setTimeout(() => { if (!this._window || typeof this._window.closed !== "boolean" || this._window.closed) { this._abort.raise(new Error("Popup blocked by user")); return;