Files
next-tjwater-frontend/src/shared/ui/floating-window.test.tsx
T
jiang 7a304a91a8
Generic Container CI/CD / test-build-publish (push) Successful in 1m13s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 1m14s
feat(workbench): dock task and chart workspaces
2026-11-12 11:42:25 +08:00

98 lines
5.5 KiB
TypeScript

import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, expect, it } from "vitest";
import { FloatingWindow } from "./floating-window";
import { floatingWindowEntries, floatingWindowOrder } from "./floating-window-layer";
import { useCallback, useRef, useState } from "react";
afterEach(cleanup);
const content = () => <p>图表内容</p>;
it("opens display requests without stealing focus and respects dismissal until the next request", () => {
const { rerender } = render(<><button autoFocus>回放控制</button><FloatingWindow title="压力分析" openRequestKey="first">{content}</FloatingWindow></>);
expect(screen.getByRole("dialog", { name: "压力分析" })).toBeVisible();
expect(screen.getByRole("button", { name: "回放控制" })).toHaveFocus();
fireEvent.click(screen.getByRole("button", { name: "关闭窗口" }));
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
rerender(<><button>回放控制</button><FloatingWindow title="压力分析" openRequestKey="first">{content}</FloatingWindow></>);
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
rerender(<><button>回放控制</button><FloatingWindow title="压力分析" openRequestKey="second">{content}</FloatingWindow></>);
expect(screen.getByRole("dialog", { name: "压力分析" })).toBeVisible();
expect(screen.getByRole("button", { name: "回放控制" })).toHaveFocus();
fireEvent.click(screen.getByRole("button", { name: "关闭窗口" }));
rerender(<><button>回放控制</button><FloatingWindow title="压力分析" openRequestKey="first">{content}</FloatingWindow></>);
expect(screen.getByRole("dialog", { name: "压力分析" })).toBeVisible();
});
it("retains manual opening, Escape dismissal and focus return", () => {
render(<FloatingWindow title="压力分析">{content}</FloatingWindow>);
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
const trigger = screen.getByRole("button", { name: "放大查看 压力分析" });
fireEvent.click(trigger);
const heading = screen.getByLabelText("窗口标题栏,可用方向键移动,Shift 加方向键调整大小");
expect(heading).toHaveFocus();
fireEvent.keyDown(heading, { key: "Escape" });
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
expect(trigger).toHaveFocus();
fireEvent.click(trigger);
expect(screen.getByRole("dialog", { name: "压力分析" })).toBeVisible();
});
function DockFixture({ multiple = false }: { multiple?: boolean }) {
const target = useRef<HTMLDivElement>(null);
const [activeId, setActiveId] = useState<string | null>(null);
const activate = useCallback((id: string) => setActiveId(id), []);
const deactivate = useCallback((id?: string) => setActiveId((current) => !id || current === id ? null : current), []);
return <>
<div ref={target} data-testid="workspace-slot" />
<button onClick={() => deactivate()}>切换工作区</button>
<FloatingWindow title="停靠分析" dock={{ target, activeId, activate, deactivate, view: "map_split", setView: () => undefined }}>
{() => <input aria-label="分析备注" />}
</FloatingWindow>
{multiple ? <FloatingWindow title="停靠对比" dock={{ target, activeId, activate, deactivate, view: "map_split", setView: () => undefined }}>
{() => <p>第二个来源</p>}
</FloatingWindow> : null}
</>;
}
it("preserves the live document when a docked window is hidden and located again", () => {
render(<DockFixture />);
const trigger = screen.getByRole("button", { name: "放大查看 停靠分析" });
fireEvent.click(trigger);
const dialog = screen.getByRole("dialog", { name: "停靠分析" });
expect(screen.getByTestId("workspace-slot")).toContainElement(dialog);
expect(dialog).toHaveAttribute("data-window-presentation", "docked");
expect(floatingWindowEntries()).toEqual([]);
expect(floatingWindowOrder()).toEqual([]);
const editor = screen.getByLabelText("分析备注");
fireEvent.change(editor, { target: { value: "保留核查说明" } });
fireEvent.click(screen.getByRole("button", { name: "切换工作区" }));
expect(dialog).not.toBeVisible();
fireEvent.click(trigger);
expect(screen.getByLabelText("分析备注")).toBe(editor);
expect(editor).toHaveValue("保留核查说明");
expect(dialog).toBeVisible();
expect(floatingWindowEntries()).toEqual([]);
expect(floatingWindowOrder()).toEqual([]);
fireEvent.keyDown(dialog, { key: "Escape" });
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
});
it("hides inactive docking hosts so another source can occupy the same workspace", () => {
render(<DockFixture multiple />);
fireEvent.click(screen.getByRole("button", { name: "放大查看 停靠分析" }));
const first = screen.getByRole("dialog", { name: "停靠分析" });
const editor = screen.getByLabelText("分析备注");
fireEvent.change(editor, { target: { value: "保留第一个来源" } });
fireEvent.click(screen.getByRole("button", { name: "放大查看 停靠对比" }));
const second = screen.getByRole("dialog", { name: "停靠对比" });
expect(first.parentElement).not.toBeVisible();
expect(first.parentElement).toHaveAttribute("hidden");
expect(second.parentElement).toBeVisible();
fireEvent.click(screen.getByRole("button", { name: "放大查看 停靠分析" }));
expect(first.parentElement).toBeVisible();
expect(second.parentElement).not.toBeVisible();
expect(screen.getByLabelText("分析备注")).toBe(editor);
expect(editor).toHaveValue("保留第一个来源");
});