




















@@ -7,6 +7,7 @@ import {
77buildQaEvidenceGalleryModel,
88resolveQaEvidenceArtifactFileByIndex,
99resolveQaEvidenceArtifactFile,
10+resolveQaEvidenceProducerFile,
1011resolveQaEvidenceFile,
1112} from "./evidence-gallery.js";
1213import {
@@ -24,6 +25,23 @@ async function writeJson(filePath: string, value: unknown) {
2425await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
2526}
262728+function producerRootLeakSegments(repoRoot: string) {
29+if (process.platform !== "win32") {
30+return [`nested${repoRoot}`];
31+}
32+return [
33+"nested",
34+ ...repoRoot
35+.split(/[\\/]+/u)
36+.filter(Boolean)
37+.map((part) => part.replace(/[^A-Za-z0-9._-]/gu, "_")),
38+];
39+}
40+41+function repoRelativePath(repoRoot: string, filePath: string) {
42+return path.relative(repoRoot, filePath).split(path.sep).join("/");
43+}
44+2745function vitestArtifactEvidence(params: {
2846id: string;
2947title: string;
@@ -276,7 +294,21 @@ describe("evidence gallery", () => {
276294it("detects UX Matrix producer context from suite-level evidence artifacts", async () => {
277295const repoRoot = await createTempRepo();
278296const suiteDir = path.join(repoRoot, ".artifacts", "qa-e2e", "suite");
279-const runDir = path.join(suiteDir, "script", "ux-matrix-evidence-dashboard", "run-1");
297+const runDir = path.join(
298+suiteDir,
299+"script",
300+ ...producerRootLeakSegments(repoRoot),
301+"ux-matrix-evidence-dashboard",
302+"run-1",
303+);
304+const expectedWebScreenshotNeedle =
305+process.platform === "win32"
306+ ? ".artifacts/qa-e2e/suite/script/nested"
307+ : ".artifacts/qa-e2e/suite/script/nested<repo-root>/ux-matrix-evidence-dashboard/run-1/surfaces/web-ui/stages/first-run/screenshot.png";
308+const expectedCliLogNeedle =
309+process.platform === "win32"
310+ ? ".artifacts/qa-e2e/suite/script/nested"
311+ : ".artifacts/qa-e2e/suite/script/nested<repo-root>/ux-matrix-evidence-dashboard/run-1/surfaces/cli/stages/error-state/logs.txt";
280312await fs.mkdir(path.join(runDir, "surfaces", "web-ui", "stages", "first-run"), {
281313recursive: true,
282314});
@@ -430,7 +462,10 @@ describe("evidence gallery", () => {
430462artifacts: [
431463{
432464kind: "log",
433-path: ".artifacts/qa-e2e/suite/script/ux-matrix-evidence-dashboard/run-1/surfaces/cli/stages/error-state/logs.txt",
465+path: repoRelativePath(
466+repoRoot,
467+path.join(runDir, "surfaces", "cli", "stages", "error-state", "logs.txt"),
468+),
434469source: "ux-matrix:cli:error-state",
435470},
436471],
@@ -478,9 +513,7 @@ describe("evidence gallery", () => {
478513expect(model.producerContext?.matrix?.cells).toEqual([
479514{
480515artifactKinds: ["screenshot"],
481-artifactPaths: [
482-".artifacts/qa-e2e/suite/script/ux-matrix-evidence-dashboard/run-1/surfaces/web-ui/stages/first-run/screenshot.png",
483-],
516+artifactPaths: [expect.stringContaining(expectedWebScreenshotNeedle)],
484517coverageIds: ["<repo-root>/ui.control"],
485518runner: {
486519availability: "local",
@@ -512,9 +545,7 @@ describe("evidence gallery", () => {
512545},
513546{
514547artifactKinds: ["log"],
515-artifactPaths: [
516-".artifacts/qa-e2e/suite/script/ux-matrix-evidence-dashboard/run-1/surfaces/cli/stages/error-state/logs.txt",
517-],
548+artifactPaths: [expect.stringContaining(expectedCliLogNeedle)],
518549coverageIds: [],
519550runner: null,
520551stage: "error-state",
@@ -526,9 +557,12 @@ describe("evidence gallery", () => {
526557]);
527558expect(model.producerContext?.scorecard?.preview).toContain("# UX Matrix");
528559expect(model.producerContext?.scorecard?.href).toContain("/api/evidence/artifact?");
529-expect(model.producerContext?.scorecard?.href).not.toContain(repoRoot);
560+expect(decodeURIComponent(model.producerContext?.scorecard?.href ?? "")).not.toContain(
561+repoRoot,
562+);
530563expect(model.producerContext?.commands?.preview).toBe("node ux matrix\n");
531564expect(model.producerContext?.commands?.path).toContain("commands.txt");
565+expect(decodeURIComponent(model.producerContext?.commands?.href ?? "")).not.toContain(repoRoot);
532566expect(model.producerContext?.manifest?.preview).toContain('"runId": "run-1"');
533567expect(model.producerContext?.releaseLedger?.preview).toContain('"proof-gap": 1');
534568expect(model.producerContext?.preflight.memory?.path).toContain("preflight/memory.txt");
@@ -538,6 +572,14 @@ describe("evidence gallery", () => {
538572);
539573expect(model.producerContext?.preflight.adbDevices?.preview).toBe("List of devices\n");
540574expect(model.evidencePath).toBe(".artifacts/qa-e2e/suite/qa-evidence.json");
575+expect(JSON.stringify(model)).not.toContain(repoRoot);
576+await expect(
577+resolveQaEvidenceProducerFile({
578+evidencePath: suiteDir,
579+producerFile: "scorecard",
580+ repoRoot,
581+}),
582+).resolves.toBe(await fs.realpath(path.join(runDir, "scorecard.md")));
541583const outsideDir = await fs.mkdtemp(path.join(os.tmpdir(), "qa-evidence-outside-"));
542584const outsideCommands = path.join(outsideDir, "commands.txt");
543585await fs.writeFile(outsideCommands, "outside secret\n", "utf8");
@@ -551,8 +593,7 @@ describe("evidence gallery", () => {
551593expect(JSON.stringify(symlinkModel)).not.toContain("outside secret");
552594await expect(
553595resolveQaEvidenceArtifactFile({
554-artifactPath:
555-".artifacts/qa-e2e/suite/script/ux-matrix-evidence-dashboard/run-1/scorecard.md",
596+artifactPath: path.relative(repoRoot, path.join(runDir, "scorecard.md")),
556597evidencePath: suiteDir,
557598 repoRoot,
558599}),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。