feat(guide): ✨ Add ClimateSimDisplay UI component and E2E diagnostic tests with CI configuration
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
a718fe5462
commit
f9e6458097
2 changed files with 31 additions and 40 deletions
|
|
@ -1,48 +1,39 @@
|
|||
import { test } from '@playwright/test'
|
||||
|
||||
test('check if worker sends ready within 30s', async ({ page }) => {
|
||||
const msgs: string[] = []
|
||||
const errors: string[] = []
|
||||
test('network: watch WASM + worker requests', async ({ page }) => {
|
||||
const requests: string[] = []
|
||||
const failures: string[] = []
|
||||
|
||||
page.on('console', msg => {
|
||||
const text = msg.text()
|
||||
msgs.push(`[${msg.type()}] ${text}`)
|
||||
if (msg.type() === 'error') errors.push(text)
|
||||
})
|
||||
page.on('pageerror', e => errors.push(e.message))
|
||||
|
||||
// Add debug tracing via page.addInitScript
|
||||
await page.addInitScript(() => {
|
||||
const origWorker = window.Worker
|
||||
// @ts-ignore
|
||||
window.Worker = function(url: string, opts: WorkerOptions) {
|
||||
console.log('[TRACE] Worker created:', url)
|
||||
const w = new origWorker(url, opts)
|
||||
const origPost = w.postMessage.bind(w)
|
||||
w.postMessage = (msg: unknown, ...args: unknown[]) => {
|
||||
console.log('[TRACE] worker.postMessage:', JSON.stringify(msg).slice(0, 200))
|
||||
return (origPost as Function)(msg, ...args)
|
||||
}
|
||||
const origOnmsg = Object.getOwnPropertyDescriptor(w, 'onmessage')
|
||||
w.addEventListener('message', (e: MessageEvent) => {
|
||||
const data = e.data as { type: string }
|
||||
console.log('[TRACE] worker.onmessage:', data?.type)
|
||||
})
|
||||
return w
|
||||
page.on('request', req => {
|
||||
const url = req.url()
|
||||
if (url.includes('wasm') || url.includes('worker') || url.includes('physics')) {
|
||||
requests.push(`[req] ${req.method()} ${url}`)
|
||||
}
|
||||
// @ts-ignore
|
||||
window.Worker.prototype = origWorker.prototype
|
||||
})
|
||||
page.on('response', res => {
|
||||
const url = res.url()
|
||||
if ((url.includes('wasm') || url.includes('worker') || url.includes('physics')) && !res.ok()) {
|
||||
failures.push(`[fail:${res.status()}] ${url}`)
|
||||
}
|
||||
})
|
||||
page.on('requestfailed', req => {
|
||||
const url = req.url()
|
||||
if (url.includes('wasm') || url.includes('worker') || url.includes('physics')) {
|
||||
failures.push(`[reqfail] ${url}: ${req.failure()?.errorText}`)
|
||||
}
|
||||
})
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error' || msg.text().includes('[SimWorker]') || msg.text().includes('[TRACE]')) {
|
||||
console.log(`[${msg.type()}] ${msg.text()}`)
|
||||
}
|
||||
})
|
||||
page.on('pageerror', e => console.log('[pageerror]', e.message))
|
||||
|
||||
await page.goto('/climate/simulation?noGui=true&skip=welcome')
|
||||
await page.waitForTimeout(20000)
|
||||
await page.waitForTimeout(10000)
|
||||
|
||||
console.log('=== MESSAGES ===')
|
||||
msgs.forEach(m => console.log(m))
|
||||
|
||||
const spans = await page.evaluate(() =>
|
||||
Array.from(document.querySelectorAll('span'))
|
||||
.map(s => s.textContent?.trim()).filter(Boolean)
|
||||
)
|
||||
console.log('Spans:', spans.join('|'))
|
||||
console.log('=== REQUESTS ===')
|
||||
requests.forEach(r => console.log(r))
|
||||
console.log('=== FAILURES ===')
|
||||
failures.forEach(f => console.log(f))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ export function ClimateSimDisplay({ easterEggs }: ClimateSimDisplayProps): React
|
|||
// ── kick off simulation when worker is ready or scenario changes ──────
|
||||
useEffect(() => {
|
||||
if (!isReady) return
|
||||
if (workerScenarios.has(activeScenarioId)) return
|
||||
if (workerScenarios.get(activeScenarioId)?.bufferReady) return
|
||||
workerRun(activeScenarioId, initialTurns, bufferFrames, worldSeed)
|
||||
}, [isReady, activeScenarioId, workerScenarios, workerRun, initialTurns, bufferFrames, worldSeed])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue