mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
refactor(cli): single-source-of-truth pass over the check branch
Every duplicated decision gets one owner: rectToBbox lives in checkTypes (was verbatim in pipeline and browser layers); the audit seek tuning is one exported AUDIT_SEEK_OPTIONS consumed by check and the deprecated inspect path; zoom padding/scale defaults export from the capture module instead of re-literalized in three files; the optional run_id property is built by one helper across all three telemetry events; check's --max-transition-samples parsing reuses its own positiveInteger helper; validate drops a leftover re-export and redundant explicit-default args go away. Tests: the contrast candidate round-trip gains a real integration anchor (the actual browser script eval'd in-page, a wrapper asserting finish receives the page-script bbox shape) replacing regex-over-source as the primary guard; the redundant geometry source-golden and a duplicated deprecation-envelope assertion are dropped.
This commit is contained in:
@@ -2,6 +2,9 @@ import { mkdirSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import type { Page } from "puppeteer-core";
|
||||
import {
|
||||
AUDIT_SEEK_OPTIONS,
|
||||
DEFAULT_ZOOM_PADDING_PX,
|
||||
DEFAULT_ZOOM_SCALE,
|
||||
captureRegionCrop,
|
||||
openSettledCompositionPage,
|
||||
padCropRegion,
|
||||
@@ -15,6 +18,7 @@ import { normalizeErrorMessage } from "./errorMessage.js";
|
||||
import { ambiguousIssue, type MotionFrame } from "./motionAudit.js";
|
||||
import type { LayoutIssue, LayoutIssueCode, LayoutRect } from "./layoutAudit.js";
|
||||
import { serveStaticProjectHtml } from "./staticProjectServer.js";
|
||||
import { rectToBbox } from "./checkTypes.js";
|
||||
import type {
|
||||
AnchoredLayoutIssue,
|
||||
CheckAnchor,
|
||||
@@ -35,18 +39,6 @@ import type {
|
||||
} from "./checkTypes.js";
|
||||
import type { ProjectDir } from "./project.js";
|
||||
|
||||
const SEEK_OPTIONS = {
|
||||
fallbackToBridgeAndTimelines: true,
|
||||
animationFrameSettle: "double" as const,
|
||||
waitForFontsMs: 500,
|
||||
settleMs: 120,
|
||||
};
|
||||
|
||||
// --zoom's default padding/scale, reused here so finding crops carry the same
|
||||
// bit of surrounding context an agent gets from `snapshot --zoom`.
|
||||
const FINDING_CROP_PADDING_PX = 24;
|
||||
const FINDING_CROP_SCALE = 3;
|
||||
|
||||
interface RuntimeDraft {
|
||||
code: string;
|
||||
severity: CheckSeverity;
|
||||
@@ -113,7 +105,7 @@ export async function runBrowserCheck(
|
||||
});
|
||||
chromeBrowser = session.browser;
|
||||
const page = session.page;
|
||||
await waitForPreferredSeekTarget(page, 500);
|
||||
await waitForPreferredSeekTarget(page);
|
||||
|
||||
const rootAnchor = await resolveRootAnchor(page);
|
||||
const launchSettleMs = Date.now() - launchSettleStart;
|
||||
@@ -157,18 +149,18 @@ export async function captureFindingCrops(
|
||||
});
|
||||
chromeBrowser = session.browser;
|
||||
const page = session.page;
|
||||
await waitForPreferredSeekTarget(page, 500);
|
||||
await waitForPreferredSeekTarget(page);
|
||||
|
||||
const snapshotDir = join(project.dir, "snapshots");
|
||||
mkdirSync(snapshotDir, { recursive: true });
|
||||
for (const request of requests) {
|
||||
await seekCompositionTimeline(page, request.time, SEEK_OPTIONS);
|
||||
await seekCompositionTimeline(page, request.time, AUDIT_SEEK_OPTIONS);
|
||||
const canvas = await page.evaluate(() => ({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
}));
|
||||
const region = padCropRegion(request.bbox, canvas, FINDING_CROP_PADDING_PX);
|
||||
const buffer = await captureRegionCrop(page, region, FINDING_CROP_SCALE);
|
||||
const region = padCropRegion(request.bbox, canvas, DEFAULT_ZOOM_PADDING_PX);
|
||||
const buffer = await captureRegionCrop(page, region, DEFAULT_ZOOM_SCALE);
|
||||
writeFileSync(join(snapshotDir, request.filename), buffer);
|
||||
written.push(join("snapshots", request.filename));
|
||||
}
|
||||
@@ -253,7 +245,7 @@ function createPageDriver(page: Page, setTime: (time: number) => void): CheckAud
|
||||
findAmbiguousSelectors: (selectors) => findAmbiguousSelectors(page, selectors),
|
||||
seek: async (time) => {
|
||||
setTime(time);
|
||||
await seekCompositionTimeline(page, time, SEEK_OPTIONS);
|
||||
await seekCompositionTimeline(page, time, AUDIT_SEEK_OPTIONS);
|
||||
},
|
||||
collectLayout: (time, tolerance) => collectLayout(page, time, tolerance),
|
||||
collectLayoutGeometry: () => collectLayoutGeometry(page),
|
||||
@@ -899,10 +891,6 @@ function fallbackAnchor(request: AnchorRequest | undefined): CheckAnchor {
|
||||
};
|
||||
}
|
||||
|
||||
function rectToBbox(rect: LayoutRect): CheckBbox {
|
||||
return { x: rect.left, y: rect.top, width: rect.width, height: rect.height };
|
||||
}
|
||||
|
||||
function parseBbox(value: unknown): CheckBbox | null {
|
||||
if (!isRecord(value)) return null;
|
||||
const x = numberValue(value, "x");
|
||||
|
||||
Reference in New Issue
Block a user