73 lines
4.3 KiB
JavaScript
73 lines
4.3 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const assert = require('assert');
|
|
const { chromium } = require('playwright');
|
|
|
|
const root = path.resolve(__dirname, '..');
|
|
const level = JSON.parse(fs.readFileSync(path.join(root, 'assets/resources/levels/custom-origin-003.json')));
|
|
const solution = level.solution_lanes;
|
|
const outDir = path.join(root, 'artifacts');
|
|
fs.mkdirSync(outDir, { recursive: true });
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ channel: 'chrome', headless: true });
|
|
const page = await browser.newPage({ viewport: { width: 430, height: 932 }, deviceScaleFactor: 1 });
|
|
page.on('console', message => {
|
|
if (message.type() === 'error') console.error('browser:', message.text());
|
|
});
|
|
await page.goto(`http://127.0.0.1:8765/?version=pass29&custom=1&r=${Date.now()}`, { waitUntil: 'networkidle' });
|
|
await page.waitForFunction(() => globalThis.Laya?.stage, null, { timeout: 15000 });
|
|
await page.evaluate(() => {
|
|
const visit = node => {
|
|
for (const component of node._components || []) {
|
|
if (Array.isArray(component.queues) && typeof component.selectLane === 'function') globalThis.g = component;
|
|
}
|
|
for (const child of node._children || []) visit(child);
|
|
};
|
|
visit(Laya.stage);
|
|
});
|
|
await page.waitForFunction(() => globalThis.g && g.currentResource === 'custom-origin-003' && !g.busy, null, { timeout: 15000 });
|
|
const initial = await page.evaluate(() => ({
|
|
resource: g.currentResource,
|
|
dimensions: [g.sourceBoardSize.rows, g.sourceBoardSize.cols],
|
|
total: g.total,
|
|
lanes: g.queues.length,
|
|
cars: g.queues.reduce((sum, lane) => sum + lane.length, 0),
|
|
slots: g.slotCount
|
|
}));
|
|
assert.deepStrictEqual(initial, { resource: 'custom-origin-003', dimensions: [48, 38], total: 1824, lanes: 5, cars: 72, slots: 5 });
|
|
await page.screenshot({ path: path.join(outDir, 'custom-level-003-start.png'), fullPage: true });
|
|
|
|
await page.evaluate(() => { Laya.timer.scale = 20; });
|
|
for (let step = 0; step < solution.length; step++) {
|
|
const lane = solution[step];
|
|
const before = await page.evaluate(index => g.queues[index].length, lane);
|
|
assert(before > 0, `step ${step + 1}: lane ${lane} is empty`);
|
|
await page.evaluate(index => g.selectLane(index), lane);
|
|
await page.waitForFunction(() => g.activeMoves === 0, null, { timeout: 10000 });
|
|
const state = await page.evaluate(() => ({ finished: g.levelFinished, modal: Boolean(g.modal), cleared: g.cleared, occupied: g.occupiedSlotCount() }));
|
|
if (state.modal && !state.finished) throw new Error(`unexpected failure after step ${step + 1}: ${JSON.stringify(state)}`);
|
|
}
|
|
|
|
await page.waitForFunction(() => g.levelFinished && g.cleared === g.total, null, { timeout: 10000 });
|
|
const final = await page.evaluate(() => ({ finished: g.levelFinished, cleared: g.cleared, total: g.total, carsLeft: g.queues.reduce((sum, lane) => sum + lane.length, 0), parked: g.parked.length }));
|
|
assert.deepStrictEqual(final, { finished: true, cleared: 1824, total: 1824, carsLeft: 0, parked: 0 });
|
|
await page.screenshot({ path: path.join(outDir, 'custom-level-003-complete.png'), fullPage: true });
|
|
|
|
await page.evaluate(() => g.loadLevel(0));
|
|
await page.waitForFunction(() => g.currentResource === 'custom-origin-003' && !g.busy && !g.modal && g.cleared === 0, null, { timeout: 15000 });
|
|
await page.evaluate(() => { Laya.timer.scale = 20; });
|
|
for (const lane of level.failure_probe_lanes) {
|
|
await page.evaluate(index => g.selectLane(index), lane);
|
|
await page.waitForFunction(() => g.activeMoves === 0, null, { timeout: 10000 });
|
|
}
|
|
const wrongPath = await page.evaluate(() => ({ finished: g.levelFinished, modal: Boolean(g.modal), cleared: g.cleared, occupied: g.occupiedSlotCount() }));
|
|
assert.deepStrictEqual(wrongPath, { finished: false, modal: true, cleared: 0, occupied: 5 });
|
|
await page.screenshot({ path: path.join(outDir, 'custom-level-003-fail.png'), fullPage: true });
|
|
console.log(JSON.stringify({ initial, style: level.graphic_style.id, orderAlgorithm: level.vehicle_order_algorithm.id, seed: level.vehicle_order_algorithm.seed, final, wrongPath, routeSteps: solution.length, screenshots: ['artifacts/custom-level-003-start.png', 'artifacts/custom-level-003-complete.png', 'artifacts/custom-level-003-fail.png'] }));
|
|
await browser.close();
|
|
})().catch(error => {
|
|
console.error(error.stack || error);
|
|
process.exitCode = 1;
|
|
});
|