|
| 1 | +import { describe, expect, it, vi } from "vitest"; |
| 2 | +import type { Page } from "puppeteer-core"; |
| 3 | +import { detectSwiftShader, resolveDrawElementCaptureMode } from "./drawElementService.js"; |
| 4 | + |
| 5 | +// ── detectSwiftShader ────────────────────────────────────────────────────────── |
| 6 | + |
| 7 | +describe("detectSwiftShader", () => { |
| 8 | + function makePage(evaluateResult: unknown): Page { |
| 9 | + return { |
| 10 | + evaluate: vi.fn().mockResolvedValue(evaluateResult), |
| 11 | + } as unknown as Page; |
| 12 | + } |
| 13 | + |
| 14 | + it("returns true when renderer includes 'swiftshader'", async () => { |
| 15 | + const page = makePage(true); |
| 16 | + expect(await detectSwiftShader(page)).toBe(true); |
| 17 | + }); |
| 18 | + |
| 19 | + it("returns false for a standard GPU renderer string", async () => { |
| 20 | + const page = makePage(false); |
| 21 | + expect(await detectSwiftShader(page)).toBe(false); |
| 22 | + }); |
| 23 | + |
| 24 | + it("returns false when WebGL is unavailable", async () => { |
| 25 | + const page = makePage(false); |
| 26 | + expect(await detectSwiftShader(page)).toBe(false); |
| 27 | + }); |
| 28 | + |
| 29 | + it("passes a function to page.evaluate", async () => { |
| 30 | + const page = makePage(false); |
| 31 | + await detectSwiftShader(page); |
| 32 | + expect(page.evaluate).toHaveBeenCalledWith(expect.any(Function)); |
| 33 | + }); |
| 34 | +}); |
| 35 | + |
| 36 | +// ── resolveDrawElementCaptureMode ────────────────────────────────────────────── |
| 37 | + |
| 38 | +describe("resolveDrawElementCaptureMode", () => { |
| 39 | + // signature: (isSwiftShader, transparent, hasVideo?, beginFramePaints?) |
| 40 | + it("opaque + SwiftShader → drawelement (opaque works on SwiftShader)", () => { |
| 41 | + expect(resolveDrawElementCaptureMode(true, false)).toBe("drawelement"); |
| 42 | + }); |
| 43 | + |
| 44 | + it("transparent + SwiftShader → screenshot (SwiftShader bug: sub-layers dropped)", () => { |
| 45 | + expect(resolveDrawElementCaptureMode(true, true)).toBe("screenshot"); |
| 46 | + }); |
| 47 | + |
| 48 | + it("transparent + GPU → drawelement (GPU handles transparent correctly)", () => { |
| 49 | + expect(resolveDrawElementCaptureMode(false, true)).toBe("drawelement"); |
| 50 | + }); |
| 51 | + |
| 52 | + it("opaque + GPU → drawelement", () => { |
| 53 | + expect(resolveDrawElementCaptureMode(false, false)).toBe("drawelement"); |
| 54 | + }); |
| 55 | + |
| 56 | + // ── video routing: needs a per-frame BeginFrame paint for a fresh snapshot ── |
| 57 | + it("video without BeginFrame paint → screenshot (stale snapshot otherwise)", () => { |
| 58 | + expect(resolveDrawElementCaptureMode(false, false, /* hasVideo */ true, /* bf */ false)).toBe( |
| 59 | + "screenshot", |
| 60 | + ); |
| 61 | + }); |
| 62 | + |
| 63 | + it("video WITH BeginFrame paint → drawelement (Linux headless-shell paints each frame)", () => { |
| 64 | + expect(resolveDrawElementCaptureMode(false, false, /* hasVideo */ true, /* bf */ true)).toBe( |
| 65 | + "drawelement", |
| 66 | + ); |
| 67 | + }); |
| 68 | + |
| 69 | + it("no video → drawelement regardless of BeginFrame", () => { |
| 70 | + expect(resolveDrawElementCaptureMode(false, false, false, false)).toBe("drawelement"); |
| 71 | + }); |
| 72 | + |
| 73 | + it("transparent + SwiftShader still screenshot even with BeginFrame", () => { |
| 74 | + expect(resolveDrawElementCaptureMode(true, true, false, true)).toBe("screenshot"); |
| 75 | + }); |
| 76 | +}); |
0 commit comments