100 lines
5.3 KiB
JavaScript
100 lines
5.3 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 directory = path.resolve('playtest-artifacts', 'dungeon-simulation');
|
||
fs.mkdirSync(directory, { recursive: true });
|
||
const databaseDirectory = path.join(directory, 'test-database');
|
||
fs.rmSync(databaseDirectory, { recursive: true, force: true });
|
||
|
||
(async () => {
|
||
const { createGameServer } = await import('../server/server.mjs');
|
||
const runtime = createGameServer({
|
||
dataDir: databaseDirectory,
|
||
enableShelvedModes: false,
|
||
});
|
||
await new Promise((resolve) => runtime.server.listen(4189, '127.0.0.1', resolve));
|
||
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
||
const context = await browser.newContext({ viewport: { width: 1600, height: 1000 }, acceptDownloads: true });
|
||
const page = await context.newPage();
|
||
page.setDefaultTimeout(90000);
|
||
const errors = [];
|
||
page.on('pageerror', (error) => errors.push(error.message));
|
||
const capture = (name) => page.screenshot({ path: path.join(directory, `${name}.png`), fullPage: true });
|
||
|
||
try {
|
||
await page.goto('http://127.0.0.1:4189', { waitUntil: 'domcontentloaded' });
|
||
await page.getByLabel('Username').fill('Phenom');
|
||
await page.getByLabel('Password').fill('dungeon-route-admin');
|
||
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('Routewatcher');
|
||
await page.getByRole('button', { name: /Create character/ }).click();
|
||
await page.getByRole('button', { name: /Continue/ }).first().click();
|
||
await page.getByRole('button', { name: /GM Tools/ }).click();
|
||
await page.getByRole('heading', { name: 'Dungeon route simulations' }).waitFor();
|
||
await capture('01-gm-route-launch');
|
||
|
||
const routeSelects = page.locator('.dungeon-sim-admin__catalog select');
|
||
await routeSelects.nth(0).selectOption('wailing-caverns');
|
||
await routeSelects.nth(1).selectOption('navigation-only');
|
||
await page.locator('.dungeon-sim-admin__catalog input').fill('browser-smoke-fixed-seed');
|
||
await page.getByRole('button', { name: 'Launch spectate mode' }).click();
|
||
await page.locator('canvas').waitFor();
|
||
await page.getByLabel('Dungeon simulation controls').waitFor();
|
||
await page.waitForTimeout(6000);
|
||
await capture('02-live-navigation-simulation');
|
||
|
||
await page.getByRole('button', { name: 'Pause' }).click();
|
||
const pausedTime = await page.locator('.dungeon-sim-hud__header > time').innerText();
|
||
await page.waitForTimeout(700);
|
||
assert.equal(await page.locator('.dungeon-sim-hud__header > time').innerText(), pausedTime, 'pause freezes simulation time');
|
||
await page.getByRole('button', { name: 'Step' }).click();
|
||
await page.getByRole('button', { name: 'Step' }).click();
|
||
await page.waitForTimeout(200);
|
||
assert.notEqual(await page.locator('.dungeon-sim-hud__header > time').innerText(), pausedTime, 'single-step advances simulation time');
|
||
await page.getByRole('button', { name: 'Follow camera' }).click();
|
||
await page.getByRole('button', { name: 'Free-fly camera' }).waitFor();
|
||
await capture('03-paused-free-fly');
|
||
|
||
await page.getByRole('button', { name: '4×' }).click();
|
||
await page.getByRole('button', { name: 'Play' }).click();
|
||
await page.waitForTimeout(1200);
|
||
await page.getByRole('button', { name: 'Stop & save' }).click();
|
||
await page.getByRole('button', { name: 'Return to GM Tools' }).waitFor();
|
||
await capture('04-finished-report');
|
||
await page.getByRole('button', { name: 'Return to GM Tools' }).click();
|
||
await page.getByRole('heading', { name: 'Dungeon route simulations' }).waitFor();
|
||
await page.locator('.dungeon-sim-admin__catalog select').nth(0).selectOption('wailing-caverns');
|
||
await page.getByText(/1 runs for this route/).waitFor();
|
||
await capture('05-saved-replay');
|
||
|
||
await page.getByRole('button', { name: 'Watch' }).first().click();
|
||
await page.getByText('Recorded replay').waitFor();
|
||
await page.getByLabel('Replay position').waitFor();
|
||
await page.waitForTimeout(6000);
|
||
await page.getByRole('button', { name: 'Play' }).click();
|
||
await page.waitForTimeout(800);
|
||
await capture('06-replay-controls');
|
||
await page.getByRole('button', { name: 'Pause' }).click();
|
||
const pausedReplayTime = await page.locator('.dungeon-sim-hud__header > time').innerText();
|
||
await page.waitForTimeout(500);
|
||
assert.equal(await page.locator('.dungeon-sim-hud__header > time').innerText(), pausedReplayTime, 'replay pause freezes playback time');
|
||
await page.getByRole('button', { name: '4×' }).click();
|
||
await page.getByRole('button', { name: 'Play' }).click();
|
||
await page.waitForTimeout(600);
|
||
await capture('07-replay-4x');
|
||
|
||
assert.deepEqual(errors, [], `No browser page errors: ${errors.join('; ')}`);
|
||
console.log('Dungeon simulation browser smoke test passed.');
|
||
} finally {
|
||
await browser.close();
|
||
await new Promise((resolve) => runtime.server.close(resolve));
|
||
}
|
||
})().catch((error) => {
|
||
console.error(error);
|
||
process.exitCode = 1;
|
||
});
|