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

80 lines
3.1 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'
/**
* 真正的滚动场景复现:行数固定(多到溢出),容器高度在「行高之和」附近连续变化。
* 这才是用户说的「表格高度 <= 行高之和」——内容溢出并出现滚动条。
*/
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(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')}`)
}
// 用 5000 行的 table-big(真实滚动)扫高度
// 表头 34 + 行 30×N;这里固定用大数据量表,只改容器高度
const heights = [500, 400, 300, 250, 200, 180, 160, 150, 140, 130, 120, 110, 100]
console.log('=== table-big(5000 行,真实滚动)扫容器高度 ===')
for (const h of heights) {
await page.evaluate((hh) => {
document.querySelector('[data-testid="table-big-wrap"]').style.height = `${hh}px`
}, h)
await page.waitForTimeout(450)
await page.locator('[data-testid="table-big-wrap"]').scrollIntoViewIfNeeded()
await page.waitForTimeout(200)
const g = await page.evaluate(() => {
const wrap = document.querySelector('[data-testid="table-big-wrap"]')
const root = wrap.querySelector('.g3-table')
const inner = wrap.querySelector('.stk-table')
const r = root.getBoundingClientRect()
const rows = [...wrap.querySelectorAll('.stk-tbody-main tr')]
const last = rows[rows.length - 1]
return {
left: Math.round(r.left),
bottom: Math.round(r.bottom),
bodyFill: root.classList.contains('is-body-fill'),
scrollH: inner.scrollHeight,
clientH: inner.clientHeight,
lastRowBottom: last ? Math.round(last.getBoundingClientRect().bottom) : null,
innerBottom: (() => {
const ir = inner.getBoundingClientRect()
return Math.round(ir.bottom)
})(),
}
})
const y = Math.max(0, g.bottom - 4)
if (1200 - y < 10) {
console.log(`h=${h} 超出视口`)
continue
}
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(
`h=${String(h).padStart(3)} fill=${String(g.bodyFill).padStart(5)} lastRowBottom=${String(g.lastRowBottom).padStart(5)} innerBottom=${String(g.innerBottom).padStart(5)} 底部 ${vec.join('')} (${n}条) ${n === 1 ? '✅' : '❌'}`,
)
}
await browser.close()