// 探测脚本:检查 Flutter renderer + 登录页 DOM + Hive 存储后端 const { chromium } = require('playwright'); const BASE = 'http://127.0.0.1:8099'; (async () => { const browser = await chromium.launch({ headless: true }); const ctx = await browser.newContext(); const page = await ctx.newPage(); // 收集 console const logs = []; page.on('console', m => logs.push(`[${m.type()}] ${m.text()}`)); page.on('pageerror', e => logs.push(`[PAGEERROR] ${e.message}`)); console.log('=== 1. 访问首页,检查 renderer ==='); await page.goto(BASE + '/', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(3000); // 检查 renderer:canvaskit 有 + flt-glass-pane;html 有 flutter-view 含 div const canvasCount = await page.locator('canvas').count(); const fltGlass = await page.locator('flt-glass-pane').count(); const htmlView = await page.locator('flutter-view, .flutter-view').count(); console.log(`canvas 元素数: ${canvasCount}`); console.log(`flt-glass-pane (canvaskit 标志): ${fltGlass}`); console.log(`flutter-view: ${htmlView}`); // body HTML 片段(判断 renderer) const bodySnippet = await page.evaluate(() => document.body.innerHTML.slice(0, 400)); console.log(`body 片段: ${bodySnippet.slice(0, 200)}`); console.log('\n=== 2. 访问登录页,检查输入框 DOM ==='); await page.goto(BASE + '/login', { waitUntil: 'networkidle', timeout: 60000 }); await page.waitForTimeout(3000); // Flutter web 输入框:canvaskit 会在聚焦时创建 ;检查有无 input const inputCount = await page.locator('input').count(); console.log(`input 元素数: ${inputCount}`); const inputs = await page.locator('input').evaluateAll(els => els.map(e => ({ type: e.type, placeholder: e.placeholder, ariaLabel: e.getAttribute('aria-label'), cls: e.className.slice(0, 40) })) ); console.log('input 详情:', JSON.stringify(inputs).slice(0, 300)); // 检查 semantics(辅助功能树) const semanticsRoles = await page.locator('[role="textbox"], [role="button"]').count(); console.log(`semantics (role=textbox/button): ${semanticsRoles}`); console.log('\n=== 3. 检查存储(localStorage + IndexedDB)==='); const ls = await page.evaluate(() => { return JSON.stringify(Object.keys(localStorage).reduce((o, k) => { o[k] = localStorage.getItem(k).slice(0, 100); return o; }, {})); }); console.log(`localStorage: ${ls}`); const idb = await page.evaluate(async () => { const dbs = indexedDB.databases ? await indexedDB.databases() : []; const result = []; for (const db of dbs) { result.push({ name: db.name, version: db.version }); } return JSON.stringify(result); }); console.log(`IndexedDB databases: ${idb}`); console.log('\n=== 4. console 日志(前 10 条)==='); console.log(logs.slice(0, 10).join('\n')); await browser.close(); })().catch(e => { console.error('探测失败:', e.message); process.exit(1); });