test(sw): stabilize Firefox hover, pixel and timing checks
- hover-stability-firefox: instant scroll and state waits instead of a fixed 60ms delay (smooth scroll in preview). - integrated-visual, viewer-regression, theme-inheritance: deterministic Chromium raster flags, animations held at time 0, layout settle wait, integer instant scroll of inner panels; tolerance stays 0. - text-weight: wait for the Viewer More panel instead of a fixed 200ms and fix the failure report.
This commit is contained in:
1 parent
1ffff67991
commit
af7f98d66b
5 files changed
+49
-14
No files matched your search
@@ -20,7 +20,9 @@ await mkdir(out, { recursive: true })
|
||||
const ids = ['overview', 'interactive-states', 'logo-slot', 'document-dropdown', 'responsive-more', 'k-guide', 'property-panel-compare', 'composed-controls', 'document-open', 'hidden-sub-controls', 'detail-buttons'].map(id => `sw-header--${id}`)
|
||||
.concat(['sw-popup--custom-content', 'sw-popup--multiple-popups'])
|
||||
const widths = [1920, 1180, 768]
|
||||
const browser = await chromium.launch({ headless: true, executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' })
|
||||
// 2026-10-20: software raster without font hinting / subpixel positioning, as integrated-visual.browser.mjs: two
|
||||
// captures of the same build otherwise differed in text anti-aliasing (Δ1 areas, 2 × 2 glyph spots). Threshold stays 0.
|
||||
const browser = await chromium.launch({ headless: true, args: ['--disable-gpu', '--font-render-hinting=none', '--disable-font-subpixel-positioning', '--disable-lcd-text', '--force-color-profile=srgb'], executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' })
|
||||
const shot = async (url, width, restore = false) => {
|
||||
const page = await browser.newPage({ viewport: { width, height: 1000 }, reducedMotion: 'reduce' })
|
||||
await page.goto(url)
|
||||
@@ -32,6 +34,15 @@ const shot = async (url, width, restore = false) => {
|
||||
const elements = []
|
||||
for (const element of await page.locator('.hm-sw-header, .hm-sw-property').all()) {
|
||||
if (!(await element.isVisible())) continue
|
||||
// 2026-10-20: panels inside an inner scroller (Property Panel · 4개 비교) were scrolled into view at varying offsets, so
|
||||
// two captures of the same build differed by 3–7px. Scroll instantly, keep every scroll offset whole, wait for stable frames.
|
||||
await element.evaluate(e => new Promise(resolve => {
|
||||
e.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'instant' })
|
||||
for (let n = e.parentElement; n; n = n.parentElement) { n.scrollTop = Math.round(n.scrollTop); n.scrollLeft = Math.round(n.scrollLeft) }
|
||||
let last = '', stable = 0
|
||||
const tick = () => { const r = e.getBoundingClientRect(), now = [r.x, r.y, r.width, r.height].join(); stable = now === last ? stable + 1 : 0; last = now; stable >= 3 ? resolve() : requestAnimationFrame(tick) }
|
||||
requestAnimationFrame(tick)
|
||||
}))
|
||||
elements.push(PNG.sync.read(await element.screenshot({ animations: 'disabled' })))
|
||||
}
|
||||
await page.close()
|
||||
|
||||
Reference in new issue
Block a user