// 细节编辑验证: ①样板编辑对话框选中玻璃格→格W/H输入→边界梃平移 ②组合页编辑细节对话框→改格→保存写回 // 用法: node verify-detail.mjs import puppeteer from 'puppeteer-core' const EDGE = 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe' const token = process.argv[2] const sleep = ms => new Promise(r => setTimeout(r, ms)) const browser = await puppeteer.launch({ executablePath: EDGE, headless: 'new', args: ['--window-size=1440,900', '--enable-unsafe-swiftshader'], defaultViewport: { width: 1440, height: 900 }, }) const page = await browser.newPage() page.on('pageerror', e => console.log(`[JS异常] ${String(e).slice(0, 200)}`)) const shots = 'D:/Code/huamenchuang/shots' // 在画布内依次尝试点击候选点, 直到 HUD 出现"格W"(选中玻璃格) async function clickUntilRegion(canvasBox) { const candidates = [[0.35, 0.30], [0.30, 0.25], [0.40, 0.35], [0.32, 0.22]] for (const [fx, fy] of candidates) { await page.mouse.click(canvasBox.x + canvasBox.width * fx, canvasBox.y + canvasBox.height * fy) await sleep(350) const ok = await page.evaluate(() => { const inputs = [...document.querySelectorAll('.hud .dim-input')] return inputs.some(d => d.textContent.includes('格W')) }) if (ok) return true } return false } // 设置指定 dim-input 的数值(按标签文本查找) async function setDim(label, value) { await page.evaluate((label, value) => { const wrap = [...document.querySelectorAll('.hud .dim-input, .el-dialog .dim-input')] .find(d => d.textContent.includes(label)) if (!wrap) throw new Error('未找到输入: ' + label) const input = wrap.querySelector('input') input.value = String(value) input.dispatchEvent(new Event('input', { bubbles: true })) input.dispatchEvent(new Event('change', { bubbles: true })) }, label, value) await sleep(500) } const hasDim = label => page.evaluate((label) => { return [...document.querySelectorAll('.hud .dim-input')].some(d => d.textContent.includes(label)) }, label) // ============ ① 样板库编辑模式: 格尺寸编辑 ============ await page.goto(`http://localhost:8000/templates?token=${encodeURIComponent(token)}`, { waitUntil: 'networkidle2' }) await sleep(1500) await page.click('.sample-card .cap, .card .cap, .cap') await sleep(1200) await page.evaluate(() => { const btn = [...document.querySelectorAll('.el-dialog button')].find(b => b.textContent.includes('编辑分格')) btn?.click() }) await sleep(900) let cv = await (await page.$('.el-dialog .canvas-box canvas')).boundingBox() await page.screenshot({ path: `${shots}/detail-1-editor.png`, clip: cv }) if (!(await clickUntilRegion(cv))) { console.error('✗ 未能选中玻璃格'); process.exit(1) } await page.screenshot({ path: `${shots}/detail-2-region-selected.png`, clip: cv }) const beforeW = await page.evaluate(() => { const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格W')) return Number(wrap.querySelector('input').value) }) await setDim('格H', 800) // 亮子高度调到 800 → 横梃下移 await page.screenshot({ path: `${shots}/detail-3-region-resized.png`, clip: cv }) // 梃位编辑: 点击中央竖梃(画布中线附近) await page.mouse.click(cv.x + cv.width * 0.50, cv.y + cv.height * 0.55) await sleep(350) if (await hasDim('梃位')) { await setDim('梃位', 900) await page.screenshot({ path: `${shots}/detail-4-mullion-moved.png`, clip: cv }) console.log('✓ 梃位编辑完成') } else { console.log('△ 未命中中梃(点击位置在格上), 跳过梃位编辑截图') } console.log(`✓ 格尺寸编辑完成 (格W ${beforeW} → 调格H=800)`) await page.close() // ============ ② 组合页: 细节编辑对话框 + 保存写回 ============ const page2 = await browser.newPage() page2.on('pageerror', e => console.log(`[JS异常2] ${String(e).slice(0, 200)}`)) await page2.goto(`http://localhost:8000/combine?token=${encodeURIComponent(token)}`, { waitUntil: 'networkidle2' }) await sleep(1000) await page2.waitForSelector('.lib-item') await page2.click('.lib-item') await sleep(600) // 点击画布中心选中单元(编辑细节按钮依赖选中态) const mbox = await (await page2.$('.canvas-box canvas')).boundingBox() await page2.mouse.click(mbox.x + mbox.width / 2, mbox.y + mbox.height / 2) await sleep(400) await page2.evaluate(() => { const btn = [...document.querySelectorAll('button')].find(b => b.textContent.includes('编辑细节')) btn?.click() }) await sleep(1200) const dcv = await (await page2.$('.el-dialog canvas')).boundingBox() if (!(await (async () => { // clickUntilRegion 绑定的是 page(已关闭), 这里内联同逻辑 const candidates = [[0.35, 0.30], [0.30, 0.25], [0.40, 0.35], [0.32, 0.22]] for (const [fx, fy] of candidates) { await page2.mouse.click(dcv.x + dcv.width * fx, dcv.y + dcv.height * fy) await sleep(350) const ok = await page2.evaluate(() => { const inputs = [...document.querySelectorAll('.hud .dim-input')] return inputs.some(d => d.textContent.includes('格W')) }) if (ok) return true } return false })())) { console.error('✗ 组合细节编辑未能选中玻璃格'); process.exit(1) } await page2.screenshot({ path: `${shots}/detail-5-combine-dialog.png` }) await page2.evaluate(() => { const wrap = [...document.querySelectorAll('.hud .dim-input')].find(d => d.textContent.includes('格H')) const input = wrap.querySelector('input') input.value = '900' input.dispatchEvent(new Event('input', { bubbles: true })) input.dispatchEvent(new Event('change', { bubbles: true })) }) await sleep(500) await page2.evaluate(() => { const btn = [...document.querySelectorAll('.el-dialog__footer button')].find(b => b.textContent.includes('保存到单元')) btn?.click() }) await sleep(900) await page2.screenshot({ path: `${shots}/detail-6-combine-saved.png` }) console.log('✓ 组合细节编辑+保存写回完成') await browser.close()