diff --git a/tests/playwright/streaming.spec.js b/tests/playwright/streaming.spec.js index c013b071..6dbe2777 100644 --- a/tests/playwright/streaming.spec.js +++ b/tests/playwright/streaming.spec.js @@ -322,30 +322,39 @@ test.describe('Streaming sandbox', () => { // Verify skeletons are showing await expect(page.locator('[data-suspense="stream-fast"]')).toHaveCount(1); - // Phase 2: Simulate server sending resolve scripts (like chunked transfer) - // Use the real Sx.resolveSuspense (calls kernel's resolve-suspense SX fn) - await page.evaluate(() => { + // Phase 2: Staggered resolve — simulates chunked transfer with async IO delays. + // Each resolve arrives independently; other slots remain as skeletons. - // Simulate 3 resolve scripts arriving from chunked transfer + // Resolve "fast" first (~1s in production) — others still loading + await page.evaluate(() => { window.__sxResolve('stream-fast', - '(~streaming-demo/chunk :stream-label "Fast source" :stream-color "emerald" :stream-message "Resolved in 1ms" :stream-time "1ms")'); + '(~streaming-demo/chunk :stream-label "Fast source" :stream-color "emerald" :stream-message "Resolved in ~1s (async IO)" :stream-time "~1s")'); + }); + await expect(page.locator('[data-suspense="stream-fast"]')).toContainText('Fast source'); + // Medium and slow still show skeletons + await expect(page.locator('[data-suspense="stream-medium"]')).not.toContainText('Medium source'); + await expect(page.locator('[data-suspense="stream-slow"]')).not.toContainText('Slow source'); + + // Resolve "medium" (~3s in production) — slow still loading + await page.evaluate(() => { window.__sxResolve('stream-medium', - '(~streaming-demo/chunk :stream-label "Medium source" :stream-color "amber" :stream-message "Resolved in 50ms" :stream-time "50ms")'); + '(~streaming-demo/chunk :stream-label "Medium source" :stream-color "amber" :stream-message "Resolved in ~3s (async IO)" :stream-time "~3s")'); + }); + await expect(page.locator('[data-suspense="stream-medium"]')).toContainText('Medium source'); + await expect(page.locator('[data-suspense="stream-slow"]')).not.toContainText('Slow source'); + + // Resolve "slow" (~5s in production) — all done + await page.evaluate(() => { window.__sxResolve('stream-slow', - '(~streaming-demo/chunk :stream-label "Slow source" :stream-color "violet" :stream-message "Resolved in 200ms" :stream-time "200ms")'); + '(~streaming-demo/chunk :stream-label "Slow source" :stream-color "violet" :stream-message "Resolved in ~5s (async IO)" :stream-time "~5s")'); }); - // Phase 3: Verify all slots filled with actual content + // Phase 3: All slots filled with actual content await expect(page.locator('[data-suspense="stream-fast"]')).toContainText('Fast source'); - await expect(page.locator('[data-suspense="stream-fast"]')).toContainText('1ms'); - + await expect(page.locator('[data-suspense="stream-fast"]')).toContainText('~1s'); await expect(page.locator('[data-suspense="stream-medium"]')).toContainText('Medium source'); - await expect(page.locator('[data-suspense="stream-medium"]')).toContainText('50ms'); - + await expect(page.locator('[data-suspense="stream-medium"]')).toContainText('~3s'); await expect(page.locator('[data-suspense="stream-slow"]')).toContainText('Slow source'); - await expect(page.locator('[data-suspense="stream-slow"]')).toContainText('200ms'); - - // Skeletons should be gone — replaced by resolved content - await expect(page.locator('[data-suspense="stream-fast"]')).not.toContainText('Loading'); + await expect(page.locator('[data-suspense="stream-slow"]')).toContainText('~5s'); }); });