@pixel-point/toolcraft 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generate-performance-iteration-execution.test.mjs +2 -2
- package/src/generate-test-demand-only-lifecycle.mjs +14 -3
- package/src/generate-test-dependency-sandbox.mjs +42 -5
- package/src/generate-test-doc-assertions.mjs +68 -18
- package/src/generate-test-doc-assertions.test.mjs +22 -0
- package/src/generate-test-file-assertions.mjs +43 -76
- package/src/generate-test-output-assertions.mjs +95 -0
- package/src/generate-test-package-assertions.mjs +6 -0
- package/src/generate-test-performance-boundary-assertions.mjs +45 -0
- package/src/generate-test-product-fixture.mjs +1 -0
- package/src/generate-test-product-fixture.test.mjs +18 -0
- package/src/generate-test-product-iteration.mjs +1 -0
- package/src/generate-test-product-iteration.test.mjs +1 -0
- package/src/generate-test-standalone-delivery-stages.mjs +14 -6
- package/src/generate.test.mjs +14 -0
- package/templates/runtime/contracts/component-contracts.choices.test.ts +12 -9
- package/templates/runtime/contracts/component-contracts.choices.ts +10 -9
- package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +17 -2
- package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +1 -1
- package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +1 -1
- package/templates/runtime/contracts/component-contracts.runtime.ts +3 -2
- package/templates/runtime/contracts/decision-contracts.test.ts +25 -4
- package/templates/runtime/contracts/decision-contracts.ts +3 -3
- package/templates/runtime/contracts/performance-verification-policy.test.ts +59 -6
- package/templates/runtime/contracts/performance-verification-policy.ts +5 -2
- package/templates/runtime/export/artifact-download.test.ts +71 -0
- package/templates/runtime/export/artifact-download.ts +80 -0
- package/templates/runtime/export/artifact-export-request.ts +23 -0
- package/templates/runtime/export/artifact-export-settings.test.ts +75 -0
- package/templates/runtime/export/artifact-export-settings.ts +96 -0
- package/templates/runtime/export/artifact-frame-renderer.test.ts +107 -0
- package/templates/runtime/export/artifact-frame-renderer.ts +96 -0
- package/templates/runtime/export/artifact-frame-state.test.ts +54 -0
- package/templates/runtime/export/artifact-frame-state.ts +44 -0
- package/templates/runtime/export/artifact-scene-frame.test.ts +84 -0
- package/templates/runtime/export/artifact-scene-frame.ts +118 -0
- package/templates/runtime/export/export-background.ts +65 -0
- package/templates/runtime/export/export-error.ts +43 -0
- package/templates/runtime/export/export.test.ts +6 -186
- package/templates/runtime/export/image-artifact-export.test.ts +111 -0
- package/templates/runtime/export/image-artifact-export.ts +145 -0
- package/templates/runtime/export/index.ts +14 -1
- package/templates/runtime/export/product-export-renderer.test.ts +77 -0
- package/templates/runtime/export/product-export-renderer.ts +63 -0
- package/templates/runtime/export/video-artifact-export.test.ts +166 -0
- package/templates/runtime/export/video-artifact-export.ts +164 -0
- package/templates/runtime/export/video-encoding-backend.ts +124 -0
- package/templates/runtime/export/video-encoding-policy.test.ts +68 -0
- package/templates/runtime/export/video-encoding-policy.ts +86 -0
- package/templates/runtime/export/video-frame-schedule.test.ts +58 -0
- package/templates/runtime/export/video-frame-schedule.ts +42 -0
- package/templates/runtime/index.ts +1 -0
- package/templates/runtime/react/app-shell/runtime-public-api-runtime.test.tsx +291 -0
- package/templates/runtime/react/app-shell/runtime-public-api-test-support.ts +21 -0
- package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +4 -303
- package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +12 -27
- package/templates/runtime/react/app-shell/toolcraft-app.tsx +22 -4
- package/templates/runtime/react/app-shell/toolcraft-source-asset-context.test.tsx +16 -57
- package/templates/runtime/react/app-shell/toolcraft-source-asset-context.tsx +75 -434
- package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.test.ts +194 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.ts +227 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-provider-ownership.test.tsx +243 -0
- package/templates/runtime/react/app-shell/toolcraft-source-asset-test-support.ts +51 -0
- package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.test.ts +138 -0
- package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.ts +378 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.footer-actions.test.tsx +7 -12
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +17 -83
- package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +42 -84
- package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +62 -0
- package/templates/runtime/react/panel-host/panel-host-runtime-placement.test.tsx +30 -0
- package/templates/runtime/react/panel-host/panel-host.tsx +4 -0
- package/templates/runtime/scene/scene-bounds.ts +1 -2
- package/templates/runtime/schema/canvas-render-scale.ts +62 -0
- package/templates/runtime/schema/controls-panel-section-id.test.ts +1 -1
- package/templates/runtime/schema/controls-panel-section-roundtrip.test.ts +3 -3
- package/templates/runtime/schema/define-toolcraft.setup-background.test.ts +1 -1
- package/templates/runtime/schema/define-toolcraft.setup-render-scale-timeline.test.ts +71 -3
- package/templates/runtime/schema/define-toolcraft.ts +1 -1
- package/templates/runtime/schema/schema-resolvers.ts +0 -56
- package/templates/runtime/schema/types.ts +4 -4
- package/templates/runtime/state/canvas-background-state.ts +6 -0
- package/templates/runtime/testing/performance-render-plan-integration.test.ts +64 -0
- package/templates/runtime/testing/performance-renderer-pipeline-validation.ts +18 -1
- package/templates/starter/AGENTS.md +8 -7
- package/templates/starter/NOTICE.md +6 -0
- package/templates/starter/docs/toolcraft/README.md +2 -1
- package/templates/starter/docs/toolcraft/acceptance-testing.md +8 -6
- package/templates/starter/docs/toolcraft/agent-worklog.md +3 -3
- package/templates/starter/docs/toolcraft/assembly-workflow.md +4 -3
- package/templates/starter/docs/toolcraft/core/media-upload.md +2 -2
- package/templates/starter/docs/toolcraft/core/performance.md +14 -3
- package/templates/starter/docs/toolcraft/core/runtime-boundary.md +3 -1
- package/templates/starter/docs/toolcraft/core/setup-export.md +16 -12
- package/templates/starter/docs/toolcraft/core/timeline-animation.md +4 -4
- package/templates/starter/docs/toolcraft/performance.md +20 -6
- package/templates/starter/docs/toolcraft/renderer-technique.md +1 -1
- package/templates/starter/docs/toolcraft/schema-reference.md +2 -6
- package/templates/starter/docs/toolcraft/workflow.md +7 -2
- package/templates/starter/e2e/app-browser-control-coverage.spec.ts +33 -0
- package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +43 -1
- package/templates/starter/e2e/app-browser-render-scale-evidence.spec.ts +60 -6
- package/templates/starter/e2e/app-browser-render-scale-requirements.spec.ts +77 -1
- package/templates/starter/e2e/app-browser-runtime-provenance.spec.ts +8 -0
- package/templates/starter/e2e/app-browser-runtime-reporter.spec.ts +35 -0
- package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +4 -1
- package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +0 -1
- package/templates/starter/e2e/app-browser-shell.spec.ts +13 -5
- package/templates/starter/e2e/app-performance-path-adapters.ts +8 -1
- package/templates/starter/e2e/app-performance.spec.ts +16 -9
- package/templates/starter/e2e/browser-infinity-canvas-evidence.ts +9 -330
- package/templates/starter/e2e/browser-infinity-canvas-unavailable-image-evidence.ts +370 -0
- package/templates/starter/e2e/browser-media-export-evidence.spec.ts +77 -0
- package/templates/starter/e2e/browser-media-export-evidence.ts +208 -0
- package/templates/starter/e2e/browser-render-scale-evidence.ts +37 -29
- package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +4 -1
- package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +43 -9
- package/templates/starter/e2e/browser-standard-timeline-evidence.ts +106 -0
- package/templates/starter/e2e/decoded-pixel-observation.spec.ts +74 -0
- package/templates/starter/e2e/decoded-pixel-observation.ts +227 -0
- package/templates/starter/e2e/export-artifact-helpers.ts +206 -25
- package/templates/starter/e2e/image-artifact-inspection.spec.ts +41 -0
- package/templates/starter/e2e/image-artifact-inspection.ts +99 -0
- package/templates/starter/e2e/performance-canvas-helpers.ts +22 -21
- package/templates/starter/e2e/performance-canvas-quality-guard.spec.ts +312 -0
- package/templates/starter/e2e/performance-canvas-quality-guard.ts +196 -0
- package/templates/starter/e2e/performance-canvas-quality-observer.ts +351 -0
- package/templates/starter/e2e/performance-control-layout-helpers.ts +2 -2
- package/templates/starter/e2e/performance-path-adapter-contract.ts +4 -4
- package/templates/starter/e2e/performance-path-helpers.spec.ts +203 -70
- package/templates/starter/e2e/performance-path-helpers.ts +210 -91
- package/templates/starter/e2e/performance-pipeline-evidence-continuity.spec.ts +76 -0
- package/templates/starter/e2e/performance-pipeline-evidence-test-fixtures.ts +11 -2
- package/templates/starter/e2e/performance-pipeline-invariants.ts +47 -4
- package/templates/starter/e2e/performance-render-scale-runner.spec.ts +140 -38
- package/templates/starter/e2e/video-artifact-inspection.spec.ts +64 -0
- package/templates/starter/e2e/video-artifact-inspection.ts +281 -0
- package/templates/starter/gitignore +1 -0
- package/templates/starter/package.json +1 -0
- package/templates/starter/scripts/check-toolcraft-docs.mjs +17 -0
- package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +60 -0
- package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +7 -2
- package/templates/starter/scripts/toolcraft-delivery-plan.mjs +7 -3
- package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +24 -2
- package/templates/starter/scripts/toolcraft-product-boundary.mjs +12 -0
- package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +46 -0
- package/templates/starter/scripts/toolcraft-product-evidence-boundary.test.mjs +85 -20
- package/templates/starter/scripts/toolcraft-product-evidence-import-policy.mjs +43 -0
- package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +168 -0
- package/templates/starter/scripts/toolcraft-typescript-analysis.d.mts +73 -0
- package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade-test-helpers.mjs +318 -0
- package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade.test.mjs +155 -206
- package/templates/starter/scripts/toolcraft-verification-inventory.mjs +1 -0
- package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +51 -0
- package/templates/starter/scripts/toolcraft-vite-env-activation.test.mjs +128 -59
- package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +113 -0
- package/templates/starter/src/app/acceptance/output-background-rules.ts +1 -1
- package/templates/starter/src/app/acceptance/output-export.ts +13 -2
- package/templates/starter/src/app/acceptance/types.ts +7 -0
- package/templates/starter/src/app/acceptance/validate-coverage.ts +2 -1
- package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +131 -0
- package/templates/starter/src/app/starter-acceptance.keyframes.test.ts +14 -4
- package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +42 -1
- package/templates/starter/src/app/starter-acceptance.ts +2 -0
- package/templates/starter/src/app/starter-performance-test-utils.ts +103 -0
- package/templates/starter/src/app/starter-performance.gates.test.ts +231 -278
- package/templates/starter/src/app/starter-performance.lifecycle.test.ts +261 -0
- package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +2 -0
- package/templates/starter/src/routes/index.tsx +1 -0
- package/templates/runtime/export/export.ts +0 -166
|
@@ -1,180 +1,25 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
2
|
import test from "node:test";
|
|
6
|
-
import { pathToFileURL } from "node:url";
|
|
7
3
|
|
|
8
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
createArtifactAction,
|
|
6
|
+
createSession,
|
|
7
|
+
executeClosurelessObservation,
|
|
8
|
+
getHarnessState,
|
|
9
|
+
loadUnavailableResourceFacade,
|
|
10
|
+
resetHarness,
|
|
11
|
+
setActivationError,
|
|
12
|
+
setCleanupFailure,
|
|
13
|
+
setMalformedActivation,
|
|
14
|
+
} from "./toolcraft-unavailable-resource-evidence-facade-test-helpers.mjs";
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
async function loadUnavailableResourceFacade(context) {
|
|
17
|
-
const outputDir = await fs.mkdtemp(
|
|
18
|
-
path.join(os.tmpdir(), "toolcraft-unavailable-resource-evidence-"),
|
|
16
|
+
test("closureless observation harness rejects browser callbacks with outer references", () => {
|
|
17
|
+
const readAttribute = (root) => root.getAttribute("data-value");
|
|
18
|
+
assert.throws(
|
|
19
|
+
() => executeClosurelessObservation((root) => readAttribute(root), {}),
|
|
20
|
+
/readAttribute is not defined/u,
|
|
19
21
|
);
|
|
20
|
-
|
|
21
|
-
const outputPath = path.join(outputDir, "browser-infinity-canvas-evidence.mjs");
|
|
22
|
-
const source = (await fs.readFile(helperPath, "utf8"))
|
|
23
|
-
.replaceAll('"@playwright/test"', '"./playwright.mjs"')
|
|
24
|
-
.replaceAll('"./browser-runtime-evidence"', '"./evidence.mjs"')
|
|
25
|
-
.replaceAll('"./browser-proof-session"', '"./proof-session.mjs"')
|
|
26
|
-
.replaceAll('"./export-artifact-helpers"', '"./artifact.mjs"');
|
|
27
|
-
const { outputText } = ts.transpileModule(source, {
|
|
28
|
-
compilerOptions: {
|
|
29
|
-
module: ts.ModuleKind.ESNext,
|
|
30
|
-
target: ts.ScriptTarget.ES2022,
|
|
31
|
-
},
|
|
32
|
-
fileName: helperPath,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
await Promise.all([
|
|
36
|
-
fs.writeFile(outputPath, outputText),
|
|
37
|
-
fs.writeFile(
|
|
38
|
-
path.join(outputDir, "playwright.mjs"),
|
|
39
|
-
`
|
|
40
|
-
import assert from "node:assert/strict";
|
|
41
|
-
function partial(actual, expected, message) {
|
|
42
|
-
for (const [key, value] of Object.entries(expected)) {
|
|
43
|
-
assert.deepEqual(actual?.[key], value, message);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
export function expect(actual, message = "Expectation failed") {
|
|
47
|
-
return {
|
|
48
|
-
not: {
|
|
49
|
-
toBe(expected) {
|
|
50
|
-
assert.notEqual(actual, expected, message);
|
|
51
|
-
},
|
|
52
|
-
toEqual(expected) {
|
|
53
|
-
assert.notDeepEqual(actual, expected, message);
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
toBe(expected) {
|
|
57
|
-
assert.equal(actual, expected, message);
|
|
58
|
-
},
|
|
59
|
-
toBeTruthy() {
|
|
60
|
-
assert.ok(actual, message);
|
|
61
|
-
},
|
|
62
|
-
toEqual(expected) {
|
|
63
|
-
assert.deepEqual(actual, expected, message);
|
|
64
|
-
},
|
|
65
|
-
toMatchObject(expected) {
|
|
66
|
-
if (expected?.status === "cleaned") {
|
|
67
|
-
globalThis.__toolcraftUnavailableEvidenceTrace.push(
|
|
68
|
-
"assert:cleaned",
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
partial(actual, expected, message);
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
`,
|
|
76
|
-
),
|
|
77
|
-
fs.writeFile(
|
|
78
|
-
path.join(outputDir, "evidence.mjs"),
|
|
79
|
-
`
|
|
80
|
-
export async function attachToolcraftBrowserRuntimeEvidence(evidence) {
|
|
81
|
-
globalThis.__toolcraftUnavailableEvidenceTrace.push(
|
|
82
|
-
"evidence:" + evidence.evidenceType,
|
|
83
|
-
);
|
|
84
|
-
globalThis.__toolcraftUnavailableEvidenceAttachments.push(evidence);
|
|
85
|
-
}
|
|
86
|
-
`,
|
|
87
|
-
),
|
|
88
|
-
fs.writeFile(
|
|
89
|
-
path.join(outputDir, "proof-session.mjs"),
|
|
90
|
-
`
|
|
91
|
-
export function assertToolcraftBrowserProofSession() {
|
|
92
|
-
globalThis.__toolcraftUnavailableEvidenceSessionAssertions += 1;
|
|
93
|
-
}
|
|
94
|
-
export function getToolcraftBrowserActionTarget(action) {
|
|
95
|
-
return action.target;
|
|
96
|
-
}
|
|
97
|
-
export async function readToolcraftBrowserObservation() {
|
|
98
|
-
return globalThis.__toolcraftUnavailableEvidenceObservation;
|
|
99
|
-
}
|
|
100
|
-
export async function runToolcraftBrowserAction() {
|
|
101
|
-
globalThis.__toolcraftUnavailableEvidenceActionCalls += 1;
|
|
102
|
-
const actionName =
|
|
103
|
-
globalThis.__toolcraftUnavailableEvidenceActionCalls === 1
|
|
104
|
-
? "activate"
|
|
105
|
-
: "cleanup";
|
|
106
|
-
globalThis.__toolcraftUnavailableEvidenceTrace.push(
|
|
107
|
-
"action:" + actionName,
|
|
108
|
-
);
|
|
109
|
-
if (
|
|
110
|
-
actionName === "cleanup" &&
|
|
111
|
-
globalThis.__toolcraftUnavailableEvidenceCleanupFailure
|
|
112
|
-
) {
|
|
113
|
-
throw new Error("cleanup failed");
|
|
114
|
-
}
|
|
115
|
-
globalThis.__toolcraftUnavailableEvidenceObservation =
|
|
116
|
-
globalThis.__toolcraftUnavailableEvidenceActionCalls === 1
|
|
117
|
-
? {
|
|
118
|
-
assetId: "image-2",
|
|
119
|
-
fileName: "unavailable.png",
|
|
120
|
-
lifecycle: "unavailable",
|
|
121
|
-
requestId: "unavailable-image-1",
|
|
122
|
-
resolverAvailable: false,
|
|
123
|
-
status: "active",
|
|
124
|
-
}
|
|
125
|
-
: {
|
|
126
|
-
assetId: "image-2",
|
|
127
|
-
fileName: "unavailable.png",
|
|
128
|
-
lifecycle: "ready",
|
|
129
|
-
requestId: "unavailable-image-1",
|
|
130
|
-
resolverAvailable: true,
|
|
131
|
-
status: "cleaned",
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
export async function runToolcraftBrowserValueAction(action) {
|
|
135
|
-
globalThis.__toolcraftUnavailableEvidenceTrace.push("artifact");
|
|
136
|
-
return action.result;
|
|
137
|
-
}
|
|
138
|
-
`,
|
|
139
|
-
),
|
|
140
|
-
fs.writeFile(
|
|
141
|
-
path.join(outputDir, "artifact.mjs"),
|
|
142
|
-
`
|
|
143
|
-
export function assertToolcraftProducedArtifact(artifact) {
|
|
144
|
-
if (!artifact) throw new Error("missing artifact");
|
|
145
|
-
}
|
|
146
|
-
export function validateToolcraftExportArtifactInspection(inspection) {
|
|
147
|
-
globalThis.__toolcraftUnavailableEvidenceArtifactValidations += 1;
|
|
148
|
-
if (!inspection?.byteLength) throw new Error("invalid inspection");
|
|
149
|
-
return inspection;
|
|
150
|
-
}
|
|
151
|
-
`,
|
|
152
|
-
),
|
|
153
|
-
]);
|
|
154
|
-
|
|
155
|
-
return import(`${pathToFileURL(outputPath).href}?test=${Date.now()}`);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function createSession() {
|
|
159
|
-
return {
|
|
160
|
-
observe(read) {
|
|
161
|
-
return { read };
|
|
162
|
-
},
|
|
163
|
-
targetAction(target, run) {
|
|
164
|
-
return { run, target };
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function resetHarness() {
|
|
170
|
-
globalThis.__toolcraftUnavailableEvidenceActionCalls = 0;
|
|
171
|
-
globalThis.__toolcraftUnavailableEvidenceArtifactValidations = 0;
|
|
172
|
-
globalThis.__toolcraftUnavailableEvidenceAttachments = [];
|
|
173
|
-
globalThis.__toolcraftUnavailableEvidenceCleanupFailure = false;
|
|
174
|
-
globalThis.__toolcraftUnavailableEvidenceObservation = { status: "missing" };
|
|
175
|
-
globalThis.__toolcraftUnavailableEvidenceSessionAssertions = 0;
|
|
176
|
-
globalThis.__toolcraftUnavailableEvidenceTrace = [];
|
|
177
|
-
}
|
|
22
|
+
});
|
|
178
23
|
|
|
179
24
|
function createFiniteObservation(width, height) {
|
|
180
25
|
return {
|
|
@@ -230,7 +75,7 @@ test("Infinity mode recipe rejects a wrong restored dormant finite size", async
|
|
|
230
75
|
},
|
|
231
76
|
),
|
|
232
77
|
);
|
|
233
|
-
assert.deepEqual(
|
|
78
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
234
79
|
});
|
|
235
80
|
|
|
236
81
|
test("Infinity mode recipe accepts exact restored dormant finite dimensions", async (context) => {
|
|
@@ -259,7 +104,7 @@ test("Infinity mode recipe accepts exact restored dormant finite dimensions", as
|
|
|
259
104
|
target: "canvas.infinity",
|
|
260
105
|
},
|
|
261
106
|
);
|
|
262
|
-
assert.deepEqual(
|
|
107
|
+
assert.deepEqual(getHarnessState().attachments, [
|
|
263
108
|
{
|
|
264
109
|
evidenceType: "viewport-side-effect",
|
|
265
110
|
requirementId: "canvas.infinity.mode",
|
|
@@ -276,18 +121,20 @@ test("Infinity mode recipe accepts exact restored dormant finite dimensions", as
|
|
|
276
121
|
test("unavailable-image export recipe proves typed fault before evidence and cleans up", async (context) => {
|
|
277
122
|
const facade = await loadUnavailableResourceFacade(context);
|
|
278
123
|
resetHarness();
|
|
124
|
+
const session = createSession();
|
|
279
125
|
const fixture = facade.createToolcraftUnavailableImageResourceFixture(
|
|
280
|
-
|
|
126
|
+
session,
|
|
281
127
|
{
|
|
282
128
|
fileName: "unavailable.png",
|
|
283
129
|
sourceTarget: "source.images",
|
|
284
130
|
target: "canvas.infinity",
|
|
285
131
|
},
|
|
286
132
|
);
|
|
287
|
-
const exportAction =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
133
|
+
const exportAction = createArtifactAction(
|
|
134
|
+
session,
|
|
135
|
+
"canvas.infinity",
|
|
136
|
+
new Uint8Array([1, 2, 3]),
|
|
137
|
+
);
|
|
291
138
|
const inspection =
|
|
292
139
|
await facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
293
140
|
fixture,
|
|
@@ -304,10 +151,12 @@ test("unavailable-image export recipe proves typed fault before evidence and cle
|
|
|
304
151
|
height: 2004,
|
|
305
152
|
width: 2048,
|
|
306
153
|
});
|
|
307
|
-
|
|
308
|
-
assert.equal(
|
|
309
|
-
assert.equal(
|
|
310
|
-
assert.
|
|
154
|
+
const state = getHarnessState();
|
|
155
|
+
assert.equal(state.actionCalls, 2);
|
|
156
|
+
assert.equal(state.artifactValidations, 1);
|
|
157
|
+
assert.equal(state.closurelessObservationCalls, 4);
|
|
158
|
+
assert.equal(state.sessionAssertions, 1);
|
|
159
|
+
assert.deepEqual(state.attachments, [
|
|
311
160
|
{
|
|
312
161
|
evidenceType: "exported-artifact",
|
|
313
162
|
requirementId: "canvas.infinity.image-export",
|
|
@@ -319,21 +168,40 @@ test("unavailable-image export recipe proves typed fault before evidence and cle
|
|
|
319
168
|
target: "canvas.infinity",
|
|
320
169
|
},
|
|
321
170
|
]);
|
|
322
|
-
assert.deepEqual(
|
|
171
|
+
assert.deepEqual(state.trace, [
|
|
323
172
|
"action:activate",
|
|
173
|
+
"assert:active",
|
|
324
174
|
"artifact",
|
|
175
|
+
"assert:active",
|
|
325
176
|
"action:cleanup",
|
|
326
177
|
"assert:cleaned",
|
|
327
178
|
"evidence:exported-artifact",
|
|
328
179
|
"evidence:infinity-scene-bounds-image-export",
|
|
329
180
|
]);
|
|
181
|
+
assert.deepEqual(state.bridgeActions, ["activate", "cleanup"]);
|
|
182
|
+
assert.deepEqual(state.eventNames, [
|
|
183
|
+
"toolcraft.browser-proof.unavailable-resource-request",
|
|
184
|
+
"toolcraft.browser-proof.unavailable-resource-request",
|
|
185
|
+
]);
|
|
186
|
+
assert.deepEqual(state.selectorNames, [
|
|
187
|
+
'[data-slot="toolcraft-runtime-app"]',
|
|
188
|
+
'[data-slot="toolcraft-runtime-app"]',
|
|
189
|
+
]);
|
|
190
|
+
assert.ok(
|
|
191
|
+
state.attributeNames.length > 0 &&
|
|
192
|
+
state.attributeNames.every(
|
|
193
|
+
(name) => name === "data-toolcraft-unavailable-resource-evidence",
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
assert.equal(state.pollCalls, 2);
|
|
330
197
|
});
|
|
331
198
|
|
|
332
199
|
test("unavailable-image export recipe cleans up and emits no evidence when decoded bounds fail", async (context) => {
|
|
333
200
|
const facade = await loadUnavailableResourceFacade(context);
|
|
334
201
|
resetHarness();
|
|
202
|
+
const session = createSession();
|
|
335
203
|
const fixture = facade.createToolcraftUnavailableImageResourceFixture(
|
|
336
|
-
|
|
204
|
+
session,
|
|
337
205
|
{
|
|
338
206
|
fileName: "unavailable.png",
|
|
339
207
|
target: "canvas.infinity",
|
|
@@ -343,10 +211,11 @@ test("unavailable-image export recipe cleans up and emits no evidence when decod
|
|
|
343
211
|
await assert.rejects(
|
|
344
212
|
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
345
213
|
fixture,
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
214
|
+
createArtifactAction(
|
|
215
|
+
session,
|
|
216
|
+
"canvas.infinity",
|
|
217
|
+
new Uint8Array([1, 2, 3]),
|
|
218
|
+
),
|
|
350
219
|
async () => ({ byteLength: 3, height: 100, width: 100 }),
|
|
351
220
|
{
|
|
352
221
|
expectedSize: { height: 2004, width: 2048 },
|
|
@@ -355,20 +224,18 @@ test("unavailable-image export recipe cleans up and emits no evidence when decod
|
|
|
355
224
|
),
|
|
356
225
|
);
|
|
357
226
|
|
|
358
|
-
assert.equal(
|
|
359
|
-
assert.deepEqual(
|
|
360
|
-
assert.equal(
|
|
361
|
-
globalThis.__toolcraftUnavailableEvidenceObservation.status,
|
|
362
|
-
"cleaned",
|
|
363
|
-
);
|
|
227
|
+
assert.equal(getHarnessState().actionCalls, 2);
|
|
228
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
229
|
+
assert.equal(getHarnessState().observation.status, "cleaned");
|
|
364
230
|
});
|
|
365
231
|
|
|
366
232
|
test("unavailable-image export recipe emits no evidence when cleanup fails", async (context) => {
|
|
367
233
|
const facade = await loadUnavailableResourceFacade(context);
|
|
368
234
|
resetHarness();
|
|
369
|
-
|
|
235
|
+
setCleanupFailure();
|
|
236
|
+
const session = createSession();
|
|
370
237
|
const fixture = facade.createToolcraftUnavailableImageResourceFixture(
|
|
371
|
-
|
|
238
|
+
session,
|
|
372
239
|
{
|
|
373
240
|
fileName: "unavailable.png",
|
|
374
241
|
target: "canvas.infinity",
|
|
@@ -378,10 +245,11 @@ test("unavailable-image export recipe emits no evidence when cleanup fails", asy
|
|
|
378
245
|
await assert.rejects(
|
|
379
246
|
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
380
247
|
fixture,
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
248
|
+
createArtifactAction(
|
|
249
|
+
session,
|
|
250
|
+
"canvas.infinity",
|
|
251
|
+
new Uint8Array([1, 2, 3]),
|
|
252
|
+
),
|
|
385
253
|
async () => ({ byteLength: 3, height: 2004, width: 2048 }),
|
|
386
254
|
{
|
|
387
255
|
expectedSize: { height: 2004, width: 2048 },
|
|
@@ -391,14 +259,75 @@ test("unavailable-image export recipe emits no evidence when cleanup fails", asy
|
|
|
391
259
|
/cleanup failed/u,
|
|
392
260
|
);
|
|
393
261
|
|
|
394
|
-
assert.deepEqual(
|
|
395
|
-
assert.deepEqual(
|
|
262
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
263
|
+
assert.deepEqual(getHarnessState().trace, [
|
|
396
264
|
"action:activate",
|
|
265
|
+
"assert:active",
|
|
397
266
|
"artifact",
|
|
267
|
+
"assert:active",
|
|
398
268
|
"action:cleanup",
|
|
399
269
|
]);
|
|
400
270
|
});
|
|
401
271
|
|
|
272
|
+
test("unavailable-image export recipe surfaces bridge errors before artifact work", async (context) => {
|
|
273
|
+
const facade = await loadUnavailableResourceFacade(context);
|
|
274
|
+
resetHarness();
|
|
275
|
+
setActivationError("activation failed");
|
|
276
|
+
const session = createSession();
|
|
277
|
+
const fixture = facade.createToolcraftUnavailableImageResourceFixture(
|
|
278
|
+
session,
|
|
279
|
+
{ fileName: "unavailable.png", target: "canvas.infinity" },
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
await assert.rejects(
|
|
283
|
+
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
284
|
+
fixture,
|
|
285
|
+
createArtifactAction(
|
|
286
|
+
session,
|
|
287
|
+
"canvas.infinity",
|
|
288
|
+
new Uint8Array([1]),
|
|
289
|
+
),
|
|
290
|
+
async () => ({ byteLength: 1, height: 1, width: 1 }),
|
|
291
|
+
{
|
|
292
|
+
expectedSize: { height: 1, width: 1 },
|
|
293
|
+
requirementId: "canvas.infinity.image-export",
|
|
294
|
+
},
|
|
295
|
+
),
|
|
296
|
+
/activation failed/u,
|
|
297
|
+
);
|
|
298
|
+
assert.deepEqual(getHarnessState().trace, ["action:activate"]);
|
|
299
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("unavailable-image export recipe rejects malformed bridge observations", async (context) => {
|
|
303
|
+
const facade = await loadUnavailableResourceFacade(context);
|
|
304
|
+
resetHarness();
|
|
305
|
+
setMalformedActivation();
|
|
306
|
+
const session = createSession();
|
|
307
|
+
const fixture = facade.createToolcraftUnavailableImageResourceFixture(
|
|
308
|
+
session,
|
|
309
|
+
{ fileName: "unavailable.png", target: "canvas.infinity" },
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
await assert.rejects(
|
|
313
|
+
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
314
|
+
fixture,
|
|
315
|
+
createArtifactAction(
|
|
316
|
+
session,
|
|
317
|
+
"canvas.infinity",
|
|
318
|
+
new Uint8Array([1]),
|
|
319
|
+
),
|
|
320
|
+
async () => ({ byteLength: 1, height: 1, width: 1 }),
|
|
321
|
+
{
|
|
322
|
+
expectedSize: { height: 1, width: 1 },
|
|
323
|
+
requirementId: "canvas.infinity.image-export",
|
|
324
|
+
},
|
|
325
|
+
),
|
|
326
|
+
/published malformed state/u,
|
|
327
|
+
);
|
|
328
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
329
|
+
});
|
|
330
|
+
|
|
402
331
|
test("unavailable-image export recipe rejects forged fixtures and target mismatch", async (context) => {
|
|
403
332
|
const facade = await loadUnavailableResourceFacade(context);
|
|
404
333
|
resetHarness();
|
|
@@ -426,14 +355,34 @@ test("unavailable-image export recipe rejects forged fixtures and target mismatc
|
|
|
426
355
|
await assert.rejects(
|
|
427
356
|
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
428
357
|
fixture,
|
|
429
|
-
|
|
358
|
+
createArtifactAction(
|
|
359
|
+
session,
|
|
360
|
+
"actions.output",
|
|
361
|
+
new Uint8Array([1]),
|
|
362
|
+
),
|
|
363
|
+
async () => ({ byteLength: 1, height: 1, width: 1 }),
|
|
364
|
+
{
|
|
365
|
+
expectedSize: { height: 1, width: 1 },
|
|
366
|
+
requirementId: "canvas.infinity.image-export",
|
|
367
|
+
},
|
|
368
|
+
),
|
|
369
|
+
);
|
|
370
|
+
await assert.rejects(
|
|
371
|
+
facade.expectToolcraftInfinityCanvasUnavailableImageExportEvidence(
|
|
372
|
+
fixture,
|
|
373
|
+
createArtifactAction(
|
|
374
|
+
createSession(),
|
|
375
|
+
"canvas.infinity",
|
|
376
|
+
new Uint8Array([1]),
|
|
377
|
+
),
|
|
430
378
|
async () => ({ byteLength: 1, height: 1, width: 1 }),
|
|
431
379
|
{
|
|
432
380
|
expectedSize: { height: 1, width: 1 },
|
|
433
381
|
requirementId: "canvas.infinity.image-export",
|
|
434
382
|
},
|
|
435
383
|
),
|
|
384
|
+
/same browser proof session/u,
|
|
436
385
|
);
|
|
437
|
-
assert.equal(
|
|
438
|
-
assert.deepEqual(
|
|
386
|
+
assert.equal(getHarnessState().actionCalls, 0);
|
|
387
|
+
assert.deepEqual(getHarnessState().attachments, []);
|
|
439
388
|
});
|
|
@@ -193,6 +193,57 @@ test("ignores workflow skills, generated output, and checkpoint directories thro
|
|
|
193
193
|
);
|
|
194
194
|
});
|
|
195
195
|
|
|
196
|
+
test("ignores browser-tool artifact create change and delete", async (t) => {
|
|
197
|
+
const rootDir = await createRootWideInventoryFixture();
|
|
198
|
+
t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
|
|
199
|
+
const baseline = await collectToolcraftVerificationInputs(rootDir);
|
|
200
|
+
const browserArtifact = path.join(
|
|
201
|
+
rootDir,
|
|
202
|
+
".playwright-mcp",
|
|
203
|
+
"nested",
|
|
204
|
+
"page.yml",
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
for (const content of ["page: initial\n", "page: updated\n"]) {
|
|
208
|
+
await fs.mkdir(path.dirname(browserArtifact), { recursive: true });
|
|
209
|
+
await fs.writeFile(browserArtifact, content);
|
|
210
|
+
const current = await collectToolcraftVerificationInputs(rootDir);
|
|
211
|
+
|
|
212
|
+
assert.equal(current.sourceHash, baseline.sourceHash);
|
|
213
|
+
assert.deepEqual(
|
|
214
|
+
getToolcraftChangedVerificationFiles(baseline.entries, current.entries),
|
|
215
|
+
[],
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
await fs.rm(path.join(rootDir, ".playwright-mcp"), {
|
|
220
|
+
force: true,
|
|
221
|
+
recursive: true,
|
|
222
|
+
});
|
|
223
|
+
const current = await collectToolcraftVerificationInputs(rootDir);
|
|
224
|
+
|
|
225
|
+
assert.equal(current.sourceHash, baseline.sourceHash);
|
|
226
|
+
assert.deepEqual(
|
|
227
|
+
getToolcraftChangedVerificationFiles(baseline.entries, current.entries),
|
|
228
|
+
[],
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("continues to hash real product raster assets", async (t) => {
|
|
233
|
+
const rootDir = await createRootWideInventoryFixture();
|
|
234
|
+
t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
|
|
235
|
+
const baseline = await collectToolcraftVerificationInputs(rootDir);
|
|
236
|
+
|
|
237
|
+
await fs.writeFile(path.join(rootDir, "public", "source.png"), "updated-source-image");
|
|
238
|
+
const current = await collectToolcraftVerificationInputs(rootDir);
|
|
239
|
+
|
|
240
|
+
assert.notEqual(current.sourceHash, baseline.sourceHash);
|
|
241
|
+
assert.deepEqual(
|
|
242
|
+
getToolcraftChangedVerificationFiles(baseline.entries, current.entries),
|
|
243
|
+
["public/source.png"],
|
|
244
|
+
);
|
|
245
|
+
});
|
|
246
|
+
|
|
196
247
|
test("does not report legacy workflow-skill receipt entries as product changes", async (t) => {
|
|
197
248
|
const rootDir = await createRootWideInventoryFixture();
|
|
198
249
|
t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
|