Skip to content

Commit 0131f8b

Browse files
committed
fix(tests): harden WebMCP evidence capture
1 parent 0bc2391 commit 0131f8b

2 files changed

Lines changed: 48 additions & 9 deletions

File tree

packages/studio-server/src/helpers/projectSignature.test.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import { afterEach, describe, expect, it } from "vitest";
2-
import { mkdtempSync, rmSync, statSync, utimesSync, writeFileSync } from "node:fs";
2+
import {
3+
closeSync,
4+
fstatSync,
5+
ftruncateSync,
6+
futimesSync,
7+
mkdtempSync,
8+
openSync,
9+
rmSync,
10+
writeSync,
11+
} from "node:fs";
312
import { tmpdir } from "node:os";
413
import { resolve } from "node:path";
514
import { affectsProjectSignature, createProjectSignature } from "./projectSignature.js";
@@ -56,13 +65,19 @@ describe("createProjectSignature", () => {
5665
const project = mkdtempSync(resolve(tmpdir(), "hf-signature-"));
5766
temporaryProjects.push(project);
5867
const file = resolve(project, "index.html");
59-
writeFileSync(file, "first");
60-
const originalMtime = statSync(file).mtime;
61-
const before = createProjectSignature(project);
68+
const descriptor = openSync(file, "w+");
69+
try {
70+
writeSync(descriptor, "first");
71+
const originalMtime = fstatSync(descriptor).mtime;
72+
const before = createProjectSignature(project);
6273

63-
writeFileSync(file, "other");
64-
utimesSync(file, originalMtime, originalMtime);
74+
ftruncateSync(descriptor, 0);
75+
writeSync(descriptor, "other", 0, "utf8");
76+
futimesSync(descriptor, originalMtime, originalMtime);
6577

66-
expect(createProjectSignature(project)).not.toBe(before);
78+
expect(createProjectSignature(project)).not.toBe(before);
79+
} finally {
80+
closeSync(descriptor);
81+
}
6782
});
6883
});

packages/studio/tests/e2e/webmcp-edit-loop.mjs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,31 @@ async function savePreviewScreenshot(page, name) {
270270
await handle.dispose();
271271
}
272272

273+
async function saveImageEvidenceFromBrowser(url, evidenceName, contentType) {
274+
assert(browser, "Browser is unavailable for image evidence");
275+
const evidencePage = await browser.newPage();
276+
try {
277+
await evidencePage.setViewport({ width: 1200, height: 800, deviceScaleFactor: 1 });
278+
await evidencePage.goto(url, {
279+
waitUntil: "networkidle0",
280+
timeout: RENDER_TIMEOUT_MS,
281+
});
282+
const image = await evidencePage.waitForSelector("img", {
283+
visible: true,
284+
timeout: RENDER_TIMEOUT_MS,
285+
});
286+
assert(image, `Browser did not render image evidence for ${url}`);
287+
const outputPath = join(EVIDENCE_DIR, evidenceName);
288+
if (contentType.includes("jpeg")) {
289+
await image.screenshot({ path: outputPath, type: "jpeg", quality: 92 });
290+
} else {
291+
await image.screenshot({ path: outputPath, type: "png" });
292+
}
293+
} finally {
294+
await evidencePage.close();
295+
}
296+
}
297+
273298
async function fetchImage(url, evidenceName, expectedContentType = null) {
274299
const controller = new AbortController();
275300
const timeout = setTimeout(() => controller.abort(), RENDER_TIMEOUT_MS);
@@ -286,7 +311,7 @@ async function fetchImage(url, evidenceName, expectedContentType = null) {
286311
}
287312
const bytes = Buffer.from(await response.arrayBuffer());
288313
assert(bytes.length > 1_000, `Image evidence was unexpectedly small (${bytes.length} bytes)`);
289-
writeFileSync(join(EVIDENCE_DIR, evidenceName), bytes);
314+
await saveImageEvidenceFromBrowser(url, evidenceName, contentType);
290315
return { contentType, sha256: sha256(bytes), size: bytes.length };
291316
} finally {
292317
clearTimeout(timeout);
@@ -700,7 +725,6 @@ try {
700725
error: error instanceof Error ? (error.stack ?? error.message) : String(error),
701726
serverLogs: serverLogs.join("").slice(-12_000),
702727
};
703-
writeFileSync(join(EVIDENCE_DIR, "failure.json"), `${JSON.stringify(failure, null, 2)}\n`);
704728
console.error(failure.error);
705729
process.exitCode = 1;
706730
} finally {

0 commit comments

Comments
 (0)