1ad25e30f8
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
199 lines
5.2 KiB
TypeScript
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');
|
|
});
|