All folders stick at --stack-reveal; higher layers paint over lower ones. Bodies hidden until panel aligns on the stack line (no vertical list). Co-authored-by: Cursor <cursoragent@cursor.com>
77 lines
2.9 KiB
JavaScript
77 lines
2.9 KiB
JavaScript
import { chromium } from 'playwright';
|
|
import { writeFileSync, mkdirSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
const BASE = process.env.BASE_URL || 'http://localhost:5173';
|
|
const OUT = '/tmp/levkin-stack-test';
|
|
mkdirSync(OUT, { recursive: true });
|
|
|
|
const pages = [
|
|
{ name: 'stack', path: '/stack/', bodySel: '.layer-inner' },
|
|
{ name: 'stack-folder', path: '/stack-folder/', bodySel: '.folder .body' },
|
|
{ name: 'stack-trace', path: '/stack-trace/', bodySel: '.frame-body' },
|
|
{ name: 'stack-rack', path: '/stack-rack/', bodySel: '.unit-body' },
|
|
];
|
|
|
|
const scrollY = [0, 400, 800, 1200, 1800, 2400];
|
|
|
|
async function analyze(page, bodySel) {
|
|
const reveal = await page.evaluate(() => {
|
|
const s = getComputedStyle(document.documentElement);
|
|
return parseFloat(s.getPropertyValue('--stack-reveal')) ||
|
|
(48 + 44 * 6 + 32);
|
|
});
|
|
|
|
return page.evaluate(({ bodySel, reveal }) => {
|
|
const bodies = [...document.querySelectorAll(bodySel)];
|
|
const stacked = bodies.filter((b) => {
|
|
const r = b.getBoundingClientRect();
|
|
return Math.abs(r.top - reveal) < 35 && r.height > 80;
|
|
});
|
|
const visible = bodies.filter((b) => {
|
|
const r = b.getBoundingClientRect();
|
|
return r.height > 80 && r.bottom > 0 && r.top < innerHeight;
|
|
});
|
|
const el = document.elementFromPoint(innerWidth / 2, reveal + 100);
|
|
const panel = el?.closest('.folder, .layer, .frame, .unit');
|
|
const layer = panel?.closest('[data-layer]')?.dataset?.layer;
|
|
const title = panel?.querySelector('h1, h2, strong')?.textContent?.trim().slice(0, 50);
|
|
return {
|
|
scrollY: Math.round(window.scrollY),
|
|
reveal: Math.round(reveal),
|
|
stackedCount: stacked.length,
|
|
visibleCount: visible.length,
|
|
topLayer: layer,
|
|
topTitle: title,
|
|
issues: [],
|
|
};
|
|
}, { bodySel, reveal });
|
|
}
|
|
|
|
const browser = await chromium.launch({ headless: true });
|
|
const report = [];
|
|
|
|
for (const { name, path, bodySel } of pages) {
|
|
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
|
|
await page.goto(BASE + path, { waitUntil: 'networkidle' });
|
|
const shots = [];
|
|
for (const y of scrollY) {
|
|
await page.evaluate((sy) => window.scrollTo(0, sy), y);
|
|
await page.waitForTimeout(250);
|
|
const data = await analyze(page, bodySel);
|
|
if (data.stackedCount < 2 && y > 200) data.issues.push('not stacking (need 2+ bodies at reveal line)');
|
|
if (data.visibleCount > 2 && y > 200) data.issues.push(`${data.visibleCount} bodies spread out, not covering`);
|
|
await page.screenshot({ path: join(OUT, `${name}-scroll-${y}.png`) });
|
|
shots.push({ y, ...data });
|
|
}
|
|
report.push({ name, shots });
|
|
await page.close();
|
|
}
|
|
|
|
await browser.close();
|
|
writeFileSync(join(OUT, 'report.json'), JSON.stringify(report, null, 2));
|
|
console.log(JSON.stringify(report.map((r) => ({
|
|
variant: r.name,
|
|
checks: r.shots.map((s) => ({ y: s.y, stacked: s.stackedCount, top: s.topTitle, issues: s.issues })),
|
|
})), null, 2));
|