Files
site-builder/craft/src/utils/self-review-capture.strips.test.ts
T
shadowdaoandClaude Opus 5.5 04c0b0a08a sitesmith capture: show the whole page as side-by-side strips (max 9000 px)
The capture stopped at 3000 CSS px, so the reviewer never saw the bottom or footer. Now the full page
height H is rendered at its normal width (1280). H <= 3000: one image, as before. Otherwise
N = min(3, ceil(H/3000)) equal-height strips (each <= 3000 px) are laid out side by side, left to
right (strip 1 = page top), with 24 px #808080 gutters, in one JPEG; H > 9000 shows the top 9000 px
(cropped). Geometry is the pure stripGeometry() (unit-tested); JPEG quality steps 0.8 -> 0.5 before
"too large" (3 MB cap, server limit 8 MB). CaptureResult gains strips/pageHeight; runSelfReview
returns them and says when only the top of a long page was reviewed. Real eval pages: 2 strips,
~0.8-1.1 s, 150-270 KB in Chromium and Firefox; e2e checks strip order/alignment/gutters/cropping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:27:56 -08:00

57 lines
3.2 KiB
TypeScript

import { describe, expect, test } from 'vitest';
import { stripGeometry } from './self-review-capture';
/**
* The self-review screenshot geometry the server-side review prompt is written against:
* H <= 3000: one image. Else N = min(3, ceil(H/3000)) equal-height strips (<= 3000 px), side by side left to
* right (strip 1 = top of the page, on the left), 24 px #808080 gutters. H > 9000: top 9000 px only (cropped).
*/
describe('stripGeometry', () => {
test('short page: one image, as before', () => {
expect(stripGeometry(1800, 1280)).toEqual({
strips: 1, stripHeight: 1800, shownHeight: 1800, cropped: false, width: 1280, height: 1800, gutter: 24,
rects: [{ sy: 0, sh: 1800, dx: 0 }],
});
expect(stripGeometry(3000, 1280)).toMatchObject({ strips: 1, width: 1280, height: 3000, cropped: false });
});
test('3001..6000: two strips side by side with one 24 px gutter', () => {
expect(stripGeometry(5000, 1280)).toEqual({
strips: 2, stripHeight: 2500, shownHeight: 5000, cropped: false, width: 2584, height: 2500, gutter: 24,
rects: [{ sy: 0, sh: 2500, dx: 0 }, { sy: 2500, sh: 2500, dx: 1304 }],
});
expect(stripGeometry(3001, 1280)).toMatchObject({ strips: 2, stripHeight: 1501, rects: [{ sy: 0, sh: 1501 }, { sy: 1501, sh: 1500 }] });
expect(stripGeometry(6000, 1280)).toMatchObject({ strips: 2, stripHeight: 3000, width: 2584 });
});
test('6001..9000: three strips', () => {
expect(stripGeometry(7500, 1280)).toEqual({
strips: 3, stripHeight: 2500, shownHeight: 7500, cropped: false, width: 3888, height: 2500, gutter: 24,
rects: [{ sy: 0, sh: 2500, dx: 0 }, { sy: 2500, sh: 2500, dx: 1304 }, { sy: 5000, sh: 2500, dx: 2608 }],
});
expect(stripGeometry(9000, 1280)).toMatchObject({ strips: 3, stripHeight: 3000, cropped: false });
});
test('taller than 9000: top 9000 px in three 3000 px strips, cropped', () => {
expect(stripGeometry(14321, 1280)).toEqual({
strips: 3, stripHeight: 3000, shownHeight: 9000, cropped: true, width: 3888, height: 3000, gutter: 24,
rects: [{ sy: 0, sh: 3000, dx: 0 }, { sy: 3000, sh: 3000, dx: 1304 }, { sy: 6000, sh: 3000, dx: 2608 }],
});
});
test('invariants over a range of heights', () => {
for (let h = 1; h <= 20000; h += 37) {
const g = stripGeometry(h, 1280);
expect(g.stripHeight).toBeLessThanOrEqual(3000);
expect(g.strips).toBe(h <= 3000 ? 1 : Math.min(3, Math.ceil(h / 3000)));
expect(g.shownHeight).toBe(Math.min(h, 9000));
expect(g.cropped).toBe(h > 9000);
expect(g.rects.reduce((s, r) => s + r.sh, 0)).toBe(g.shownHeight); // every shown row exactly once
g.rects.forEach((r, i) => { expect(r.sy).toBe(i * g.stripHeight); expect(r.dx).toBe(i * (1280 + 24)); expect(r.sh).toBeGreaterThan(0); });
expect(g.width).toBe(g.strips * 1280 + (g.strips - 1) * 24);
}
});
test('non-integer / degenerate heights', () => {
expect(stripGeometry(0, 1280)).toMatchObject({ strips: 1, height: 1 });
expect(stripGeometry(Number.NaN, 1280)).toMatchObject({ strips: 1, height: 1 });
expect(stripGeometry(3000.4, 1280)).toMatchObject({ strips: 1, height: 3000 });
expect(stripGeometry(3000.6, 1280)).toMatchObject({ strips: 2 });
});
});