Files
ark-stronghold-protocol/test/render/battle-perf.browser.test.js
T
Cloudnyco e8ba091298 feedback7 G-TOOLS: add the battle performance bench under public/dev (PR #198 by @Cloudnyco)
Applied as-is. Captured real battles live in public/dev/perf (including the round-13 联防 on the wide round battlefield), with a browser speed page and a headless benchmark. public/dev stays out of the package. The Chrome benchmark was not run. The numbers in the original pull request are from 0.1.4 and are not quoted here.

Tests: node --test test/perfbench.test.js test/render/battle-perf.browser.test.js — 13 pass, 0 fail; the Chrome suite skipped (RENDER_E2E unset).
2026-10-08 18:48:42 +08:00

62 lines
3.3 KiB
JavaScript

// test/render/battle-perf.browser.test.js — the battle perf page (public/dev/battle-perf.html) in headless Chrome: every
// committed spec starts, the battle runner steps the sim and the field view draws it, with a clean console; the sample
// hook tools/perfbench.mjs reads returns its figures.
//
// Opt-in (starts Chrome, needs the downloaded assets): RENDER_E2E=1 node --test test/render/battle-perf.browser.test.js
// Chrome path: $CHROME_PATH or the platform default of tools/perfbench.mjs.
import { test, describe, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { existsSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { gpuArgs } from '../../tools/perfbench.mjs';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
const CHROME = process.env.CHROME_PATH || {
win32: 'C:/Program Files/Google/Chrome/Application/chrome.exe',
darwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
linux: '/usr/bin/google-chrome',
}[process.platform];
const enabled = process.env.RENDER_E2E === '1' && !!CHROME && existsSync(CHROME) && existsSync(path.join(ROOT, 'public/assets'));
const skip = enabled ? false : 'set RENDER_E2E=1 (needs Chrome and the downloaded assets)';
const index = JSON.parse(readFileSync(path.join(ROOT, 'public/dev/perf/index.json'), 'utf8'));
describe('battle perf page in headless Chrome', { skip }, () => {
let srv, browser;
before(async () => {
const puppeteer = (await import('puppeteer-core')).default;
const { startServer } = await import('../../server/index.js');
srv = await startServer({ port: 0, host: '127.0.0.1', quiet: true });
browser = await puppeteer.launch({ executablePath: CHROME, headless: true, args: gpuArgs() });
});
after(async () => {
await browser?.close();
await srv?.close();
});
for (const s of index) {
test(`${s.name}: the battle runs and draws, the sample hook reports`, async () => {
const page = await browser.newPage();
const problems = [];
page.on('pageerror', (e) => problems.push(`pageerror: ${e.message}`));
page.on('console', (m) => { if (m.type() === 'error') problems.push(`console: ${m.text()}`); });
page.on('response', (r) => { if (r.status() >= 400) problems.push(`HTTP ${r.status()} ${r.url()}`); });
await page.setViewport({ width: 844, height: 390, deviceScaleFactor: 2 });
await page.goto(`http://127.0.0.1:${srv.port}/dev/battle-perf.html?spec=${s.name}`);
await page.waitForFunction('window.__perf && (window.__perf.ready || window.__perf.error)', { timeout: 60000 });
assert.equal(await page.evaluate(() => window.__perf.error), null);
await new Promise((r) => setTimeout(r, 3000));
const r = await page.evaluate(() => window.__perf.sample(2000));
const short = await page.evaluate(() => window.__perf.sample(0)); // still a full frame time, not 0 / 0
await page.close();
assert.deepEqual(problems, []);
assert.ok(r.fps > 10, `fps ${r.fps}`);
assert.ok(r.ticks > 60, `sim ticks ${r.ticks}`);
assert.ok(r.units > 0, `units ${r.units}`);
assert.ok(Number.isFinite(r.p95) && r.p95 > 0);
assert.ok(Number.isFinite(short.fps) && short.fps > 0 && short.p95 > 0, `sample(0): ${JSON.stringify(short)}`);
});
}
});