72 lines
5.0 KiB
JavaScript
72 lines
5.0 KiB
JavaScript
const { chromium } = require('C:/Users/phenom/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const { DEFAULT_TEST_DUNGEON_ID } = require('./playtest-defaults.cjs');
|
|
|
|
// Start the review server with node scripts/dungeon-pipeline/serve-environment-preview.mjs.
|
|
// Captures are isolated asset QA, not movement or encounter proof.
|
|
const output = path.resolve('artifacts/playtest/wow-environment-quality');
|
|
const resume = process.argv.includes('--resume');
|
|
const requested = process.argv.slice(2).filter((entry) => entry !== '--resume');
|
|
const baseUrl = process.env.WOW_ENVIRONMENT_REVIEW_URL || 'http://127.0.0.1:4208';
|
|
fs.mkdirSync(output, { recursive: true });
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
const resultsFile = path.join(output, 'results.json');
|
|
const results = (resume || requested.length) && fs.existsSync(resultsFile)
|
|
? JSON.parse(fs.readFileSync(resultsFile, 'utf8')).results.filter((entry) => !requested.includes(entry.id)) : [];
|
|
try {
|
|
const discovery = await browser.newPage();
|
|
discovery.on('pageerror', (error) => console.error(`Discovery: ${error.stack}`));
|
|
await discovery.goto(`${baseUrl}/scripts/dungeon-pipeline/environment-preview.html?dungeon=${DEFAULT_TEST_DUNGEON_ID}`, { waitUntil: 'domcontentloaded', timeout: 180_000 });
|
|
await discovery.waitForFunction(() => window.wowEnvironmentReview?.ready, null, { timeout: 60_000 });
|
|
const catalog = await discovery.evaluate(() => window.wowEnvironmentReview.catalog);
|
|
await discovery.close();
|
|
const ids = requested.length ? requested : [DEFAULT_TEST_DUNGEON_ID, ...catalog.map((entry) => entry.id)];
|
|
for (const id of ids) {
|
|
if (resume && results.some((entry) => entry.id === id && entry.status === 'loaded')) continue;
|
|
const previous = results.findIndex((entry) => entry.id === id);
|
|
if (previous >= 0) results.splice(previous, 1);
|
|
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));
|
|
page.on('console', (message) => { if (message.type() === 'error') errors.push(message.text()); });
|
|
try {
|
|
await page.goto(`${baseUrl}/scripts/dungeon-pipeline/environment-preview.html?dungeon=${encodeURIComponent(id)}`, { waitUntil: 'domcontentloaded', timeout: 180_000 });
|
|
await page.waitForFunction(() => window.wowEnvironmentReview?.ready, null, { timeout: 180_000 });
|
|
const data = await page.evaluate(() => ({ viewpoints: window.wowEnvironmentReview.viewpoints, presentation: window.wowEnvironmentReview.presentation }));
|
|
await page.waitForTimeout(300);
|
|
await page.screenshot({ path: path.join(output, `${id}-standard.png`) });
|
|
const standard = await page.evaluate(() => window.wowEnvironmentReview.diagnostics());
|
|
await page.evaluate(() => window.wowEnvironmentReview.setQuality('high'));
|
|
const views = [...new Set([0, Math.floor((data.viewpoints.length - 1) / 2), data.viewpoints.length - 1])];
|
|
for (const viewpoint of views) {
|
|
await page.evaluate((value) => window.wowEnvironmentReview.view(value), viewpoint);
|
|
await page.waitForTimeout(300);
|
|
await page.screenshot({ path: path.join(output, `${id}-high-view-${viewpoint}.png`) });
|
|
}
|
|
await page.evaluate(() => window.wowEnvironmentReview.view(0, Math.PI));
|
|
await page.waitForTimeout(300);
|
|
await page.screenshot({ path: path.join(output, `${id}-entrance-reverse.png`) });
|
|
const high = await page.evaluate(() => window.wowEnvironmentReview.diagnostics());
|
|
if (high.lightTarget.some((value, index) => Math.abs(value - high.camera[index]) > 0.00001)) errors.push('High light target does not track the camera');
|
|
if (high.textures.some((texture) => texture.anisotropy !== Math.min(16, high.maxAnisotropy))) errors.push('High texture filtering was not applied');
|
|
results.push({ id, status: errors.length ? 'error' : 'loaded', errors, standard, high, ...data });
|
|
console.log(`${id}: ${errors.length ? 'ERROR' : 'loaded'}; ${high.textures.length} textures; ${high.casters} High casters`);
|
|
} catch (error) {
|
|
results.push({ id, status: 'error', errors: [...errors, error.message] });
|
|
await page.screenshot({ path: path.join(output, `${id}-failure.png`) }).catch(() => {});
|
|
console.error(`${id}: ${error.message}`);
|
|
} finally {
|
|
await context.close();
|
|
fs.writeFileSync(path.join(output, 'results.json'), `${JSON.stringify({ scope: 'isolated shipping asset review: entrance Standard/High, midpoint/final boss-area High, reverse entrance; no traversal or combat certification', results }, null, 2)}\n`);
|
|
}
|
|
}
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
if (results.some((entry) => entry.status === 'error')) process.exitCode = 1;
|
|
})().catch((error) => { console.error(error); process.exitCode = 1; });
|