const { chromium } = require('C:/Users/phenom/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const base = process.env.RACE_TEST_URL || 'http://127.0.0.1:5173'; const out = path.resolve('playtest-artifacts/dungeon-race-exit'); fs.mkdirSync(out, { recursive: true }); async function raceState(page) { return page.evaluate(async () => { const { useDungeonRaceStore } = await import('/src/app/dungeonRaceStore.ts'); const race = useDungeonRaceStore.getState(); return { mode: race.mode, status: race.status, inGame: race.inGame, matchId: race.matchId, opponentType: race.opponent?.type, error: race.error }; }); } async function leaveGame(page) { await page.evaluate(async () => { const { useGameStore } = await import('/src/game/store.ts'); useGameStore.getState().openOverlay('pause'); }); await page.getByRole('dialog', { name: 'Paused' }).getByRole('button', { name: 'Main menu' }).click(); await page.locator('.main-menu-screen').waitFor(); } (async () => { const browser = await chromium.launch({ channel: 'msedge', headless: true }); const page = await browser.newPage({ viewport: { width: 1280, height: 800 } }); const errors = []; page.on('pageerror', (error) => errors.push(error.stack || error.message)); try { await page.goto(base, { waitUntil: 'domcontentloaded', timeout: 120_000 }); await page.getByLabel('Username').fill(`RaceExit${Date.now().toString(36)}`.slice(0, 20)); await page.getByLabel('Password').fill('raceTestPassword123'); await page.getByRole('button', { name: /Create account/ }).click(); await page.getByRole('button', { name: /Create character/ }).click(); await page.getByRole('button', { name: /Customize & name/ }).click(); await page.getByLabel('Character name').fill('ExitTester'); await page.getByRole('button', { name: /Create character/ }).click(); await page.getByRole('button', { name: /Continue|Enter world/ }).first().click({ force: true }); await page.getByRole('button', { name: 'Continue', exact: true }).click({ force: true }); await page.locator('.main-menu-screen').waitFor(); await page.getByRole('button', { name: /Dungeon Race/ }).click(); await page.locator('.dungeon-race-screen__setup select').first() .selectOption('bite-sized-stormwind-stockade'); await page.getByRole('button', { name: 'Enter race queue' }).click(); await page.locator('.dungeon-race-hud').waitFor({ timeout: 120_000 }); await page.locator('.loading-screen').waitFor({ state: 'hidden', timeout: 120_000 }); await page.locator('.dungeon-boss-intro').waitFor({ state: 'hidden', timeout: 120_000 }); await page.locator('.dungeon-race-wait').waitFor({ state: 'hidden', timeout: 120_000 }); await page.locator('.dungeon-race-countdown').waitFor({ state: 'hidden', timeout: 120_000 }); const first = await raceState(page); assert.equal(first.opponentType, 'bot'); await page.screenshot({ path: path.join(out, '01-ranked-race.png') }); await leaveGame(page); const afterExit = await raceState(page); assert.deepEqual(afterExit, { mode: null, status: 'idle', inGame: false, matchId: null, opponentType: undefined, error: '' }); await page.screenshot({ path: path.join(out, '02-main-menu-after-exit.png') }); await page.locator('.main-menu-mode strong').getByText('Dungeons', { exact: true }).click(); await page.locator('.dungeon-category-tab').filter({ hasText: 'Bite-Sized' }).click(); await page.locator('.dungeon-select-row').filter({ hasText: 'Cellblock Rush' }).click(); await page.locator('.dungeon-select-enter').click(); await page.locator('.dungeon-role-option').first().click(); await page.locator('.game-shell').waitFor({ timeout: 120_000 }); await page.locator('.loading-screen').waitFor({ state: 'hidden', timeout: 120_000 }); assert.equal(await page.locator('.dungeon-race-hud').count(), 0); await page.screenshot({ path: path.join(out, '03-ordinary-dungeon-no-race-hud.png') }); await leaveGame(page); await page.getByRole('button', { name: /Dungeon Race/ }).click(); await page.locator('.dungeon-race-screen__setup select').first() .selectOption('bite-sized-stormwind-stockade'); await page.getByRole('button', { name: 'Enter race queue' }).click(); await page.locator('.dungeon-race-hud').waitFor({ timeout: 120_000 }); const second = await raceState(page); assert.equal(second.mode, 'online'); assert.equal(second.inGame, true); assert.ok(second.matchId); assert.notEqual(second.matchId, first.matchId); assert.equal(second.error, ''); assert.deepEqual(errors, []); console.log(JSON.stringify({ ok: true, first, afterExit, second, screenshots: out }, null, 2)); } catch (error) { await page.screenshot({ path: path.join(out, 'failure.png') }); console.error((await page.locator('body').innerText()).slice(0, 5000)); throw error; } finally { await browser.close(); } })().catch((error) => { console.error(error); process.exitCode = 1; });