Files
healer-man/scripts/playtest-dungeon-race-exit.cjs
2026-09-26 18:57:44 -04:00

95 lines
5.1 KiB
JavaScript

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; });