c0e377f479
appSurface 图集/图标规范入口的提示词仍是 textarea,helper 不能只走 Lexical 编辑器 API 两种字段分别用原生 change 与编辑器 update,读回同样两种口径 补 targetCategory 随任务保存与恢复的断言
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
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 Selection,Lexical 会
|
||
* 忽略浏览器输入事件——`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 ?? '';
|
||
}
|