_e2e_admin_login2.cjs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * Refined admin-login attempt (temp, not committed). Handles identity
  3. * auto-select after phone entry and the spaced "登 录" button label.
  4. */
  5. const { chromium } = require('@playwright/test');
  6. const fs = require('fs');
  7. const path = require('path');
  8. const BASE = process.env.PW_BASE_URL || 'http://cfc.iwintrue.com';
  9. const MJ = process.env.MACHINE_JSON_PATH;
  10. async function main() {
  11. const out = { base: BASE, attempt: 'identity-aware' };
  12. let phone = '13800138000', pw = 'admin123';
  13. if (MJ && fs.existsSync(MJ)) {
  14. try {
  15. const cfg = JSON.parse(fs.readFileSync(MJ, 'utf8'));
  16. const a = cfg.e2e_test_target && cfg.e2e_test_target.admin;
  17. if (a) { if (a.phone) phone = a.phone; if (a.password) pw = a.password; }
  18. } catch (e) {}
  19. }
  20. const launchOpts = { headless: true, args: ['--no-sandbox'] };
  21. if (process.env.CHROME_PATH) launchOpts.executablePath = process.env.CHROME_PATH;
  22. const browser = await chromium.launch(launchOpts);
  23. try {
  24. const ctx = await browser.newContext();
  25. const page = await ctx.newPage();
  26. await page.goto(BASE + '/admin/login', { waitUntil: 'networkidle', timeout: 30000 });
  27. await page.waitForTimeout(1500);
  28. // 1) phone
  29. await page.locator('input').first().fill(phone);
  30. await page.waitForTimeout(1500);
  31. // 2) identity auto-select: capture any role/identity pickers that appeared
  32. const identityInfo = await page.evaluate(() => {
  33. const picks = Array.from(document.querySelectorAll(
  34. '[class*="identity"], [class*="role"], .el-radio, .el-radio-group label, [class*="account"]'
  35. )).map(e => ({ cls: e.className.toString().slice(0,40), text: (e.textContent||'').trim().slice(0,30) }));
  36. return picks.slice(0, 8);
  37. });
  38. out.identityCandidates = identityInfo;
  39. // click first clickable identity/role if present
  40. const pick = page.locator('[class*="identity"] li, .el-radio, [class*="role"] label, .el-radio-group label').first();
  41. if (await pick.count() > 0) { try { await pick.click({ timeout: 3000 }); } catch (e) {} }
  42. await page.waitForTimeout(800);
  43. // 3) password
  44. const pwd = page.locator('input[type="password"]').first();
  45. if (await pwd.count() > 0) await pwd.fill(pw);
  46. // 4) exact spaced button "登 录"
  47. const btn = page.locator('button:has-text("登 录")').first();
  48. let clicked = false;
  49. if (await btn.count() > 0) {
  50. try { await btn.click({ timeout: 8000 }); clicked = true; } catch (e) { out.btnClickErr = String(e.message).slice(0,100); }
  51. }
  52. out.buttonClicked = clicked;
  53. await page.waitForTimeout(4000);
  54. out.after = {
  55. url: page.url().slice(0, 120),
  56. tokenLen: await page.evaluate(() => (localStorage.getItem('token') || '').length),
  57. hasSidebar: await page.locator('.sidebar-container, .el-menu, .el-aside, .el-container').count()
  58. };
  59. await ctx.close();
  60. } catch (e) {
  61. out.fatal = String(e && e.message ? e.message : e).slice(0, 300);
  62. } finally {
  63. await browser.close();
  64. }
  65. fs.writeFileSync(path.join(__dirname, '_e2e_admin_login2.json'), JSON.stringify(out, null, 2));
  66. console.log(JSON.stringify(out, null, 2));
  67. }
  68. main().then(() => process.exit(0)).catch(e => { console.error(String(e).slice(0,300)); process.exit(1); });