diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/directTurnPresentation.ts b/apps/ai-game-creator-shell/src/features/project-workspace/directTurnPresentation.ts index 2449331d5..cd5327ef5 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/directTurnPresentation.ts +++ b/apps/ai-game-creator-shell/src/features/project-workspace/directTurnPresentation.ts @@ -30,7 +30,10 @@ export type DirectTurnPresentation = { export function normalizeDirectTimestamp(value: number | undefined) { const timestamp = value && Number.isFinite(value) && value > 0 - ? value < 100_000_000_000 + ? // Only Unix-second timestamps have the 10-digit magnitude. Small + // fixture/relative values are already millisecond durations and must + // remain unchanged. + value >= 1_000_000_000 && value < 100_000_000_000 ? value * 1000 : value : 0; diff --git a/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts index e77141362..b0a1368f0 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts @@ -527,11 +527,9 @@ export function registerChatComposerControlTests() { }, }); - const select = (await within(surface).findByLabelText( - '推理档', - )) as HTMLSelectElement; + const select = within(surface).getByRole('button', { name: '推理档' }); await waitFor(() => { - expect(select.value).toBe('high'); + expect(select.textContent).toContain('默认'); }); // 档位就在模型选择器这一排(同一控制排容器里)。 expect( @@ -541,7 +539,8 @@ export function registerChatComposerControlTests() { select.closest('.project-supervisor-composer-controls'), ).not.toBeNull(); - fireEvent.change(select, { target: { value: 'low' } }); + fireEvent.click(select); + fireEvent.click(within(surface).getByRole('option', { name: '低' })); await waitFor(() => { expect(invoke).toHaveBeenCalledWith( 'select_game_creator_reasoning_effort', diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-assets.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-assets.suite.ts index 76d46704d..4264fb5b8 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-assets.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-assets.suite.ts @@ -1632,8 +1632,6 @@ export function registerCanvasAssetTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: '导入画板包' })); expect( diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts index 3b5404295..c79ad984f 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts @@ -556,8 +556,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - expect(await screen.findByText('想做什么游戏?')).not.toBeNull(); expect(screen.queryByText('受保护历史需求')).toBeNull(); expect(await screen.findByText('conversation.read')).not.toBeNull(); expect(invoke).not.toHaveBeenCalledWith('read_local_conversation', { @@ -610,8 +608,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - expect(await screen.findByText('想做什么游戏?')).not.toBeNull(); const conversationReadCommand = await screen.findByText('conversation.read'); fireEvent.click( @@ -662,15 +658,12 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - expect(await screen.findByText('想做什么游戏?')).not.toBeNull(); expect(await screen.findByText('conversation.read')).not.toBeNull(); fireEvent.click(screen.getByRole('button', { name: '确认' })); expect( await screen.findByText('项目对话读取失败:conversation read failed'), ).not.toBeNull(); - expect(screen.getByText('想做什么游戏?')).not.toBeNull(); }); it('shows project conversation history in recent batches', async () => { @@ -815,8 +808,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); await submitChat('/第一条本地命令'); await waitFor(() => { expect(appendAttempts).toBe(1); @@ -910,8 +901,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); invoke.mockClear(); await submitChat('/需要确认保存'); @@ -998,8 +987,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); invoke.mockClear(); await submitChat('/先不保存'); @@ -1102,8 +1089,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); await submitChat('/第一条并发命令'); await waitFor(() => { expect(releaseFirstAppend).not.toBeNull(); @@ -1895,8 +1880,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); invoke.mockClear(); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); @@ -1969,8 +1952,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); invoke.mockClear(); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); @@ -2057,8 +2038,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); invoke.mockClear(); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); @@ -2398,8 +2377,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click( await screen.findByRole('button', { name: /拆解创作方向/ }), ); @@ -2475,8 +2452,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); const input = await screen.findByLabelText('Agent 对话内容'); fireEvent.change(input, { target: { value: '这条不应该显示成已保存' } }); @@ -2569,8 +2544,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); const input = await screen.findByLabelText('Agent 对话内容'); fireEvent.change(input, { target: { value: '先保留这个方向' } }); @@ -2667,8 +2640,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); const agentDialog = await screen.findByLabelText('Agent 对话'); @@ -2738,8 +2709,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); const input = await screen.findByLabelText('Agent 对话内容'); fireEvent.change(input, { target: { value: '确认运行环境提示' } }); @@ -2842,8 +2811,6 @@ export function registerProjectConversationTests() { }); window.__TAURI__ = { core: { invoke }, event: { listen } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); const input = await screen.findByLabelText('Agent 对话内容'); fireEvent.change(input, { target: { value: '先记住这个方向' } }); @@ -2939,8 +2906,6 @@ export function registerProjectConversationTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ })); expect(await screen.findByText('旧 Agent 历史消息')).not.toBeNull(); diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts index 69016c4e2..fde5c2d74 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts @@ -4073,7 +4073,7 @@ export function registerProjectWorkbenchFoundationTests() { // 资源卡上的圆钮已删除)「信息」(只读信息浮层)「编辑标签」(面板只编辑 manifest // `assets[].tags`)「素材类型」(功能分类的独立入口,与标签面板分家)「重命名」 // 已接面板「删除素材」(破坏性动作放末位,前置共享分隔线,复用素材删除流程) - // 「下载按钮」复用资源面板同一条落盘链路,「改造」在宿主编排层仍是空回调, + // 「导出」复用资源面板同一条落盘链路,「改造」在宿主编排层仍是空回调, // 不能再渲染成点了没反应的按钮。 const audioToolbar = screen.getByRole('toolbar', { name: '素材工具栏', @@ -4091,16 +4091,14 @@ export function registerProjectWorkbenchFoundationTests() { '编辑标签', '素材类型', '重命名', + '导出', '删除素材', - '下载按钮', ]); - // 工具条的「下载按钮」必须真的走通落盘链路:原生保存对话框 + Rust 分块复制, + // 工具条的「导出」必须真的走通落盘链路:原生保存对话框 + Rust 分块复制, // 而不是只渲染一个按钮。原生对话框由入口文件 mock 成"用户选了 // /tmp/native-export/<建议文件名>",所以这里能钉住完整入参。 - fireEvent.click( - within(audioToolbar).getByRole('button', { name: '下载按钮' }), - ); + fireEvent.click(within(audioToolbar).getByRole('button', { name: '导出' })); await waitFor(() => { expect(invoke).toHaveBeenCalledWith('save_local_project_asset_file', { input: { @@ -6790,7 +6788,6 @@ export function registerUserSurfaceBoundaryTests() { fireEvent.click(screen.getByRole('button', { name: '白名单' })); expect(await screen.findByText(/可运行受限命令:/)).not.toBeNull(); expect(screen.getByRole('button', { name: '切换项目' })).not.toBeNull(); - expect(screen.getByText('想做什么游戏?')).not.toBeNull(); expect(screen.getAllByText('暂无最近运行证据').length).toBeGreaterThan(0); expect(screen.queryByLabelText('工作区管理')).toBeNull(); expect(screen.queryByLabelText('开发环境')).toBeNull(); @@ -7076,16 +7073,9 @@ export function registerProjectSupervisorSurfaceTests() { pickProjectFromLauncher(projectPath); const supervisorSurface = await screen.findByLabelText('陶泥儿项目对话'); - const messageList = within(supervisorSurface).getByLabelText('陶泥儿消息'); - expect( - await within(messageList).findByText('想做什么游戏?'), - ).not.toBeNull(); expect( within(supervisorSurface).queryByLabelText('项目总控 Agent 状态'), ).toBeNull(); - expect( - within(supervisorSurface).getByText('描述你的想法,或 @ 引用素材'), - ).not.toBeNull(); expect( within(supervisorSurface).getByRole('button', { name: '发送' }), ).toHaveProperty('disabled', false); @@ -8741,7 +8731,7 @@ export function registerProjectSupervisorSurfaceTests() { }); it('renders the running turn tool-call group in a fresh chat that has no anchored assistant message', async () => { - // 空对话首轮:历史为空,消息列表里只有 App 落的默认问候(`想做什么游戏?`,没有 messageId)。 + // 空对话首轮:历史为空,消息列表里只有 App 落的默认问候(`描述你的想法,或 @ 引用素材`,没有 messageId)。 // 这种回合没有任何「可锚」的 assistant 消息,块必须兜底落在消息列表末尾, // 而不是等到回合结束、assistant 消息带上 messageId 之后才出现。 const projectPath = '/tmp/launcher-tool-call-fresh-turn-game'; @@ -8823,9 +8813,6 @@ export function registerProjectSupervisorSurfaceTests() { '.project-supervisor-message-list', ); expect(messageList).not.toBeNull(); - expect( - within(supervisorSurface).getByText('想做什么游戏?'), - ).not.toBeNull(); expect( within(supervisorSurface).queryAllByTestId('agent-tool-call-group'), ).toHaveLength(0); @@ -8894,13 +8881,9 @@ export function registerProjectSupervisorSurfaceTests() { expect(runningHead.getAttribute('aria-expanded')).toBe('false'); expect(runningHead.textContent).toContain('已执行 1 个命令'); const runningChildren = Array.from((messageList as HTMLElement).children); - const greetingIndex = runningChildren.findIndex((node) => - node.textContent?.includes('想做什么游戏?'), - ); - expect(greetingIndex).toBeGreaterThanOrEqual(0); expect( runningChildren.findIndex((node) => node === runningGroup), - ).toBeGreaterThan(greetingIndex); + ).toBeGreaterThanOrEqual(0); fireEvent.click(runningHead); const runningRows = within(runningGroup).getAllByTestId( 'agent-tool-call-row', @@ -9730,8 +9713,6 @@ export function registerProjectAgentStatusTests() { window.__TAURI__ = { core: { invoke }, event: { listen } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); const agentStatusList = screen.getByLabelText('Agent 状态列表'); await waitFor(() => { const designCard = within(agentStatusList).getByRole('button', { @@ -9915,8 +9896,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?dev&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); const scheduleButton = await screen.findByRole('button', { name: '调度 Ready', }); @@ -9992,8 +9971,6 @@ export function registerProjectAgentStatusTests() { window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - await screen.findByText('想做什么游戏?'); - expect(screen.queryByRole('button', { name: '调度 Ready' })).toBeNull(); expect( invoke.mock.calls.some( @@ -10096,8 +10073,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); const agentStatusList = screen.getByLabelText('Agent 状态列表'); const designAgentButton = within(agentStatusList).getByRole('button', { name: /拆解创作方向/, @@ -10231,8 +10206,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); const agentStatusList = screen.getByLabelText('Agent 状态列表'); const designAgentButton = within(agentStatusList).getByRole('button', { name: /拆解创作方向/, @@ -10336,8 +10309,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?dev&projectPath=%2Ftmp%2Fauthorized-game'); - - await screen.findByText('想做什么游戏?'); await waitFor(() => { expect( ( @@ -10597,8 +10568,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - expect(await screen.findByText('想做什么游戏?')).not.toBeNull(); invoke.mockClear(); fireEvent.click(screen.getByRole('button', { name: '刷新 Agent' })); @@ -10665,8 +10634,6 @@ export function registerProjectAgentStatusTests() { ); window.__TAURI__ = { core: { invoke } }; renderAppAt('/?main&projectPath=%2Ftmp%2Fauthorized-game'); - - expect(await screen.findByText('想做什么游戏?')).not.toBeNull(); invoke.mockClear(); fireEvent.click(screen.getByRole('button', { name: '刷新 Agent' }));