WUXIA: 100 Days After — full game
Single-file ink-painting wuxia sect-survival RPG. Lead a sect through 100 days: martial arts combos, cultivation, tactical combat, faction war, chronicle endings. - src/ 13 modules (data, sim, combat, render, UI, app shell) - wuxia.html self-contained build (no dependencies) - tools/build.js bundler - tests: headless 100-day sims + jsdom UI smoke + real-browser Chromium click-through (playwright)
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
#!/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); });
|
||||
Reference in New Issue
Block a user