测试助手同时支持纯文本与引用输入区

appSurface 图集/图标规范入口的提示词仍是 textarea,helper 不能只走 Lexical 编辑器 API
两种字段分别用原生 change 与编辑器 update,读回同样两种口径
补 targetCategory 随任务保存与恢复的断言
This commit is contained in:
2026-09-17 18:53:34 +08:00
parent 6001b87215
commit c0e377f479
2 changed files with 35 additions and 13 deletions
@@ -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('有在途任务时下一条不可派发,前一条终态后才轮到它', () => {
@@ -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 SelectionLexical 因此会忽略浏览器输入事件——`userEvent.type` 与
* `beforeinput` 都不会落字,`fireEvent.change` 更不适用。所以这条链路只能在编辑器实例上做
* 等价更新:仍然走 Lexical 的 `update()` `OnChangePlugin` → 面板状态,断言的是面板真正收到
* 的提示词与引用。浏览器里的真实输入路径由引用输入区自己的测试与实机验收覆盖。
* 提示词输入区有**两种**实现,按入口不同而不同,这个 helper 两种都要支持:
* - 图片类入口(生成图片 / 生成规范 / 生成角色形象 / 生成 UI 设计图)用的是与聊天、资源快速编辑
* 同一份 `@` 引用输入区(Lexical contenteditable)。jsdom 没有可用的 DOM SelectionLexical 会
* 忽略浏览器输入事件——`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 ?? '';
}