fix: resolve lint and formatting failures

- Fix ESLint errors in compare.ts: remove unused params, use toSorted(),
  restructure negated conditions, move imgTag to module scope, replace
  process.exit with throw
- Fix ESLint errors in analyze-deps.ts: use toSorted(), wrap callback
  in arrow function, replace process.exit with throw
- Run Prettier on compare.ts, run-scenarios.ts, and navigation-bar.svelte

https://claude.ai/code/session_01XSTqDJXuR4jaLN7SGm3uES
This commit is contained in:
Claude
2026-03-01 22:22:33 +00:00
parent d20def9f66
commit b374d7eb87
4 changed files with 39 additions and 47 deletions
+3 -3
View File
@@ -222,8 +222,8 @@ export function analyzeAffectedRoutes(changedFiles: string[]): AnalysisResult {
const pages = findAffectedPages(resolvedChanged, reverseGraph); const pages = findAffectedPages(resolvedChanged, reverseGraph);
const affectedPages = [...pages].sort(); const affectedPages = [...pages].toSorted();
const affectedRoutes = [...new Set(affectedPages.map(pageFileToRoute))].sort(); const affectedRoutes = [...new Set(affectedPages.map((f) => pageFileToRoute(f)))].toSorted();
return { affectedPages, affectedRoutes }; return { affectedPages, affectedRoutes };
} }
@@ -234,7 +234,7 @@ if (process.argv[1]?.endsWith('analyze-deps.ts') || process.argv[1]?.endsWith('a
if (files.length === 0) { if (files.length === 0) {
console.log('Usage: analyze-deps.ts <changed-file1> <changed-file2> ...'); console.log('Usage: analyze-deps.ts <changed-file1> <changed-file2> ...');
console.log('Files should be relative to the repo root (e.g. web/src/lib/components/Button.svelte)'); console.log('Files should be relative to the repo root (e.g. web/src/lib/components/Button.svelte)');
process.exit(1); throw new Error('No files provided');
} }
const result = analyzeAffectedRoutes(files); const result = analyzeAffectedRoutes(files);
+18 -33
View File
@@ -15,13 +15,7 @@ import { PNG } from 'pngjs';
// based on the approach from the pixelmatch library to avoid adding a new dependency. // based on the approach from the pixelmatch library to avoid adding a new dependency.
// The e2e package already has pngjs. // The e2e package already has pngjs.
function pixelMatch( function pixelMatch(img1Data: Uint8Array, img2Data: Uint8Array, diffData: Uint8Array): number {
img1Data: Uint8Array,
img2Data: Uint8Array,
diffData: Uint8Array,
width: number,
height: number,
): number {
let diffCount = 0; let diffCount = 0;
for (let i = 0; i < img1Data.length; i += 4) { for (let i = 0; i < img1Data.length; i += 4) {
@@ -79,14 +73,12 @@ export function compareScreenshots(baseDir: string, prDir: string, outputDir: st
const baseFiles = existsSync(baseDir) const baseFiles = existsSync(baseDir)
? new Set(readdirSync(baseDir).filter((f) => f.endsWith('.png'))) ? new Set(readdirSync(baseDir).filter((f) => f.endsWith('.png')))
: new Set<string>(); : new Set<string>();
const prFiles = existsSync(prDir) const prFiles = existsSync(prDir) ? new Set(readdirSync(prDir).filter((f) => f.endsWith('.png'))) : new Set<string>();
? new Set(readdirSync(prDir).filter((f) => f.endsWith('.png')))
: new Set<string>();
const allNames = new Set([...baseFiles, ...prFiles]); const allNames = new Set([...baseFiles, ...prFiles]);
const results: ComparisonResult[] = []; const results: ComparisonResult[] = [];
for (const fileName of [...allNames].sort()) { for (const fileName of [...allNames].toSorted()) {
const name = basename(fileName, '.png'); const name = basename(fileName, '.png');
const basePath = join(baseDir, fileName); const basePath = join(baseDir, fileName);
const prPath = join(prDir, fileName); const prPath = join(prDir, fileName);
@@ -123,13 +115,7 @@ export function compareScreenshots(baseDir: string, prDir: string, outputDir: st
const diffPng = new PNG({ width, height }); const diffPng = new PNG({ width, height });
const totalPixels = width * height; const totalPixels = width * height;
const diffPixels = pixelMatch( const diffPixels = pixelMatch(normalizedBase, normalizedPr, diffPng.data as unknown as Uint8Array);
normalizedBase,
normalizedPr,
diffPng.data as unknown as Uint8Array,
width,
height,
);
const diffImagePath = join(outputDir, `${name}-diff.png`); const diffImagePath = join(outputDir, `${name}-diff.png`);
writeFileSync(diffImagePath, PNG.sync.write(diffPng)); writeFileSync(diffImagePath, PNG.sync.write(diffPng));
@@ -194,12 +180,12 @@ export function generateMarkdownReport(results: ComparisonResult[]): string {
md += '|------|--------|--------|\n'; md += '|------|--------|--------|\n';
for (const result of changed) { for (const result of changed) {
if (!result.baseExists) { if (result.baseExists && result.prExists) {
md += `| ${result.name} | New | - |\n`;
} else if (!result.prExists) {
md += `| ${result.name} | Removed | - |\n`;
} else {
md += `| ${result.name} | Changed | ${result.changePercent.toFixed(1)}% |\n`; md += `| ${result.name} | Changed | ${result.changePercent.toFixed(1)}% |\n`;
} else if (result.prExists) {
md += `| ${result.name} | New | - |\n`;
} else {
md += `| ${result.name} | Removed | - |\n`;
} }
} }
@@ -216,19 +202,19 @@ export function generateMarkdownReport(results: ComparisonResult[]): string {
return md; return md;
} }
function imgTag(filePath: string | null, alt: string): string {
if (!filePath || !existsSync(filePath)) {
return `<div class="no-image">${alt} not available</div>`;
}
const data = readFileSync(filePath);
return `<img src="data:image/png;base64,${data.toString('base64')}" alt="${alt}" loading="lazy" />`;
}
/** Generate an HTML report with embedded base64 images for the artifact. */ /** Generate an HTML report with embedded base64 images for the artifact. */
export function generateHtmlReport(results: ComparisonResult[]): string { export function generateHtmlReport(results: ComparisonResult[]): string {
const changed = results.filter((r) => r.changePercent > 0.1); const changed = results.filter((r) => r.changePercent > 0.1);
const unchanged = results.filter((r) => r.changePercent <= 0.1); const unchanged = results.filter((r) => r.changePercent <= 0.1);
function imgTag(filePath: string | null, alt: string): string {
if (!filePath || !existsSync(filePath)) {
return `<div class="no-image">${alt} not available</div>`;
}
const data = readFileSync(filePath);
return `<img src="data:image/png;base64,${data.toString('base64')}" alt="${alt}" loading="lazy" />`;
}
let html = `<!DOCTYPE html> let html = `<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@@ -320,8 +306,7 @@ if (process.argv[1]?.endsWith('compare.ts') || process.argv[1]?.endsWith('compar
const [baseDir, prDir, outputDir] = process.argv.slice(2); const [baseDir, prDir, outputDir] = process.argv.slice(2);
if (!baseDir || !prDir || !outputDir) { if (!baseDir || !prDir || !outputDir) {
console.log('Usage: compare.ts <base-dir> <pr-dir> <output-dir>'); throw new Error('Usage: compare.ts <base-dir> <pr-dir> <output-dir>');
process.exit(1);
} }
const resolvedOutputDir = resolve(outputDir); const resolvedOutputDir = resolve(outputDir);
+14 -10
View File
@@ -82,12 +82,17 @@ for (const scenario of allScenarios) {
if (scenario.mocks.includes('timeline')) { if (scenario.mocks.includes('timeline')) {
const testContext = new TimelineTestContext(); const testContext = new TimelineTestContext();
testContext.adminId = adminUserId; testContext.adminId = adminUserId;
await setupTimelineMockApiRoutes(context, timelineData, { await setupTimelineMockApiRoutes(
albumAdditions: [], context,
assetDeletions: [], timelineData,
assetArchivals: [], {
assetFavorites: [], albumAdditions: [],
}, testContext); assetDeletions: [],
assetArchivals: [],
assetFavorites: [],
},
testContext,
);
} }
if (scenario.mocks.includes('memory')) { if (scenario.mocks.includes('memory')) {
@@ -118,10 +123,9 @@ for (const scenario of allScenarios) {
// Wait for loading spinners to disappear // Wait for loading spinners to disappear
await page await page
.waitForFunction( .waitForFunction(() => document.querySelectorAll('[data-testid="loading-spinner"]').length === 0, {
() => document.querySelectorAll('[data-testid="loading-spinner"]').length === 0, timeout: 10_000,
{ timeout: 10_000 }, })
)
.catch(() => {}); .catch(() => {});
// Wait for animations/transitions to settle // Wait for animations/transitions to settle
@@ -50,7 +50,10 @@
<svelte:window bind:innerWidth /> <svelte:window bind:innerWidth />
<nav id="dashboard-navbar" class="max-md:h-(--navbar-height-md) h-(--navbar-height) w-dvw text-sm bg-red-50 dark:bg-red-950"> <nav
id="dashboard-navbar"
class="max-md:h-(--navbar-height-md) h-(--navbar-height) w-dvw text-sm bg-red-50 dark:bg-red-950"
>
<SkipLink text={$t('skip_to_content')} /> <SkipLink text={$t('skip_to_content')} />
<div <div
class="grid h-full grid-cols-[--spacing(32)_auto] items-center py-2 sidebar:grid-cols-[--spacing(64)_auto] {noBorder class="grid h-full grid-cols-[--spacing(32)_auto] items-center py-2 sidebar:grid-cols-[--spacing(64)_auto] {noBorder