import { expect, test, type TestInfo } from "@playwright/test"; import { expectToolcraftAcceptanceOutcome, expectToolcraftExportedArtifact } from "./browser-acceptance-outcome-helpers"; test("acceptance outcome rejects a return to its baseline during stability sampling", async () => { let actionStarted = false; let postActionObservations = 0; await expect( expectToolcraftAcceptanceOutcome( async () => { if (!actionStarted) return "before"; postActionObservations += 1; return postActionObservations === 1 ? "after" : "before"; }, async () => { actionStarted = true; }, { evidenceType: "command-side-effect", requirementId: "command.delayed-transient", stabilityIntervalMs: 0, }, ), ).rejects.toThrow(/stability window/i); }); test("acceptance outcome snapshots a reused mutable observation", async ({}) => { const outcome = { value: "before" }; await expect( expectToolcraftAcceptanceOutcome( async () => outcome, async () => { outcome.value = "after"; }, { evidenceType: "command-side-effect", requirementId: "command.mutable-observation", stabilityIntervalMs: 0, }, ), ).resolves.toEqual({ value: "after" }); }); test("generic acceptance outcomes cannot claim specialized runtime evidence", async ({ page, }) => { await page.setContent('
before
'); await expect( expectToolcraftAcceptanceOutcome( () => page.locator("#outcome").textContent(), () => page.locator("#outcome").evaluate((node) => { node.textContent = "after"; }), { evidenceType: "timeline-duration" as never, requirementId: "timeline.duration", }, ), ).rejects.toThrow(/specialized evidence/i); }); test("export evidence requires a typed positive artifact inspection", async ({}, testInfo: TestInfo) => { const attachmentCount = testInfo.attachments.length; await expect( expectToolcraftExportedArtifact( async () => new Uint8Array([1, 2, 3]), async () => ({ ok: true }), { requirementId: "export.nominal-object" }, ), ).rejects.toThrow(/byteLength/i); await expect( expectToolcraftExportedArtifact( async () => new Uint8Array([1, 2, 3]), async () => ({ byteLength: 0 }), { requirementId: "export.zero-bytes" }, ), ).rejects.toThrow(/positive byteLength/i); await expect( expectToolcraftExportedArtifact( async () => new Uint8Array([1, 2, 3]), async () => ({ byteLength: 2.5 }), { requirementId: "export.fractional-bytes" }, ), ).rejects.toThrow(/byteLength integer/i); await expect( expectToolcraftExportedArtifact( async () => new Uint8Array([1, 2, 3]), async () => ({ byteLength: 3, width: 1.5 }), { requirementId: "export.fractional-width" }, ), ).rejects.toThrow(/width integer/i); expect(testInfo.attachments).toHaveLength(attachmentCount); await expectToolcraftExportedArtifact( async () => new Uint8Array([1, 2, 3]), async (artifact) => ({ byteLength: artifact.byteLength, contentHash: "pixel-hash", height: 1, mediaType: "image/png", width: 1, }), { requirementId: "export.valid-inspection" }, ); expect(testInfo.attachments).toHaveLength(attachmentCount + 1); });