u
This commit is contained in:
1 parent
b4498e5350
commit
bf9dca19de
47 files changed
+8592
-313
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import { chromium } from '@playwright/test'
|
||||
|
||||
/**
|
||||
* 方向验证:在滚动容器底部覆盖一条 1px 的同色线(画在格线之上、外框之下),
|
||||
* 把"被裁切行留下的底边线"盖掉,使可视底边恒为一条。
|
||||
*
|
||||
* 用 ::after 伪元素实现(absolute,画在内容上层)。
|
||||
*/
|
||||
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')}`)
|
||||
}
|
||||
|
||||
const applyPatch = () =>
|
||||
page.evaluate(() => {
|
||||
const s = document.createElement('style')
|
||||
s.id = 'probe-cover'
|
||||
s.textContent = `
|
||||
/* 覆盖式收边:在 .stk-table 可视底部画一条与外框同色的线,压住被裁行的底边 */
|
||||
.g3-table.is-bordered .g3-table__inner.stk-table { position: relative; }
|
||||
.g3-table.is-bordered .g3-table__inner.stk-table::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset-inline: 0;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
background: var(--g3-border-color, #d9d9d9);
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
`
|
||||
document.head.appendChild(s)
|
||||
})
|
||||
|
||||
const heights = [500, 400, 300, 250, 200, 180, 160, 150, 140, 130, 120, 110, 100]
|
||||
|
||||
const sweep = async (label) => {
|
||||
const bad = []
|
||||
for (const h of heights) {
|
||||
await page.evaluate((hh) => {
|
||||
document.querySelector('[data-testid="table-big-wrap"]').style.height = `${hh}px`
|
||||
}, h)
|
||||
await page.waitForTimeout(420)
|
||||
await page.locator('[data-testid="table-big-wrap"]').scrollIntoViewIfNeeded()
|
||||
await page.waitForTimeout(180)
|
||||
|
||||
const g = await page.evaluate(() => {
|
||||
const wrap = document.querySelector('[data-testid="table-big-wrap"]')
|
||||
const root = wrap.querySelector('.g3-table')
|
||||
const r = root.getBoundingClientRect()
|
||||
return { left: Math.round(r.left), bottom: Math.round(r.bottom) }
|
||||
})
|
||||
const y = Math.max(0, g.bottom - 4)
|
||||
if (1200 - y < 10) 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)
|
||||
if (n !== 1) bad.push(`h=${h}(${n})`)
|
||||
console.log(` ${label} h=${String(h).padStart(3)} ${vec.join('')} (${n}条) ${n === 1 ? '✅' : '❌'}`)
|
||||
}
|
||||
console.log(` → ${label} 失败档位: ${bad.length ? bad.join(', ') : '无 ✅'}\n`)
|
||||
}
|
||||
|
||||
console.log('===== 修复前(table-big,真实滚动)=====')
|
||||
await sweep('before')
|
||||
|
||||
console.log('===== 加覆盖式收边 =====')
|
||||
await applyPatch()
|
||||
await sweep('patch ')
|
||||
|
||||
await browser.close()
|
||||
Reference in new issue
Block a user