From 70981b9ca9fc13b39b33d17b78a5fd45ae84a65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Mon, 14 Sep 2026 19:01:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20UI=20=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E7=BB=93=E6=9E=9C=E5=BC=B9=E7=AA=97=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加普通保存成功与保存后生成失败的场景断言 验证路径弹窗和失败重试按钮的可见行为 --- .../tests/uiEditorPage.test.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts b/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts index a133f480c..ebe0dd9ea 100644 --- a/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts +++ b/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts @@ -873,6 +873,67 @@ describe('UiEditorPage', () => { expect(screen.getByRole('button', { name: '已复制' })).toBeTruthy(); }); + it('shows a save-success modal without a generated path', async () => { + const stateStore: IUiDesignStateStore = { + load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)), + save: vi.fn().mockResolvedValue({ + status: 'saved', + state: structuredClone(EMPTY_SNAPSHOT.state), + revision: 1, + committedProjectRevision: 1, + }), + generateCode: vi.fn().mockRejectedValue(new Error('not requested')), + }; + + render( + createElement(UiEditorPage, { + projectPath: '/tmp/ui-editor', + resourceId: 'ui-resource', + stateStore, + }), + ); + + fireEvent.click(await screen.findByRole('button', { name: '保存' })); + fireEvent.click(await screen.findByRole('button', { name: '仍然保存' })); + + const dialog = await screen.findByRole('dialog'); + expect(dialog.textContent).toContain('保存成功'); + expect(dialog.textContent).not.toContain('生成文件路径'); + }); + + it('reports partial success when saving succeeds but generation fails', async () => { + const stateStore: IUiDesignStateStore = { + load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)), + save: vi.fn().mockResolvedValue({ + status: 'saved', + state: structuredClone(EMPTY_SNAPSHOT.state), + revision: 1, + committedProjectRevision: 1, + }), + generateCode: vi.fn().mockRejectedValue(new Error('生成服务不可用')), + }; + + render( + createElement(UiEditorPage, { + projectPath: '/tmp/ui-editor', + resourceId: 'ui-resource', + stateStore, + }), + ); + + fireEvent.click( + await screen.findByRole('button', { name: '保存并生成代码' }), + ); + fireEvent.click( + await screen.findByRole('button', { name: '仍然保存并生成' }), + ); + + const dialog = await screen.findByRole('dialog'); + expect(dialog.textContent).toContain('项目已保存,但代码生成失败'); + expect(dialog.textContent).toContain('生成服务不可用'); + expect(screen.getByRole('button', { name: '重试保存并生成' })).toBeTruthy(); + }); + it('shows a manual-copy hint when the native clipboard rejects a path', async () => { const stateStore: IUiDesignStateStore = { load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)),