_probe_frontend.cjs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Instrumented read-only UI probe. Logs each step immediately so a hang is visible.
  2. const { chromium } = require('playwright-core');
  3. const fs = require('fs');
  4. const path = require('path');
  5. const CACHE = path.join(process.env.LOCALAPPDATA || 'C:/Users/iwt/AppData/Local', 'ms-playwright');
  6. function findChrome() {
  7. for (const rev of ['chromium-1234', 'chromium-1228']) {
  8. const exe = path.join(CACHE, rev, 'chrome-win64', 'chrome.exe');
  9. if (fs.existsSync(exe)) return exe;
  10. }
  11. return null;
  12. }
  13. const TARGET = process.env.PW_BASE_URL || 'http://cfc.iwintrue.com/frontend';
  14. const EXE = findChrome();
  15. const log = (...a) => { process.stdout.write('[' + new Date().toISOString().slice(11, 19) + '] ' + a.join(' ') + '\n'); };
  16. // Hard kill switch so we never hang the session.
  17. const KILL = setTimeout(() => { log('HARD_TIMEOUT 60s -> exiting'); process.exit(3); }, 60000);
  18. (async () => {
  19. log('chrome_exe=' + EXE);
  20. if (!EXE) { log('NO CHROME'); process.exit(2); }
  21. const browser = await chromium.launch({
  22. executablePath: EXE, headless: true,
  23. args: ['--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu'],
  24. });
  25. log('launched');
  26. const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
  27. page.on('console', (m) => { if (m.type() === 'error') log('console.error: ' + m.text().slice(0, 120)); });
  28. page.on('pageerror', (e) => log('pageerror: ' + e.message.slice(0, 120)));
  29. page.on('requestfailed', (r) => log('requestfailed: ' + r.url().slice(0, 80) + ' ' + (r.failure() && r.failure().errorText)));
  30. log('goto ' + TARGET);
  31. const resp = await page.goto(TARGET, { waitUntil: 'domcontentloaded', timeout: 20000 });
  32. log('goto done status=' + (resp ? resp.status() : 'null') + ' url=' + page.url());
  33. const ua = await page.evaluate(() => navigator.userAgent);
  34. log('ua=' + ua);
  35. await page.waitForTimeout(2000).catch(() => {});
  36. const title = await page.title();
  37. const bodyLen = await page.evaluate(() => (document.body ? document.body.innerText.length : 0));
  38. log('title=' + JSON.stringify(title) + ' bodyTextLen=' + bodyLen);
  39. const mount = await page.evaluate(() => {
  40. const out = [];
  41. for (const id of ['app', 'root']) if (document.getElementById(id)) out.push(id);
  42. return out;
  43. });
  44. log('mountRoots=' + JSON.stringify(mount));
  45. const markers = await page.evaluate(() => {
  46. const txt = (document.body ? document.body.innerText : '').toLowerCase();
  47. const inputs = Array.from(document.querySelectorAll('input')).map((i) => i.type || 'text');
  48. return { inputTypes: [...new Set(inputs)], mentionsLogin: /登录|login|用户名|密码|password/i.test(txt) };
  49. });
  50. log('markers=' + JSON.stringify(markers));
  51. log('PROBE_OK');
  52. await browser.close();
  53. clearTimeout(KILL);
  54. process.exit(0);
  55. })().catch((e) => { log('ERR ' + (e && e.message ? e.message : e)); process.exit(1); });