Skip to content
Source
Sign inSign up

HistorySwipeNavigation.browser.test.tsx

74 lines3.3 KB

1import { describe, expect, it, vi } from "vite-plus/test";
2​
3import { render } from "../../test/render";
4import { HistorySwipeNavigation } from "./HistorySwipeNavigation";
5​
6const navigateHistory = vi.hoisted(() => vi.fn());
7vi.mock("../navigationHistory", () => ({ canNavigateHistory: () => true, navigateHistory }));
8​
9function swipe(target: Element, deltaX: number) {
10 for (const delta of [deltaX, 0]) {
11 target.dispatchEvent(new WheelEvent("wheel", { deltaX: delta, bubbles: true, composed: true }));
12 }
14​
15describe("HistorySwipeNavigation", () => {
16 it.each([
17 ["scrolling left inside a shadow-root scroller keeps the thread", "shadow", 100, -130, false],
18 ["scrolling right inside a shadow-root scroller keeps the thread", "shadow", 100, 130, false],
19 [
20 "scrolling after a shadow scroller remount keeps the thread",
21 "shadow-remount",
22 100,
23 130,
24 false,
25 ],
26 ["scrolling left inside a scroller keeps the thread", "light", 100, -130, false],
27 ["swiping back at a shadow-root scroller's left edge navigates", "shadow", 0, -130, true],
28 ["swiping back over a panel without overflow navigates", "none", 0, -130, true],
29 ["a swipe that started in a closed dialog keeps the thread", "closed-dialog", 0, -130, false],
30 ] as const)("%s", async (_name, scroller, scrollLeft, deltaX, navigates) => {
31 navigateHistory.mockReset();
32 using _platform = vi.spyOn(navigator, "platform", "get").mockReturnValue("MacIntel");
33 await using screen = await render(<HistorySwipeNavigation />);
34 const panel = screen.container.appendChild(document.createElement("div"));
35 const root = scroller.startsWith("shadow") ? panel.attachShadow({ mode: "open" }) : panel;
36 const viewport = root.appendChild(document.createElement("div"));
37 const noOverflow = scroller === "none" || scroller === "closed-dialog";
38 viewport.style.cssText = `width: 200px; overflow-x: ${noOverflow ? "visible" : "auto"}`;
39 const content = viewport.appendChild(document.createElement("div"));
40 content.style.cssText = `height: 20px; width: ${noOverflow ? 100 : 1000}px`;
41 viewport.scrollLeft = scrollLeft;
42​
43 if (scroller === "closed-dialog") {
44 panel.setAttribute("role", "dialog");
45 content.dispatchEvent(new WheelEvent("wheel", { deltaX: -1, bubbles: true, composed: true }));
46 panel.remove();
47 screen.container.appendChild(viewport);
48 }
49​
50 if (scroller === "shadow-remount") {
51 content.dispatchEvent(new WheelEvent("wheel", { deltaX: 1, bubbles: true, composed: true }));
52 const replacement = viewport.cloneNode(true) as HTMLDivElement;
53 viewport.replaceWith(replacement);
54 replacement.scrollLeft = scrollLeft;
55 swipe(replacement, deltaX);
56 } else {
57 swipe(content, deltaX);
58 }
59​
60 expect(navigateHistory).toHaveBeenCalledTimes(navigates ? 1 : 0);
61 });
62​
63 it("a horizontal mouse wheel tick off macOS keeps the thread", async () => {
64 navigateHistory.mockReset();
65 using _platform = vi.spyOn(navigator, "platform", "get").mockReturnValue("Win32");
66 await using screen = await render(<HistorySwipeNavigation />);
67 const content = screen.container.appendChild(document.createElement("div"));
68 content.style.cssText = "height: 20px; width: 100px";
69​
70 swipe(content, -120);
71​
72 expect(navigateHistory).not.toHaveBeenCalled();
73 });
74});