@kumwe/studio-testkit 0.1.0-alpha.8 → 0.1.0-rc.1

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.
Files changed (42) hide show
  1. package/README.md +48 -14
  2. package/THIRD_PARTY_NOTICES.md +9 -0
  3. package/conformance/authoring-web/non-drag-move-equivalence.json +199 -0
  4. package/conformance/renderer-web/blob-default-deny.json +47 -0
  5. package/conformance/renderer-web/chart-fallback.json +39 -0
  6. package/conformance/renderer-web/complete-catalog.json +634 -0
  7. package/conformance/renderer-web/escaped-heading.json +28 -0
  8. package/conformance/renderer-web/interactive-behaviors.json +226 -0
  9. package/conformance/renderer-web/presentation-capabilities.json +76 -0
  10. package/conformance/renderer-web/responsive-grid.json +33 -0
  11. package/conformance/renderer-web/security-fallbacks.json +169 -0
  12. package/conformance/rich-text/advanced.first-party.json +67 -0
  13. package/corpus-manifest.json +106 -0
  14. package/dist/host-testbed.d.ts +3 -4
  15. package/dist/host-testbed.d.ts.map +1 -1
  16. package/dist/host-testbed.js +46 -6
  17. package/dist/host-testbed.js.map +1 -1
  18. package/dist/http-host-adapter.d.ts.map +1 -1
  19. package/dist/http-host-adapter.js +8 -0
  20. package/dist/http-host-adapter.js.map +1 -1
  21. package/dist/index.d.ts +44 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +38 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/web-conformance.d.ts +105 -0
  26. package/dist/web-conformance.d.ts.map +1 -0
  27. package/dist/web-conformance.js +72 -0
  28. package/dist/web-conformance.js.map +1 -0
  29. package/fixtures/authoring-message-catalog.en.json +649 -0
  30. package/invalid/binding-projection-vector.unknown-status.json +85 -0
  31. package/invalid/studio-chart.script-config.json +10 -0
  32. package/invalid/studio-drawing.svg-payload.json +10 -0
  33. package/invalid/studio-money.float.json +8 -0
  34. package/invalid/studio-presentation.css-injection.json +8 -0
  35. package/invalid/studio-table.html-cell.json +8 -0
  36. package/package.json +7 -3
  37. package/studio-release.json +28 -0
  38. package/vectors/binding-projection/app-content-fields.resolved.json +286 -0
  39. package/vectors/binding-projection/field-removed.diagnostic.json +135 -0
  40. package/vectors/binding-projection/model-revision-mismatch.diagnostic.json +124 -0
  41. package/vectors/host/model.get.stored.json +37 -0
  42. package/vectors/host/model.list.authorized.json +31 -0
@@ -0,0 +1,105 @@
1
+ import type { BlueprintDocument, JsonObject, JsonValue, QualifiedName, StableId } from '@kumwe/studio-protocol';
2
+ export type AuthoringWebRegion = 'canvas' | 'command-palette' | 'inspector' | 'outline' | 'palette' | 'preview' | 'viewport';
3
+ export type AuthoringWebAction = {
4
+ kind: 'focus-node';
5
+ nodeId: StableId;
6
+ region: AuthoringWebRegion;
7
+ } | {
8
+ key: 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'ArrowUp' | 'Delete' | 'End' | 'Enter' | 'Escape' | 'Home' | 'Tab' | 'd' | 'y' | 'z';
9
+ kind: 'key';
10
+ modifiers: ('Alt' | 'Control' | 'Meta' | 'Shift')[];
11
+ region: AuthoringWebRegion;
12
+ } | {
13
+ destination: {
14
+ parentNodeId?: StableId;
15
+ position: number;
16
+ slot?: string;
17
+ };
18
+ kind: 'drag-node';
19
+ nodeId: StableId;
20
+ } | {
21
+ kind: 'activate-command';
22
+ payload: JsonObject;
23
+ region: AuthoringWebRegion;
24
+ type: QualifiedName;
25
+ } | {
26
+ kind: 'edit-property';
27
+ nodeId: StableId;
28
+ property: string;
29
+ value: JsonValue;
30
+ viewport?: string;
31
+ };
32
+ export interface AuthoringWebGiven {
33
+ direction: 'ltr' | 'rtl';
34
+ document: BlueprintDocument;
35
+ locale: string;
36
+ readOnly: boolean;
37
+ reducedMotion: boolean;
38
+ selection: StableId | null;
39
+ viewport: {
40
+ height: number;
41
+ width: number;
42
+ zoomPercent: number;
43
+ };
44
+ }
45
+ export interface AuthoringWebCommandObservation {
46
+ payload: JsonObject;
47
+ type: QualifiedName;
48
+ }
49
+ export interface AuthoringWebObservation {
50
+ announcements: {
51
+ key: QualifiedName;
52
+ politeness: 'assertive' | 'polite';
53
+ }[];
54
+ commands: AuthoringWebCommandObservation[];
55
+ dirty: boolean;
56
+ document: BlueprintDocument;
57
+ focus: {
58
+ nodeId?: StableId;
59
+ region: AuthoringWebRegion;
60
+ };
61
+ selection: StableId | null;
62
+ }
63
+ export interface AuthoringWebLane {
64
+ name: string;
65
+ steps: AuthoringWebAction[];
66
+ surface: 'keyboard' | 'pointer' | 'structural-control';
67
+ }
68
+ export interface AuthoringWebVector {
69
+ contractVersion: string;
70
+ description: string;
71
+ expect: AuthoringWebObservation;
72
+ given: AuthoringWebGiven;
73
+ id: QualifiedName;
74
+ kind: 'authoring-web-vector';
75
+ lanes: AuthoringWebLane[];
76
+ requirements: string[];
77
+ }
78
+ export interface AuthoringWebConformanceSession {
79
+ dispose?(): Promise<void> | void;
80
+ observe(): Promise<AuthoringWebObservation> | AuthoringWebObservation;
81
+ perform(action: Readonly<AuthoringWebAction>): Promise<void> | void;
82
+ }
83
+ export interface AuthoringWebConformanceAdapter {
84
+ open(given: Readonly<AuthoringWebGiven>, lane: Readonly<AuthoringWebLane>): Promise<AuthoringWebConformanceSession> | AuthoringWebConformanceSession;
85
+ }
86
+ export interface AuthoringWebLaneResult {
87
+ mismatches: string[];
88
+ name: string;
89
+ observation: AuthoringWebObservation;
90
+ passed: boolean;
91
+ surface: AuthoringWebLane['surface'];
92
+ }
93
+ export interface AuthoringWebVectorResult {
94
+ lanes: AuthoringWebLaneResult[];
95
+ passed: boolean;
96
+ profile: 'studio.profile/authoring-web';
97
+ vectorId: QualifiedName;
98
+ }
99
+ /**
100
+ * Replay every interaction lane from an independent copy of the same initial
101
+ * state. The adapter owns browser automation; this runner owns fixture
102
+ * isolation and deterministic observation comparison.
103
+ */
104
+ export declare function runAuthoringWebVector(vector: Readonly<AuthoringWebVector>, adapter: Readonly<AuthoringWebConformanceAdapter>): Promise<AuthoringWebVectorResult>;
105
+ //# sourceMappingURL=web-conformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-conformance.d.ts","sourceRoot":"","sources":["../src/web-conformance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Replay every interaction lane from an independent copy of the same initial
3
+ * state. The adapter owns browser automation; this runner owns fixture
4
+ * isolation and deterministic observation comparison.
5
+ */
6
+ export async function runAuthoringWebVector(vector, adapter) {
7
+ const pristine = stableJson(vector);
8
+ const lanes = [];
9
+ for (const lane of vector.lanes) {
10
+ const session = await adapter.open(cloneJson(vector.given), cloneJson(lane));
11
+ let observation;
12
+ try {
13
+ for (const action of lane.steps) {
14
+ await session.perform(cloneJson(action));
15
+ }
16
+ observation = cloneJson(await session.observe());
17
+ }
18
+ finally {
19
+ await session.dispose?.();
20
+ }
21
+ const mismatches = compareAuthoringObservation(observation, vector.expect);
22
+ if (stableJson(vector) !== pristine) {
23
+ mismatches.push('adapter mutated the conformance vector');
24
+ }
25
+ lanes.push({
26
+ mismatches,
27
+ name: lane.name,
28
+ observation,
29
+ passed: mismatches.length === 0,
30
+ surface: lane.surface,
31
+ });
32
+ }
33
+ return {
34
+ lanes,
35
+ passed: lanes.every((lane) => lane.passed),
36
+ profile: 'studio.profile/authoring-web',
37
+ vectorId: vector.id,
38
+ };
39
+ }
40
+ function compareAuthoringObservation(actual, expected) {
41
+ const mismatches = [];
42
+ compareExact(mismatches, 'announcements', actual.announcements, expected.announcements);
43
+ compareExact(mismatches, 'commands', actual.commands, expected.commands);
44
+ compareExact(mismatches, 'dirty', actual.dirty, expected.dirty);
45
+ compareExact(mismatches, 'document', actual.document, expected.document);
46
+ compareExact(mismatches, 'focus', actual.focus, expected.focus);
47
+ compareExact(mismatches, 'selection', actual.selection, expected.selection);
48
+ return mismatches;
49
+ }
50
+ function compareExact(mismatches, field, actual, expected) {
51
+ if (stableJson(actual) !== stableJson(expected)) {
52
+ mismatches.push(`${field} differs from the vector expectation`);
53
+ }
54
+ }
55
+ function cloneJson(value) {
56
+ return JSON.parse(JSON.stringify(value));
57
+ }
58
+ function stableJson(value) {
59
+ return JSON.stringify(sortJson(value)) ?? 'undefined';
60
+ }
61
+ function sortJson(value) {
62
+ if (Array.isArray(value)) {
63
+ return value.map((member) => sortJson(member));
64
+ }
65
+ if (value !== null && typeof value === 'object') {
66
+ return Object.fromEntries(Object.entries(value)
67
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
68
+ .map(([key, member]) => [key, sortJson(member)]));
69
+ }
70
+ return value;
71
+ }
72
+ //# sourceMappingURL=web-conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-conformance.js","sourceRoot":"","sources":["../src/web-conformance.ts"],"names":[],"mappings":"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"}