Skip to content

Commit 968aa52

Browse files
PrateekJannuclaude
andcommitted
chore(e2e): screenshot harness — scroll/theme/many-runs edge scenarios
Seeds the theme preference (so the footer switcher's active state matches the rendered theme), adds a tall many-runs page scrolled to the bottom to prove the sidebar stays fixed, and viewport (not full-page) capture for scroll scenarios. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e512d57 commit 968aa52

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

e2e/scripts/render-screens.mjs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ const SCREENS = [
212212
{ name: 'runs-mobile', path: '/runs', theme: 'dark', w: 390, h: 900 },
213213
{ name: 'home-collapsed', path: '/', theme: 'dark', w: 1280, h: 900, collapsed: true },
214214
{ name: 'home-collapsed-light', path: '/', theme: 'light', w: 1280, h: 900, collapsed: true },
215+
// Tall content scrolled to the bottom — the sidebar must stay fixed in place.
216+
{
217+
name: 'runs-scroll',
218+
path: '/runs',
219+
theme: 'dark',
220+
w: 1280,
221+
h: 700,
222+
manyRuns: true,
223+
scroll: true,
224+
},
215225
];
216226

217227
await mkdir(OUT, { recursive: true });
@@ -269,14 +279,49 @@ try {
269279
}
270280
});
271281
}
282+
// Seed the theme preference so the footer switcher's active state matches.
283+
await context.addInitScript((theme) => {
284+
try {
285+
// eslint-disable-next-line no-undef
286+
localStorage.setItem('oc-theme', theme);
287+
} catch {
288+
/* storage unavailable */
289+
}
290+
}, s.theme);
291+
if (s.manyRuns) {
292+
const many = Array.from({ length: 30 }, (_, i) =>
293+
run({
294+
id: `rm${i}`,
295+
status: ['running', 'succeeded', 'awaiting_human', 'failed'][i % 4],
296+
task: `Task ${i + 1} — reconcile, validate, and file the result`,
297+
costCents: (i * 37) % 600,
298+
stepsCompleted: (i % 12) + 1,
299+
}),
300+
);
301+
// Registered after the general route, so it wins for this exact path.
302+
await context.route('**/api/runs', (route) =>
303+
route.fulfill({
304+
status: 200,
305+
contentType: 'application/json',
306+
body: JSON.stringify({ runs: many }),
307+
}),
308+
);
309+
}
272310
const page = await context.newPage();
273311
await page.goto(`${BASE_URL}${s.path}`, { waitUntil: 'networkidle' }).catch(() => {});
274312
await page.evaluate((t) => {
275313
// eslint-disable-next-line no-undef
276314
document.documentElement.dataset.theme = t;
277315
}, s.theme);
316+
if (s.scroll) {
317+
await page.evaluate(() => {
318+
// eslint-disable-next-line no-undef
319+
const m = document.querySelector('.app-main');
320+
if (m) m.scrollTop = m.scrollHeight;
321+
});
322+
}
278323
await page.waitForTimeout(350);
279-
await page.screenshot({ path: path.join(OUT, `${s.name}.png`), fullPage: true });
324+
await page.screenshot({ path: path.join(OUT, `${s.name}.png`), fullPage: !s.scroll });
280325
console.log(`shot ${s.name} (${s.w}×${s.h}, ${s.theme})`);
281326
await context.close();
282327
}

0 commit comments

Comments
 (0)