@delacour/warden-e2e 0.7.0 → 0.8.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.
- package/{chunk-empqr9n0.mjs → chunk-vs5npy59.mjs} +2010 -169
- package/index.mjs +214 -13
- package/package.json +2 -2
- package/preload.mjs +3002 -798
- package/types/core/src/a11y/a11y.config.d.ts +47 -0
- package/types/core/src/affected/affected.schema.d.ts +49 -1
- package/types/core/src/android-keyguard.d.ts +2 -0
- package/types/core/src/batch/preset.schema.d.ts +12 -1
- package/types/core/src/builds/app-option.schema.d.ts +1 -1
- package/types/core/src/builds/config.schema.d.ts +93 -2
- package/types/core/src/builds/define-config.d.ts +55 -0
- package/types/core/src/camera-mode.d.ts +17 -0
- package/types/core/src/camera-placeholder.d.ts +9 -0
- package/types/core/src/camera-profile.d.ts +12 -0
- package/types/core/src/claim-errors.d.ts +34 -0
- package/types/core/src/conditions/a11y-keys.d.ts +45 -0
- package/types/core/src/conditions/camera-media.d.ts +30 -0
- package/types/core/src/conditions/conditions.config.d.ts +24 -0
- package/types/core/src/conditions/conditions.types.d.ts +30 -0
- package/types/core/src/conditions/inject-state.d.ts +1 -1
- package/types/core/src/ios-runner/build.d.ts +28 -0
- package/types/core/src/ios-runner/cache.d.ts +44 -0
- package/types/core/src/ios-runner/pack.d.ts +17 -0
- package/types/core/src/ios-runner/signing.d.ts +40 -0
- package/types/core/src/ios-runner/sim-build.d.ts +36 -0
- package/types/core/src/ios-runner/stage.d.ts +26 -0
- package/types/core/src/lease-events.d.ts +126 -0
- package/types/core/src/ownership.d.ts +44 -0
- package/types/core/src/providers/android.d.ts +10 -1
- package/types/core/src/providers/provider.types.d.ts +9 -0
- package/types/core/src/queue.d.ts +43 -0
- package/types/core/src/store.d.ts +61 -5
- package/types/core/src/types.d.ts +10 -0
- package/types/core/src/xcode.d.ts +22 -0
- package/types/e2e/src/a11y/a11y-target.d.ts +23 -0
- package/types/e2e/src/a11y/a11y.types.d.ts +81 -0
- package/types/e2e/src/a11y/announcements.d.ts +24 -0
- package/types/e2e/src/a11y/audit.d.ts +22 -0
- package/types/e2e/src/a11y/native/atf.d.ts +51 -0
- package/types/e2e/src/a11y/native/xcuitest.d.ts +60 -0
- package/types/e2e/src/a11y/order.d.ts +5 -0
- package/types/e2e/src/a11y/rules/duplicate-name.d.ts +6 -0
- package/types/e2e/src/a11y/rules/hidden-focusable.d.ts +3 -0
- package/types/e2e/src/a11y/rules/image-no-name.d.ts +6 -0
- package/types/e2e/src/a11y/rules/label-in-name.d.ts +7 -0
- package/types/e2e/src/a11y/rules/missing-name.d.ts +3 -0
- package/types/e2e/src/a11y/rules/role-in-name.d.ts +3 -0
- package/types/e2e/src/a11y/rules/rule.context.d.ts +22 -0
- package/types/e2e/src/a11y/rules/target-size.d.ts +21 -0
- package/types/e2e/src/a11y/rules/text-clipped.d.ts +9 -0
- package/types/e2e/src/a11y/speech.d.ts +26 -0
- package/types/e2e/src/a11y/talkback-log.d.ts +13 -0
- package/types/e2e/src/app.d.ts +0 -1
- package/types/e2e/src/conditions/condition-events.d.ts +6 -1
- package/types/e2e/src/conditions/device-conditions.d.ts +30 -2
- package/types/e2e/src/device-a11y.d.ts +97 -0
- package/types/e2e/src/device.d.ts +11 -2
- package/types/e2e/src/driver/a11y-events.d.ts +30 -0
- package/types/e2e/src/driver/a11y-read.d.ts +12 -0
- package/types/e2e/src/driver/android/android-animations.d.ts +7 -0
- package/types/e2e/src/driver/android/android-argv.d.ts +2 -0
- package/types/e2e/src/driver/android/android-camera-host.d.ts +23 -0
- package/types/e2e/src/driver/android/android-camera.d.ts +28 -0
- package/types/e2e/src/driver/android/android-driver.d.ts +5 -0
- package/types/e2e/src/driver/android/android-screen-reader.d.ts +23 -0
- package/types/e2e/src/driver/android/android-settings.d.ts +9 -2
- package/types/e2e/src/driver/android/android-spoken.d.ts +18 -0
- package/types/e2e/src/driver/android/android-talkback.d.ts +57 -0
- package/types/e2e/src/driver/android/atf-device.d.ts +23 -0
- package/types/e2e/src/driver/android/atf-dex.generated.d.ts +7 -0
- package/types/e2e/src/driver/android/uiad-dex.generated.d.ts +5 -5
- package/types/e2e/src/driver/android/uiad-ops.d.ts +27 -1
- package/types/e2e/src/driver/android/uiad-protocol.d.ts +8 -0
- package/types/e2e/src/driver/android/uiad-screen-reader.d.ts +33 -0
- package/types/e2e/src/driver/driver.types.d.ts +71 -5
- package/types/e2e/src/driver/element-actions.d.ts +16 -0
- package/types/e2e/src/driver/ios/inject.d.ts +16 -2
- package/types/e2e/src/driver/ios/ios-a11y.d.ts +73 -0
- package/types/e2e/src/driver/ios/ios-audit.d.ts +36 -0
- package/types/e2e/src/driver/ios/ios-driver.d.ts +21 -1
- package/types/e2e/src/driver/ios/ios-network.d.ts +7 -2
- package/types/e2e/src/driver/ios/sim-runner.d.ts +41 -0
- package/types/e2e/src/driver/ios/simd-transport.d.ts +11 -2
- package/types/e2e/src/driver/native-audit.d.ts +26 -0
- package/types/e2e/src/driver/physical-conditions.d.ts +1 -1
- package/types/e2e/src/driver/screen-reader.d.ts +26 -0
- package/types/e2e/src/env.d.ts +16 -1
- package/types/e2e/src/expect/a11y-matchers.d.ts +33 -0
- package/types/e2e/src/expect/expect.d.ts +7 -2
- package/types/e2e/src/expect/matchers.d.ts +14 -0
- package/types/e2e/src/index.d.ts +5 -1
- package/types/e2e/src/runner/callsite.d.ts +3 -1
- package/types/e2e/src/screen/render.d.ts +8 -0
package/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
E2eError2,
|
|
4
|
+
a11yTargetOf,
|
|
4
5
|
canObserve,
|
|
5
6
|
fieldValue,
|
|
6
7
|
normalizeText,
|
|
@@ -15,14 +16,21 @@ import {
|
|
|
15
16
|
runStep,
|
|
16
17
|
attemptSession,
|
|
17
18
|
getSession,
|
|
19
|
+
accessibleName,
|
|
20
|
+
announce,
|
|
21
|
+
failing,
|
|
22
|
+
formatIssues,
|
|
23
|
+
toE2eError,
|
|
24
|
+
withA11yRead,
|
|
25
|
+
renderA11yScreen,
|
|
18
26
|
IOS_DEVICE_CAPABILITIES,
|
|
27
|
+
callerFile,
|
|
19
28
|
conditionsOf,
|
|
20
29
|
perfStartFor,
|
|
21
30
|
hash6,
|
|
22
31
|
attemptDir,
|
|
23
32
|
specIdOf,
|
|
24
33
|
captureNativeLog,
|
|
25
|
-
callerFile,
|
|
26
34
|
BUN_TIMEOUT_MARGIN_MS2,
|
|
27
35
|
ownHook,
|
|
28
36
|
currentScope,
|
|
@@ -33,10 +41,106 @@ import {
|
|
|
33
41
|
registrationDefaults,
|
|
34
42
|
markOnly,
|
|
35
43
|
WARDEN_E2E_VERSION2
|
|
36
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-vs5npy59.mjs";
|
|
37
45
|
// ../../packages/e2e/src/expect/expect.ts
|
|
38
46
|
import { expect as bunExpect } from "bun:test";
|
|
39
47
|
|
|
48
|
+
// ../../packages/e2e/src/expect/a11y-matchers.ts
|
|
49
|
+
function show(match) {
|
|
50
|
+
return typeof match === "string" ? JSON.stringify(match) : String(match);
|
|
51
|
+
}
|
|
52
|
+
function checkMillis(matcher, key, value) {
|
|
53
|
+
if (value !== undefined && (typeof value !== "number" || !Number.isFinite(value) || value < 0)) {
|
|
54
|
+
throw new E2eError2("INVALID_ARGUMENT", `${matcher}: "${key}" must be a non-negative number of milliseconds`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
class DeviceAssertions {
|
|
59
|
+
target;
|
|
60
|
+
context;
|
|
61
|
+
constructor(target, context) {
|
|
62
|
+
this.target = target;
|
|
63
|
+
this.context = context;
|
|
64
|
+
}
|
|
65
|
+
get not() {
|
|
66
|
+
return new DeviceAssertions(this.target, { ...this.context, negate: !this.context.negate });
|
|
67
|
+
}
|
|
68
|
+
async toPassA11yAudit(options = {}) {
|
|
69
|
+
const call = `toPassA11yAudit(${Object.keys(options).length === 0 ? "" : JSON.stringify(options)})`;
|
|
70
|
+
return this.run(call, async () => {
|
|
71
|
+
const result = await this.target.audit(options);
|
|
72
|
+
const min = options.minSeverity ?? "error";
|
|
73
|
+
const bad = failing(result, min);
|
|
74
|
+
const passes = bad.length === 0;
|
|
75
|
+
if (passes !== this.context.negate)
|
|
76
|
+
return;
|
|
77
|
+
const table = formatIssues(result, min);
|
|
78
|
+
const lines = [
|
|
79
|
+
`expect(device)${this.context.negate ? ".not" : ""}.${call}`,
|
|
80
|
+
`Expected: ${this.context.negate ? "at least one" : "no"} ${min}${min === "error" ? "" : " or worse"} accessibility issue`,
|
|
81
|
+
`Received: ${table}`
|
|
82
|
+
];
|
|
83
|
+
throw await this.failure(lines);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async toHaveAnnounced(expected, options = {}) {
|
|
87
|
+
for (const key of Object.keys(options)) {
|
|
88
|
+
if (key !== "timeoutMs" && key !== "timeout" && key !== "since") {
|
|
89
|
+
throw new E2eError2("INVALID_ARGUMENT", `toHaveAnnounced does not take "${key}"; it takes timeoutMs, since`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
checkMillis("toHaveAnnounced", "timeoutMs", options.timeoutMs);
|
|
93
|
+
checkMillis("toHaveAnnounced", "timeout", options.timeout);
|
|
94
|
+
const timeoutMs = options.timeoutMs ?? options.timeout ?? this.target.assertionTimeout();
|
|
95
|
+
const call = `toHaveAnnounced(${show(expected)})`;
|
|
96
|
+
return this.run(call, async () => {
|
|
97
|
+
const waited = await this.target.waitForAnnouncement(expected, {
|
|
98
|
+
timeoutMs,
|
|
99
|
+
...options.since === undefined ? {} : { since: options.since }
|
|
100
|
+
});
|
|
101
|
+
const { negate } = this.context;
|
|
102
|
+
if (waited.success) {
|
|
103
|
+
if (!negate)
|
|
104
|
+
return;
|
|
105
|
+
throw await this.failure([
|
|
106
|
+
`expect(device).not.${call}`,
|
|
107
|
+
`Expected: no announcement matching ${show(expected)}`,
|
|
108
|
+
`Received: ${JSON.stringify(waited.data.event.text ?? "")}`
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
if (waited.error.code !== "E_TIMEOUT")
|
|
112
|
+
throw toE2eError(waited.error, "read announcements");
|
|
113
|
+
if (negate)
|
|
114
|
+
return;
|
|
115
|
+
const seen = waited.error.detail?.seen ?? [];
|
|
116
|
+
throw await this.failure([
|
|
117
|
+
`expect(device).${call}`,
|
|
118
|
+
`Expected: an announcement matching ${show(expected)} within ${timeoutMs} ms`,
|
|
119
|
+
`Received: ${seen.length === 0 ? "(no announcements)" : seen.map((text) => JSON.stringify(text)).join(", ")}`
|
|
120
|
+
]);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async failure(lines) {
|
|
124
|
+
const screen = await this.target.a11yScreen();
|
|
125
|
+
const head = lines.join(`
|
|
126
|
+
`);
|
|
127
|
+
return new E2eError2("ASSERTION", screen === undefined ? head : `${head}
|
|
128
|
+
|
|
129
|
+
${screen}`, screen);
|
|
130
|
+
}
|
|
131
|
+
async run(call, body) {
|
|
132
|
+
try {
|
|
133
|
+
await this.target.step(`expect device.${call}`, body);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (this.context.soft !== undefined && error instanceof E2eError2 && error.code !== "TIMEOUT") {
|
|
136
|
+
this.context.soft(error);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
40
144
|
// ../../packages/e2e/src/expect/matchers.ts
|
|
41
145
|
var NEGATION_GRACE_MS = 1000;
|
|
42
146
|
var NEGATION_QUIET_MS = 250;
|
|
@@ -47,7 +151,7 @@ function missing() {
|
|
|
47
151
|
function judged(matches, received) {
|
|
48
152
|
return { kind: "judged", matches, received };
|
|
49
153
|
}
|
|
50
|
-
function
|
|
154
|
+
function show2(match) {
|
|
51
155
|
return typeof match === "string" ? JSON.stringify(match) : String(match);
|
|
52
156
|
}
|
|
53
157
|
function assertOptions(matcher, options, allowed) {
|
|
@@ -114,8 +218,8 @@ class LocatorAssertions {
|
|
|
114
218
|
assertOptions("toHaveText", options, ["exact", "timeout"]);
|
|
115
219
|
const exact = options.exact ?? true;
|
|
116
220
|
return this.assert({
|
|
117
|
-
call: `toHaveText(${
|
|
118
|
-
expected: exact ?
|
|
221
|
+
call: `toHaveText(${show2(expected)})`,
|
|
222
|
+
expected: exact ? show2(expected) : `${show2(expected)} (substring, ignoring case)`,
|
|
119
223
|
strict: true,
|
|
120
224
|
judge: (entry) => {
|
|
121
225
|
if (entry === undefined)
|
|
@@ -129,8 +233,8 @@ class LocatorAssertions {
|
|
|
129
233
|
assertOptions("toContainText", options, ["ignoreCase", "timeout"]);
|
|
130
234
|
const ignoreCase = options.ignoreCase ?? false;
|
|
131
235
|
return this.assert({
|
|
132
|
-
call: `toContainText(${
|
|
133
|
-
expected: `text containing ${
|
|
236
|
+
call: `toContainText(${show2(expected)})`,
|
|
237
|
+
expected: `text containing ${show2(expected)}`,
|
|
134
238
|
strict: true,
|
|
135
239
|
judge: (entry) => {
|
|
136
240
|
if (entry === undefined)
|
|
@@ -143,8 +247,8 @@ class LocatorAssertions {
|
|
|
143
247
|
async toHaveValue(expected, options = {}) {
|
|
144
248
|
assertOptions("toHaveValue", options, ["timeout"]);
|
|
145
249
|
return this.assert({
|
|
146
|
-
call: `toHaveValue(${
|
|
147
|
-
expected:
|
|
250
|
+
call: `toHaveValue(${show2(expected)})`,
|
|
251
|
+
expected: show2(expected),
|
|
148
252
|
strict: true,
|
|
149
253
|
judge: (entry) => {
|
|
150
254
|
if (entry === undefined)
|
|
@@ -191,6 +295,78 @@ class LocatorAssertions {
|
|
|
191
295
|
judge: (entry) => entry === undefined ? missing() : judged(entry.states.disabled, entry.states.disabled ? "disabled" : "enabled")
|
|
192
296
|
}, options);
|
|
193
297
|
}
|
|
298
|
+
async toHaveAccessibleName(expected, options = {}) {
|
|
299
|
+
assertOptions("toHaveAccessibleName", options, ["timeout"]);
|
|
300
|
+
return this.assert({
|
|
301
|
+
call: `toHaveAccessibleName(${show2(expected)})`,
|
|
302
|
+
expected: show2(expected),
|
|
303
|
+
strict: true,
|
|
304
|
+
a11y: true,
|
|
305
|
+
judge: (entry, _count, ctx) => {
|
|
306
|
+
if (entry === undefined)
|
|
307
|
+
return missing();
|
|
308
|
+
const name = accessibleName(ctx.element(entry), ctx.platform) ?? "";
|
|
309
|
+
return judged(matchesText(name, expected, { exact: true }), JSON.stringify(name));
|
|
310
|
+
}
|
|
311
|
+
}, options);
|
|
312
|
+
}
|
|
313
|
+
async toHaveRole(expected, options = {}) {
|
|
314
|
+
assertOptions("toHaveRole", options, ["timeout"]);
|
|
315
|
+
return this.assert({
|
|
316
|
+
call: `toHaveRole(${JSON.stringify(expected)})`,
|
|
317
|
+
expected: JSON.stringify(expected),
|
|
318
|
+
strict: true,
|
|
319
|
+
judge: (entry) => entry === undefined ? missing() : judged(entry.role === expected, JSON.stringify(entry.role))
|
|
320
|
+
}, options);
|
|
321
|
+
}
|
|
322
|
+
async toHaveHint(expected, options = {}) {
|
|
323
|
+
assertOptions("toHaveHint", options, ["timeout"]);
|
|
324
|
+
return this.assert({
|
|
325
|
+
call: `toHaveHint(${show2(expected)})`,
|
|
326
|
+
expected: show2(expected),
|
|
327
|
+
strict: true,
|
|
328
|
+
a11y: true,
|
|
329
|
+
judge: (entry, _count, ctx) => {
|
|
330
|
+
if (entry === undefined)
|
|
331
|
+
return missing();
|
|
332
|
+
const hint = ctx.element(entry).a11y?.hint;
|
|
333
|
+
if (hint === undefined || hint === "")
|
|
334
|
+
return judged(false, "(no hint)");
|
|
335
|
+
return judged(matchesText(hint, expected, { exact: true }), JSON.stringify(hint));
|
|
336
|
+
}
|
|
337
|
+
}, options);
|
|
338
|
+
}
|
|
339
|
+
async toAnnounce(expected, options = {}) {
|
|
340
|
+
assertOptions("toAnnounce", options, ["exact", "timeout"]);
|
|
341
|
+
const exact = options.exact ?? true;
|
|
342
|
+
return this.assert({
|
|
343
|
+
call: `toAnnounce(${show2(expected)})`,
|
|
344
|
+
expected: exact ? show2(expected) : `${show2(expected)} (substring, ignoring case)`,
|
|
345
|
+
strict: true,
|
|
346
|
+
a11y: true,
|
|
347
|
+
judge: (entry, _count, ctx) => {
|
|
348
|
+
if (entry === undefined)
|
|
349
|
+
return missing();
|
|
350
|
+
const text = announce(ctx.element(entry), ctx.platform).text;
|
|
351
|
+
return judged(matchesText(text, expected, { exact }), JSON.stringify(text));
|
|
352
|
+
}
|
|
353
|
+
}, options);
|
|
354
|
+
}
|
|
355
|
+
async toBeA11yFocused(options = {}) {
|
|
356
|
+
assertOptions("toBeA11yFocused", options, ["timeout"]);
|
|
357
|
+
return this.assert({
|
|
358
|
+
call: "toBeA11yFocused()",
|
|
359
|
+
expected: "a11y-focused",
|
|
360
|
+
strict: true,
|
|
361
|
+
a11y: true,
|
|
362
|
+
judge: (entry, _count, ctx) => {
|
|
363
|
+
if (entry === undefined)
|
|
364
|
+
return missing();
|
|
365
|
+
const focused = ctx.element(entry).a11y?.a11yFocused === true;
|
|
366
|
+
return judged(focused, focused ? "a11y-focused" : "not a11y-focused");
|
|
367
|
+
}
|
|
368
|
+
}, options);
|
|
369
|
+
}
|
|
194
370
|
async toHaveCount(expected, options = {}) {
|
|
195
371
|
assertOptions("toHaveCount", options, ["timeout"]);
|
|
196
372
|
if (!Number.isInteger(expected) || expected < 0) {
|
|
@@ -231,7 +407,8 @@ class LocatorAssertions {
|
|
|
231
407
|
const entries = resolve(this.locator.expr, observed.index);
|
|
232
408
|
if (spec.strict && entries.length > 1)
|
|
233
409
|
pickOne(rt, this.locator.expr, entries, observed);
|
|
234
|
-
const
|
|
410
|
+
const { seen, context } = await judgementContext(spec, observed);
|
|
411
|
+
const judgement = spec.judge(entries[0], entries.length, context);
|
|
235
412
|
const verdict = await hold.next(judgement.kind === "judged" && judgement.matches !== negate, observed.driver);
|
|
236
413
|
if (verdict === "pass")
|
|
237
414
|
return { done: true, value: true };
|
|
@@ -239,7 +416,7 @@ class LocatorAssertions {
|
|
|
239
416
|
done: false,
|
|
240
417
|
state: {
|
|
241
418
|
received: judgement.kind === "missing" ? NOT_FOUND : judgement.received,
|
|
242
|
-
snapshot:
|
|
419
|
+
snapshot: seen
|
|
243
420
|
},
|
|
244
421
|
...verdict.wakeMs === undefined ? {} : { maxWaitMs: verdict.wakeMs }
|
|
245
422
|
};
|
|
@@ -255,7 +432,7 @@ class LocatorAssertions {
|
|
|
255
432
|
`Expected: ${negate ? "not " : ""}${spec.expected}`,
|
|
256
433
|
`Received: ${last?.received ?? NOT_FOUND}`
|
|
257
434
|
];
|
|
258
|
-
const screen = last?.snapshot === undefined ? undefined : this.locator.runtime.excerpt(last.snapshot);
|
|
435
|
+
const screen = last?.snapshot === undefined ? undefined : spec.a11y === true ? renderA11yScreen(last.snapshot) : this.locator.runtime.excerpt(last.snapshot);
|
|
259
436
|
const message = screen === undefined ? lines.join(`
|
|
260
437
|
`) : `${lines.join(`
|
|
261
438
|
`)}
|
|
@@ -264,6 +441,19 @@ ${screen}`;
|
|
|
264
441
|
return new E2eError2("ASSERTION", message, screen);
|
|
265
442
|
}
|
|
266
443
|
}
|
|
444
|
+
async function judgementContext(spec, observed) {
|
|
445
|
+
let seen = observed.snapshot;
|
|
446
|
+
if (spec.a11y === true) {
|
|
447
|
+
const merged = await withA11yRead(observed.driver, observed.snapshot);
|
|
448
|
+
if (merged.success)
|
|
449
|
+
seen = merged.data;
|
|
450
|
+
}
|
|
451
|
+
const byId = new Map(seen.flat.map((element) => [element.id, element]));
|
|
452
|
+
return {
|
|
453
|
+
seen,
|
|
454
|
+
context: { platform: seen.platform, element: (entry) => byId.get(entry.element.id) ?? entry.element }
|
|
455
|
+
};
|
|
456
|
+
}
|
|
267
457
|
function conditionHold(negate, holdMs, now) {
|
|
268
458
|
let since;
|
|
269
459
|
let asked = false;
|
|
@@ -347,11 +537,22 @@ function softMatchers(target, sink) {
|
|
|
347
537
|
}
|
|
348
538
|
var NOT_STATIC = new Set(["length", "name", "prototype"]);
|
|
349
539
|
function createExpect(deps) {
|
|
350
|
-
const call = (actual, message) =>
|
|
540
|
+
const call = (actual, message) => {
|
|
541
|
+
if (isLocator(actual))
|
|
542
|
+
return new LocatorAssertions(actual, { negate: false });
|
|
543
|
+
const target = a11yTargetOf(actual);
|
|
544
|
+
if (target !== undefined)
|
|
545
|
+
return new DeviceAssertions(target, { negate: false });
|
|
546
|
+
return valueExpect(actual, message);
|
|
547
|
+
};
|
|
351
548
|
const soft = (actual, message) => {
|
|
352
549
|
const sink = deps.softSink();
|
|
353
550
|
if (isLocator(actual))
|
|
354
551
|
return new LocatorAssertions(actual, { negate: false, ...sink === undefined ? {} : { soft: sink } });
|
|
552
|
+
const target = a11yTargetOf(actual);
|
|
553
|
+
if (target !== undefined) {
|
|
554
|
+
return new DeviceAssertions(target, { negate: false, ...sink === undefined ? {} : { soft: sink } });
|
|
555
|
+
}
|
|
355
556
|
const matchers = valueExpect(actual, message);
|
|
356
557
|
return sink === undefined ? matchers : softMatchers(matchers, sink);
|
|
357
558
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delacour/warden-e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "TypeScript spec API for `warden e2e`: test, expect, screen, device, app",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"LICENSE"
|
|
38
38
|
],
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@delacour/warden": "0.
|
|
40
|
+
"@delacour/warden": "0.8.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"zod": "^4.4.3"
|