feat: 完善多账号连接诊断与聊天媒体导出

- 新增微信账号发现、环境诊断和分步数据库连接引导
- 支持按账号安全保存数据库密钥及快速切换账号
- 完善 WCDB 历史消息分片读取和分页状态提示
- 支持导出图片、视频和语音,提供原图优先及缩略图回退
- 更新安装指引、兼容版本说明和相关自动化测试
This commit is contained in:
Wxw-Gu
2026-08-03 10:43:14 +08:00
parent 224308f0e0
commit 08e1294e5d
37 changed files with 2011 additions and 255 deletions
+44 -7
View File
@@ -23,13 +23,8 @@ test('KEY-01 KEY-02 invalid key remains recoverable and valid key enters the app
await fixture.page.getByRole('tab', { name: /高级用户/ }).click()
const keyInput = fixture.page.getByLabel('数据库密钥')
await keyInput.fill('b'.repeat(64))
const errorDialog = fixture.page.waitForEvent('dialog')
await fixture.page
.getByRole('button', { name: '连接数据库' })
.evaluate((element: HTMLButtonElement) => element.click())
const dialog = await errorDialog
expect(dialog.message()).toContain('数据库密钥无效')
await dialog.dismiss()
await fixture.page.getByRole('button', { name: '连接数据库' }).click()
await expect(fixture.page.getByText('数据库密钥无效')).toBeVisible()
await expect(keyInput).toBeVisible()
await keyInput.fill('a'.repeat(64))
@@ -40,6 +35,46 @@ test('KEY-01 KEY-02 invalid key remains recoverable and valid key enters the app
}
})
test('P0-01 an invalid directory can be corrected and retried without restarting', async () => {
test.skip(process.platform !== 'win32', 'Manual database directory editing is Windows-only')
const fixture = await launchTestApp({ mode: 'disconnected' })
try {
await fixture.page.getByRole('tab', { name: /高级用户/ }).click()
await fixture.page.getByLabel('数据库密钥').fill('a'.repeat(64))
await fixture.page.getByLabel('微信数据目录').fill('Z:\\missing-wechat-data')
await fixture.page.getByRole('button', { name: '连接数据库' }).click()
await expect(fixture.page.getByText('微信数据目录不存在,请重新选择目录')).toBeVisible()
await expect(fixture.page.getByLabel('微信数据目录')).toBeEditable()
await expect(fixture.page.getByRole('button', { name: '选择目录' })).toBeEnabled()
await fixture.page.getByRole('button', { name: '选择目录' }).click()
await expect(fixture.page.getByLabel('微信数据目录')).toHaveValue('fixture-account')
await fixture.page.getByRole('button', { name: '连接数据库' }).click()
await expect(fixture.page.getByRole('navigation', { name: '一级导航' })).toBeVisible()
} finally {
await fixture.close()
}
})
test('P2-01 P2-02 guided connection exposes safe diagnostics and completes all stages', async () => {
const fixture = await launchTestApp({ mode: 'disconnected' })
try {
await expect(fixture.page.getByText('4.1.9.57')).toBeVisible()
await expect(fixture.page.getByText('微信 4.xWCDB')).toBeVisible()
await expect(fixture.page.getByRole('button', { name: '复制脱敏诊断摘要' })).toBeEnabled()
await fixture.page.getByRole('button', { name: '检查完成,继续' }).click()
await fixture.page.getByRole('button', { name: '我已准备好' }).click()
await fixture.page.getByRole('button', { name: '开始准备连接组件' }).click()
await expect(fixture.page.getByRole('button', { name: '微信已登录,验证连接' })).toBeEnabled()
await fixture.page.getByRole('button', { name: '微信已登录,验证连接' }).click()
await expect(fixture.page.getByRole('navigation', { name: '一级导航' })).toBeVisible()
} finally {
await fixture.close()
}
})
test('KEY-03 changing one key does not invalidate archive data or unrelated settings', async () => {
const fixture = await launchTestApp()
try {
@@ -188,6 +223,7 @@ test('REPORT-01 REPORT-02 generates a fixed report with non-empty local assets',
await fixture.page.getByRole('button', { name: '开始生成日报' }).click()
await expect(fixture.page.getByRole('heading', { name: '生成群聊日报' })).toBeVisible()
await fixture.page.locator('.report-source-item').filter({ hasText: '产品测试群' }).click()
await fixture.page.getByRole('button', { name: '近 7 天' }).click()
const generate = fixture.page.getByRole('button', { name: '开始生成日报' })
await expect(generate).toBeEnabled()
await generate.click()
@@ -218,6 +254,7 @@ test('REPORT-03 report failure is retryable and leaves other pages usable', asyn
await fixture.page.getByRole('button', { name: '日报' }).click()
await fixture.page.getByRole('button', { name: '开始生成日报' }).click()
await fixture.page.locator('.report-source-item').filter({ hasText: '产品测试群' }).click()
await fixture.page.getByRole('button', { name: '近 7 天' }).click()
await fixture.page.getByRole('button', { name: '开始生成日报' }).click()
await expect(fixture.page.getByText(/本地假服务错误 401/).first()).toBeVisible()
await expect(fixture.page.getByRole('button', { name: '重试' })).toBeEnabled()