Files
Genarrative/src/components/common/PlatformTextField.test.tsx
T
kdletters 1ad25e30f8 收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件
迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome
补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
2026-06-10 10:24:18 +08:00

199 lines
5.2 KiB
TypeScript

/* @vitest-environment jsdom */
import { fireEvent, render, screen } from '@testing-library/react';
import { expect, test, vi } from 'vitest';
import { PlatformSelectField, PlatformTextField } from './PlatformTextField';
test('renders shared platform input chrome', () => {
const onChange = vi.fn();
render(
<PlatformTextField
aria-label="作品名称"
value="水果抓大鹅"
onChange={onChange}
size="lg"
/>,
);
const input = screen.getByLabelText('作品名称');
fireEvent.change(input, { target: { value: '水果乐园' } });
expect(input.tagName).toBe('INPUT');
expect(input.className).toContain('bg-white/86');
expect(input.className).toContain('text-base');
expect(input.className).toContain(
'focus:border-[var(--platform-surface-hover-border)]',
);
expect(input.className).toContain('focus:ring-2');
expect(input.className).toContain('focus:ring-[var(--platform-warm-border)]');
expect(onChange).toHaveBeenCalledTimes(1);
});
test('renders shared platform textarea chrome', () => {
render(
<PlatformTextField
variant="textarea"
aria-label="作品描述"
value="简介"
rows={5}
size="md"
onChange={vi.fn()}
/>,
);
const textarea = screen.getByLabelText('作品描述');
expect(textarea.tagName).toBe('TEXTAREA');
expect(textarea.getAttribute('rows')).toBe('5');
expect(textarea.className).toContain('resize-none');
expect(textarea.className).toContain('leading-6');
});
test('keeps local classes and disabled state', () => {
render(
<PlatformTextField
aria-label="物品名称"
value=""
disabled
className="mt-2"
onChange={vi.fn()}
/>,
);
const input = screen.getByLabelText('物品名称');
expect(input).toHaveProperty('disabled', true);
expect(input.className).toContain('mt-2');
expect(input.className).toContain('disabled:cursor-not-allowed');
});
test('renders compact field chrome', () => {
render(
<PlatformTextField
aria-label="形状名称"
value="方块"
density="compact"
onChange={vi.fn()}
/>,
);
const input = screen.getByLabelText('形状名称');
expect(input.className).toContain('rounded-[0.85rem]');
expect(input.className).toContain('bg-white/90');
expect(input.className).toContain('py-2');
});
test('renders roomy textarea chrome', () => {
render(
<PlatformTextField
variant="textarea"
aria-label="作品简介"
value="简介"
rows={4}
size="md"
density="roomy"
onChange={vi.fn()}
/>,
);
const textarea = screen.getByLabelText('作品简介');
expect(textarea.className).toContain('bg-white/90');
expect(textarea.className).toContain('px-4');
expect(textarea.className).toContain('py-3');
expect(textarea.className).toContain('leading-6');
});
test('renders focused field tone variants', () => {
render(
<>
<PlatformTextField
aria-label="主题"
value=""
tone="rose"
onChange={vi.fn()}
/>
<PlatformTextField
aria-label="物品"
value=""
tone="emerald"
onChange={vi.fn()}
/>
</>,
);
expect(screen.getByLabelText('主题').className).toContain(
'focus:border-rose-200 focus:ring-rose-100',
);
expect(screen.getByLabelText('物品').className).toContain(
'focus:border-emerald-200 focus:ring-emerald-100',
);
});
test('renders shared platform select chrome', () => {
render(
<PlatformSelectField
aria-label="目标洞口"
value="hole-1"
density="compact"
onChange={vi.fn()}
>
<option value="hole-1">洞口 1</option>
</PlatformSelectField>,
);
const select = screen.getByLabelText('目标洞口');
expect(select.tagName).toBe('SELECT');
expect(select.className).toContain('rounded-[0.85rem]');
expect(select.className).toContain('text-sm');
});
test('renders editor dark input textarea and select chrome', () => {
render(
<>
<PlatformTextField
aria-label="角色名字"
value="沈行"
surface="editorDark"
tone="emerald"
density="roomy"
onChange={vi.fn()}
/>
<PlatformTextField
variant="textarea"
aria-label="聊天草稿"
value="问问线索"
surface="editorDark"
tone="sky"
rows={4}
onChange={vi.fn()}
/>
<PlatformSelectField
aria-label="生成模式"
value="fast"
surface="editorDark"
tone="sky"
onChange={vi.fn()}
>
<option value="fast">快速</option>
</PlatformSelectField>
</>,
);
const input = screen.getByLabelText('角色名字');
const textarea = screen.getByLabelText('聊天草稿');
const select = screen.getByLabelText('生成模式');
expect(input.className).toContain('platform-text-field--editor-dark');
expect(input.className).toContain('bg-black/30');
expect(input.className).toContain('focus:border-emerald-400/40');
expect(textarea.className).toContain('resize-none');
expect(textarea.className).toContain('focus:border-sky-400/40');
expect(select.className).toContain('platform-text-field--editor-dark');
expect(select.className).toContain('focus:border-sky-400/40');
});