25c5ecdf6e
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m58s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m34s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m29s
Project CI / Backend tests (pull_request) Failing after 4m38s
Project CI / Frontend tests (pull_request) Successful in 3m33s
Project CI / Repository checks (pull_request) Failing after 4m4s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m13s
Project CI / Native shell tests (pull_request) Successful in 6m35s
- 78 处内联 window.__TAURI__ 赋值改为 installTauriRuntime,覆盖 appSurface 之外的 37 个测试文件 - 31 处 delete window.__TAURI__ / window.__TAURI__ = undefined 复位改为 resetTauriRuntime - 删除 recentProjectsHook、projectCreationDirectory、projectResourceLiveIntegration、useProjectResourceCardPreviews、resourceVersionReplacementModel、unityProjectOpen 里的本地 asTauriInvoke / asTauriListen 适配器与相关类型别名 - designProjectRestore 的 setup 参数由 ReturnType<typeof vi.fn> 收窄为具体 invoke 签名 - 迁移后仅 tests/tauriRuntimeFake.ts 直接读写 window.__TAURI__
121 lines
3.8 KiB
TypeScript
121 lines
3.8 KiB
TypeScript
/** @vitest-environment jsdom */
|
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { createGameCreationAppManifest } from '../../../packages/shared/src/contracts/gameCreationApp';
|
|
import ProjectDevelopmentView from '../src/view/project-development';
|
|
import { installTauriRuntime } from './tauriRuntimeFake';
|
|
|
|
const openUrl = vi.fn(async (_url: string) => undefined);
|
|
vi.mock('@tauri-apps/plugin-opener', () => ({
|
|
openUrl: (url: string) => openUrl(url),
|
|
}));
|
|
|
|
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(options: { withPreview?: boolean } = {}) {
|
|
installInvoke();
|
|
const manifest = createGameCreationAppManifest(
|
|
'run-preview-browser-open',
|
|
'运行页浏览器入口',
|
|
);
|
|
const onNotice = vi.fn();
|
|
render(
|
|
<ProjectDevelopmentView
|
|
projectName={manifest.name}
|
|
projectPath="/tmp/run-preview-browser-open"
|
|
manifest={manifest}
|
|
attachments={[]}
|
|
recentRunStatus={null}
|
|
recentRunStopReason={null}
|
|
preview={
|
|
options.withPreview === false
|
|
? null
|
|
: { status: 'running', url: PREVIEW_URL, port: 4173 }
|
|
}
|
|
chat={<div>项目总控</div>}
|
|
onHomeOpen={vi.fn()}
|
|
onProjectsOpen={vi.fn()}
|
|
onNotice={onNotice}
|
|
/>,
|
|
);
|
|
return { onNotice };
|
|
}
|
|
|
|
afterEach(() => {
|
|
document.body.innerHTML = '';
|
|
vi.clearAllMocks();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('运行页「在浏览器打开」', () => {
|
|
it('点顶栏那枚按钮就把当前预览地址交给系统浏览器', async () => {
|
|
renderRunView();
|
|
|
|
const entry = await screen.findByRole('button', {
|
|
name: '在浏览器打开',
|
|
});
|
|
// 入口住在工作台顶栏的动作区里,与版本入口同一排;预览地址本身不再以文字出现。
|
|
expect(entry.closest('.game-workbench-view-actions')).not.toBeNull();
|
|
expect(document.body.textContent ?? '').not.toContain(PREVIEW_URL);
|
|
expect(document.querySelector('.game-run-status-hint')).toBeNull();
|
|
fireEvent.click(entry);
|
|
|
|
await waitFor(() => expect(openUrl).toHaveBeenCalledWith(PREVIEW_URL));
|
|
// 成功不弹提示:浏览器真的起来了,用户自己看得见。
|
|
expect(openUrl).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('没有活预览时不渲染这枚入口', async () => {
|
|
renderRunView({ withPreview: false });
|
|
|
|
await screen.findByRole('tab', { name: '运行' });
|
|
expect(screen.queryByRole('button', { name: '在浏览器打开' })).toBeNull();
|
|
});
|
|
|
|
it('打开失败时把原因交给统一提示通道,而不是静默吞掉', async () => {
|
|
openUrl.mockRejectedValueOnce(new Error('permission denied'));
|
|
const { onNotice } = renderRunView();
|
|
|
|
fireEvent.click(
|
|
await screen.findByRole('button', { name: '在浏览器打开' }),
|
|
);
|
|
|
|
await waitFor(() =>
|
|
expect(onNotice).toHaveBeenCalledWith({
|
|
tone: 'error',
|
|
message: '在浏览器打开失败:permission denied',
|
|
}),
|
|
);
|
|
});
|
|
});
|