// @vitest-environment jsdom // // A reload under two overlays, in a tab whose entries below the dead one are not this document's // (Chrome dropped them, see backStaysInDocument): closing the reopened player cannot step over both, // so it steps back one — onto the dead entry, still in the app — rather than leaving it. Its own file: // the entry is read as the module loads, so it is set up before the import. import { afterEach, describe, expect, it, vi } from "vitest"; import { act, renderHook } from "@testing-library/react"; afterEach(() => { Reflect.deleteProperty(window, "navigation"); }); describe("an overlay reopened over a dead entry with nothing of this document below it", () => { it("closes one step back, staying in the document", async () => { window.history.replaceState({ sfPage: "feed", _ov: 1, _ovd: 1 }, "", "/?page=feed&watch=v1"); window.history.pushState({ sfPage: "feed", _ov: 2, _ovd: 2 }, "", "/?page=feed&watch=v1"); const { useBackToClose } = await import("./history"); // Two steps back would leave the document; one stays in it. Object.defineProperty(window, "navigation", { configurable: true, value: { currentEntry: { index: 2 }, entries: () => [{ sameDocument: false }, { sameDocument: true }, { sameDocument: true }], }, }); const go = vi.spyOn(window.history, "go"); const back = vi.spyOn(window.history, "back"); const r = renderHook(() => useBackToClose(() => {}, { watch: "v1" })); await act(async () => { await Promise.resolve(); }); await act(async () => { const landed = new Promise((res) => window.addEventListener("popstate", res, { once: true })); r.unmount(); await landed; }); expect(go).not.toHaveBeenCalled(); expect(back).toHaveBeenCalledTimes(1); expect(window.history.state?._ov).toBe(1); }); });