diff --git a/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationQueue.test.ts b/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationQueue.test.ts index 8cdfb6247..422fe0b86 100644 --- a/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationQueue.test.ts +++ b/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationQueue.test.ts @@ -92,11 +92,14 @@ describe('生成任务模型', () => { aspectRatio: '16:9', imageSize: '1K', referenceAssetIds: ['asset-a', ' asset-b ', 'asset-a', ''], + targetCategory: 'ui-interaction', outputPath: null, projectId: 'project-1', nowMillis: 10, }); expect(task.referenceAssetIds).toEqual(['asset-a', 'asset-b']); + // 入口栏目只是随任务带给原生的可选入参(原生 `target_category`);前端不据它做分类。 + expect(task.targetCategory).toBe('ui-interaction'); const restored = applyLocalProjectAssetGenerationRecords( [], @@ -104,6 +107,7 @@ describe('生成任务模型', () => { ); expect(restored).toHaveLength(1); expect(restored[0]?.referenceAssetIds).toEqual([]); + expect(restored[0]?.targetCategory).toBeNull(); }); test('有在途任务时下一条不可派发,前一条终态后才轮到它', () => { diff --git a/apps/ai-game-creator-shell/tests/resourceGenerationPromptTestUtils.ts b/apps/ai-game-creator-shell/tests/resourceGenerationPromptTestUtils.ts index 950fca4e5..5d2def0a8 100644 --- a/apps/ai-game-creator-shell/tests/resourceGenerationPromptTestUtils.ts +++ b/apps/ai-game-creator-shell/tests/resourceGenerationPromptTestUtils.ts @@ -1,4 +1,4 @@ -import { act, within } from '@testing-library/react'; +import { act, fireEvent, within } from '@testing-library/react'; import { $createParagraphNode, $createTextNode, @@ -6,22 +6,36 @@ import { type LexicalEditor, } from 'lexical'; +type GenerationPromptField = HTMLTextAreaElement & { + __lexicalEditor?: LexicalEditor; +}; + +function generationPromptField(scope: HTMLElement) { + return within(scope).getByLabelText('生成提示词') as GenerationPromptField; +} + /** * 往生成面板的提示词输入区写一段文本。 * - * 提示词输入区与聊天、资源快速编辑共用同一个 `@` 引用输入区(Lexical contenteditable)。 - * jsdom 没有可用的 DOM Selection,Lexical 因此会忽略浏览器输入事件——`userEvent.type` 与 - * `beforeinput` 都不会落字,`fireEvent.change` 更不适用。所以这条链路只能在编辑器实例上做 - * 等价更新:仍然走 Lexical 的 `update()` → `OnChangePlugin` → 面板状态,断言的是面板真正收到 - * 的提示词与引用。浏览器里的真实输入路径由引用输入区自己的测试与实机验收覆盖。 + * 提示词输入区有**两种**实现,按入口不同而不同,这个 helper 两种都要支持: + * - 图片类入口(生成图片 / 生成规范 / 生成角色形象 / 生成 UI 设计图)用的是与聊天、资源快速编辑 + * 同一份 `@` 引用输入区(Lexical contenteditable)。jsdom 没有可用的 DOM Selection,Lexical 会 + * 忽略浏览器输入事件——`userEvent.type` 与 `beforeinput` 都不会落字,`fireEvent.change` 更不适用, + * 所以这条链路只能在编辑器实例上做等价更新:仍然走 Lexical 的 `update()` → `OnChangePlugin` → + * 面板状态。 + * - 纯文本入口(图集 / 图标规范 / 音效 / 背景音乐)仍然是普通 `textarea`,`fireEvent.change` 就是 + * 它真实的输入路径,不需要也不应该套用编辑器 API。 + * + * 两种路径断言的都是面板真正收到的提示词;浏览器里的真实输入由引用输入区自己的测试与实机验收覆盖。 */ export async function typeGenerationPrompt(scope: HTMLElement, text: string) { - const element = within(scope).getByLabelText('生成提示词') as HTMLElement & { - __lexicalEditor?: LexicalEditor; - }; - const editor = element.__lexicalEditor; + const field = generationPromptField(scope); + const editor = field.__lexicalEditor; if (!editor) { - throw new Error('生成提示词输入区不是 Lexical 编辑器'); + await act(async () => { + fireEvent.change(field, { target: { value: text } }); + }); + return; } await act(async () => { editor.update(() => { @@ -34,7 +48,11 @@ export async function typeGenerationPrompt(scope: HTMLElement, text: string) { }); } -/** 读回提示词输入区当前呈现的文本(contenteditable 没有 `value`)。 */ +/** 读回提示词输入区当前的文本:`textarea` 读 `value`,contenteditable 读文本内容。 */ export function generationPromptText(scope: HTMLElement) { - return within(scope).getByLabelText('生成提示词').textContent ?? ''; + const field = generationPromptField(scope) as GenerationPromptField & { + value?: string; + textContent?: string | null; + }; + return field.value ?? field.textContent ?? ''; }