/* @vitest-environment jsdom */ import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, test, vi } from 'vitest'; import { Badge, Button, Checkbox, EmptyState, IconButton, Label, Modal, PlatformActionButton, PlatformIconButton, ProgressBar, SegmentedTabs, SelectField, Skeleton, Status, Subpanel, Switch, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, TextField, } from './index'; describe('shared UI components', () => { test('keeps native button semantics and states', () => { const onClick = vi.fn(); render(
, ); const button = screen.getByRole('button', { name: '保存' }); expect(button.getAttribute('type')).toBe('button'); fireEvent.click(button); expect(onClick).toHaveBeenCalledTimes(1); expect( (screen.getByRole('button', { name: '稍等' }) as HTMLButtonElement) .disabled, ).toBe(true); expect( screen.getByRole('button', { name: '关闭' }).getAttribute('title'), ).toBe('关闭'); }); test('connects field labels and descriptions to native controls', () => { render(
, ); const input = screen.getByLabelText('名称'); expect(input.getAttribute('aria-invalid')).toBe('true'); expect(input.getAttribute('aria-describedby')).toContain('hint'); expect(screen.getByLabelText('描述').tagName).toBe('TEXTAREA'); expect(screen.getByLabelText('主题').tagName).toBe('SELECT'); expect(screen.getByRole('alert').textContent).toContain('名称已存在'); }); test('renders slots, selected tabs and semantic status content', () => { const onChange = vi.fn(); render(
稳定}> 内容 完成
, ); expect(screen.getByRole('heading', { name: '设置' })).toBeTruthy(); expect(screen.getByRole('status').textContent).toContain('完成'); expect(screen.getByRole('progressbar').getAttribute('aria-valuenow')).toBe( '100', ); expect( screen.getByRole('tab', { name: 'A' }).getAttribute('aria-selected'), ).toBe('true'); fireEvent.click(screen.getByRole('tab', { name: 'B' })); expect(onChange).toHaveBeenCalledWith('b'); expect( screen.getByRole('switch', { name: '启用' }).getAttribute('aria-checked'), ).toBe('true'); }); test('provides semantic label, checkbox, skeleton and table primitives', () => { render(
最近项目 名称 状态 珊瑚岛 已发布
, ); expect(screen.getByLabelText('自动保存')).toHaveProperty('checked', true); expect(screen.getByLabelText('读取中').getAttribute('data-slot')).toBe( 'skeleton', ); expect(screen.getByRole('table', { name: '最近项目' })).toBeTruthy(); expect(screen.getByRole('cell', { name: '珊瑚岛' })).toBeTruthy(); }); test('closes modal on escape and backdrop click', () => { const onClose = vi.fn(); render( 正文 , ); expect(screen.getByRole('dialog', { name: '确认' })).toBeTruthy(); fireEvent.keyDown(document, { key: 'Escape' }); expect(onClose).toHaveBeenCalledTimes(1); fireEvent.mouseDown( document.querySelector('.genarrative-ui-modal__backdrop')!, ); expect(onClose).toHaveBeenCalledTimes(2); }); test('can keep modal open when backdrop and escape closing are disabled', () => { const onClose = vi.fn(); render( 正文 , ); fireEvent.keyDown(document, { key: 'Escape' }); fireEvent.mouseDown( document.querySelector('.genarrative-ui-modal__backdrop')!, ); expect(onClose).not.toHaveBeenCalled(); }); test('keeps platform wrappers generic and supports label/span hosts', () => { const onClick = vi.fn(); render(
上传
, ); expect(screen.getByText('上传').closest('label')?.htmlFor).toBe('upload'); const spanButton = screen.getByRole('button', { name: '打开' }); fireEvent.keyDown(spanButton, { key: 'Enter' }); expect(onClick).toHaveBeenCalledTimes(1); }); });