#!/usr/bin/env node /* Real-browser repro: loads the game in headless Chromium, captures console errors, and performs TRUE hit-tested clicks on the title menu buttons. */ const { chromium } = require('/app/node_modules/.pnpm/playwright@1.61.1/node_modules/playwright'); (async () => { const browser = await chromium.launch({ executablePath: '/root/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome', args: ['--no-sandbox'] }); const page = await browser.newPage({ viewport: { width: 1280, height: 800 } }); const logs = []; page.on('console', m => logs.push(`[console.${m.type()}] ${m.text()}`)); page.on('pageerror', e => logs.push(`[PAGEERROR] ${e.message}`)); await page.goto(process.argv[2] || 'http://127.0.0.1:8914/wuxia.html', { waitUntil: 'load' }); await page.waitForTimeout(1200); // What's at the center of the New Journey button? const probe = await page.evaluate(() => { const btns = [...document.querySelectorAll('.title-menu .btn')]; return btns.map(b => { const r = b.getBoundingClientRect(); const cx = r.x + r.width / 2, cy = r.y + r.height / 2; const top = document.elementFromPoint(cx, cy); return { label: b.textContent.trim().slice(0, 24), rect: `${Math.round(r.x)},${Math.round(r.y)} ${Math.round(r.width)}x${Math.round(r.height)}`, topElement: top ? (top.tagName + '.' + String(top.className).split(' ').join('.')) : 'NULL (offscreen?)', topIsButtonOrChild: top ? b.contains(top) || top === b : false, }; }); }); console.log('Title buttons hit-test:'); for (const p of probe) console.log(' •', JSON.stringify(p)); // True click attempt on New Journey const nj = page.locator('.title-menu .btn', { hasText: 'New Journey' }).first(); try { await nj.click({ timeout: 3000 }); console.log('CLICK: dispatched'); } catch (e) { console.log('CLICK FAILED:', e.message.split('\n')[0]); } await page.waitForTimeout(400); const createVisible = await page.evaluate(() => !document.querySelector('.screen-create').classList.contains('hidden')); console.log('creation screen visible after click:', createVisible); // Screenshot for visual confirmation await page.screenshot({ path: '/tmp/title_after_click.png' }); console.log('\nConsole/page errors:'); logs.length ? logs.forEach(l => console.log(' ', l)) : console.log(' (none)'); await browser.close(); })().catch(e => { console.error('REPRO ERROR:', e.message); process.exit(1); });