/* Browser boot test: loads the game, starts a match, screenshots it. */ 'use strict'; const { chromium } = require('/tmp/node_modules/playwright-core'); (async () => { const browser = await chromium.launch({ executablePath: '/root/.cache/ms-playwright/chromium_headless_shell-1148/chrome-linux/headless_shell', args: ['--no-sandbox', '--disable-gpu'], }); const page = await browser.newPage({ viewport: { width: 1440, height: 860 } }); const errors = []; page.on('console', m => { if (m.type() === 'error') errors.push(m.text()); }); page.on('pageerror', e => errors.push('PAGEERROR: ' + e.message)); await page.goto('http://127.0.0.1:8933/', { waitUntil: 'load' }); await page.waitForTimeout(1200); await page.screenshot({ path: '/root/dinorts/shots/01-menu.png' }); console.log('menu loaded'); // start normal difficulty await page.click('[data-diff="normal"]'); await page.waitForTimeout(2500); await page.screenshot({ path: '/root/dinorts/shots/02-start.png' }); const st1 = await page.evaluate(() => { const s = RTS.sim.state(); return { day: s.day, dinos: s.dinos.length, units: s.units.length, blds: s.buildings.length, res: { ...s.res } }; }); console.log('game state:', JSON.stringify(st1)); // select HQ by clicking near center of screen await page.mouse.click(720, 430); await page.waitForTimeout(400); await page.screenshot({ path: '/root/dinorts/shots/03-selected.png' }); // place a house via the palette (target the button by its label, not position) await page.evaluate(() => { const btns = [...document.querySelectorAll('.palbtn')]; const house = btns.find(b => b.textContent.includes('House')); house.click(); }); await page.waitForTimeout(200); // click a spot anchored to the HQ (world is randomly generated each run) for (const [dx, dy] of [[4, 1], [-4, 2], [3, -4], [-3, -4], [5, 4]]) { const pt = await page.evaluate(([dx2, dy2]) => { const hq = RTS.sim.hq(); return RTS.render.worldToScreen(hq.x + dx2, hq.y + dy2); }, [dx, dy]); await page.mouse.click(pt.x, pt.y); await page.waitForTimeout(250); const done = await page.evaluate(() => RTS.sim.state().buildings.some(b => b.defId === 'house')); if (done) break; } const st2 = await page.evaluate(() => { const s = RTS.sim.state(); return { blds: s.buildings.map(b => b.defId), gold: Math.floor(s.res.gold) }; }); console.log('after house placement:', JSON.stringify(st2)); await page.keyboard.press('Escape'); await page.keyboard.press('Escape'); // fast-forward 30s of game time at 3x await page.keyboard.press('3'); // no-op key (speed buttons are UI) — use UI button instead await page.click('#topbtns .tbtn:nth-child(3)'); // 2× await page.waitForTimeout(9000); const st3 = await page.evaluate(() => { const s = RTS.sim.state(); return { time: Math.floor(s.time), kills: s.stats.kills, dinos: s.dinos.length }; }); console.log('after fast-forward:', JSON.stringify(st3)); await page.screenshot({ path: '/root/dinorts/shots/04-later.png' }); // pause overlay (Save/Load buttons visible) await page.keyboard.press('Space'); await page.waitForTimeout(300); const pauseBtns = await page.evaluate(() => ({ save: !!document.getElementById('savebtn'), loadDisabled: document.getElementById('loadbtn') && document.getElementById('loadbtn').disabled, })); console.log('pause menu:', JSON.stringify(pauseBtns)); await page.screenshot({ path: '/root/dinorts/shots/05-paused.png' }); await page.keyboard.press('Space'); // ---- save → reload → continue from the main menu ---- const saved = await page.evaluate(() => RTS.storage.save(true) && RTS.storage.has()); console.log('saved to localStorage:', saved); if (!saved) throw new Error('save failed'); await page.reload(); await page.waitForTimeout(700); const contVisible = await page.evaluate(() => { const b = document.getElementById('continueBtn'); return b && b.style.display !== 'none'; }); if (!contVisible) throw new Error('Continue button not shown despite existing save'); await page.click('#continueBtn'); await page.waitForTimeout(600); const st4 = await page.evaluate(() => { const s = RTS.sim.state(); return { day: s.day, time: Math.floor(s.time), blds: s.buildings.length }; }); if (!(st4.time > 5)) throw new Error('loaded colony did not restore progress: ' + JSON.stringify(st4)); console.log('after continue:', JSON.stringify(st4)); console.log('console errors:', errors.length ? errors : 'none'); await browser.close(); if (errors.length) process.exit(2); console.log('BROWSER BOOT TEST PASSED ✔'); })().catch(e => { console.error('TEST CRASH:', e); process.exit(1); });