89 lines
4.9 KiB
JavaScript
89 lines
4.9 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 id = process.argv[2];
|
|
if (!id || !/^[a-z0-9-]+$/.test(id)) throw new Error('Provide a dungeon ID for this targeted asset review.');
|
|
function option(name) {
|
|
const index = process.argv.indexOf(name);
|
|
if (index < 0) return null;
|
|
if (!process.argv[index + 1]) throw new Error(`${name} requires a value.`);
|
|
return process.argv[index + 1];
|
|
}
|
|
const override = option('--visual-override');
|
|
const hotspotsFile = option('--hotspots');
|
|
const runtimePreparation = process.argv.includes('--runtime-preparation');
|
|
const sampleMs = Number(option('--sample-ms') || 0);
|
|
if (!Number.isFinite(sampleMs) || sampleMs < 0 || sampleMs > 10_000) {
|
|
throw new Error('--sample-ms must be between 0 and 10000.');
|
|
}
|
|
const label = override ? path.basename(override, '.glb') : 'shipping';
|
|
const output = path.resolve(option('--output-dir')
|
|
|| `artifacts/playtest/wow-environment-quality/continuation/${id}-${label}${runtimePreparation ? '-runtime-prepared' : ''}`);
|
|
const hotspots = hotspotsFile ? JSON.parse(fs.readFileSync(hotspotsFile, 'utf8')) : [];
|
|
fs.mkdirSync(output, { recursive: true });
|
|
|
|
(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.message));
|
|
const params = new URLSearchParams({ dungeon: id });
|
|
if (override) params.set('visualOverride', override);
|
|
if (runtimePreparation) params.set('runtimePreparation', '1');
|
|
const baseUrl = process.env.WOW_ENVIRONMENT_REVIEW_URL || 'http://127.0.0.1:4208';
|
|
try {
|
|
await page.goto(`${baseUrl}/scripts/dungeon-pipeline/environment-preview.html?${params}`, {
|
|
waitUntil: 'domcontentloaded', timeout: 180_000,
|
|
});
|
|
await page.waitForFunction(() => window.wowEnvironmentReview?.ready, null, { timeout: 180_000 });
|
|
if (runtimePreparation && !(await page.evaluate(() => window.wowEnvironmentReview.diagnostics().runtimePreparation === true))) {
|
|
throw new Error('The preview renderer is stale; restart the preview server before runtime-prepared checks.');
|
|
}
|
|
await page.evaluate(() => window.wowEnvironmentReview.setQuality('high'));
|
|
const ground = await page.evaluate(() => window.wowEnvironmentReview.groundSamples());
|
|
const viewpoints = await page.evaluate(() => window.wowEnvironmentReview.viewpoints);
|
|
const captures = [];
|
|
async function diagnostics() {
|
|
if (sampleMs) {
|
|
await page.evaluate(() => window.wowEnvironmentReview.resetFrameSample());
|
|
await page.waitForTimeout(sampleMs);
|
|
}
|
|
return page.evaluate((sampled) => ({ ...window.wowEnvironmentReview.diagnostics(),
|
|
...(sampled ? { frameSample: window.wowEnvironmentReview.frameSample() } : {}) }), Boolean(sampleMs));
|
|
}
|
|
const indices = [...new Set([0, Math.floor((viewpoints.length - 1) / 2), viewpoints.length - 1])];
|
|
for (const index of indices) {
|
|
for (const [heading, yaw] of [['forward', 0], ['side', Math.PI / 2], ['reverse', Math.PI]]) {
|
|
await page.evaluate(({ index, yaw }) => window.wowEnvironmentReview.view(index, yaw), { index, yaw });
|
|
await page.waitForTimeout(500);
|
|
const file = `view-${index}-${heading}.png`;
|
|
await page.screenshot({ path: path.join(output, file) });
|
|
captures.push({ name: viewpoints[index].name, heading, file, diagnostics: await diagnostics() });
|
|
}
|
|
}
|
|
for (const [index, hotspot] of hotspots.entries()) {
|
|
if (!Array.isArray(hotspot.eye) || !Array.isArray(hotspot.target)
|
|
|| [...hotspot.eye, ...hotspot.target].length !== 6
|
|
|| ![...hotspot.eye, ...hotspot.target].every(Number.isFinite)) {
|
|
throw new Error(`Hotspot ${index} requires finite eye and target triples.`);
|
|
}
|
|
await page.evaluate(({ eye, target }) => window.wowEnvironmentReview.setCamera(eye, target), hotspot);
|
|
await page.waitForTimeout(500);
|
|
const file = `hotspot-${index}.png`;
|
|
await page.screenshot({ path: path.join(output, file) });
|
|
captures.push({ ...hotspot, file, diagnostics: await diagnostics() });
|
|
}
|
|
const result = { scope: 'targeted isolated asset review; no gameplay certification', id, override,
|
|
runtimePreparation, sampleMs, errors, ground, captures };
|
|
fs.writeFileSync(path.join(output, 'results.json'), `${JSON.stringify(result, null, 2)}\n`);
|
|
if (errors.length) throw new Error(errors.join('\n'));
|
|
console.log(JSON.stringify({ id, override, output, captures: captures.length, errors }));
|
|
} catch (error) {
|
|
await page.screenshot({ path: path.join(output, 'failure.png') }).catch(() => {});
|
|
throw error;
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
})().catch((error) => { console.error(error); process.exitCode = 1; });
|