0e75d132a7
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m59s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m13s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 5m20s
Project CI / Backend tests (pull_request) Successful in 6m36s
Project CI / Frontend tests (pull_request) Successful in 3m15s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m16s
Project CI / Native shell tests (pull_request) Successful in 7m14s
Project CI / Repository checks (pull_request) Successful in 6m4s
- runPreviewRefresh 的 preview 形参从自造字面量类型改为契约类型,避免 status 被放宽成 string 与 view 的 props 冲突(tsconfig.tests.json 才会覆盖 tests/ 目录,此前只跑 tsc -p tsconfig.json 漏检) - 已跑 npm run ai-game-creator-shell:typecheck(含 check:tests:types)与定向用例确认通过
116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
/** @vitest-environment jsdom */
|
|
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import {
|
|
createGameCreationAppManifest,
|
|
type GameCreationAppPreviewState,
|
|
} from '../../../packages/shared/src/contracts/gameCreationApp';
|
|
import ProjectDevelopmentView from '../src/view/project-development';
|
|
import { installTauriRuntime } from './tauriRuntimeFake';
|
|
|
|
const PREVIEW_URL = 'http://127.0.0.1:4173/';
|
|
|
|
function installInvoke() {
|
|
installTauriRuntime({
|
|
core: {
|
|
invoke: vi.fn(async (command: string, args?: Record<string, unknown>) => {
|
|
if (command === 'read_local_project_resource_graph') {
|
|
return {
|
|
resourceIds: [],
|
|
referenceEdges: [],
|
|
taskFlows: [],
|
|
categories: [],
|
|
diagnostics: [],
|
|
};
|
|
}
|
|
if (command === 'read_local_project_resource_canvas_layout') {
|
|
return {
|
|
schemaVersion: 'game-creator-resource-layout.v1',
|
|
projectId: args?.expectedProjectId,
|
|
mode: args?.mode,
|
|
revision: 0,
|
|
positions: [],
|
|
updatedAt: 0,
|
|
};
|
|
}
|
|
throw new Error(`unexpected invoke ${command}`);
|
|
}),
|
|
},
|
|
});
|
|
}
|
|
|
|
function renderRunView(
|
|
preview: GameCreationAppPreviewState = {
|
|
status: 'running',
|
|
url: PREVIEW_URL,
|
|
port: 4173,
|
|
},
|
|
) {
|
|
installInvoke();
|
|
const onPlay = vi.fn();
|
|
const manifest = createGameCreationAppManifest(
|
|
'run-preview-refresh',
|
|
'运行页刷新画面',
|
|
);
|
|
manifest.tasks = manifest.tasks.map((task) =>
|
|
task.id === 'code-prototype' ? { ...task, status: 'completed' } : task,
|
|
);
|
|
render(
|
|
<ProjectDevelopmentView
|
|
projectName={manifest.name}
|
|
projectPath="/tmp/run-preview-refresh"
|
|
manifest={manifest}
|
|
attachments={[]}
|
|
recentRunStatus="completed"
|
|
recentRunStopReason={null}
|
|
preview={preview}
|
|
chat={null}
|
|
onHomeOpen={vi.fn()}
|
|
onProjectsOpen={vi.fn()}
|
|
onNotice={vi.fn()}
|
|
onPlay={onPlay}
|
|
/>,
|
|
);
|
|
return { onPlay };
|
|
}
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.clearAllMocks();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('运行页「刷新运行画面」', () => {
|
|
it('点一下就重新载入画面:iframe 换新节点、地址不变,并顺带把预览确认成活体', async () => {
|
|
const { onPlay } = renderRunView();
|
|
await screen.findByTitle('运行页刷新画面 游戏运行画面');
|
|
|
|
const before = document.querySelector('iframe');
|
|
expect(before).not.toBeNull();
|
|
expect(before?.getAttribute('src')).toBe(PREVIEW_URL);
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '刷新运行画面' }));
|
|
|
|
const after = document.querySelector('iframe');
|
|
// 换元素身份=浏览器重新载入这一页:游戏预览不是 vite dev 的实时刷新,只有这一条路。
|
|
expect(after).not.toBe(before);
|
|
expect(after?.getAttribute('src')).toBe(PREVIEW_URL);
|
|
expect(onPlay).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('没有活预览时不渲染刷新,而不是留一个点了没反应的入口', async () => {
|
|
// 非 loopback 地址会被 `resolveEmbeddedPreviewUrl` 拒掉。此时切到运行页只有空态,
|
|
// 该走的是顶栏「运行」页签——刷新入口不该在没画面可刷的时候出现。
|
|
renderRunView({
|
|
status: 'running',
|
|
url: 'https://example.com/game',
|
|
port: 443,
|
|
});
|
|
|
|
fireEvent.click(screen.getByRole('tab', { name: '运行' }));
|
|
await screen.findByText('客户端运行画面尚未载入');
|
|
expect(screen.queryByRole('button', { name: '刷新运行画面' })).toBeNull();
|
|
});
|
|
});
|