aria-ease 6.9.1 → 6.11.0

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 (38) hide show
  1. package/README.md +3 -3
  2. package/{bin/buildContracts-GBOY7UXG.js → dist/buildContracts-FT6KWUJN.js} +31 -3
  3. package/{bin/chunk-LMSKLN5O.js → dist/chunk-NI3MQCAS.js} +34 -0
  4. package/{bin → dist}/cli.cjs +239 -24
  5. package/{bin → dist}/cli.js +4 -4
  6. package/dist/{configLoader-WTGJAP4Z.js → configLoader-DWHOHXHL.js} +34 -0
  7. package/{bin/configLoader-Q6A4JLKW.js → dist/configLoader-UJZHQBYS.js} +1 -1
  8. package/{bin/contractTestRunnerPlaywright-ZZNWDUYP.js → dist/contractTestRunnerPlaywright-QDXSK3FE.js} +173 -20
  9. package/dist/{contractTestRunnerPlaywright-XBWJZMR3.js → contractTestRunnerPlaywright-WNWQYSXZ.js} +173 -20
  10. package/dist/index.cjs +568 -298
  11. package/dist/index.d.cts +53 -53
  12. package/dist/index.d.ts +53 -53
  13. package/dist/index.js +364 -281
  14. package/dist/src/combobox/index.cjs +21 -7
  15. package/dist/src/combobox/index.js +21 -7
  16. package/dist/src/utils/test/{configLoader-YE2CYGDG.js → configLoader-SHJSRG2A.js} +34 -0
  17. package/dist/src/utils/test/{contractTestRunnerPlaywright-LC5OAVXB.js → contractTestRunnerPlaywright-Z2AHXSNM.js} +173 -20
  18. package/dist/src/utils/test/dsl/index.cjs +338 -269
  19. package/dist/src/utils/test/dsl/index.d.cts +53 -53
  20. package/dist/src/utils/test/dsl/index.d.ts +53 -53
  21. package/dist/src/utils/test/dsl/index.js +338 -269
  22. package/dist/src/utils/test/index.cjs +207 -20
  23. package/dist/src/utils/test/index.js +2 -2
  24. package/{bin/test-OND56UUL.js → dist/test-O3J4ZPQR.js} +2 -2
  25. package/package.json +4 -5
  26. package/bin/AccordionComponentStrategy-4ZEIQ2V6.js +0 -42
  27. package/bin/ComboboxComponentStrategy-OGRVZXAF.js +0 -64
  28. package/bin/MenuComponentStrategy-JAMTCSNF.js +0 -81
  29. package/bin/TabsComponentStrategy-3SQURPMX.js +0 -29
  30. package/bin/chunk-I2KLQ2HA.js +0 -22
  31. package/bin/chunk-PK5L2SAF.js +0 -17
  32. package/bin/chunk-XERMSYEH.js +0 -363
  33. /package/{bin → dist}/audit-RM6TCZ5C.js +0 -0
  34. /package/{bin → dist}/badgeHelper-JOWO6RQG.js +0 -0
  35. /package/{bin → dist}/chunk-JJEPLK7L.js +0 -0
  36. /package/{bin → dist}/cli.d.cts +0 -0
  37. /package/{bin → dist}/cli.d.ts +0 -0
  38. /package/{bin → dist}/formatters-32KQIIYS.js +0 -0
@@ -1,4 +1,206 @@
1
- // src/utils/test/dsl/index.ts
1
+ // src/utils/test/dsl/src/state-packs/comboboxStatePack.ts
2
+ function hasCapabilities(ctx, requiredCaps) {
3
+ return requiredCaps.some((cap) => ctx.capabilities.includes(cap));
4
+ }
5
+ function resolveSetup(setup, ctx) {
6
+ if (Array.isArray(setup) && setup.length && !setup[0].when) {
7
+ setup = [{ when: ["keyboard"], steps: () => setup }];
8
+ }
9
+ for (const strat of setup) {
10
+ if (hasCapabilities(ctx, strat.when)) {
11
+ return strat.steps(ctx);
12
+ }
13
+ }
14
+ throw new Error(
15
+ `No setup strategy matches capabilities: ${ctx.capabilities.join(", ")}`
16
+ );
17
+ }
18
+ var COMBOBOX_STATES = {
19
+ "listbox.open": {
20
+ setup: [
21
+ {
22
+ when: ["keyboard", "textInput"],
23
+ steps: () => [
24
+ { type: "keypress", target: "input", key: "ArrowDown" }
25
+ ]
26
+ },
27
+ {
28
+ when: ["pointer"],
29
+ steps: () => [
30
+ { type: "click", target: "button" }
31
+ ]
32
+ }
33
+ ],
34
+ assertion: isComboboxOpen
35
+ },
36
+ "listbox.closed": {
37
+ setup: [
38
+ {
39
+ when: ["keyboard"],
40
+ steps: () => [
41
+ /* { type: "keypress", target: "input", key: "Escape" } */
42
+ ]
43
+ },
44
+ {
45
+ when: ["pointer"],
46
+ steps: () => [
47
+ /* { type: "click", target: "button" } */
48
+ ]
49
+ }
50
+ ],
51
+ assertion: isComboboxClosed
52
+ },
53
+ "input.focused": {
54
+ setup: [
55
+ {
56
+ when: ["keyboard"],
57
+ steps: () => [
58
+ { type: "focus", target: "input" }
59
+ ]
60
+ }
61
+ ],
62
+ assertion: isInputFocused
63
+ },
64
+ "input.filled": {
65
+ setup: [
66
+ {
67
+ when: ["keyboard", "textInput"],
68
+ steps: () => [
69
+ { type: "type", target: "input", value: "test" }
70
+ ]
71
+ }
72
+ ],
73
+ assertion: isInputFilled
74
+ },
75
+ "activeOption.first": {
76
+ requires: ["listbox.open"],
77
+ setup: [
78
+ {
79
+ when: ["keyboard"],
80
+ steps: () => [
81
+ { type: "keypress", target: "input", key: "ArrowDown" }
82
+ ]
83
+ }
84
+ ],
85
+ assertion: isActiveDescendantNotEmpty
86
+ },
87
+ "activeOption.last": {
88
+ requires: ["activeOption.first"],
89
+ setup: [
90
+ {
91
+ when: ["keyboard"],
92
+ steps: () => [
93
+ { type: "keypress", target: "input", key: "ArrowUp" }
94
+ ]
95
+ }
96
+ ],
97
+ assertion: isActiveDescendantNotEmpty
98
+ },
99
+ "selectedOption.first": {
100
+ requires: ["listbox.open"],
101
+ setup: [
102
+ {
103
+ when: ["pointer"],
104
+ steps: () => [
105
+ { type: "click", target: "relative", relativeTarget: "first" }
106
+ ]
107
+ }
108
+ ],
109
+ assertion: () => isAriaSelected("first")
110
+ },
111
+ "selectedOption.last": {
112
+ requires: ["listbox.open"],
113
+ setup: [
114
+ {
115
+ when: ["pointer"],
116
+ steps: () => [
117
+ { type: "click", target: "relative", relativeTarget: "last" }
118
+ ]
119
+ }
120
+ ],
121
+ assertion: () => isAriaSelected("last")
122
+ }
123
+ };
124
+ function isComboboxOpen() {
125
+ return [
126
+ {
127
+ target: "listbox",
128
+ assertion: "toBeVisible",
129
+ failureMessage: "Expected listbox to be visible"
130
+ },
131
+ {
132
+ target: "input",
133
+ assertion: "toHaveAttribute",
134
+ attribute: "aria-expanded",
135
+ expectedValue: "true",
136
+ failureMessage: "Expect combobox input to have aria-expanded='true'"
137
+ }
138
+ ];
139
+ }
140
+ function isComboboxClosed() {
141
+ return [
142
+ {
143
+ target: "listbox",
144
+ assertion: "notToBeVisible",
145
+ failureMessage: "Expected listbox to be closed"
146
+ },
147
+ {
148
+ target: "input",
149
+ assertion: "toHaveAttribute",
150
+ attribute: "aria-expanded",
151
+ expectedValue: "false",
152
+ failureMessage: "Expect combobox input to have aria-expanded='false'"
153
+ }
154
+ ];
155
+ }
156
+ function isActiveDescendantNotEmpty() {
157
+ return [
158
+ {
159
+ target: "input",
160
+ assertion: "toHaveAttribute",
161
+ attribute: "aria-activedescendant",
162
+ expectedValue: "!empty",
163
+ failureMessage: "Expected aria-activedescendant to not be empty"
164
+ }
165
+ ];
166
+ }
167
+ function isAriaSelected(index) {
168
+ return [
169
+ {
170
+ target: "relative",
171
+ relativeTarget: index,
172
+ assertion: "toHaveAttribute",
173
+ attribute: "aria-selected",
174
+ expectedValue: "true",
175
+ failureMessage: `Expected ${index} option to have aria-selected='true'`
176
+ }
177
+ ];
178
+ }
179
+ function isInputFocused() {
180
+ return [
181
+ {
182
+ target: "input",
183
+ assertion: "toHaveFocus",
184
+ failureMessage: "Expected input to be focused"
185
+ }
186
+ ];
187
+ }
188
+ function isInputFilled() {
189
+ return [
190
+ {
191
+ target: "input",
192
+ assertion: "toHaveValue",
193
+ expectedValue: "test",
194
+ failureMessage: "Expected input to have the value 'test'"
195
+ }
196
+ ];
197
+ }
198
+
199
+ // src/utils/test/dsl/src/contractBuilder.ts
200
+ var STATE_PACKS = {
201
+ "combobox.listbox": COMBOBOX_STATES
202
+ // Add more mappings as needed
203
+ };
2
204
  var FluentContract = class {
3
205
  constructor(jsonContract) {
4
206
  this.jsonContract = jsonContract;
@@ -7,306 +209,173 @@ var FluentContract = class {
7
209
  return this.jsonContract;
8
210
  }
9
211
  };
10
- var StaticTargetBuilder = class {
11
- constructor(targetName, sink) {
12
- this.targetName = targetName;
13
- this.sink = sink;
14
- }
15
- has(attribute, expectedValue) {
16
- const create = (level) => {
17
- this.sink.push({
18
- target: this.targetName,
19
- attribute,
20
- expectedValue,
21
- failureMessage: `Expected ${this.targetName} to have ${attribute}${expectedValue !== void 0 ? `=${expectedValue}` : ""}.`,
22
- level
23
- });
24
- };
25
- return {
26
- required: () => create("required"),
27
- recommended: () => create("recommended"),
28
- optional: () => create("optional")
29
- };
30
- }
31
- };
32
- var StaticBuilder = class {
33
- constructor(sink) {
34
- this.sink = sink;
35
- }
36
- target(targetName) {
37
- return new StaticTargetBuilder(targetName, this.sink);
38
- }
39
- };
40
- var DynamicChain = class {
41
- constructor(key, testsSink, selectors) {
42
- this.key = key;
43
- this.testsSink = testsSink;
44
- this.selectors = selectors;
45
- }
46
- selectorTarget = "";
47
- actions = [];
48
- assertions = [];
49
- explicitDescription = "";
50
- on(target) {
51
- this.selectorTarget = target;
52
- this.actions.push({ type: "keypress", target, key: this.key });
53
- return this;
54
- }
55
- describe(description) {
56
- this.explicitDescription = description;
57
- return this;
212
+ var ContractBuilder = class {
213
+ constructor(componentName) {
214
+ this.componentName = componentName;
215
+ this.statePack = STATE_PACKS[componentName] || {};
58
216
  }
59
- focus(targetExpression) {
60
- const parsed = this.parseRelativeExpression(targetExpression);
61
- if (parsed) {
62
- if (!this.selectors[parsed.selectorKey]) {
63
- const availableSelectors = Object.keys(this.selectors).sort().join(", ") || "(none)";
64
- throw new Error(
65
- `Invalid focus target expression "${targetExpression}": selector "${parsed.selectorKey}" is not defined. Available selectors: ${availableSelectors}`
66
- );
67
- }
68
- if (!this.selectors.relative && this.selectors[parsed.selectorKey]) {
69
- this.selectors.relative = this.selectors[parsed.selectorKey];
70
- }
71
- this.assertions.push({
72
- target: "relative",
73
- assertion: "toHaveFocus",
74
- relativeTarget: parsed.relativeTarget
75
- });
76
- } else {
77
- this.assertions.push({
78
- target: targetExpression,
79
- assertion: "toHaveFocus"
80
- });
81
- }
217
+ metaValue = {};
218
+ selectorsValue = {};
219
+ relationshipInvariants = [];
220
+ staticAssertions = [];
221
+ dynamicTests = [];
222
+ statePack;
223
+ meta(meta) {
224
+ this.metaValue = meta;
82
225
  return this;
83
226
  }
84
- visible(target) {
85
- this.assertions.push({ target, assertion: "toBeVisible" });
227
+ selectors(selectors) {
228
+ this.selectorsValue = selectors;
86
229
  return this;
87
230
  }
88
- hidden(target) {
89
- this.assertions.push({ target, assertion: "notToBeVisible" });
231
+ relationships(fn) {
232
+ const api = {
233
+ ariaReference: (from, attribute, to) => ({
234
+ required: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "required" }),
235
+ optional: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "optional" })
236
+ }),
237
+ contains: (parent, child) => ({
238
+ required: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "required" }),
239
+ optional: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "optional" })
240
+ })
241
+ };
242
+ fn(api);
90
243
  return this;
91
244
  }
92
- has(target, attribute, expectedValue) {
93
- this.assertions.push({
94
- target,
95
- assertion: "toHaveAttribute",
96
- attribute,
97
- expectedValue
98
- });
245
+ static(fn) {
246
+ const api = {
247
+ target: (target) => ({
248
+ has: (attribute, expectedValue) => ({
249
+ required: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "required" }),
250
+ optional: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "optional" })
251
+ })
252
+ })
253
+ };
254
+ fn(api);
99
255
  return this;
100
256
  }
101
- required() {
102
- this.finalize("required");
257
+ when(event) {
258
+ return new DynamicTestBuilder(this, this.statePack, event);
103
259
  }
104
- recommended() {
105
- this.finalize("recommended");
260
+ addDynamicTest(test) {
261
+ this.dynamicTests.push(test);
106
262
  }
107
- optional() {
108
- this.finalize("optional");
109
- }
110
- finalize(level) {
111
- if (!this.selectorTarget) {
112
- throw new Error("Dynamic contract chain requires .on(<selectorKey>) before level terminator.");
113
- }
114
- const description = this.explicitDescription || `Pressing ${this.key} on ${this.selectorTarget} satisfies expected behavior.`;
115
- this.testsSink.push({
116
- description,
117
- level,
118
- action: this.actions,
119
- assertions: this.assertions.map((a) => ({ ...a, level }))
120
- });
121
- }
122
- parseRelativeExpression(input) {
123
- const match = input.match(/^(next|previous|first|last)\(([^)]+)\)$/);
124
- if (!match) return null;
125
- const relativeTarget = match[1];
126
- const selectorKey = match[2].trim();
127
- return { relativeTarget, selectorKey };
263
+ build() {
264
+ return {
265
+ meta: this.metaValue,
266
+ selectors: this.selectorsValue,
267
+ relationships: this.relationshipInvariants.length ? this.relationshipInvariants : void 0,
268
+ static: this.staticAssertions.length ? [{ assertions: this.staticAssertions }] : [],
269
+ dynamic: this.dynamicTests
270
+ };
128
271
  }
129
272
  };
130
- var ContractBuilder = class {
131
- constructor(componentName) {
132
- this.componentName = componentName;
273
+ var DynamicTestBuilder = class {
274
+ constructor(parent, statePack, event) {
275
+ this.parent = parent;
276
+ this.statePack = statePack;
277
+ this.event = event;
133
278
  }
134
- metaValue = {};
135
- selectorsValue = {};
136
- relationshipInvariants = [];
137
- staticAssertions = [];
138
- dynamicTests = [];
139
- meta(meta) {
140
- this.metaValue = { ...this.metaValue, ...meta };
279
+ _as;
280
+ _on;
281
+ _given = [];
282
+ _then = [];
283
+ _desc = "";
284
+ _level = "required";
285
+ as(actionType) {
286
+ this._as = actionType;
141
287
  return this;
142
288
  }
143
- selectors(selectors) {
144
- this.selectorsValue = { ...this.selectorsValue, ...selectors };
289
+ on(target) {
290
+ this._on = target;
145
291
  return this;
146
292
  }
147
- relationship(invariant) {
148
- this.relationshipInvariants.push(invariant);
293
+ given(states) {
294
+ this._given = Array.isArray(states) ? states : [states];
149
295
  return this;
150
296
  }
151
- relationships(builderFn) {
152
- builderFn({
153
- ariaReference: (from, attribute, to) => {
154
- const create = (level) => {
155
- this.relationshipInvariants.push({
156
- type: "aria-reference",
157
- from,
158
- attribute,
159
- to,
160
- level
161
- });
162
- };
163
- return {
164
- required: () => create("required"),
165
- recommended: () => create("recommended"),
166
- optional: () => create("optional")
167
- };
168
- },
169
- contains: (parent, child) => {
170
- const create = (level) => {
171
- this.relationshipInvariants.push({
172
- type: "contains",
173
- parent,
174
- child,
175
- level
176
- });
177
- };
178
- return {
179
- required: () => create("required"),
180
- recommended: () => create("recommended"),
181
- optional: () => create("optional")
182
- };
183
- }
184
- });
297
+ then(states) {
298
+ this._then = Array.isArray(states) ? states : [states];
185
299
  return this;
186
300
  }
187
- static(builderFn) {
188
- builderFn(new StaticBuilder(this.staticAssertions));
301
+ describe(desc) {
302
+ this._desc = desc;
189
303
  return this;
190
304
  }
191
- when(key) {
192
- return new DynamicChain(key, this.dynamicTests, this.selectorsValue);
305
+ required() {
306
+ this._level = "required";
307
+ this._finalize();
308
+ return this.parent;
193
309
  }
194
- validateRelationshipInvariants() {
195
- if (this.relationshipInvariants.length === 0) {
196
- return;
197
- }
198
- const selectorKeys = new Set(Object.keys(this.selectorsValue));
199
- const available = Object.keys(this.selectorsValue).sort().join(", ");
200
- const errors = [];
201
- this.relationshipInvariants.forEach((invariant, index) => {
202
- const prefix = `relationships[${index}] (${invariant.type})`;
203
- if (invariant.type === "aria-reference") {
204
- if (!selectorKeys.has(invariant.from)) {
205
- errors.push(`${prefix}: "from" references unknown selector "${invariant.from}"`);
206
- }
207
- if (!selectorKeys.has(invariant.to)) {
208
- errors.push(`${prefix}: "to" references unknown selector "${invariant.to}"`);
310
+ optional() {
311
+ this._level = "optional";
312
+ this._finalize();
313
+ return this.parent;
314
+ }
315
+ recommended() {
316
+ this._level = "recommended";
317
+ this._finalize();
318
+ return this.parent;
319
+ }
320
+ _finalize() {
321
+ const capabilityMap = {
322
+ keypress: "keyboard",
323
+ click: "pointer",
324
+ type: "textInput",
325
+ focus: "keyboard",
326
+ hover: "pointer"
327
+ // add more mappings as needed
328
+ };
329
+ const capability = capabilityMap[this._as || "keyboard"] || (this._as || "keyboard");
330
+ const ctx = { capabilities: [capability] };
331
+ const resolveAllSetups = (stateName, visited = /* @__PURE__ */ new Set()) => {
332
+ if (visited.has(stateName)) return [];
333
+ visited.add(stateName);
334
+ const s = this.statePack[stateName];
335
+ if (!s) return [];
336
+ let actions = [];
337
+ if (Array.isArray(s.requires)) {
338
+ for (const req of s.requires) {
339
+ actions = actions.concat(resolveAllSetups(req, visited));
209
340
  }
210
341
  }
211
- if (invariant.type === "contains") {
212
- if (!selectorKeys.has(invariant.parent)) {
213
- errors.push(`${prefix}: "parent" references unknown selector "${invariant.parent}"`);
214
- }
215
- if (!selectorKeys.has(invariant.child)) {
216
- errors.push(`${prefix}: "child" references unknown selector "${invariant.child}"`);
342
+ if (s.setup) actions = actions.concat(resolveSetup(s.setup, ctx));
343
+ return actions;
344
+ };
345
+ const setup = [];
346
+ for (const state of this._given) {
347
+ setup.push(...resolveAllSetups(state));
348
+ }
349
+ const assertions = [];
350
+ for (const state of this._then) {
351
+ const s = this.statePack[state];
352
+ if (s && s.assertion !== void 0) {
353
+ let value = s.assertion;
354
+ if (typeof value === "function") {
355
+ try {
356
+ value = value();
357
+ } catch (e) {
358
+ throw new Error(`Error calling assertion function for state '${state}': ${e.message}`);
359
+ }
217
360
  }
361
+ if (Array.isArray(value)) assertions.push(...value);
362
+ else assertions.push(value);
218
363
  }
219
- });
220
- if (errors.length > 0) {
221
- const availableSelectorsMessage = available.length > 0 ? available : "(none)";
222
- throw new Error(
223
- [
224
- `Contract invariant validation failed for component "${this.componentName}".`,
225
- ...errors.map((error) => `- ${error}`),
226
- `Available selectors: ${availableSelectorsMessage}`
227
- ].join("\n")
228
- );
229
364
  }
230
- }
231
- validateStaticTargets() {
232
- const selectorKeys = new Set(Object.keys(this.selectorsValue));
233
- const available = Object.keys(this.selectorsValue).sort().join(", ") || "(none)";
234
- const errors = [];
235
- this.staticAssertions.forEach((assertion, index) => {
236
- if (!selectorKeys.has(assertion.target)) {
237
- errors.push(`static.assertions[${index}]: target "${assertion.target}" is not defined in selectors`);
365
+ const action = [
366
+ {
367
+ type: this._as,
368
+ target: this._on,
369
+ key: this._as === "keypress" ? this.event : void 0
238
370
  }
371
+ ];
372
+ this.parent.addDynamicTest({
373
+ description: this._desc || "",
374
+ level: this._level,
375
+ action,
376
+ assertions,
377
+ ...setup.length ? { setup } : {}
239
378
  });
240
- if (errors.length > 0) {
241
- throw new Error(
242
- [
243
- `Contract static target validation failed for component "${this.componentName}".`,
244
- ...errors.map((error) => `- ${error}`),
245
- `Available selectors: ${available}`
246
- ].join("\n")
247
- );
248
- }
249
- }
250
- validateDynamicTargets() {
251
- const selectorKeys = new Set(Object.keys(this.selectorsValue));
252
- const available = Object.keys(this.selectorsValue).sort().join(", ") || "(none)";
253
- const errors = [];
254
- const isValidActionTarget = (target) => {
255
- return selectorKeys.has(target) || target === "document" || target === "relative";
256
- };
257
- const isValidAssertionTarget = (target) => {
258
- return selectorKeys.has(target) || target === "relative";
259
- };
260
- this.dynamicTests.forEach((test, testIndex) => {
261
- test.action.forEach((action, actionIndex) => {
262
- if (!isValidActionTarget(action.target)) {
263
- errors.push(
264
- `dynamic[${testIndex}].action[${actionIndex}]: target "${action.target}" is not defined in selectors`
265
- );
266
- }
267
- });
268
- test.assertions.forEach((assertion, assertionIndex) => {
269
- if (!isValidAssertionTarget(assertion.target)) {
270
- errors.push(
271
- `dynamic[${testIndex}].assertions[${assertionIndex}]: target "${assertion.target}" is not defined in selectors`
272
- );
273
- }
274
- if (assertion.target === "relative" && !this.selectorsValue.relative) {
275
- errors.push(
276
- `dynamic[${testIndex}].assertions[${assertionIndex}]: target "relative" requires selectors.relative to be defined`
277
- );
278
- }
279
- });
280
- });
281
- if (errors.length > 0) {
282
- throw new Error(
283
- [
284
- `Contract dynamic target validation failed for component "${this.componentName}".`,
285
- ...errors.map((error) => `- ${error}`),
286
- `Available selectors: ${available}`,
287
- `Allowed special targets: document, relative`
288
- ].join("\n")
289
- );
290
- }
291
- }
292
- build() {
293
- this.validateRelationshipInvariants();
294
- this.validateStaticTargets();
295
- this.validateDynamicTargets();
296
- const fallbackId = this.metaValue.id || `aria-ease.contract.${this.componentName}`;
297
- return {
298
- meta: {
299
- id: fallbackId,
300
- version: this.metaValue.version || "1.0.0",
301
- description: this.metaValue.description || `Fluent contract for ${this.componentName}`,
302
- source: this.metaValue.source,
303
- W3CName: this.metaValue.W3CName
304
- },
305
- selectors: this.selectorsValue,
306
- relationships: this.relationshipInvariants,
307
- static: [{ assertions: this.staticAssertions }],
308
- dynamic: this.dynamicTests
309
- };
310
379
  }
311
380
  };
312
381
  function createContract(componentName, define) {