const { chromium } = require('C:/Users/phenom/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright'); const fs = require('node:fs'); const path = require('node:path'); const out = path.resolve('playtest-artifacts/pause-memory'); fs.mkdirSync(out, { recursive: true }); async function sample(page, cdp, label) { await cdp.send('HeapProfiler.collectGarbage'); const metrics = await cdp.send('Performance.getMetrics'); const values = Object.fromEntries(metrics.metrics.map(({ name, value }) => [name, value])); const scene = await page.locator('.scene-shell').evaluate((element) => ({ frameLoop: element.dataset.frameLoop, performance: document.documentElement.dataset.gamePerformance ?? null, })); return { label, heapMiB: Math.round(values.JSHeapUsedSize / 1048576), nodes: values.Nodes, documents: values.Documents, ...scene }; } (async () => { const { createGameServer } = await import('../server/server.mjs'); const runtime = createGameServer({ dataDir: path.join(out, 'test-database'), enableShelvedModes: false }); await new Promise((resolve) => runtime.server.listen(4190, '127.0.0.1', resolve)); const browser = await chromium.launch({ channel: 'msedge', headless: true }); const page = await browser.newPage({ viewport: { width: 1280, height: 800 } }); page.setDefaultTimeout(45000); const cdp = await page.context().newCDPSession(page); await cdp.send('Performance.enable'); await cdp.send('HeapProfiler.enable'); const errors = []; page.on('pageerror', (error) => errors.push(error.message)); try { console.log('Opening game'); await page.goto(process.env.PAUSE_TEST_URL || 'http://127.0.0.1:4190', { waitUntil: 'domcontentloaded' }); console.log('Choosing offline play'); await page.getByRole('button', { name: /Play offline/ }).click(); console.log('Creating character'); await page.getByRole('button', { name: /Create character/ }).click(); await page.getByRole('button', { name: /Customize & name/ }).click(); await page.getByLabel('Character name').fill('Memorytester'); await page.getByRole('button', { name: /Create character/ }).click(); await page.getByRole('button', { name: /Continue|Enter world/ }).first().evaluate((button) => button.click()); console.log('Entering adventure menu'); await page.locator('.main-menu-screen').waitFor(); console.log('Choosing bundled Wailing Caverns'); await page.getByRole('button', { name: /^Dungeons/ }).click(); await page.locator('.dungeon-select-row').filter({ hasText: /Wailing Caverns/i }).first().click(); await page.getByRole('button', { name: 'Choose role' }).click(); await page.locator('.dungeon-role-option--healer').click(); console.log('Waiting for scene'); await page.locator('.scene-shell').waitFor(); await page.locator('.loading-screen').waitFor({ state: 'hidden', timeout: 120000 }); await page.locator('.dungeon-boss-intro').waitFor({ state: 'hidden', timeout: 120000 }); await page.waitForTimeout(2000); await page.screenshot({ path: path.join(out, 'before-pause.png') }); await page.keyboard.press('Escape'); console.log('Waiting for pause'); await page.getByRole('dialog', { name: 'Paused' }).waitFor(); await page.screenshot({ path: path.join(out, 'paused.png') }); const samples = [await sample(page, cdp, 'paused-start')]; console.log(JSON.stringify(samples[0])); for (const seconds of [15, 30, 60]) { await page.waitForTimeout((seconds - (samples.length === 1 ? 0 : [0, 15, 30][samples.length - 1])) * 1000); samples.push(await sample(page, cdp, `paused-${seconds}s`)); console.log(JSON.stringify(samples.at(-1))); } fs.writeFileSync(path.join(out, 'results.json'), `${JSON.stringify({ samples, errors }, null, 2)}\n`); console.log(JSON.stringify({ samples, errors }, null, 2)); } catch (error) { await page.screenshot({ path: path.join(out, 'failure.png') }); console.error((await page.locator('body').innerText()).slice(-2000)); console.error(errors); throw error; } finally { await browser.close(); await new Promise((resolve) => runtime.server.close(resolve)); } })();