test(web): assembled session-log download e2e and refreshed golden
The navigation-panes replay scenario clicks the trajectory toolbar export button and asserts the real host-streamed download: filename, a single session.jsonl entry, and byte-verbatim seed content. The toolbar golden refreshes for the localized export button.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
"playwright": "^1.49.0",
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^6.0.0",
|
||||
"vitest": "^4.1.8"
|
||||
"vitest": "^4.1.8",
|
||||
"fflate": "^0.8.2"
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { fileURLToPath } from 'node:url'
|
||||
import { join } from 'node:path'
|
||||
import type { Browser, Page, Response } from 'playwright'
|
||||
import { chromium } from 'playwright'
|
||||
import { strFromU8, unzipSync } from 'fflate'
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, onTestFailed } from 'vitest'
|
||||
import { parseSessionLog } from '@deepseek-ai/dsh-llm-replay'
|
||||
import type { SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
@@ -274,6 +275,23 @@ describe('web e2e: navigation & panes over a rich seeded session', () => {
|
||||
await details.getByRole('button', { name: 'Close details' }).click()
|
||||
}, 60_000)
|
||||
|
||||
it.skipIf(MODE === 'record')('downloads the session-log ZIP from the trajectory toolbar', async () => {
|
||||
onTestFailed(() => saveFailureShot(page, 'web-e2e-navigation-export'))
|
||||
await ensureSeedOpen(page)
|
||||
await page.getByRole('tab', { name: 'Trajectory' }).click()
|
||||
const downloadPromise = page.waitForEvent('download', { timeout: 30_000 })
|
||||
await page.getByRole('button', { name: 'Export session log' }).click()
|
||||
const download = await downloadPromise
|
||||
expect(download.suggestedFilename()).toMatch(/^dsh-session-.+\.zip$/)
|
||||
// The real host streamed the ZIP; its root entry is the persisted log
|
||||
// text verbatim (the assembled seam: real route, real persistence read).
|
||||
const files = unzipSync(await readFile(await download.path()))
|
||||
expect(Object.keys(files)).toEqual(['session.jsonl'])
|
||||
const content = strFromU8(files['session.jsonl'] as Uint8Array)
|
||||
expect(content.split('\n')[0]).toContain(SEED_ID)
|
||||
expect(content).toContain('FIRST_DONE')
|
||||
}, 60_000)
|
||||
|
||||
it.skipIf(MODE === 'record')('focuses the ledger by dragging an overview interval', async () => {
|
||||
onTestFailed(() => saveFailureShot(page, 'web-e2e-navigation-timeline'))
|
||||
await ensureSeedOpen(page)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
- button "Use actual duration": Duration
|
||||
- button "Collapse turns": Turns
|
||||
- button "Collapse calls": Calls
|
||||
- button "导出会话日志": 导出
|
||||
- button "Export session log": Export
|
||||
- img
|
||||
- searchbox "Search trajectory"
|
||||
- region "Trajectory timeline":
|
||||
|
||||
Generated
+3
@@ -364,6 +364,9 @@ importers:
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.0.0
|
||||
version: 4.7.0(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
|
||||
fflate:
|
||||
specifier: ^0.8.2
|
||||
version: 0.8.3
|
||||
playwright:
|
||||
specifier: ^1.49.0
|
||||
version: 1.61.1
|
||||
|
||||
Reference in New Issue
Block a user