d3c117de01
同步主分支的错误反馈重试与工作台入口调整 保留回合流去重、快照落盘收尾与对话输入文案
145 lines
4.3 KiB
TypeScript
145 lines
4.3 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
import type { GameCreatorDirectActiveTurn } from '../src/app/types';
|
|
import { WindowChrome } from '../src/components/WindowChrome';
|
|
import { useWindowChrome } from '../src/components/windowChromeContext';
|
|
|
|
function TitleSetter({ value }: { value: string }) {
|
|
const { setTitle } = useWindowChrome();
|
|
return (
|
|
<button type="button" onClick={() => setTitle(value)}>
|
|
更新标题
|
|
</button>
|
|
);
|
|
}
|
|
|
|
function ActiveRunsSetter({
|
|
activeTurns,
|
|
}: {
|
|
activeTurns: GameCreatorDirectActiveTurn[];
|
|
}) {
|
|
const { setActiveProjectRuns } = useWindowChrome();
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={() =>
|
|
setActiveProjectRuns({ activeTurns, onOpenProject: () => undefined })
|
|
}
|
|
>
|
|
显示运行项目
|
|
</button>
|
|
);
|
|
}
|
|
|
|
describe('WindowChrome', () => {
|
|
it('renders the陶泥儿 brand, default title, and controls', async () => {
|
|
const user = userEvent.setup();
|
|
render(
|
|
<WindowChrome>
|
|
<div>工作区内容</div>
|
|
</WindowChrome>,
|
|
);
|
|
|
|
expect(screen.getByRole('banner', { name: '窗口标题栏' })).toBeTruthy();
|
|
expect(screen.getByLabelText('陶泥儿 GameAgent')).toBeTruthy();
|
|
expect(screen.queryByLabelText('本地工作区')).toBeNull();
|
|
expect(screen.getByText('创作工作台')).toBeTruthy();
|
|
expect(screen.getByText('工作区内容')).toBeTruthy();
|
|
expect(screen.queryByRole('menubar')).toBeNull();
|
|
|
|
await user.click(screen.getByRole('button', { name: '最小化' }));
|
|
await user.click(screen.getByRole('button', { name: '最大化' }));
|
|
await user.click(screen.getByRole('button', { name: '关闭' }));
|
|
});
|
|
|
|
it('updates the centered title through the shell context', async () => {
|
|
const user = userEvent.setup();
|
|
render(
|
|
<WindowChrome>
|
|
<TitleSetter value="星尘花园" />
|
|
</WindowChrome>,
|
|
);
|
|
|
|
await user.click(screen.getByRole('button', { name: '更新标题' }));
|
|
|
|
expect(screen.getByText('星尘花园')).toBeTruthy();
|
|
expect(screen.getByLabelText('当前工作区:星尘花园')).toBeTruthy();
|
|
});
|
|
|
|
it('restores the default title when a page clears its title', async () => {
|
|
const user = userEvent.setup();
|
|
function ClearTitle() {
|
|
const { setTitle } = useWindowChrome();
|
|
return (
|
|
<button type="button" onClick={() => setTitle(' ')}>
|
|
清空标题
|
|
</button>
|
|
);
|
|
}
|
|
render(
|
|
<WindowChrome>
|
|
<ClearTitle />
|
|
</WindowChrome>,
|
|
);
|
|
|
|
await user.click(screen.getByRole('button', { name: '清空标题' }));
|
|
|
|
expect(screen.getByText('创作工作台')).toBeTruthy();
|
|
});
|
|
|
|
it('closes no menus because the title bar has no application menu bar', () => {
|
|
render(
|
|
<WindowChrome>
|
|
<button type="button">页面按钮</button>
|
|
</WindowChrome>,
|
|
);
|
|
|
|
fireEvent.pointerDown(screen.getByRole('button', { name: '页面按钮' }));
|
|
expect(screen.queryByRole('menu')).toBeNull();
|
|
});
|
|
|
|
it('renders the latest active project in the title bar and expands the full list', async () => {
|
|
const user = userEvent.setup();
|
|
render(
|
|
<WindowChrome>
|
|
<ActiveRunsSetter
|
|
activeTurns={[
|
|
{
|
|
projectPath: 'C:/projects/first',
|
|
projectName: '先开始',
|
|
turnId: 'turn-first',
|
|
startedAt: 100,
|
|
status: 'running',
|
|
updatedAt: 120,
|
|
sequence: 1,
|
|
},
|
|
{
|
|
projectPath: 'C:/projects/later',
|
|
projectName: '后开始',
|
|
turnId: 'turn-later',
|
|
startedAt: 200,
|
|
status: 'streaming',
|
|
updatedAt: 220,
|
|
sequence: 2,
|
|
},
|
|
]}
|
|
/>
|
|
</WindowChrome>,
|
|
);
|
|
|
|
await user.click(screen.getByRole('button', { name: '显示运行项目' }));
|
|
expect(
|
|
screen.getByRole('button', { name: /正在运行的项目:后开始/ }),
|
|
).toBeTruthy();
|
|
expect(screen.queryByRole('menu')).toBeNull();
|
|
await user.click(
|
|
screen.getByRole('button', { name: /正在运行的项目:后开始/ }),
|
|
);
|
|
expect(screen.getAllByRole('menuitem')).toHaveLength(2);
|
|
});
|
|
});
|