@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
package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade-test-helpers.mjs
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
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
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
|
|
9
|
+
const harnessStateKey = Symbol.for(
|
|
10
|
+
"toolcraft.unavailable-resource-evidence-facade-harness",
|
|
11
|
+
);
|
|
12
|
+
const evidenceAttribute = "data-toolcraft-unavailable-resource-evidence";
|
|
13
|
+
const proofEventName = "toolcraft.browser-proof.unavailable-resource-request";
|
|
14
|
+
const runtimeAppSelector = '[data-slot="toolcraft-runtime-app"]';
|
|
15
|
+
const starterRoot = path.resolve(import.meta.dirname, "..");
|
|
16
|
+
const helperPath = path.join(
|
|
17
|
+
starterRoot,
|
|
18
|
+
"e2e/browser-infinity-canvas-evidence.ts",
|
|
19
|
+
);
|
|
20
|
+
const unavailableImageHelperPath = path.join(
|
|
21
|
+
starterRoot,
|
|
22
|
+
"e2e/browser-infinity-canvas-unavailable-image-evidence.ts",
|
|
23
|
+
);
|
|
24
|
+
let sessionSequence = 0;
|
|
25
|
+
|
|
26
|
+
function getState() {
|
|
27
|
+
const state = globalThis[harnessStateKey];
|
|
28
|
+
assert.ok(state, "Unavailable-resource evidence harness must be reset first.");
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function executeClosurelessObservation(read, root) {
|
|
33
|
+
const execute = new Function(
|
|
34
|
+
"root",
|
|
35
|
+
`"use strict"; return (${read.toString()})(root);`,
|
|
36
|
+
);
|
|
37
|
+
return execute(root);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function publishObservation(state, observation) {
|
|
41
|
+
state.observation = observation;
|
|
42
|
+
state.attributeValue = JSON.stringify(observation);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function createProtocolState() {
|
|
46
|
+
const state = {
|
|
47
|
+
actionCalls: 0,
|
|
48
|
+
activationError: null,
|
|
49
|
+
artifactValidations: 0,
|
|
50
|
+
attachments: [],
|
|
51
|
+
attributeNames: [],
|
|
52
|
+
attributeValue: null,
|
|
53
|
+
bridgeActions: [],
|
|
54
|
+
bridgeStatus: "missing",
|
|
55
|
+
cleanupFailure: false,
|
|
56
|
+
closurelessObservationCalls: 0,
|
|
57
|
+
eventNames: [],
|
|
58
|
+
executeClosurelessObservation,
|
|
59
|
+
malformedActivation: false,
|
|
60
|
+
observation: { status: "missing" },
|
|
61
|
+
pollCalls: 0,
|
|
62
|
+
selectorNames: [],
|
|
63
|
+
sessionAssertions: 0,
|
|
64
|
+
trace: [],
|
|
65
|
+
};
|
|
66
|
+
state.root = {
|
|
67
|
+
getAttribute(attributeName) {
|
|
68
|
+
state.attributeNames.push(attributeName);
|
|
69
|
+
assert.equal(attributeName, evidenceAttribute);
|
|
70
|
+
return state.attributeValue;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
state.document = {
|
|
74
|
+
dispatchEvent(event) {
|
|
75
|
+
state.eventNames.push(event.type);
|
|
76
|
+
assert.equal(event.type, proofEventName);
|
|
77
|
+
const detail = event.detail;
|
|
78
|
+
assert.equal(typeof detail, "object");
|
|
79
|
+
const expectedAction = state.bridgeStatus === "missing"
|
|
80
|
+
? "activate"
|
|
81
|
+
: "cleanup";
|
|
82
|
+
assert.equal(detail.action, expectedAction);
|
|
83
|
+
state.bridgeActions.push(detail.action);
|
|
84
|
+
state.trace.push(`action:${detail.action}`);
|
|
85
|
+
if (detail.action === "cleanup" && state.cleanupFailure) {
|
|
86
|
+
throw new Error("cleanup failed");
|
|
87
|
+
}
|
|
88
|
+
if (detail.action === "activate" && state.activationError) {
|
|
89
|
+
state.bridgeStatus = "error";
|
|
90
|
+
publishObservation(state, {
|
|
91
|
+
message: state.activationError,
|
|
92
|
+
requestId: detail.requestId,
|
|
93
|
+
status: "error",
|
|
94
|
+
});
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
if (detail.action === "activate" && state.malformedActivation) {
|
|
98
|
+
state.bridgeStatus = "error";
|
|
99
|
+
state.attributeValue = "{";
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
state.bridgeStatus = detail.action === "activate" ? "active" : "cleaned";
|
|
103
|
+
publishObservation(state, {
|
|
104
|
+
assetId: "image-2",
|
|
105
|
+
fileName: detail.fileName,
|
|
106
|
+
lifecycle: detail.action === "activate" ? "unavailable" : "ready",
|
|
107
|
+
requestId: detail.requestId,
|
|
108
|
+
resolverAvailable: detail.action !== "activate",
|
|
109
|
+
status: state.bridgeStatus,
|
|
110
|
+
});
|
|
111
|
+
return true;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
state.page = {
|
|
115
|
+
async evaluate(run, payload) {
|
|
116
|
+
const previousDocument = globalThis.document;
|
|
117
|
+
const previousCustomEvent = globalThis.CustomEvent;
|
|
118
|
+
globalThis.document = state.document;
|
|
119
|
+
globalThis.CustomEvent = class ToolcraftHarnessCustomEvent {
|
|
120
|
+
constructor(type, options) {
|
|
121
|
+
this.detail = options.detail;
|
|
122
|
+
this.type = type;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
try {
|
|
126
|
+
return await run(payload);
|
|
127
|
+
} finally {
|
|
128
|
+
if (previousDocument === undefined) delete globalThis.document;
|
|
129
|
+
else globalThis.document = previousDocument;
|
|
130
|
+
if (previousCustomEvent === undefined) delete globalThis.CustomEvent;
|
|
131
|
+
else globalThis.CustomEvent = previousCustomEvent;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
locator(selector) {
|
|
135
|
+
state.selectorNames.push(selector);
|
|
136
|
+
assert.equal(selector, runtimeAppSelector);
|
|
137
|
+
return {
|
|
138
|
+
getAttribute: (attributeName) =>
|
|
139
|
+
state.root.getAttribute(attributeName),
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
return state;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function transpileEvidenceModule(sourcePath, outputPath) {
|
|
147
|
+
const source = (await fs.readFile(sourcePath, "utf8"))
|
|
148
|
+
.replaceAll('"@playwright/test"', '"./playwright.mjs"')
|
|
149
|
+
.replaceAll('"./browser-runtime-evidence"', '"./evidence.mjs"')
|
|
150
|
+
.replaceAll('"./browser-proof-session"', '"./proof-session.mjs"')
|
|
151
|
+
.replaceAll('"./export-artifact-helpers"', '"./artifact.mjs"')
|
|
152
|
+
.replaceAll(
|
|
153
|
+
'"./browser-infinity-canvas-unavailable-image-evidence"',
|
|
154
|
+
'"./browser-infinity-canvas-unavailable-image-evidence.mjs"',
|
|
155
|
+
);
|
|
156
|
+
const { outputText } = ts.transpileModule(source, {
|
|
157
|
+
compilerOptions: {
|
|
158
|
+
module: ts.ModuleKind.ESNext,
|
|
159
|
+
target: ts.ScriptTarget.ES2022,
|
|
160
|
+
},
|
|
161
|
+
fileName: sourcePath,
|
|
162
|
+
});
|
|
163
|
+
await fs.writeFile(outputPath, outputText);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export async function loadUnavailableResourceFacade(context) {
|
|
167
|
+
const outputDir = await fs.mkdtemp(
|
|
168
|
+
path.join(os.tmpdir(), "toolcraft-unavailable-resource-evidence-"),
|
|
169
|
+
);
|
|
170
|
+
context.after(() => fs.rm(outputDir, { force: true, recursive: true }));
|
|
171
|
+
const outputPath = path.join(outputDir, "browser-infinity-canvas-evidence.mjs");
|
|
172
|
+
const stateAccessor =
|
|
173
|
+
`globalThis[Symbol.for("${Symbol.keyFor(harnessStateKey)}")]`;
|
|
174
|
+
|
|
175
|
+
await Promise.all([
|
|
176
|
+
transpileEvidenceModule(helperPath, outputPath),
|
|
177
|
+
transpileEvidenceModule(
|
|
178
|
+
unavailableImageHelperPath,
|
|
179
|
+
path.join(
|
|
180
|
+
outputDir,
|
|
181
|
+
"browser-infinity-canvas-unavailable-image-evidence.mjs",
|
|
182
|
+
),
|
|
183
|
+
),
|
|
184
|
+
fs.writeFile(
|
|
185
|
+
path.join(outputDir, "playwright.mjs"),
|
|
186
|
+
`
|
|
187
|
+
import assert from "node:assert/strict";
|
|
188
|
+
const state = () => ${stateAccessor};
|
|
189
|
+
function partial(actual, expected, message) {
|
|
190
|
+
for (const [key, value] of Object.entries(expected)) {
|
|
191
|
+
assert.deepEqual(actual?.[key], value, message);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
export function expect(actual, message = "Expectation failed") {
|
|
195
|
+
return {
|
|
196
|
+
not: {
|
|
197
|
+
toBe: (expected) => assert.notEqual(actual, expected, message),
|
|
198
|
+
toEqual: (expected) => assert.notDeepEqual(actual, expected, message),
|
|
199
|
+
},
|
|
200
|
+
toBe: (expected) => assert.equal(actual, expected, message),
|
|
201
|
+
toBeTruthy: () => assert.ok(actual, message),
|
|
202
|
+
toEqual: (expected) => assert.deepEqual(actual, expected, message),
|
|
203
|
+
toMatchObject(expected) {
|
|
204
|
+
if (expected?.status) state().trace.push("assert:" + expected.status);
|
|
205
|
+
partial(actual, expected, message);
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
expect.poll = (read, options) => ({
|
|
210
|
+
async toBe(expected) {
|
|
211
|
+
state().pollCalls += 1;
|
|
212
|
+
assert.equal(await read(), expected, options?.message);
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
`,
|
|
216
|
+
),
|
|
217
|
+
fs.writeFile(
|
|
218
|
+
path.join(outputDir, "evidence.mjs"),
|
|
219
|
+
`
|
|
220
|
+
const state = () => ${stateAccessor};
|
|
221
|
+
export async function attachToolcraftBrowserRuntimeEvidence(evidence) {
|
|
222
|
+
state().trace.push("evidence:" + evidence.evidenceType);
|
|
223
|
+
state().attachments.push(evidence);
|
|
224
|
+
}
|
|
225
|
+
`,
|
|
226
|
+
),
|
|
227
|
+
fs.writeFile(
|
|
228
|
+
path.join(outputDir, "proof-session.mjs"),
|
|
229
|
+
`
|
|
230
|
+
import assert from "node:assert/strict";
|
|
231
|
+
const state = () => ${stateAccessor};
|
|
232
|
+
export function assertToolcraftBrowserProofSession(observation, ...actions) {
|
|
233
|
+
state().sessionAssertions += 1;
|
|
234
|
+
for (const action of actions) {
|
|
235
|
+
assert.equal(
|
|
236
|
+
action.sessionToken,
|
|
237
|
+
observation.sessionToken,
|
|
238
|
+
"Semantic evidence observations and actions must belong to the same browser proof session.",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export function getToolcraftBrowserActionTarget(action) {
|
|
243
|
+
return action.target;
|
|
244
|
+
}
|
|
245
|
+
export async function readToolcraftBrowserObservation(observation) {
|
|
246
|
+
const current = state();
|
|
247
|
+
current.closurelessObservationCalls += 1;
|
|
248
|
+
return current.executeClosurelessObservation(
|
|
249
|
+
observation.read,
|
|
250
|
+
current.root,
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
export async function runToolcraftBrowserAction(action) {
|
|
254
|
+
state().actionCalls += 1;
|
|
255
|
+
await action.run(state().page);
|
|
256
|
+
}
|
|
257
|
+
export async function runToolcraftBrowserValueAction(action) {
|
|
258
|
+
return action.run(state().page);
|
|
259
|
+
}
|
|
260
|
+
`,
|
|
261
|
+
),
|
|
262
|
+
fs.writeFile(
|
|
263
|
+
path.join(outputDir, "artifact.mjs"),
|
|
264
|
+
`
|
|
265
|
+
const state = () => ${stateAccessor};
|
|
266
|
+
export function assertToolcraftProducedArtifact(artifact) {
|
|
267
|
+
if (!artifact) throw new Error("missing artifact");
|
|
268
|
+
}
|
|
269
|
+
export function validateToolcraftExportArtifactInspection(inspection) {
|
|
270
|
+
state().artifactValidations += 1;
|
|
271
|
+
if (!inspection?.byteLength) throw new Error("invalid inspection");
|
|
272
|
+
return inspection;
|
|
273
|
+
}
|
|
274
|
+
`,
|
|
275
|
+
),
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
return import(`${pathToFileURL(outputPath).href}?test=${Date.now()}`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export function createSession() {
|
|
282
|
+
const sessionToken = `session-${++sessionSequence}`;
|
|
283
|
+
return {
|
|
284
|
+
observe(read) {
|
|
285
|
+
return Object.freeze({ read, sessionToken });
|
|
286
|
+
},
|
|
287
|
+
targetAction(target, run) {
|
|
288
|
+
return Object.freeze({ run, sessionToken, target });
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function createArtifactAction(session, target, result) {
|
|
294
|
+
return session.targetAction(target, async () => {
|
|
295
|
+
getState().trace.push("artifact");
|
|
296
|
+
return result;
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function resetHarness() {
|
|
301
|
+
globalThis[harnessStateKey] = createProtocolState();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function getHarnessState() {
|
|
305
|
+
return getState();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function setCleanupFailure() {
|
|
309
|
+
getState().cleanupFailure = true;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function setActivationError(message) {
|
|
313
|
+
getState().activationError = message;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function setMalformedActivation() {
|
|
317
|
+
getState().malformedActivation = true;
|
|
318
|
+
}
|