98 lines
5.5 KiB
TypeScript
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("保留第一个来源");
|
|
});
|