test: 建立桌面端自动化回归测试体系并完善跨平台 CI

(cherry picked from commit 74267ae2f63f8256c3da84b04f5b330e6e9d4c67)
This commit is contained in:
电摇小子
2026-08-03 10:08:28 +08:00
committed by Wxw-Gu
parent b4f909a597
commit 3e57a8432d
36 changed files with 2598 additions and 110 deletions
+81
View File
@@ -0,0 +1,81 @@
// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { Message } from '../../src/shared/types'
import {
buildMessageGroups,
formatMessageTime
} from '../../src/renderer/src/components/chat/messageGrouping'
import {
buildSearchCacheKey,
parseSearchCacheKey,
readSearchCache,
writeSearchCache
} from '../../src/renderer/src/components/search/searchUtils'
const message = (id: string, createTime: number, from = 'user'): Message => ({
id,
from,
type: '文本',
datetime: new Date(createTime * 1000).toISOString(),
content: id,
isSender: from === 'assistant',
senderId: from,
createTime
})
describe('message grouping and dates', () => {
it('groups adjacent messages but keeps system and distant messages separate', () => {
const groups = buildMessageGroups([
message('one', 1000),
message('two', 1060),
{ ...message('system', 1070, 'system'), type: '系统消息' },
message('three', 2000)
])
expect(groups.map((group) => group.messages.map((item) => item.id))).toEqual([
['one', 'two'],
['system'],
['three']
])
})
it('formats today and yesterday deterministically', () => {
vi.useFakeTimers()
vi.setSystemTime(new Date('2026-08-01T12:00:00+08:00'))
expect(
formatMessageTime(
message('today', Math.floor(Date.parse('2026-08-01T10:00:00+08:00') / 1000))
)
).toContain('今天')
expect(
formatMessageTime(
message('yesterday', Math.floor(Date.parse('2026-07-31T10:00:00+08:00') / 1000))
)
).toContain('昨天')
vi.useRealTimers()
})
})
describe('search cache', () => {
beforeEach(() => localStorage.clear())
it('normalizes the key and survives invalid persisted state', () => {
const key = buildSearchCacheKey('global', '', '7d', ' Windows 性能 ')
expect(parseSearchCacheKey(key)).toMatchObject({ query: 'windows 性能', range: '7d' })
localStorage.setItem('wxe_ai_search_cache_v1', '{broken')
expect(readSearchCache(key)).toBeNull()
})
it('writes and reads an isolated cache record', () => {
const key = buildSearchCacheKey('conversation', 'fixture-contact', 'today', '图片')
const record = {
version: 1 as const,
key,
query: '图片',
answer: '固定假回答',
evidence: [],
createdAt: 1
}
writeSearchCache(record)
expect(readSearchCache(key)).toMatchObject({ answer: '固定假回答' })
})
})