mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-21 21:47:00 +08:00
feat: 优化全局 UI 交互与页面视觉体验
统一按钮、输入框、选择控件和开关的交互状态 优化日报、导出、设置、Agent Hub 和 API Center 的UI 完善组件、单元及 Electron E2E 测试
This commit is contained in:
@@ -74,6 +74,23 @@ describe('AI model settings', () => {
|
||||
expect(screen.getByLabelText('模型 ID')).toHaveAttribute('placeholder', '例如:deepseek-chat')
|
||||
})
|
||||
|
||||
it('reveals and focuses the provider editor when editing an existing provider', async () => {
|
||||
vi.mocked(window.api.listAIProviders).mockResolvedValue({
|
||||
success: true,
|
||||
providers: [provider]
|
||||
})
|
||||
render(<AIModelPage onRuntimeChange={vi.fn()} onNotice={vi.fn()} />)
|
||||
|
||||
await act(async () => {
|
||||
await Promise.resolve()
|
||||
})
|
||||
await userEvent.click(screen.getByRole('button', { name: '编辑' }))
|
||||
|
||||
expect(scrollIntoView).toHaveBeenCalledWith({ behavior: 'smooth', block: 'start' })
|
||||
expect(screen.getByLabelText('供应商名称')).toHaveFocus()
|
||||
expect(screen.getByLabelText('供应商名称')).toHaveValue(provider.name)
|
||||
})
|
||||
|
||||
it('does not reload providers when the parent callback identity changes', async () => {
|
||||
const firstRuntimeChange = vi.fn()
|
||||
const secondRuntimeChange = vi.fn()
|
||||
|
||||
@@ -11,8 +11,8 @@ describe('empty states', () => {
|
||||
})
|
||||
|
||||
it('labels an unavailable settings section explicitly', () => {
|
||||
render(<SettingsEmptyState label="测试设置" />)
|
||||
expect(screen.getByRole('heading', { name: '测试设置' })).toBeVisible()
|
||||
expect(screen.getByText('该设置将在后续阶段接入。')).toBeVisible()
|
||||
render(<SettingsEmptyState label="存储与导出" description="请前往导出工作区设置。" />)
|
||||
expect(screen.getByRole('heading', { name: '存储与导出' })).toBeVisible()
|
||||
expect(screen.getByText('请前往导出工作区设置。')).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,7 +12,8 @@ import {
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
Switch
|
||||
Switch,
|
||||
Textarea
|
||||
} from '../../src/renderer/src/components/ui'
|
||||
import { IconButton } from '../../src/renderer/src/components/ui/icon-button'
|
||||
import {
|
||||
@@ -79,6 +80,7 @@ describe('TraceMemo UI control states', () => {
|
||||
<>
|
||||
<Button disabled>不可用操作</Button>
|
||||
<Input aria-label="不可用输入" value="仍可读取" disabled readOnly />
|
||||
<Textarea aria-label="不可用多行输入" value="仍可读取" disabled readOnly />
|
||||
<Checkbox aria-label="不可用多选" disabled />
|
||||
<RadioGroup aria-label="不可用单选组">
|
||||
<RadioGroupItem value="disabled" aria-label="不可用单选" disabled />
|
||||
@@ -90,6 +92,7 @@ describe('TraceMemo UI control states', () => {
|
||||
for (const control of [
|
||||
screen.getByRole('button', { name: '不可用操作' }),
|
||||
screen.getByRole('textbox', { name: '不可用输入' }),
|
||||
screen.getByRole('textbox', { name: '不可用多行输入' }),
|
||||
screen.getByRole('checkbox', { name: '不可用多选' }),
|
||||
screen.getByRole('radio', { name: '不可用单选' }),
|
||||
screen.getByRole('switch', { name: '不可用开关' })
|
||||
@@ -103,6 +106,15 @@ describe('TraceMemo UI control states', () => {
|
||||
'disabled:text-disabled-foreground',
|
||||
'disabled:!text-disabled-foreground'
|
||||
)
|
||||
expect(screen.getByRole('textbox', { name: '不可用多行输入' })).toHaveClass(
|
||||
'border-border-subtle',
|
||||
'disabled:border-disabled-border',
|
||||
'disabled:bg-disabled-surface',
|
||||
'disabled:text-disabled-foreground'
|
||||
)
|
||||
expect(screen.getByRole('textbox', { name: '不可用多行输入' })).not.toHaveClass(
|
||||
'shadow-surface'
|
||||
)
|
||||
expect(screen.getByRole('checkbox', { name: '不可用多选' })).toHaveClass(
|
||||
'border-muted-foreground/60'
|
||||
)
|
||||
@@ -148,6 +160,8 @@ describe('TraceMemo UI control states', () => {
|
||||
expect(screen.getByRole('radio', { name: '舒适密度' })).toBeChecked()
|
||||
|
||||
const toggle = screen.getByRole('switch', { name: '显示头像' })
|
||||
expect(toggle).toHaveClass('h-5', 'w-9', 'border-0', 'p-0.5')
|
||||
expect(toggle.firstElementChild).toHaveClass('h-4', 'w-4')
|
||||
await user.click(toggle)
|
||||
expect(toggle).toBeChecked()
|
||||
})
|
||||
|
||||
@@ -79,5 +79,10 @@ describe('TraceMemo UI infrastructure', () => {
|
||||
await user.click(screen.getByRole('button', { name: '显示通知' }))
|
||||
expect(screen.getByText('已保存')).toBeVisible()
|
||||
expect(screen.getByText('设置已更新')).toBeVisible()
|
||||
|
||||
const close = screen.getByRole('button', { name: '关闭通知' })
|
||||
expect(close).toHaveClass('h-7', 'w-7', 'border-0', 'bg-transparent')
|
||||
await user.click(close)
|
||||
expect(screen.queryByText('已保存')).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -93,7 +93,13 @@ describe('voice recognition settings', () => {
|
||||
...window.api,
|
||||
getContacts: vi.fn().mockResolvedValue([
|
||||
{ md5: 'contact-a', m_nsNickName: '联系人 A', m_nsUsrName: 'contact-a', type: 'user' },
|
||||
{ md5: 'group-b', m_nsNickName: '群聊 B', m_nsUsrName: 'group-b@chatroom', type: 'group' }
|
||||
{
|
||||
md5: 'group-b',
|
||||
m_nsNickName: '群聊 B',
|
||||
m_nsUsrName: 'group-b@chatroom',
|
||||
type: 'group',
|
||||
avatar: 'data:image/png;base64,voice-fixture-avatar'
|
||||
}
|
||||
]),
|
||||
getSelf: vi.fn().mockResolvedValue({
|
||||
ready: true,
|
||||
@@ -142,6 +148,9 @@ describe('voice recognition settings', () => {
|
||||
|
||||
expect(await screen.findByText('群聊 B')).toBeInTheDocument()
|
||||
expect(await screen.findByText('7 条语音')).toBeInTheDocument()
|
||||
expect(
|
||||
document.querySelector('img[src="data:image/png;base64,voice-fixture-avatar"]')
|
||||
).toBeInTheDocument()
|
||||
expect(window.api.getVoiceBatchConversationSummaries).toHaveBeenCalledWith({
|
||||
conversationIds: ['group-b'],
|
||||
range: 'recent_30_days'
|
||||
|
||||
Reference in New Issue
Block a user