const fs = require('fs'); const path = require('path'); const { chromium } = require('playwright'); const ROOT = path.resolve(__dirname, '..'); const PROFILE = path.join(ROOT, 'diagnostics', 'erp-playwright-profile'); const RUN_ID = new Date().toISOString().replace(/[-:T.Z]/g, '').slice(0, 14); const RUN_DIR = path.join(ROOT, 'diagnostics', 'split-parent-inspect', `run-${RUN_ID}`); fs.mkdirSync(RUN_DIR, { recursive: true }); async function dumpPage(page, name) { const data = []; for (const frame of page.frames()) { const frameData = await frame.evaluate(() => { const controls = Array.from(document.querySelectorAll('input, button, a, select, textarea')).map((el, index) => { const attrs = {}; for (const attr of ['id', 'name', 'type', 'value', 'title', 'class', 'onclick', 'href']) { const value = el.getAttribute(attr); if (value != null) attrs[attr] = value; } const rect = el.getBoundingClientRect(); return { index, tag: el.tagName.toLowerCase(), text: (el.innerText || el.value || '').replace(/\s+/g, ' ').trim().slice(0, 240), attrs, rect: { x: Math.round(rect.x), y: Math.round(rect.y), w: Math.round(rect.width), h: Math.round(rect.height) }, }; }); return { url: location.href, title: document.title, bodyText: document.body.innerText.replace(/\s+/g, ' ').slice(0, 3000), controls, }; }).catch((error) => ({ url: frame.url(), title: '', bodyText: `ERROR:${error.message}`, controls: [] })); data.push({ frameUrl: frame.url(), frameName: frame.name(), ...frameData }); } fs.writeFileSync(path.join(RUN_DIR, `${name}.json`), JSON.stringify(data, null, 2), 'utf8'); await page.screenshot({ path: path.join(RUN_DIR, `${name}.png`), fullPage: false }); console.log(JSON.stringify({ name, RUN_DIR, frames: data.map((f) => ({ url: f.url, controls: f.controls.length, body: f.bodyText.slice(0, 240) })) }, null, 2)); } async function main() { const context = await chromium.launchPersistentContext(PROFILE, { headless: false, viewport: { width: 1920, height: 1000 }, acceptDownloads: true, }); const page = context.pages()[0] || await context.newPage(); page.setDefaultTimeout(15000); try { await page.goto('https://ltjt.yunzhi.run/System/Business/plan.asp', { waitUntil: 'domcontentloaded', timeout: 30000 }); await page.waitForTimeout(1500); await dumpPage(page, '01-list'); await page.locator('input[value="新增计划"], a:has-text("新增计划"), button:has-text("新增计划")').first().click(); await page.waitForTimeout(2500); await dumpPage(page, '02-new-plan'); } finally { await context.close(); } } main().catch((error) => { console.error(error); process.exit(1); });