const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch({ headless: true, executablePath: 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe' }); const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } }); const errors = []; page.on('pageerror', error => errors.push(error.message)); await page.goto('http://127.0.0.1:8931/AI%E5%BF%AB%E9%80%9F%E6%8A%A5%E4%BB%B7_Demo2.html?v=excel-rules-20260805', { waitUntil: 'load' }); await page.evaluate(() => { switchView('rules'); renderRules(); }); const result = await page.evaluate(() => { const wardrobeExpected = { '板门补差价': 538, '玻璃门补差价': 1852, '灯带': 386, '变压器+开关': 536, '自弹器': 115, '见光板': 1138, '铰链': 40, '护墙板': 1852, '拉手': 226, '抽屉': 1300, '金属拉手': 225, '铝格栅金属拉手': 680, '衣杆': 288, '圆弧': 1560 }; const kitchenExpected = { '地柜': 2380, '吊柜': 1748, '冰箱吊柜': 2622, '高柜': 5950, '见光板×2': 1138, '台面': 1480, '台面超出部分': 2480, '碗篮': 1268, '锅篮': 1628, '自弹': 115, '切角': 500, '台下盆': 500, '包管': 500 }; const wardrobe = DEFAULT_RULES.wardrobe; const kitchen = DEFAULT_RULES.kitchen; const validate = (rules, expected, method, unit) => Object.entries(expected).every(([name, value]) => { const rule = rules.find(item => item.name === name); return rule && Number(rule.value) === value && rule.method === method && rule.unit === unit; }); return { wardrobeCount: wardrobe.length, kitchenCount: kitchen.length, wardrobeValid: validate(wardrobe, wardrobeExpected, '按投影面积', '元/㎡'), kitchenValid: validate(kitchen, kitchenExpected, '按延米', '元/m'), wardrobeButtons: document.querySelectorAll('#rule-table-wardrobe .btn').length, kitchenButtons: document.querySelectorAll('#rule-table-kitchen .btn').length, headers: [...document.querySelectorAll('#view-rules table thead th')].map(el => el.textContent.trim()) }; }); console.log(JSON.stringify({ ...result, errors })); await browser.close(); })().catch(error => { console.error(error); process.exit(1); });