Skip to content

Commit 3518fa5

Browse files
committed
fix(qa): sanitize evidence preview roots
1 parent a5e33b3 commit 3518fa5

2 files changed

Lines changed: 41 additions & 6 deletions

File tree

extensions/qa-lab/src/evidence-gallery.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ describe("evidence gallery", () => {
181181
const outputDir = path.join(repoRoot, ".artifacts", "qa-e2e", "vitest");
182182
const artifactPath = path.join(outputDir, "absolute.log");
183183
await fs.mkdir(outputDir, { recursive: true });
184-
await fs.writeFile(artifactPath, "absolute artifact\n", "utf8");
184+
await fs.writeFile(
185+
artifactPath,
186+
`absolute artifact ${repoRoot}\nfile://${repoRoot}/trace.log\n`,
187+
"utf8",
188+
);
185189
const evidence: QaEvidenceSummaryJson = vitestArtifactEvidence({
186190
id: "qa-lab.absolute-artifact-path",
187191
title: "Absolute artifact path",
@@ -205,7 +209,7 @@ describe("evidence gallery", () => {
205209
expect(artifact).toMatchObject({
206210
exists: true,
207211
path: ".artifacts/qa-e2e/vitest/absolute.log",
208-
preview: "absolute artifact\n",
212+
preview: "absolute artifact <repo-root>\nfile://<repo-root>/trace.log\n",
209213
});
210214
expect(artifact?.href).toContain(
211215
"artifactPath=%3Crepo-root%3E%2F.artifacts%2Fqa-e2e%2Fvitest%2Fabsolute.log",

extensions/qa-lab/src/evidence-gallery.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ function displayGalleryPath(
104104
return sanitizeGalleryText(value, params);
105105
}
106106

107+
function sanitizeGalleryPreview(
108+
value: string | null,
109+
params: {
110+
extraRoots?: readonly string[];
111+
repoRoot: string;
112+
},
113+
) {
114+
return value === null ? null : sanitizeGalleryText(value, params);
115+
}
116+
107117
async function realpathIfExists(filePath: string): Promise<string | null> {
108118
return fs.realpath(filePath).catch(() => null);
109119
}
@@ -356,6 +366,7 @@ function artifactHref(evidencePath: string, artifactPath: string) {
356366
async function buildProducerContextFile(params: {
357367
allowedRoots: readonly string[];
358368
artifactPath: string;
369+
extraRoots: readonly string[];
359370
filePath: string;
360371
hrefEvidencePath: string;
361372
previewKind: "json" | "text";
@@ -369,7 +380,14 @@ async function buildProducerContextFile(params: {
369380
return {
370381
href: artifactHref(params.hrefEvidencePath, params.artifactPath),
371382
path: repoPath,
372-
preview: await readPreview(realFile, params.previewKind).catch(() => null),
383+
preview: await readPreview(realFile, params.previewKind)
384+
.then((preview) =>
385+
sanitizeGalleryPreview(preview, {
386+
extraRoots: params.extraRoots,
387+
repoRoot: params.repoRoot,
388+
}),
389+
)
390+
.catch(() => null),
373391
};
374392
}
375393

@@ -422,9 +440,19 @@ async function buildArtifactView(params: {
422440
kind: params.artifact.kind,
423441
mediaKind,
424442
path: displayPath,
425-
preview: await readPreview(realFile, mediaKind).catch(
426-
(error: unknown) => `Preview unavailable: ${formatErrorMessage(error)}`,
427-
),
443+
preview: await readPreview(realFile, mediaKind)
444+
.then((preview) =>
445+
sanitizeGalleryPreview(preview, {
446+
extraRoots: params.extraRoots,
447+
repoRoot: params.repoRoot,
448+
}),
449+
)
450+
.catch((error: unknown) =>
451+
sanitizeGalleryText(`Preview unavailable: ${formatErrorMessage(error)}`, {
452+
extraRoots: params.extraRoots,
453+
repoRoot: params.repoRoot,
454+
}),
455+
),
428456
source: params.artifact.source,
429457
};
430458
}
@@ -603,6 +631,7 @@ async function findUxMatrixProducerRoot(params: {
603631

604632
async function buildProducerContext(params: {
605633
evidencePath: string;
634+
extraRoots: readonly string[];
606635
hrefEvidencePath: string;
607636
repoRoot: string;
608637
summaryEntries: readonly QaEvidenceSummaryEntry[];
@@ -632,6 +661,7 @@ async function buildProducerContext(params: {
632661
await buildProducerContextFile({
633662
allowedRoots,
634663
artifactPath: toRepoRelativePath(repoRoot, producerPaths[file.key]),
664+
extraRoots: params.extraRoots,
635665
filePath: producerPaths[file.key],
636666
hrefEvidencePath: params.hrefEvidencePath,
637667
previewKind: file.previewKind,
@@ -784,6 +814,7 @@ export async function buildQaEvidenceGalleryModel(params: {
784814
profile: summary.profile ?? null,
785815
producerContext: await buildProducerContext({
786816
evidencePath,
817+
extraRoots: [requestedRepoRoot],
787818
hrefEvidencePath,
788819
repoRoot,
789820
summaryEntries: summary.entries,

0 commit comments

Comments
 (0)