import { chromium } from '@playwright/test' /** * 真实场景:内容多、需要垂直滚动。 * 用 table-big-wrap(5000 行虚拟滚动)与 table-wrap 塞满行两种方式, * 看底部到底是几条线、以及滚动到不同位置时是否稳定。 */ const BASE = process.env.PROBE_URL || 'http://localhost:5200' const browser = await chromium.launch() const page = await browser.newPage({ viewport: { width: 1400, height: 1200 } }) await page.goto(BASE, { waitUntil: 'networkidle' }) const clipSample = async (x, y, w, h) => { const shot = await page.screenshot({ clip: { x, y, width: w, height: h } }) return page.evaluate(async (dataUrl) => { const img = new Image() await new Promise((res) => { img.onload = res img.src = dataUrl }) const cv = document.createElement('canvas') cv.width = img.width cv.height = img.height const ctx = cv.getContext('2d') ctx.drawImage(ctx.canvas, 0, 0) ctx.drawImage(img, 0, 0) const d = ctx.getImageData(0, 0, img.width, img.height).data const out = [] for (let i = 0; i < d.length; i += 4) out.push([d[i], d[i + 1], d[i + 2]]) return out }, `data:image/png;base64,${shot.toString('base64')}`) } const probe = async (testid, label) => { const el = page.locator(`[data-testid="${testid}"]`) await el.scrollIntoViewIfNeeded() await page.waitForTimeout(300) const g = await el.evaluate((wrap) => { const root = wrap.querySelector('.g3-table') const inner = wrap.querySelector('.stk-table') const r = root.getBoundingClientRect() return { left: Math.round(r.left), bottom: Math.round(r.bottom), rootCls: root.className, overflow: inner.scrollHeight > inner.clientHeight + 1, scrollH: inner.scrollHeight, clientH: inner.clientHeight, rowCount: wrap.querySelectorAll('.stk-tbody-main tr').length, } }) const y = Math.max(0, g.bottom - 4) if (1200 - y < 10) { console.log(`${label}: 采样超出视口 (bottom=${g.bottom})`) return } const px = await clipSample(g.left + 300, y, 1, 10) const vec = px.map(([r, gg, b]) => (r < 246 || gg < 246 || b < 246 ? 1 : 0)) const n = vec.reduce((a, b) => a + b, 0) console.log( `${label.padEnd(18)} overflow=${String(g.overflow).padStart(5)} (${g.scrollH}/${g.clientH}) rows=${String(g.rowCount).padStart(3)} 底部 ${vec.join('')} (${n}条) ${n === 1 ? '✅' : '❌'} bodyFill=${g.rootCls.includes('is-body-fill')}`, ) } console.log('===== 现有 playground 表格 =====') for (const [id, label] of [ ['table-wrap', 'table-wrap(3行)'], ['table-big-wrap', 'table-big(5000行)'], ['table-plain-wrap', 'table-plain(2行)'], ['table-fixed-wrap', 'table-fixed'], ]) { if ((await page.locator(`[data-testid="${id}"]`).count()) === 0) continue await probe(id, label) } await browser.close()