返回 DeepSeek-Reasonix
screenshot.test.ts
根目录 / desktop / electron / src / main / browser / screenshot.test.ts
1 import assert from "node:assert/strict";
2 import { test } from "node:test";
3 import { DEBUGGER_IDLE_MS } from "./debuggerLease.js";
4 import { crc32, deflateSync } from "node:zlib";
5 import { FakePage } from "./fakeGuestViews.js";
6 import { captureScreenshot } from "./screenshot.js";
7 import { validatePNG } from "./png.js";
8
9 function png() {
10 const chunk = (kind: string, data: Buffer) => {
11 const out = Buffer.alloc(data.length + 12);
12 out.writeUInt32BE(data.length); out.write(kind, 4); data.copy(out, 8);
13 out.writeUInt32BE(crc32(out.subarray(4, -4)), out.length - 4);
14 return out;
15 };
16 const header = Buffer.alloc(13);
17 header.writeUInt32BE(1); header.writeUInt32BE(1, 4); header[8] = 8; header[9] = 6;
18 return Buffer.concat([Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), chunk("IHDR", header), chunk("IDAT", deflateSync(Buffer.from([0, 255, 0, 0, 255]))), chunk("IEND", Buffer.alloc(0))]);
19 }
20
21 test("captures are validated before any file is published", async () => {
22 const page = new FakePage(1);
23 let writes = 0;
24 const deps = { directoryExists: () => true, writeFile: () => { writes++; } };
25 const request = { ref: "", fullPage: false, directory: "/scratch" };
26 for (const data of [Buffer.alloc(0), Buffer.from("png"), png().subarray(0, 33)]) {
27 page.image = { toPNG: () => data, getSize: () => ({ width: 1, height: 1 }) };
28 await assert.rejects(captureScreenshot(page, null, 1, request, deps), /invalid_image/);
29 }
30 page.image = { toPNG: png, getSize: () => ({ width: 0, height: 0 }) };
31 await assert.rejects(captureScreenshot(page, null, 1, request, deps), /dimensions/);
32 assert.equal(writes, 0);
33 page.image = { toPNG: png, getSize: () => ({ width: 1, height: 1 }) };
34 assert.equal((await captureScreenshot(page, null, 1, request, deps)).width, 1);
35 assert.equal(writes, 1);
36 });
37
38 test("a changed owner cannot publish a captured image", async () => {
39 const page = new FakePage(1);
40 page.image = { toPNG: png, getSize: () => ({ width: 1, height: 1 }) };
41 let checkpoints = 0;
42 await assert.rejects(captureScreenshot(page, null, 1, { ref: "", fullPage: false, directory: "/scratch" }, {
43 directoryExists: () => true,
44 verify: () => { if (++checkpoints === 2) throw new Error("revoked"); },
45 writeFile: () => assert.fail("stale image was published"),
46 }), /revoked/);
47 });
48
49 test("CRC corruption and excessive full-page geometry fail before delivery", async t => {
50 t.mock.timers.enable({ apis: ["setTimeout"] });
51 const corrupt = png(); corrupt[corrupt.length - 1] ^= 1;
52 assert.throws(() => validatePNG(corrupt), /invalid_image/);
53 const page = new FakePage(1);
54 page.debugger.respond = () => ({ cssContentSize: { width: 100000, height: 100000 } });
55 await assert.rejects(captureScreenshot(page, null, 1, { ref: "", fullPage: true, directory: "/scratch" }, {
56 directoryExists: () => true, writeFile: () => assert.fail("oversize page was written"),
57 }), /pixel budget/);
58 t.mock.timers.tick(DEBUGGER_IDLE_MS);
59 assert.equal(page.debugger.isAttached(), false);
60 assert.equal(page.debugger.commands.some((entry) => entry.method === "Page.captureScreenshot"), false);
61 });
62
62 lines TYPESCRIPT