This commit is contained in:
Felix Klement committed 2026-09-18 18:28:28 +02:00
1 parent d97f541738
commit 0c2b4e7df2
16 files changed
+696 -179

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
import { chromium } from 'playwright';
/* Jumps to card 3 via its dot, then back to card 1 via its dot, and reports where the page rests. */
const [,, url, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const snaps = await page.evaluate(() => Array.from(document.querySelectorAll('[data-deck-snap]')).map((a) => Math.round(a.getBoundingClientRect().top + window.scrollY - parseFloat(getComputedStyle(a).scrollMarginTop))));
const dots = page.locator('[data-deck-dots] a');
await page.evaluate((y) => window.scrollTo(0, y), snaps[2]);
await page.waitForTimeout(800);
const before = await page.evaluate(() => Math.round(window.scrollY));
await dots.nth(0).click();
await page.waitForTimeout(1500);
const back = await page.evaluate(() => Math.round(window.scrollY));
await dots.nth(3).click();
await page.waitForTimeout(1500);
const fwd = await page.evaluate(() => Math.round(window.scrollY));
const active = await page.evaluate(() => Array.from(document.querySelectorAll('[data-deck-dots] a')).map((a) => a.getAttribute('aria-current') === 'true'));
const hint = await page.evaluate(() => { const h = document.querySelector('[data-deck-hint]'); return { href: h?.getAttribute('href'), last: h?.hasAttribute('data-last') }; });
console.log({ snaps, before, backTo1: back, expected1: snaps[0], fwdTo4: fwd, expected4: snaps[3], active, hint });
await browser.close();
+20
View File
@@ -0,0 +1,20 @@
import { chromium } from 'playwright';
/* Reports where the chevron hint sits at the first snap and whether anything covers it. */
const [,, url, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const snaps = await page.evaluate(() => Array.from(document.querySelectorAll('[data-deck-snap]')).map((a) => Math.round(a.getBoundingClientRect().top + window.scrollY - parseFloat(getComputedStyle(a).scrollMarginTop))));
await page.evaluate((y) => window.scrollTo(0, y), snaps[0]);
await page.waitForTimeout(800);
const info = await page.evaluate(() => {
const h = document.querySelector('[data-deck-hint]');
const r = h.getBoundingClientRect();
const cs = getComputedStyle(h);
const svg = h.querySelector('svg').getBoundingClientRect();
const atPoint = document.elementFromPoint(window.innerWidth / 2, window.innerHeight - 10);
const next = document.querySelectorAll('[data-deck-card]')[1].getBoundingClientRect();
return { hint: { top: r.top, bottom: r.bottom, h: r.height }, svg: { top: svg.top, bottom: svg.bottom }, position: cs.position, display: cs.display, bottom: cs.bottom, zIndex: cs.zIndex, opacity: cs.opacity, atPoint: atPoint && (atPoint.tagName + '.' + atPoint.className), nextCardTop: next.top, innerHeight: window.innerHeight };
});
console.log(JSON.stringify(info, null, 1));
await browser.close();
+14
View File
@@ -0,0 +1,14 @@
import { chromium } from 'playwright';
/* Hovers one node group of a schematic and captures the drawing. */
const [,, url, out, selector, group] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto(url, { waitUntil: 'networkidle' });
const svg = page.locator(selector).first();
await svg.scrollIntoViewIfNeeded();
await page.waitForTimeout(3500);
await svg.locator(`[data-group="${group}"] .s-ring`).first().hover({ force: true, position: { x: 6, y: 36 } });
await page.waitForTimeout(400);
await svg.screenshot({ path: out });
await browser.close();
console.log('hovered', group);
+16
View File
@@ -0,0 +1,16 @@
import { chromium } from 'playwright';
/* Scrolls a target into view and captures it at several moments, to see a draw-in happen. */
const [,, url, prefix, selector, width = '1440', times = '150,700,1600,3200'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: 900 } });
await page.goto(url, { waitUntil: 'networkidle' });
const el = page.locator(selector).first();
await el.scrollIntoViewIfNeeded();
const t0 = Date.now();
for (const t of times.split(',').map(Number)) {
const wait = t - (Date.now() - t0);
if (wait > 0) await page.waitForTimeout(wait);
await el.screenshot({ path: `${prefix}-${t}.png` });
}
await browser.close();
console.log('captured', selector);
+28
View File
@@ -0,0 +1,28 @@
import { chromium } from 'playwright';
/* Scrolls to positions around each deck card's snap point and reports where the page comes to rest. */
const [,, url, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const info = await page.evaluate(() => {
const cards = Array.from(document.querySelectorAll('[data-deck-snap]'));
const cs = getComputedStyle(document.documentElement);
return cards.map((c, i) => {
const st = getComputedStyle(c);
return { i, naturalTop: c.offsetTop + (c.offsetParent?.getBoundingClientRect().top ?? 0) + window.scrollY, marginTop: st.scrollMarginTop, snapAlign: st.scrollSnapAlign, snapStop: st.scrollSnapStop, htmlSnap: cs.scrollSnapType };
});
});
console.log(JSON.stringify(info, null, 1));
// expected snap points: naturalTop - scrollMarginTop
const results = [];
for (const c of info) {
const expected = Math.round(c.naturalTop - parseFloat(c.marginTop));
for (const off of [-220, 180, 320, 352]) {
await page.evaluate((y) => window.scrollTo({ top: y, behavior: 'auto' }), expected + off);
await page.waitForTimeout(1200);
const y = await page.evaluate(() => Math.round(window.scrollY));
results.push({ card: c.i, expected, offset: off, landed: y, snapped: Math.abs(y - expected) < 2 });
}
}
console.table(results);
await browser.close();
+13
View File
@@ -0,0 +1,13 @@
import { chromium } from 'playwright';
const [,, url, prefix, anchor, width = '1440', height = '900', step = '450', count = '10'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const start = await page.evaluate((sel) => document.querySelector(sel).getBoundingClientRect().top + window.scrollY, anchor);
for (let i = 0; i < Number(count); i++) {
await page.evaluate((y) => window.scrollTo(0, y), start + i * Number(step));
await page.waitForTimeout(i === 0 ? 3000 : 1800);
await page.screenshot({ path: `${prefix}-${String(i).padStart(2, '0')}.png` });
}
await browser.close();
console.log('stack shots', count);
+13
View File
@@ -0,0 +1,13 @@
import { chromium } from 'playwright';
const [,, url, prefix, anchor, width = '1440', height = '900', step = '450', count = '10'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const start = await page.evaluate((sel) => document.querySelector(sel).getBoundingClientRect().top + window.scrollY, anchor);
for (let i = 0; i < Number(count); i++) {
await page.evaluate((y) => window.scrollTo(0, y), start + i * Number(step));
await page.waitForTimeout(i === 0 ? 2500 : 1500);
await page.screenshot({ path: `${prefix}-${String(i).padStart(2, '0')}.png` });
}
await browser.close();
console.log('stack shots', count);
+14
View File
@@ -0,0 +1,14 @@
import { chromium } from 'playwright';
/* Scrolls from an anchor downwards in steps, capturing the viewport each time. */
const [,, url, prefix, anchor, width = '1440', height = '900', step = '450', count = '10'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const start = await page.evaluate((sel) => document.querySelector(sel).getBoundingClientRect().top + window.scrollY, anchor);
for (let i = 0; i < Number(count); i++) {
await page.evaluate((y) => window.scrollTo(0, y), start + i * Number(step));
await page.waitForTimeout(i === 0 ? 3000 : 1800);
await page.screenshot({ path: `${prefix}-${String(i).padStart(2, '0')}.png` });
}
await browser.close();
console.log('stack shots', count);