Files
Genarrative/apps/ai-game-creator-shell/tests/resourceGenerationPromptTestUtils.ts
T
suzmii c0e377f479 测试助手同时支持纯文本与引用输入区
appSurface 图集/图标规范入口的提示词仍是 textarea,helper 不能只走 Lexical 编辑器 API
两种字段分别用原生 change 与编辑器 update,读回同样两种口径
补 targetCategory 随任务保存与恢复的断言
2026-09-17 19:01:35 +08:00

59 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { act, fireEvent, within } from '@testing-library/react';
import {
$createParagraphNode,
$createTextNode,
$getRoot,
type LexicalEditor,
} from 'lexical';
type GenerationPromptField = HTMLTextAreaElement & {
__lexicalEditor?: LexicalEditor;
};
function generationPromptField(scope: HTMLElement) {
return within(scope).getByLabelText('生成提示词') as GenerationPromptField;
}
/**
* 往生成面板的提示词输入区写一段文本。
*
* 提示词输入区有**两种**实现,按入口不同而不同,这个 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 field = generationPromptField(scope);
const editor = field.__lexicalEditor;
if (!editor) {
await act(async () => {
fireEvent.change(field, { target: { value: text } });
});
return;
}
await act(async () => {
editor.update(() => {
const root = $getRoot();
root.clear();
const paragraph = $createParagraphNode();
paragraph.append($createTextNode(text));
root.append(paragraph);
});
});
}
/** 读回提示词输入区当前的文本:`textarea` 读 `value`contenteditable 读文本内容。 */
export function generationPromptText(scope: HTMLElement) {
const field = generationPromptField(scope) as GenerationPromptField & {
value?: string;
textContent?: string | null;
};
return field.value ?? field.textContent ?? '';
}