const { chromium } = require('@playwright/test'); (async () => { const browser = await chromium.launch(); const page = await browser.newPage(); const errors = []; page.on('pageerror', e => errors.push('PE:' + e.message.substring(0,180))); page.on('console', m => { if (m.type()==='error') errors.push('CON:' + m.text().substring(0,180)); }); await page.goto('http://localhost/geograsim/App/sims/wal/game.html'); await page.waitForTimeout(2200); // 1) Sind die Plattform-Globals da? const info = await page.evaluate(() => ({ engine: typeof window.WalEngine, state: typeof window.GGS_LIVE_STATE, tutorial: typeof window.GGS_TUTORIAL, eraScreenActive: !!document.querySelector('#screen-era.active'), hasEraCards: document.querySelectorAll('.era-card').length, })); console.log('Boot:', JSON.stringify(info)); // 2) GGS_LIVE_STATE vor Start gibt null const preStart = await page.evaluate(() => window.GGS_LIVE_STATE && window.GGS_LIVE_STATE()); console.log('LiveState before start:', preStart); // 3) Era 2026 starten await page.click('[data-era-cta="2026"]'); await page.waitForTimeout(800); const afterStart = await page.evaluate(() => ({ gameActive: !!document.querySelector('#screen-game.active'), badge: document.getElementById('era-badge')?.textContent, modalActive: !!document.querySelector('#modal.active'), modalTitle: document.getElementById('modalTitle')?.textContent, })); console.log('After 2026 start:', JSON.stringify(afterStart)); // 4) Tutorial wegklicken (4 Schritte → Skip-Button) for (let i = 0; i < 5; i++) { const closeBtn = await page.locator('.modal-foot button:has-text("Los geht\'s")').count(); if (closeBtn > 0) { await page.click('.modal-foot button:has-text("Los geht\'s")'); break; } const nextBtn = await page.locator('.modal-foot button:has-text("Weiter")').count(); if (nextBtn > 0) { await page.click('.modal-foot button:has-text("Weiter")'); await page.waitForTimeout(200); } else break; } await page.waitForTimeout(400); // 5) Stage-Intro Weiter const stageIntroTitle = await page.evaluate(() => document.getElementById('modalTitle')?.textContent); console.log('Stage-Intro:', stageIntroTitle); if (await page.locator('.modal-foot button:has-text("Weiterreisen")').count()) { await page.click('.modal-foot button:has-text("Weiterreisen")'); await page.waitForTimeout(400); } // 6) Erste Begegnung öffnen const panelTitle = await page.evaluate(() => document.getElementById('panelText')?.textContent); console.log('Panel before event:', panelTitle?.substring(0, 80)); if (await page.locator('.panel-actions button:has-text("Hinsehen")').count()) { await page.click('.panel-actions button:has-text("Hinsehen")'); await page.waitForTimeout(400); } const encounterTitle = await page.evaluate(() => document.getElementById('modalTitle')?.textContent); console.log('Encounter:', encounterTitle); // 7) Erste Choice wählen await page.click('.choices .choice:first-child'); await page.waitForTimeout(400); const afterChoice = await page.evaluate(() => ({ body: document.getElementById('modalBody')?.textContent?.substring(0, 80), chips: document.querySelectorAll('.effect-chip').length, })); console.log('After choice:', JSON.stringify(afterChoice)); if (await page.locator('.modal-foot button:has-text("Weiter")').count()) { await page.click('.modal-foot button:has-text("Weiter")'); await page.waitForTimeout(400); } // 8) GGS_LIVE_STATE nach 1 Begegnung const liveState = await page.evaluate(() => window.GGS_LIVE_STATE && window.GGS_LIVE_STATE()); console.log('LiveState mid-game:'); console.log(JSON.stringify(liveState, null, 2)); // 9) localStorage Save? const save = await page.evaluate(() => localStorage.getItem('ggs-save-wal-2026')); console.log('Save present:', save ? 'YES (' + save.length + ' chars)' : 'NO'); if (errors.length) { console.log('\nERRORS:'); errors.forEach(e => console.log(' ', e)); } else { console.log('\nNo JS errors ✓'); } await browser.close(); })();