/** * Temporary admin-login diagnostic (NOT committed). Classifies why /admin * login returned no token: credential rejection vs selector mismatch. * Credentials read from local machine.json; never printed. */ const { chromium } = require('@playwright/test'); const fs = require('fs'); const path = require('path'); const BASE = process.env.PW_BASE_URL || 'http://cfc.iwintrue.com'; const MJ = process.env.MACHINE_JSON_PATH; async function main() { const out = { base: BASE, steps: {} }; let admin = { phone: '13800138000' }; let pw = 'admin123'; if (MJ && fs.existsSync(MJ)) { try { const cfg = JSON.parse(fs.readFileSync(MJ, 'utf8')); if (cfg.e2e_test_target && cfg.e2e_test_target.admin) { if (cfg.e2e_test_target.admin.phone) admin.phone = cfg.e2e_test_target.admin.phone; if (cfg.e2e_test_target.admin.password) pw = cfg.e2e_test_target.admin.password; } } catch (e) {} } const launchOpts = { headless: true, args: ['--no-sandbox'] }; if (process.env.CHROME_PATH) launchOpts.executablePath = process.env.CHROME_PATH; const browser = await chromium.launch(launchOpts); try { const ctx = await browser.newContext(); const page = await ctx.newPage(); const resp = await page.goto(BASE + '/admin/login', { waitUntil: 'networkidle', timeout: 30000 }); await page.waitForTimeout(2000); out.steps.loginPage = { status: resp ? resp.status() : null, url: page.url().slice(0, 120), title: String(await page.title()).slice(0, 80) }; // Inventory inputs & buttons (safe DOM metadata only) out.steps.dom = await page.evaluate(() => { const inputs = Array.from(document.querySelectorAll('input')).map(i => ({ type: i.type || i.getAttribute('type'), placeholder: i.placeholder || '', name: i.name || '' })); const buttons = Array.from(document.querySelectorAll('button')).map(b => (b.textContent || '').trim().slice(0, 20)); return { inputCount: inputs.length, inputs, buttonTexts: buttons.slice(0, 10) }; }); // Attempt fill + submit const phoneIn = page.locator('input').first(); if (await phoneIn.count() > 0) await phoneIn.fill(admin.phone); const pwdIn = page.locator('input[type="password"]').first(); if (await pwdIn.count() > 0) await pwdIn.fill(pw); const btn = page.locator('button[type="submit"], .el-button--primary, button:has-text("登录")').first(); if (await btn.count() > 0) await btn.click(); await page.waitForTimeout(4000); out.steps.afterLogin = { url: page.url().slice(0, 120), tokenLen: await page.evaluate(() => (localStorage.getItem('token') || '').length), errorText: await page.evaluate(() => { const el = document.querySelector('.el-message, .el-notification, [class*="error"], .tip, .err'); return el ? el.textContent.trim().slice(0, 120) : null; }) }; await ctx.close(); } catch (e) { out.fatal = String(e && e.message ? e.message : e).slice(0, 300); } finally { await browser.close(); } fs.writeFileSync(path.join(__dirname, '_e2e_admin_debug.json'), JSON.stringify(out, null, 2)); console.log(JSON.stringify(out, null, 2)); } main().then(() => process.exit(0)).catch(e => { console.error(String(e).slice(0,300)); process.exit(1); });