// 无头回归: 网页购物车 — 选型 → 加入清单 → 角标计数 → 切系列清单不丢 (2026-08-24) // 适配参数化引擎 (2026-08-25): range 参数为输入框, 选第一个标准档位 let chromium; try { chromium = require('playwright-core').chromium; } catch (e) { chromium = require('C:/Users/ruigu/AppData/Local/Temp/nds3dtest/node_modules/playwright-core').chromium; } const edge = 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe'; (async () => { const url = process.argv[2] || 'http://localhost:8080/'; const browser = await chromium.launch({ executablePath: edge, headless: true }); const page = await browser.newPage({ viewport: { width: 1600, height: 900 } }); const errs = []; page.on('pageerror', e => errs.push(e.message)); await page.goto(url, { waitUntil: 'domcontentloaded' }); await page.waitForTimeout(2500); // 选满一个系列的全部参数 (select 取第一个非空值; input(range) 取第一个标准档位) const pickAll = async () => { const sels = await page.$$('#paramPanel select'); for (let i = 0; i < sels.length; i++) { const opts = await sels[i].$$eval('option', os => os.map(o => o.value)); const pick = opts.find(v => v !== '' && v !== '__EMPTY__') || opts[opts.length - 1]; await sels[i].selectOption(pick); await page.waitForTimeout(250); } const inputs = await page.$$('#paramPanel input'); for (let i = 0; i < inputs.length; i++) { const dl = await page.$eval('#' + (await inputs[i].getAttribute('list')), dl => Array.from(dl.options).map(o => o.value)); await inputs[i].fill(dl[0] || '10'); await inputs[i].dispatchEvent('change'); await page.waitForTimeout(250); } await page.waitForTimeout(500); }; await page.click('.tree .series'); await page.waitForTimeout(400); await pickAll(); const dlVisible = await page.$eval('#btnDownload', el => !el.classList.contains('hidden') && !el.disabled); const addVisible = await page.$eval('#btnAddCart', el => !el.classList.contains('hidden')); await page.click('#btnAddCart'); await page.waitForTimeout(300); const badge1 = await page.$eval('#btnCart', el => el.textContent); // 换第二个系列再选再加入 (清单跨系列不丢) const series = await page.$$('.tree .series'); if (series.length > 1) { await series[1].click(); await page.waitForTimeout(400); await pickAll(); await page.click('#btnAddCart'); await page.waitForTimeout(300); } const badge2 = await page.$eval('#btnCart', el => el.textContent); // 打开抽屉看条目数 await page.click('#btnCart'); await page.waitForTimeout(300); const items = await page.$$eval('#cartList .cart-item', els => els.length); console.log('下载按钮可见:', dlVisible, '| 加入清单可见:', addVisible); console.log('第一次加入后角标:', badge1, '| 第二次后:', badge2, '| 抽屉条目:', items); console.log('页面错误:', errs.length ? errs.join(' | ') : '无'); await browser.close(); if (!dlVisible || !addVisible || badge1.indexOf('(1)') < 0 || badge2.indexOf('(2)') < 0 || items !== 2 || errs.length) process.exit(1); })().catch(e => { console.error('FAIL:', e.message); process.exit(1); });