@dreamboard-games/sdk 0.4.0-alpha.0 → 0.4.0-alpha.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.
- package/README.md +8 -1
- package/REFERENCE.md +488 -108
- package/dist/attributes-BrZtP9az.d.ts +53 -0
- package/dist/browser-interaction.d.ts +44 -42
- package/dist/browser-interaction.js +2 -1
- package/dist/{chunk-4G7552LO.js → chunk-3K362ZKR.js} +17 -12
- package/dist/chunk-3K362ZKR.js.map +1 -0
- package/dist/{chunk-U5KBV2BA.js → chunk-7LZZEI25.js} +444 -223
- package/dist/chunk-7LZZEI25.js.map +1 -0
- package/dist/{chunk-Q5O7GPVY.js → chunk-7W6TQO3X.js} +18 -10
- package/dist/chunk-7W6TQO3X.js.map +1 -0
- package/dist/chunk-AEUXCFGM.js +124 -0
- package/dist/chunk-AEUXCFGM.js.map +1 -0
- package/dist/{chunk-P7F4L2FF.js → chunk-CZMFAS3E.js} +327 -248
- package/dist/chunk-CZMFAS3E.js.map +1 -0
- package/dist/{chunk-MNKDSGIA.js → chunk-IUGKW2GS.js} +2 -2
- package/dist/{chunk-MNKDSGIA.js.map → chunk-IUGKW2GS.js.map} +1 -1
- package/dist/{chunk-QLG6VEMW.js → chunk-MALRKLRR.js} +19 -11
- package/dist/chunk-MALRKLRR.js.map +1 -0
- package/dist/{chunk-2LDZ5C3T.js → chunk-XJYUSD5F.js} +2 -2
- package/dist/{chunk-NBAEEHAU.js → chunk-XXBSIPJX.js} +5952 -5364
- package/dist/chunk-XXBSIPJX.js.map +1 -0
- package/dist/codegen.d.ts +3 -1
- package/dist/codegen.js +1 -1
- package/dist/{components-DaIqi9QM.d.ts → components-Dqr_LuZJ.d.ts} +1 -65
- package/dist/index.js +1 -1
- package/dist/package-set.d.ts +2 -2
- package/dist/package-set.js +1 -1
- package/dist/reducer/advanced.d.ts +2 -2
- package/dist/reducer/advanced.js +1 -1
- package/dist/reducer-contract.js +1 -1
- package/dist/reducer.d.ts +7 -7
- package/dist/reducer.js +190 -183
- package/dist/reducer.js.map +1 -1
- package/dist/runtime/primitives.d.ts +4 -3
- package/dist/runtime/primitives.js +5 -4
- package/dist/runtime/workspace-contract.d.ts +10 -69
- package/dist/runtime/workspace-contract.js +6 -5
- package/dist/runtime-json-CQ9QbLZ5.d.ts +5 -0
- package/dist/runtime.d.ts +70 -5
- package/dist/runtime.js +483 -129
- package/dist/runtime.js.map +1 -1
- package/dist/testing.d.ts +509 -2
- package/dist/testing.js +481 -1
- package/dist/testing.js.map +1 -1
- package/dist/{attributes-BeRyboMS.d.ts → types-BqzHkNMA.d.ts} +1 -51
- package/dist/types.d.ts +4 -2
- package/dist/ui/components.d.ts +1 -1
- package/dist/ui/components.js +1 -1
- package/dist/ui/plugin-styles.css +1 -1
- package/dist/{ui-contract-BUC6iS3s.d.ts → ui-contract-W2-kxObe.d.ts} +2 -1
- package/dist/ui.d.ts +3 -7
- package/dist/ui.js +2 -2
- package/dist/{views-B0hlW6IT.d.ts → views-fn2RuXOx.d.ts} +59 -44
- package/package.json +31 -13
- package/dist/chunk-4G7552LO.js.map +0 -1
- package/dist/chunk-NBAEEHAU.js.map +0 -1
- package/dist/chunk-P7F4L2FF.js.map +0 -1
- package/dist/chunk-Q5O7GPVY.js.map +0 -1
- package/dist/chunk-QLG6VEMW.js.map +0 -1
- package/dist/chunk-U5KBV2BA.js.map +0 -1
- /package/dist/{chunk-2LDZ5C3T.js.map → chunk-XJYUSD5F.js.map} +0 -0
package/dist/testing.js
CHANGED
|
@@ -2,6 +2,14 @@ import {
|
|
|
2
2
|
StaleContractArtifactError,
|
|
3
3
|
isStaleContractArtifactError
|
|
4
4
|
} from "./chunk-3OZMHZK3.js";
|
|
5
|
+
import {
|
|
6
|
+
BROWSER_INTERACTION_ACTUATOR_KINDS,
|
|
7
|
+
DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
|
|
8
|
+
browserInteractionEffectSchema
|
|
9
|
+
} from "./chunk-MALRKLRR.js";
|
|
10
|
+
import {
|
|
11
|
+
RuntimeJsonSchema
|
|
12
|
+
} from "./chunk-AEUXCFGM.js";
|
|
5
13
|
import "./chunk-PZ5AY32C.js";
|
|
6
14
|
|
|
7
15
|
// src/testing/definitions.ts
|
|
@@ -666,12 +674,484 @@ function createTestRuntime(options) {
|
|
|
666
674
|
setControllingPlayer
|
|
667
675
|
};
|
|
668
676
|
}
|
|
677
|
+
|
|
678
|
+
// src/testing/ui-fixture/canonical.ts
|
|
679
|
+
import { createHash } from "crypto";
|
|
680
|
+
var sha256DigestPattern = /^sha256:[a-f0-9]{64}$/;
|
|
681
|
+
function isSha256Digest(value) {
|
|
682
|
+
return sha256DigestPattern.test(value);
|
|
683
|
+
}
|
|
684
|
+
function canonicalizeUIFixtureJson(value) {
|
|
685
|
+
if (value === null) {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
switch (typeof value) {
|
|
689
|
+
case "boolean":
|
|
690
|
+
case "string":
|
|
691
|
+
return value;
|
|
692
|
+
case "number":
|
|
693
|
+
if (Number.isFinite(value)) {
|
|
694
|
+
return value;
|
|
695
|
+
}
|
|
696
|
+
break;
|
|
697
|
+
case "object": {
|
|
698
|
+
if (Array.isArray(value)) {
|
|
699
|
+
return value.map((item) => canonicalizeUIFixtureJson(item));
|
|
700
|
+
}
|
|
701
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
const entries = Object.entries(value);
|
|
705
|
+
return Object.fromEntries(
|
|
706
|
+
entries.filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, canonicalizeUIFixtureJson(item)])
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
throw new Error(
|
|
711
|
+
`UI fixture values must be deterministic JSON. Received ${typeof value}.`
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
function canonicalUIFixtureJson(value) {
|
|
715
|
+
return JSON.stringify(canonicalizeUIFixtureJson(value));
|
|
716
|
+
}
|
|
717
|
+
function digestUIFixtureJson(value) {
|
|
718
|
+
return sha256(canonicalUIFixtureJson(value));
|
|
719
|
+
}
|
|
720
|
+
function digestUIFixtureRequest(request) {
|
|
721
|
+
return digestUIFixtureJson({
|
|
722
|
+
digestVersion: "ui-replay-request@1",
|
|
723
|
+
request
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
function canonicalizeUIScenarioFixture(fixture) {
|
|
727
|
+
return canonicalizeUIFixtureJson({
|
|
728
|
+
...fixture,
|
|
729
|
+
tags: [...fixture.tags].sort(),
|
|
730
|
+
environment: {
|
|
731
|
+
...fixture.environment,
|
|
732
|
+
viewportTags: [...fixture.environment.viewportTags].sort()
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
function serializeUIScenarioFixture(fixture) {
|
|
737
|
+
return `${JSON.stringify(canonicalizeUIScenarioFixture(fixture), null, 2)}
|
|
738
|
+
`;
|
|
739
|
+
}
|
|
740
|
+
function digestUIScenarioFixture(fixture) {
|
|
741
|
+
return sha256(serializeUIScenarioFixture(fixture));
|
|
742
|
+
}
|
|
743
|
+
function sha256(value) {
|
|
744
|
+
return `sha256:${createHash("sha256").update(value).digest("hex")}`;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// src/testing/ui-fixture/schema.ts
|
|
748
|
+
import { z } from "zod";
|
|
749
|
+
var UI_SCENARIO_FIXTURE_SCHEMA_VERSION = 1;
|
|
750
|
+
var UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION = 1;
|
|
751
|
+
var UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR = 2;
|
|
752
|
+
var digestSchema = z.string().refine(isSha256Digest, {
|
|
753
|
+
message: "Expected a sha256:<64 lowercase hex> digest."
|
|
754
|
+
});
|
|
755
|
+
var nonEmptyStringSchema = z.string().min(1);
|
|
756
|
+
var jsonSchema = RuntimeJsonSchema;
|
|
757
|
+
var environmentSchema = z.object({
|
|
758
|
+
clockIso: nonEmptyStringSchema,
|
|
759
|
+
randomSeed: nonEmptyStringSchema,
|
|
760
|
+
locale: z.literal("en-US"),
|
|
761
|
+
timezone: z.literal("UTC"),
|
|
762
|
+
viewportTags: z.array(z.enum(["desktop", "tablet", "phone", "touch"]))
|
|
763
|
+
}).strict();
|
|
764
|
+
var pluginSessionSchema = z.object({
|
|
765
|
+
sessionId: nonEmptyStringSchema,
|
|
766
|
+
controllablePlayerIds: z.array(nonEmptyStringSchema),
|
|
767
|
+
controllingPlayerId: nonEmptyStringSchema.nullable(),
|
|
768
|
+
userId: nonEmptyStringSchema.nullable()
|
|
769
|
+
}).catchall(jsonSchema);
|
|
770
|
+
var gameplaySnapshotSchema = z.object({
|
|
771
|
+
currentPhase: nonEmptyStringSchema.nullable(),
|
|
772
|
+
currentStage: nonEmptyStringSchema.nullable(),
|
|
773
|
+
activePlayers: z.array(nonEmptyStringSchema),
|
|
774
|
+
simultaneousPhase: jsonSchema.nullable().optional(),
|
|
775
|
+
availableInteractions: z.array(jsonSchema),
|
|
776
|
+
zones: z.record(z.string(), jsonSchema)
|
|
777
|
+
}).catchall(jsonSchema);
|
|
778
|
+
var uiFixturePluginStateSnapshotSchema = z.object({
|
|
779
|
+
view: jsonSchema.nullable(),
|
|
780
|
+
gameplay: gameplaySnapshotSchema,
|
|
781
|
+
lobby: jsonSchema.nullable(),
|
|
782
|
+
notifications: z.array(jsonSchema),
|
|
783
|
+
session: pluginSessionSchema,
|
|
784
|
+
history: jsonSchema.nullable(),
|
|
785
|
+
syncId: z.number().int().nonnegative()
|
|
786
|
+
}).strict();
|
|
787
|
+
var uiFixtureFrameSchema = z.object({
|
|
788
|
+
id: nonEmptyStringSchema,
|
|
789
|
+
snapshot: uiFixturePluginStateSnapshotSchema,
|
|
790
|
+
projectionDigest: digestSchema
|
|
791
|
+
}).strict();
|
|
792
|
+
var uiFixtureTransportExchangeSchema = z.object({
|
|
793
|
+
id: nonEmptyStringSchema,
|
|
794
|
+
fromFrameId: nonEmptyStringSchema,
|
|
795
|
+
operation: z.enum(["validate", "submit", "refresh"]),
|
|
796
|
+
requestDigest: digestSchema,
|
|
797
|
+
response: z.union([
|
|
798
|
+
z.object({
|
|
799
|
+
kind: z.literal("accepted"),
|
|
800
|
+
nextFrameId: nonEmptyStringSchema
|
|
801
|
+
}).strict(),
|
|
802
|
+
z.object({
|
|
803
|
+
kind: z.literal("rejected"),
|
|
804
|
+
diagnostics: z.array(
|
|
805
|
+
z.object({
|
|
806
|
+
code: nonEmptyStringSchema,
|
|
807
|
+
message: nonEmptyStringSchema
|
|
808
|
+
}).strict()
|
|
809
|
+
)
|
|
810
|
+
}).strict()
|
|
811
|
+
])
|
|
812
|
+
}).strict();
|
|
813
|
+
var browserInteractionIntentRequestSchema = z.object({
|
|
814
|
+
surface: nonEmptyStringSchema,
|
|
815
|
+
scopeId: nonEmptyStringSchema.optional(),
|
|
816
|
+
interactionKey: nonEmptyStringSchema.optional(),
|
|
817
|
+
interactionId: nonEmptyStringSchema.optional(),
|
|
818
|
+
intent: nonEmptyStringSchema,
|
|
819
|
+
inputKey: nonEmptyStringSchema.optional(),
|
|
820
|
+
candidateValue: jsonSchema.optional(),
|
|
821
|
+
candidateValueKey: nonEmptyStringSchema.optional(),
|
|
822
|
+
actuatorKind: z.enum(BROWSER_INTERACTION_ACTUATOR_KINDS).optional(),
|
|
823
|
+
allowDisabled: z.boolean().optional()
|
|
824
|
+
}).strict();
|
|
825
|
+
var browserInteractionEffectRequestSchema = z.object({
|
|
826
|
+
surface: nonEmptyStringSchema,
|
|
827
|
+
scopeId: nonEmptyStringSchema.optional(),
|
|
828
|
+
interactionKey: nonEmptyStringSchema.optional(),
|
|
829
|
+
interactionId: nonEmptyStringSchema.optional(),
|
|
830
|
+
effect: browserInteractionEffectSchema,
|
|
831
|
+
allowDisabled: z.boolean().optional()
|
|
832
|
+
}).strict();
|
|
833
|
+
var uiReplayRequestSchema = z.union([
|
|
834
|
+
browserInteractionIntentRequestSchema,
|
|
835
|
+
browserInteractionEffectRequestSchema
|
|
836
|
+
]);
|
|
837
|
+
var uiReplayExecutionSchema = z.union([
|
|
838
|
+
z.object({
|
|
839
|
+
kind: z.literal("activate")
|
|
840
|
+
}).strict(),
|
|
841
|
+
z.object({
|
|
842
|
+
kind: z.literal("fill"),
|
|
843
|
+
value: z.string()
|
|
844
|
+
}).strict(),
|
|
845
|
+
z.object({
|
|
846
|
+
kind: z.literal("drag"),
|
|
847
|
+
target: browserInteractionEffectRequestSchema
|
|
848
|
+
}).strict()
|
|
849
|
+
]);
|
|
850
|
+
var uiStepExpectationSchema = z.object({
|
|
851
|
+
frameId: nonEmptyStringSchema.optional(),
|
|
852
|
+
projectionDigest: digestSchema.optional(),
|
|
853
|
+
semanticDigest: digestSchema.optional(),
|
|
854
|
+
draftDigest: digestSchema.optional(),
|
|
855
|
+
submissionDigest: digestSchema.optional(),
|
|
856
|
+
focusedInteractionKey: nonEmptyStringSchema.optional(),
|
|
857
|
+
visibleInteractionKeys: z.array(nonEmptyStringSchema).optional()
|
|
858
|
+
}).strict();
|
|
859
|
+
var uiResolvedReplayIdentitySchema = z.object({
|
|
860
|
+
stepId: nonEmptyStringSchema,
|
|
861
|
+
surface: nonEmptyStringSchema,
|
|
862
|
+
scopeId: nonEmptyStringSchema,
|
|
863
|
+
interactionKey: nonEmptyStringSchema,
|
|
864
|
+
interactionId: nonEmptyStringSchema,
|
|
865
|
+
actuatorId: nonEmptyStringSchema,
|
|
866
|
+
descriptorDigest: digestSchema.optional(),
|
|
867
|
+
draftDigest: digestSchema.optional()
|
|
868
|
+
}).strict();
|
|
869
|
+
var portableSemanticReplayStepSchema = z.object({
|
|
870
|
+
stepId: nonEmptyStringSchema,
|
|
871
|
+
requestDigest: digestSchema,
|
|
872
|
+
resolve: uiReplayRequestSchema,
|
|
873
|
+
execute: uiReplayExecutionSchema,
|
|
874
|
+
expectedIdentity: uiResolvedReplayIdentitySchema.optional(),
|
|
875
|
+
expect: uiStepExpectationSchema
|
|
876
|
+
}).strict();
|
|
877
|
+
var uiScenarioReplayStepSchema = z.union([
|
|
878
|
+
portableSemanticReplayStepSchema,
|
|
879
|
+
z.object({
|
|
880
|
+
stepId: nonEmptyStringSchema,
|
|
881
|
+
kind: z.literal("assert"),
|
|
882
|
+
expect: uiStepExpectationSchema
|
|
883
|
+
}).strict()
|
|
884
|
+
]);
|
|
885
|
+
var uiScenarioFixtureSchema = z.object({
|
|
886
|
+
schemaVersion: z.literal(UI_SCENARIO_FIXTURE_SCHEMA_VERSION),
|
|
887
|
+
browserInteractionProtocol: z.literal(
|
|
888
|
+
DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION
|
|
889
|
+
),
|
|
890
|
+
id: nonEmptyStringSchema,
|
|
891
|
+
title: nonEmptyStringSchema,
|
|
892
|
+
gameId: nonEmptyStringSchema,
|
|
893
|
+
tags: z.array(nonEmptyStringSchema),
|
|
894
|
+
source: z.object({
|
|
895
|
+
scenarioId: nonEmptyStringSchema,
|
|
896
|
+
reducerFingerprint: nonEmptyStringSchema,
|
|
897
|
+
uiContractFingerprint: nonEmptyStringSchema,
|
|
898
|
+
renderModule: nonEmptyStringSchema,
|
|
899
|
+
renderModuleDigest: digestSchema,
|
|
900
|
+
sourceDigest: digestSchema
|
|
901
|
+
}).strict(),
|
|
902
|
+
viewer: z.object({
|
|
903
|
+
seatId: nonEmptyStringSchema,
|
|
904
|
+
playerId: nonEmptyStringSchema.optional()
|
|
905
|
+
}).strict(),
|
|
906
|
+
environment: environmentSchema,
|
|
907
|
+
frames: z.array(uiFixtureFrameSchema).min(1),
|
|
908
|
+
transport: z.array(uiFixtureTransportExchangeSchema),
|
|
909
|
+
replay: z.array(uiScenarioReplayStepSchema),
|
|
910
|
+
expected: z.object({
|
|
911
|
+
initialProjectionDigest: digestSchema,
|
|
912
|
+
finalProjectionDigest: digestSchema,
|
|
913
|
+
finalSemanticDigest: digestSchema,
|
|
914
|
+
submissionDigest: digestSchema
|
|
915
|
+
}).strict()
|
|
916
|
+
}).strict();
|
|
917
|
+
var uiScenarioFixtureBundleIndexSchema = z.object({
|
|
918
|
+
schemaVersion: z.literal(UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION),
|
|
919
|
+
bundleId: nonEmptyStringSchema,
|
|
920
|
+
sdkCommit: nonEmptyStringSchema,
|
|
921
|
+
browserInteractionProtocol: z.literal(
|
|
922
|
+
DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION
|
|
923
|
+
),
|
|
924
|
+
fixtures: z.array(
|
|
925
|
+
z.object({
|
|
926
|
+
id: nonEmptyStringSchema,
|
|
927
|
+
file: nonEmptyStringSchema,
|
|
928
|
+
sha256: digestSchema,
|
|
929
|
+
renderModule: nonEmptyStringSchema,
|
|
930
|
+
renderModuleSha256: digestSchema,
|
|
931
|
+
components: z.array(nonEmptyStringSchema),
|
|
932
|
+
capabilities: z.array(nonEmptyStringSchema)
|
|
933
|
+
}).strict()
|
|
934
|
+
)
|
|
935
|
+
}).strict();
|
|
936
|
+
function parseUIScenarioFixture(value) {
|
|
937
|
+
const fixture = uiScenarioFixtureSchema.parse(
|
|
938
|
+
value
|
|
939
|
+
);
|
|
940
|
+
validateUIScenarioFixtureReferences(fixture);
|
|
941
|
+
return fixture;
|
|
942
|
+
}
|
|
943
|
+
function parseUIScenarioFixtureBundleIndex(value) {
|
|
944
|
+
const bundle = uiScenarioFixtureBundleIndexSchema.parse(value);
|
|
945
|
+
assertSupportedBrowserInteractionProtocol(bundle.browserInteractionProtocol);
|
|
946
|
+
const ids = /* @__PURE__ */ new Set();
|
|
947
|
+
for (const entry of bundle.fixtures) {
|
|
948
|
+
if (ids.has(entry.id)) {
|
|
949
|
+
throw new Error(`Duplicate fixture id '${entry.id}' in bundle index.`);
|
|
950
|
+
}
|
|
951
|
+
ids.add(entry.id);
|
|
952
|
+
}
|
|
953
|
+
return bundle;
|
|
954
|
+
}
|
|
955
|
+
function assertSupportedBrowserInteractionProtocol(version) {
|
|
956
|
+
const major = Number(version.split(".")[0]);
|
|
957
|
+
if (major !== UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR) {
|
|
958
|
+
throw new Error(
|
|
959
|
+
`Unsupported browser-interaction protocol '${version}'. Expected major ${UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR}.`
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
function validateUIScenarioFixtureReferences(fixture) {
|
|
964
|
+
assertSupportedBrowserInteractionProtocol(fixture.browserInteractionProtocol);
|
|
965
|
+
const frameIds = /* @__PURE__ */ new Set();
|
|
966
|
+
for (const frame of fixture.frames) {
|
|
967
|
+
if (frameIds.has(frame.id)) {
|
|
968
|
+
throw new Error(`Duplicate fixture frame id '${frame.id}'.`);
|
|
969
|
+
}
|
|
970
|
+
frameIds.add(frame.id);
|
|
971
|
+
}
|
|
972
|
+
for (const exchange of fixture.transport) {
|
|
973
|
+
if (!frameIds.has(exchange.fromFrameId)) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
`Transport exchange '${exchange.id}' references missing fromFrameId '${exchange.fromFrameId}'.`
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
if (exchange.response.kind === "accepted" && !frameIds.has(exchange.response.nextFrameId)) {
|
|
979
|
+
throw new Error(
|
|
980
|
+
`Transport exchange '${exchange.id}' references missing nextFrameId '${exchange.response.nextFrameId}'.`
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
for (const step of fixture.replay) {
|
|
985
|
+
if ("resolve" in step) {
|
|
986
|
+
const actualDigest = digestUIFixtureRequest(
|
|
987
|
+
step.resolve
|
|
988
|
+
);
|
|
989
|
+
if (step.requestDigest !== actualDigest) {
|
|
990
|
+
throw new Error(
|
|
991
|
+
`Replay step '${step.stepId}' requestDigest ${step.requestDigest} does not match ${actualDigest}.`
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
const expectedFrameId = step.expect.frameId;
|
|
996
|
+
if (expectedFrameId && !frameIds.has(expectedFrameId)) {
|
|
997
|
+
throw new Error(
|
|
998
|
+
`Replay step '${step.stepId}' expects missing frameId '${expectedFrameId}'.`
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// src/testing/ui-fixture/compiler.ts
|
|
1005
|
+
function compileUIScenarioFixture(options) {
|
|
1006
|
+
const firstFrame = options.frames[0];
|
|
1007
|
+
const finalFrame = options.frames[options.frames.length - 1];
|
|
1008
|
+
if (!firstFrame || !finalFrame) {
|
|
1009
|
+
throw new Error("compileUIScenarioFixture requires at least one frame.");
|
|
1010
|
+
}
|
|
1011
|
+
const replay = options.replay ?? [];
|
|
1012
|
+
const submissionDigest = options.expected?.submissionDigest ?? digestUIFixtureJson({
|
|
1013
|
+
digestVersion: "ui-submission@1",
|
|
1014
|
+
fixtureId: options.id,
|
|
1015
|
+
replay: replay.map(
|
|
1016
|
+
(step) => "requestDigest" in step ? step.requestDigest : step.stepId
|
|
1017
|
+
)
|
|
1018
|
+
});
|
|
1019
|
+
const finalSemanticDigest = options.expected?.finalSemanticDigest ?? digestUIFixtureJson({
|
|
1020
|
+
digestVersion: "ui-semantic@1",
|
|
1021
|
+
fixtureId: options.id,
|
|
1022
|
+
frameId: finalFrame.id,
|
|
1023
|
+
projectionDigest: finalFrame.projectionDigest
|
|
1024
|
+
});
|
|
1025
|
+
return parseUIScenarioFixture(
|
|
1026
|
+
canonicalizeUIScenarioFixture({
|
|
1027
|
+
schemaVersion: 1,
|
|
1028
|
+
browserInteractionProtocol: DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
|
|
1029
|
+
id: options.id,
|
|
1030
|
+
title: options.title,
|
|
1031
|
+
gameId: options.gameId,
|
|
1032
|
+
tags: [...options.tags ?? []],
|
|
1033
|
+
source: options.source,
|
|
1034
|
+
viewer: options.viewer,
|
|
1035
|
+
environment: options.environment,
|
|
1036
|
+
frames: options.frames,
|
|
1037
|
+
transport: [...options.transport ?? []],
|
|
1038
|
+
replay,
|
|
1039
|
+
expected: {
|
|
1040
|
+
initialProjectionDigest: options.expected?.initialProjectionDigest ?? firstFrame.projectionDigest,
|
|
1041
|
+
finalProjectionDigest: options.expected?.finalProjectionDigest ?? finalFrame.projectionDigest,
|
|
1042
|
+
finalSemanticDigest,
|
|
1043
|
+
submissionDigest
|
|
1044
|
+
}
|
|
1045
|
+
})
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
function assertDeterministicUIScenarioFixture(first, second) {
|
|
1049
|
+
const firstBytes = serializeUIScenarioFixture(first);
|
|
1050
|
+
const secondBytes = serializeUIScenarioFixture(second);
|
|
1051
|
+
if (firstBytes !== secondBytes) {
|
|
1052
|
+
throw new Error(
|
|
1053
|
+
`UI scenario fixture '${first.id}' is non-deterministic across compilation runs.`
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function assertUniqueReplayIdentity(step, candidates) {
|
|
1058
|
+
if (candidates.length !== 1) {
|
|
1059
|
+
throw new Error(
|
|
1060
|
+
`Replay step '${step.stepId}' resolved ${candidates.length} identities; expected exactly one.`
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
const candidate = candidates[0];
|
|
1064
|
+
if (!candidate) {
|
|
1065
|
+
throw new Error(`Replay step '${step.stepId}' did not resolve.`);
|
|
1066
|
+
}
|
|
1067
|
+
const expected = step.expectedIdentity;
|
|
1068
|
+
if (!expected) {
|
|
1069
|
+
return candidate;
|
|
1070
|
+
}
|
|
1071
|
+
for (const key of [
|
|
1072
|
+
"surface",
|
|
1073
|
+
"scopeId",
|
|
1074
|
+
"interactionKey",
|
|
1075
|
+
"interactionId",
|
|
1076
|
+
"actuatorId",
|
|
1077
|
+
"descriptorDigest",
|
|
1078
|
+
"draftDigest"
|
|
1079
|
+
]) {
|
|
1080
|
+
const expectedValue = expected[key];
|
|
1081
|
+
if (expectedValue !== void 0 && candidate[key] !== expectedValue) {
|
|
1082
|
+
throw new Error(
|
|
1083
|
+
`Replay step '${step.stepId}' resolved ${key} '${String(
|
|
1084
|
+
candidate[key]
|
|
1085
|
+
)}', expected '${expectedValue}'.`
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return candidate;
|
|
1090
|
+
}
|
|
1091
|
+
function assertUIStepExpectationSatisfied(stepId, expected, actual) {
|
|
1092
|
+
for (const key of [
|
|
1093
|
+
"frameId",
|
|
1094
|
+
"projectionDigest",
|
|
1095
|
+
"semanticDigest",
|
|
1096
|
+
"draftDigest",
|
|
1097
|
+
"submissionDigest",
|
|
1098
|
+
"focusedInteractionKey"
|
|
1099
|
+
]) {
|
|
1100
|
+
if (expected[key] !== void 0 && expected[key] !== actual[key]) {
|
|
1101
|
+
throw new Error(
|
|
1102
|
+
`Replay step '${stepId}' expected ${key} '${expected[key]}', received '${actual[key]}'.`
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
if (expected.visibleInteractionKeys) {
|
|
1107
|
+
const actualKeys = new Set(actual.visibleInteractionKeys ?? []);
|
|
1108
|
+
const missing = expected.visibleInteractionKeys.filter(
|
|
1109
|
+
(key) => !actualKeys.has(key)
|
|
1110
|
+
);
|
|
1111
|
+
if (missing.length > 0) {
|
|
1112
|
+
throw new Error(
|
|
1113
|
+
`Replay step '${stepId}' missing visible interactions: ${missing.join(
|
|
1114
|
+
", "
|
|
1115
|
+
)}.`
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
669
1120
|
export {
|
|
670
1121
|
StaleContractArtifactError,
|
|
1122
|
+
UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION,
|
|
1123
|
+
UI_SCENARIO_FIXTURE_SCHEMA_VERSION,
|
|
1124
|
+
UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR,
|
|
1125
|
+
assertDeterministicUIScenarioFixture,
|
|
1126
|
+
assertSupportedBrowserInteractionProtocol,
|
|
1127
|
+
assertUIStepExpectationSatisfied,
|
|
1128
|
+
assertUniqueReplayIdentity,
|
|
1129
|
+
canonicalUIFixtureJson,
|
|
1130
|
+
canonicalizeUIFixtureJson,
|
|
1131
|
+
canonicalizeUIScenarioFixture,
|
|
1132
|
+
compileUIScenarioFixture,
|
|
671
1133
|
createExpectApi,
|
|
672
1134
|
createTestRuntime,
|
|
673
1135
|
defineBase,
|
|
674
1136
|
defineScenario,
|
|
675
|
-
|
|
1137
|
+
digestUIFixtureJson,
|
|
1138
|
+
digestUIFixtureRequest,
|
|
1139
|
+
digestUIScenarioFixture,
|
|
1140
|
+
isSha256Digest,
|
|
1141
|
+
isStaleContractArtifactError,
|
|
1142
|
+
parseUIScenarioFixture,
|
|
1143
|
+
parseUIScenarioFixtureBundleIndex,
|
|
1144
|
+
portableSemanticReplayStepSchema,
|
|
1145
|
+
serializeUIScenarioFixture,
|
|
1146
|
+
uiFixtureFrameSchema,
|
|
1147
|
+
uiFixturePluginStateSnapshotSchema,
|
|
1148
|
+
uiFixtureTransportExchangeSchema,
|
|
1149
|
+
uiReplayExecutionSchema,
|
|
1150
|
+
uiReplayRequestSchema,
|
|
1151
|
+
uiResolvedReplayIdentitySchema,
|
|
1152
|
+
uiScenarioFixtureBundleIndexSchema,
|
|
1153
|
+
uiScenarioFixtureSchema,
|
|
1154
|
+
uiScenarioReplayStepSchema,
|
|
1155
|
+
uiStepExpectationSchema
|
|
676
1156
|
};
|
|
677
1157
|
//# sourceMappingURL=testing.js.map
|