const { chromium } = require('C:/Users/phenom/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright'); const assert = require('node:assert/strict'); const base = process.env.RACE_TEST_URL || 'http://127.0.0.1:5173'; const nonce = Date.now().toString(36); async function createPlayer(browser, suffix) { const context = await browser.newContext({ viewport: { width: 1280, height: 800 } }); const page = await context.newPage(); const errors = []; page.on('pageerror', (error) => errors.push(error.message)); await page.goto(base, { waitUntil: 'domcontentloaded', timeout: 120_000 }); await page.getByLabel('Username').fill(`Race${suffix}${nonce}`.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(`Racer${suffix}`); 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 }); try { await page.locator('.main-menu-screen').waitFor(); } catch (error) { console.error((await page.locator('body').innerText()).slice(0, 2500)); throw error; } await page.getByRole('button', { name: /Dungeon Race/ }).click(); await page.locator('.dungeon-race-screen').waitFor(); assert.equal(await page.getByRole('button', { name: 'Online ranked' }).getAttribute('aria-pressed'), 'true'); return { page, context, errors }; } (async () => { const browser = await chromium.launch({ channel: 'msedge', headless: true }); const players = []; try { players.push(await createPlayer(browser, 'A')); players.push(await createPlayer(browser, 'B')); await Promise.all(players.map(({ page }) => page.getByRole('button', { name: 'Enter race queue' }).click())); await Promise.all(players.map(({ page }) => page.locator('.game-shell').waitFor({ timeout: 120_000 }))); const states = await Promise.all(players.map(async ({ page }) => page.evaluate(async () => { const { useDungeonRaceStore } = await import('/src/app/dungeonRaceStore.ts'); const race = useDungeonRaceStore.getState(); return { matchId: race.matchId, dungeonId: race.dungeonId, seed: race.seed, opponentType: race.opponent?.type, opponentName: race.opponent?.name }; }))); assert.equal(states[0].matchId, states[1].matchId); assert.equal(states[0].dungeonId, states[1].dungeonId); assert.equal(states[0].seed, states[1].seed); assert.equal(states[0].opponentType, 'human'); assert.equal(states[1].opponentType, 'human'); assert.deepEqual(players.flatMap(({ errors }) => errors), []); await Promise.all(players.map(({ context }) => context.close())); const solo = await createPlayer(browser, 'Solo'); players.push(solo); await solo.page.getByRole('button', { name: 'Enter race queue' }).click(); await solo.page.locator('.game-shell').waitFor({ timeout: 120_000 }); const fallback = await solo.page.evaluate(async () => { const { useDungeonRaceStore } = await import('/src/app/dungeonRaceStore.ts'); const race = useDungeonRaceStore.getState(); return { matchId: race.matchId, opponentType: race.opponent?.type, seats: race.opponent?.type === 'bot' ? race.opponent.roster.length : 0 }; }); assert.equal(fallback.opponentType, 'bot'); assert.equal(fallback.seats, 5); assert.deepEqual(solo.errors, []); console.log(JSON.stringify({ ok: true, states, fallback }, null, 2)); } finally { await Promise.all(players.map(({ context }) => context.close())); await browser.close(); } })().catch((error) => { console.error(error); process.exitCode = 1; });