Update something.ts
This commit is contained in:
336
something.ts
Normal file
336
something.ts
Normal file
@@ -0,0 +1,336 @@
|
||||
/**
|
||||
* PokeRogue Extension E2E Test - v2
|
||||
*/
|
||||
const { chromium } = require('playwright');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const EXTENSION_PATH = '/home/ceo/Desktop/poke-extension';
|
||||
const USER_DATA_DIR = '/tmp/poke-ext-test-profile-' + Date.now();
|
||||
const SCREENSHOT_DIR = '/home/ceo/Desktop/poke-extension';
|
||||
const USERNAME = 'ClaudeCode';
|
||||
const PASSWORD = '5454%penilesurgery%5656';
|
||||
const consoleMessages = [];
|
||||
const extMessages = [];
|
||||
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||
async function shot(page, name) {
|
||||
const fp = path.join(SCREENSHOT_DIR, `test-${name}.png`);
|
||||
await page.screenshot({ path: fp });
|
||||
console.log(`[SHOT] ${fp}`);
|
||||
}
|
||||
async function main() {
|
||||
console.log('[TEST] === PokeRogue Extension E2E Test v2 ===');
|
||||
// Step 1: Launch
|
||||
console.log('\n[STEP 1] Launching Chromium with extension...');
|
||||
const context = await chromium.launchPersistentContext(USER_DATA_DIR, {
|
||||
headless: false,
|
||||
args: [
|
||||
'--ignore-gpu-blacklist',
|
||||
'--disable-gpu-sandbox',
|
||||
`--disable-extensions-except=${EXTENSION_PATH}`,
|
||||
`--load-extension=${EXTENSION_PATH}`,
|
||||
'--no-first-run',
|
||||
'--disable-blink-features=AutomationControlled',
|
||||
'--window-size=1280,900',
|
||||
],
|
||||
viewport: { width: 1280, height: 900 },
|
||||
ignoreDefaultArgs: ['--disable-extensions'],
|
||||
});
|
||||
let page = context.pages()[0] || await context.newPage();
|
||||
page.on('console', msg => {
|
||||
const t = msg.text();
|
||||
consoleMessages.push({ type: msg.type(), text: t });
|
||||
if (t.includes('[PokeRogue Ext]')) {
|
||||
extMessages.push(t);
|
||||
console.log(` [EXT] ${t}`);
|
||||
}
|
||||
});
|
||||
page.on('pageerror', err => console.log(` [PERR] ${err.message.substring(0, 150)}`));
|
||||
// Step 2: Navigate
|
||||
console.log('\n[STEP 2] Navigating to pokerogue.net...');
|
||||
await page.goto('https://pokerogue.net/', { waitUntil: 'domcontentloaded', timeout: 60000 });
|
||||
console.log(' Waiting 20s for Phaser...');
|
||||
await sleep(20000);
|
||||
await shot(page, '01-initial-load');
|
||||
// Step 3: Check messages
|
||||
console.log('\n[STEP 3] Extension messages check:');
|
||||
for (const c of ['Game bridge loaded', 'SceneManager prototype patch installed', 'Game instance captured']) {
|
||||
console.log(` ${extMessages.some(m => m.includes(c)) ? '✓' : '✗'} ${c}`);
|
||||
}
|
||||
const gameCheck = await page.evaluate(() => ({
|
||||
exists: !!window.__POKEXT_GAME__,
|
||||
hasScene: !!(window.__POKEXT_GAME__?.scene),
|
||||
hasCanvas: !!(window.__POKEXT_GAME__?.canvas),
|
||||
}));
|
||||
console.log(` __POKEXT_GAME__: ${JSON.stringify(gameCheck)}`);
|
||||
// Step 4: Login
|
||||
console.log('\n[STEP 4] Logging in...');
|
||||
|
||||
// Focus canvas and press Enter to get to login screen
|
||||
await page.mouse.click(640, 450);
|
||||
await sleep(1000);
|
||||
await page.keyboard.press('Enter');
|
||||
await sleep(2000);
|
||||
await shot(page, '02-login-screen');
|
||||
// Find visible inputs by coordinates
|
||||
const inputInfo = await page.evaluate(() => {
|
||||
const all = Array.from(document.querySelectorAll('input'));
|
||||
return all.map((inp, i) => {
|
||||
const r = inp.getBoundingClientRect();
|
||||
const s = window.getComputedStyle(inp);
|
||||
return {
|
||||
i, type: inp.type,
|
||||
vis: r.width > 0 && r.height > 0 && s.display !== 'none' && s.visibility !== 'hidden',
|
||||
x: r.x, y: r.y, w: r.width, h: r.height,
|
||||
};
|
||||
}).filter(x => x.vis);
|
||||
});
|
||||
console.log(` Visible inputs: ${JSON.stringify(inputInfo)}`);
|
||||
const textInputs = inputInfo.filter(i => i.type === 'text');
|
||||
const pwdInputs = inputInfo.filter(i => i.type === 'password');
|
||||
if (textInputs.length > 0 && pwdInputs.length > 0) {
|
||||
const ui = textInputs[0];
|
||||
const pi = pwdInputs[0];
|
||||
// Click username field and type
|
||||
await page.mouse.click(ui.x + ui.w / 2, ui.y + ui.h / 2);
|
||||
await sleep(300);
|
||||
await page.keyboard.press('Control+a');
|
||||
await sleep(100);
|
||||
await page.keyboard.type(USERNAME, { delay: 30 });
|
||||
await sleep(300);
|
||||
// Click password field and type
|
||||
await page.mouse.click(pi.x + pi.w / 2, pi.y + pi.h / 2);
|
||||
await sleep(300);
|
||||
await page.keyboard.press('Control+a');
|
||||
await sleep(100);
|
||||
await page.keyboard.type(PASSWORD, { delay: 30 });
|
||||
await sleep(300);
|
||||
await shot(page, '03-login-filled');
|
||||
// Verify
|
||||
const vals = await page.evaluate(({ uIdx, pIdx }) => {
|
||||
const inputs = document.querySelectorAll('input');
|
||||
return { u: inputs[uIdx]?.value, pLen: inputs[pIdx]?.value?.length };
|
||||
}, { uIdx: ui.i, pIdx: pi.i });
|
||||
console.log(` Filled: user="${vals.u}", pwdLen=${vals.pLen}`);
|
||||
// Submit - press Enter
|
||||
await page.keyboard.press('Enter');
|
||||
console.log(' Submitted login form');
|
||||
await sleep(5000);
|
||||
await shot(page, '04-after-login');
|
||||
// Check if we need to retry
|
||||
const loginResult = await page.evaluate(() => {
|
||||
const text = document.body.innerText || '';
|
||||
return {
|
||||
hasError: text.includes('incorrect') || text.includes('must not be empty') || text.includes('Invalid'),
|
||||
snippet: text.substring(0, 200),
|
||||
};
|
||||
});
|
||||
|
||||
if (loginResult.hasError) {
|
||||
console.log(` Login may have failed: ${loginResult.snippet.substring(0, 100)}`);
|
||||
// Try again - click username, clear, retype
|
||||
await page.mouse.click(ui.x + ui.w / 2, ui.y + ui.h / 2);
|
||||
await sleep(200);
|
||||
await page.keyboard.press('Control+a');
|
||||
await page.keyboard.press('Backspace');
|
||||
await sleep(100);
|
||||
await page.keyboard.type(USERNAME, { delay: 50 });
|
||||
await sleep(200);
|
||||
|
||||
await page.mouse.click(pi.x + pi.w / 2, pi.y + pi.h / 2);
|
||||
await sleep(200);
|
||||
await page.keyboard.press('Control+a');
|
||||
await page.keyboard.press('Backspace');
|
||||
await sleep(100);
|
||||
await page.keyboard.type(PASSWORD, { delay: 50 });
|
||||
await sleep(200);
|
||||
|
||||
// Now find and click the Login button in the canvas area
|
||||
// The button is below the password field typically
|
||||
// Try pressing Enter from password field
|
||||
await page.keyboard.press('Enter');
|
||||
await sleep(5000);
|
||||
await shot(page, '05-login-retry');
|
||||
}
|
||||
} else {
|
||||
console.log(' No visible login inputs found!');
|
||||
}
|
||||
// Wait for login to complete and main menu to appear
|
||||
await sleep(3000);
|
||||
await shot(page, '06-post-login');
|
||||
// Step 5: Start battle
|
||||
console.log('\n[STEP 5] Starting a battle...');
|
||||
|
||||
// Focus canvas
|
||||
await page.mouse.click(640, 450);
|
||||
await sleep(500);
|
||||
// Check current game phase/state
|
||||
const preMenuState = await page.evaluate(() => {
|
||||
const g = window.__POKEXT_GAME__;
|
||||
if (!g?.scene) return { noGame: true };
|
||||
const scenes = g.scene.scenes || [];
|
||||
const battleScene = scenes.find(s => s.currentBattle !== undefined);
|
||||
return {
|
||||
sceneKeys: scenes.map(s => s.sys?.settings?.key).slice(0, 10),
|
||||
hasBattleScene: !!battleScene,
|
||||
currentPhase: battleScene?.currentPhase?.constructor?.name || 'none',
|
||||
currentBattle: battleScene?.currentBattle ? {
|
||||
waveIndex: battleScene.currentBattle.waveIndex,
|
||||
turn: battleScene.currentBattle.turn,
|
||||
} : null,
|
||||
};
|
||||
});
|
||||
console.log(` Pre-menu state: ${JSON.stringify(preMenuState)}`);
|
||||
// Navigate through menus
|
||||
// After login: main menu appears. Press Enter to select first option.
|
||||
// If "Continue" is available, it starts from last save.
|
||||
// If "New Game", it starts character selection.
|
||||
|
||||
let battleFound = false;
|
||||
|
||||
for (let attempt = 0; attempt < 25; attempt++) {
|
||||
const bc = await page.evaluate(() => {
|
||||
const g = window.__POKEXT_GAME__;
|
||||
if (!g?.scene) return { battle: false };
|
||||
const scenes = g.scene.scenes || [];
|
||||
for (const s of scenes) {
|
||||
if (s.currentBattle) {
|
||||
const pf = typeof s.getPlayerField === 'function' ? s.getPlayerField() : [];
|
||||
const ef = typeof s.getEnemyField === 'function' ? s.getEnemyField() : [];
|
||||
if (pf.length > 0 && ef.length > 0) {
|
||||
return { battle: true, wave: s.currentBattle.waveIndex, players: pf.length, enemies: ef.length };
|
||||
}
|
||||
return { battle: false, partial: true, wave: s.currentBattle.waveIndex };
|
||||
}
|
||||
}
|
||||
return { battle: false };
|
||||
});
|
||||
if (bc.battle) {
|
||||
console.log(` Battle found at attempt ${attempt + 1}! Wave: ${bc.wave}, Players: ${bc.players}, Enemies: ${bc.enemies}`);
|
||||
battleFound = true;
|
||||
break;
|
||||
}
|
||||
if (attempt % 5 === 0 && attempt > 0) {
|
||||
console.log(` Attempt ${attempt}: no battle yet (${JSON.stringify(bc)})`);
|
||||
await shot(page, `07-nav-attempt-${attempt}`);
|
||||
}
|
||||
// Press Enter to advance through menus/dialogs
|
||||
await page.keyboard.press('Enter');
|
||||
await sleep(1500);
|
||||
}
|
||||
if (!battleFound) {
|
||||
console.log(' Battle not found after Enter presses, trying arrow navigation...');
|
||||
// Try selecting different menu options
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await page.keyboard.press('ArrowDown');
|
||||
await sleep(500);
|
||||
}
|
||||
await page.keyboard.press('Enter');
|
||||
await sleep(3000);
|
||||
|
||||
for (let attempt = 0; attempt < 10; attempt++) {
|
||||
const bc = await page.evaluate(() => {
|
||||
const g = window.__POKEXT_GAME__;
|
||||
if (!g?.scene) return { battle: false };
|
||||
return { battle: (g.scene.scenes || []).some(s => s.currentBattle) };
|
||||
});
|
||||
if (bc.battle) {
|
||||
battleFound = true;
|
||||
console.log(` Battle found after arrow nav!`);
|
||||
break;
|
||||
}
|
||||
await page.keyboard.press('Enter');
|
||||
await sleep(2000);
|
||||
}
|
||||
}
|
||||
// Wait for battle to fully load
|
||||
await sleep(5000);
|
||||
await shot(page, '08-battle-state');
|
||||
// Step 6: Verify overlay
|
||||
console.log('\n[STEP 6] Verifying overlay...');
|
||||
await sleep(3000); // Let polling catch up
|
||||
const finalState = await page.evaluate(() => {
|
||||
const g = window.__POKEXT_GAME__;
|
||||
const overlay = document.getElementById('poke-ext-overlay');
|
||||
|
||||
let battleInfo = null;
|
||||
if (g?.scene) {
|
||||
for (const s of (g.scene.scenes || [])) {
|
||||
if (s.currentBattle) {
|
||||
try {
|
||||
const pf = typeof s.getPlayerField === 'function' ? s.getPlayerField() : [];
|
||||
const ef = typeof s.getEnemyField === 'function' ? s.getEnemyField() : [];
|
||||
battleInfo = {
|
||||
wave: s.currentBattle.waveIndex,
|
||||
double: !!s.currentBattle.double,
|
||||
player: pf.filter(Boolean).map(p => ({
|
||||
name: typeof p.getNameToRender === 'function' ? p.getNameToRender() : (p.name || '?'),
|
||||
types: typeof p.getTypes === 'function' ? p.getTypes() : [],
|
||||
moves: (p.moveset || []).filter(Boolean).map(m => {
|
||||
const mv = typeof m.getMove === 'function' ? m.getMove() : m;
|
||||
return { name: typeof m.getName === 'function' ? m.getName() : (mv?.name || '?'), type: mv?.type ?? -1, power: mv?.power ?? 0, cat: mv?.category ?? -1 };
|
||||
}),
|
||||
})),
|
||||
enemy: ef.filter(Boolean).map(p => ({
|
||||
name: typeof p.getNameToRender === 'function' ? p.getNameToRender() : (p.name || '?'),
|
||||
types: typeof p.getTypes === 'function' ? p.getTypes() : [],
|
||||
})),
|
||||
};
|
||||
} catch (e) { battleInfo = { error: e.message }; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
gameExists: !!g,
|
||||
battleInfo,
|
||||
overlay: {
|
||||
exists: !!overlay,
|
||||
visible: overlay ? overlay.style.display !== 'none' : false,
|
||||
html: overlay ? overlay.innerHTML : '',
|
||||
text: overlay ? overlay.innerText : '',
|
||||
},
|
||||
};
|
||||
});
|
||||
console.log(` Game exists: ${finalState.gameExists}`);
|
||||
console.log(` Battle: ${JSON.stringify(finalState.battleInfo, null, 2)}`);
|
||||
console.log(` Overlay exists: ${finalState.overlay.exists}, visible: ${finalState.overlay.visible}`);
|
||||
console.log(` Overlay text:\n${finalState.overlay.text}`);
|
||||
console.log(` Overlay HTML (1500 chars):\n${finalState.overlay.html.substring(0, 1500)}`);
|
||||
await shot(page, '09-final-with-overlay');
|
||||
// Try to get overlay closeup
|
||||
if (finalState.overlay.exists) {
|
||||
try {
|
||||
const el = await page.$('#poke-ext-overlay');
|
||||
if (el) {
|
||||
await el.screenshot({ path: path.join(SCREENSHOT_DIR, 'test-10-overlay-closeup.png') });
|
||||
console.log('[SHOT] test-10-overlay-closeup.png');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
// Step 7: All ext messages
|
||||
console.log('\n[STEP 7] All [PokeRogue Ext] messages:');
|
||||
console.log('─'.repeat(60));
|
||||
extMessages.forEach((m, i) => console.log(` ${i + 1}. ${m}`));
|
||||
if (!extMessages.length) console.log(' (none)');
|
||||
console.log('─'.repeat(60));
|
||||
const errs = consoleMessages.filter(m => m.type === 'error');
|
||||
if (errs.length) {
|
||||
console.log(`\n Errors (${errs.length}):`);
|
||||
errs.slice(0, 10).forEach(e => console.log(` ${e.text.substring(0, 200)}`));
|
||||
}
|
||||
console.log('\n[SUMMARY]');
|
||||
console.log(` ${gameCheck.exists ? '✓' : '✗'} Game captured via SceneManager patch`);
|
||||
console.log(` ${finalState.overlay.exists ? '✓' : '✗'} Overlay created`);
|
||||
console.log(` ${finalState.battleInfo ? '✓' : '✗'} Battle detected`);
|
||||
if (finalState.battleInfo && !finalState.battleInfo.error) {
|
||||
console.log(` ${finalState.overlay.text.includes('Effectiveness') ? '✓' : '✗'} Overlay shows type effectiveness`);
|
||||
}
|
||||
console.log(` Extension messages: ${extMessages.length}`);
|
||||
await context.close();
|
||||
try { fs.rmSync(USER_DATA_DIR, { recursive: true, force: true }); } catch (_) {}
|
||||
console.log('\n[TEST] Done!');
|
||||
}
|
||||
main().catch(err => {
|
||||
console.error('[FATAL]', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user