Files
workspace/code/g3soft-libs/packages/ui/probe-scroll.mjs
T
2026-10-15 17:31:35 +08:00

79 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()