@delacour/warden-e2e 0.8.0 → 0.10.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.
@@ -4351,6 +4351,9 @@ var healthDataSchema = z6.looseObject({
4351
4351
  socket: z6.object({ path: z6.string(), clients: z6.number() }).optional(),
4352
4352
  idb: z6.string().optional(),
4353
4353
  xcode: z6.string().optional(),
4354
+ builtWith: z6.object({ xcode: z6.string().optional(), idb: z6.string().optional() }).optional(),
4355
+ coreSimulatorVersion: z6.string().nullish(),
4356
+ frontmost: z6.object({ unresolvedAgoMs: z6.number(), method: z6.string() }).optional(),
4354
4357
  state: z6.string().optional(),
4355
4358
  uptimeMs: z6.number().optional()
4356
4359
  });
@@ -4362,6 +4365,7 @@ var snapshotDataSchema = z6.looseObject({
4362
4365
  elements: z6.array(z6.custom(isWireElement, { error: (issue) => wireElementProblem(issue.input) })),
4363
4366
  ms: z6.number(),
4364
4367
  fallback: z6.object({ from: z6.string(), to: z6.string(), reason: z6.string() }).optional(),
4368
+ target: z6.object({ pid: z6.number(), source: z6.string() }).optional(),
4365
4369
  readMs: z6.number().optional(),
4366
4370
  nodes: z6.number().optional()
4367
4371
  });
@@ -9170,6 +9174,6 @@ function onlyWasSeen() {
9170
9174
 
9171
9175
  // ../../packages/e2e/src/version.ts
9172
9176
  var WORKSPACE_VERSION = "0.0.0-workspace";
9173
- var WARDEN_E2E_VERSION2 = "0.8.0";
9177
+ var WARDEN_E2E_VERSION2 = "0.10.0";
9174
9178
 
9175
9179
  export { E2eError2, registerA11yTarget, a11yTargetOf, canActOnElements, noteSpanDetail, addSpanDetail, canObserve, canDetectAlerts, settleDetailOf, DEFAULT_SETTLE_QUIET_MS, DEFAULT_SETTLE_TIMEOUT_MS, settleByHash, snapshotHash, ok, err, swipeVector, screenRect, fieldValue, PINCH_MS, ROTATE_MS, PATH_MS, centreOf, pinchRadius, rotateRadius, requireGesture, assertScale, assertDegrees, isInteractiveRole, resolveRole, normalizeText, matchesText, indexSnapshot, testIdQuery, textQuery, roleQuery, selectorExpression, renderSnapshot, renderHeader, resolve, locateByTestIdViaReact, isLocator, Locator, pickOne, textOf, scrollUntilVisible, bunExec, execError, driverError, driverErr, logEventSchema, fatalEventSchema, responseSchema, mapWireError, createLineSplitter, encodeRequest, bunSpawn, stdioTransport, socketTransport, createSimdClient, spawnSimd, connectSimd, isRecoverableLoss, CAMERA_FACINGS, CONDITION_AREAS, resolveNetwork, resolveTextSize, androidFontScale, ENV_NAMES, DEFAULT_ASSERTION_TIMEOUT_MS, readEnv, runStep, setDefaultHidRecovery, setDefaultNativeLog, setDefaultDriverFactory, hasDefaultDriverFactory, setDefaultFixtureFactory, hasDefaultFixtureFactory, attemptSession, getSession, accessibleName, announce, failing, formatIssues, toE2eError, settled, unwrap, parseUiadA11yEvents, parseInjectEvents, withA11yRead, renderA11yScreen, createDeviceA11y, IOS_DEVICE_CAPABILITIES, sniffCameraMedia, cameraFeedDir, clearCameraFeeds, isLeaseAlive, processAlive, describeOwner, isPhysicalIosId, wardenHome, defaultDbPath, ownerKey, openStore, callerFile, formatCoord, DEFAULT_SPEED_MPS, DEFAULT_INTERVAL_S, realTickerClock, startRouteTicker, startFlap, registerConditions, conditionsOf, conditionSinkFor, createDeviceConditions, parseBudgets, createDevicePerf, perfStartFor, spawnWarden, hash6, attemptDir, screenshotPath, specIdOf, realNativeLogDeps, captureNativeLog, BUN_TIMEOUT_MARGIN_MS2, ownHook, currentScope, createScope, runInScope, hooksFor, resolveUse, registrationDefaults, markOnly, onlyWasSeen, WORKSPACE_VERSION, WARDEN_E2E_VERSION2 };
package/index.mjs CHANGED
@@ -41,7 +41,7 @@ import {
41
41
  registrationDefaults,
42
42
  markOnly,
43
43
  WARDEN_E2E_VERSION2
44
- } from "./chunk-vs5npy59.mjs";
44
+ } from "./chunk-p7618aj5.mjs";
45
45
  // ../../packages/e2e/src/expect/expect.ts
46
46
  import { expect as bunExpect } from "bun:test";
47
47
 
package/package.json CHANGED
@@ -1,21 +1,25 @@
1
1
  {
2
2
  "name": "@delacour/warden-e2e",
3
- "version": "0.8.0",
4
- "description": "TypeScript spec API for `warden e2e`: test, expect, screen, device, app",
3
+ "version": "0.10.0",
4
+ "description": "TypeScript e2e testing for React Native and Expo on iOS simulators and Android emulators, run by `warden e2e`: test, expect, screen, device, app",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/delacournz/warden.git"
9
9
  },
10
- "homepage": "https://github.com/delacournz/warden#readme",
10
+ "homepage": "https://warden.co.nz/docs/e2e",
11
11
  "bugs": {
12
12
  "url": "https://github.com/delacournz/warden/issues"
13
13
  },
14
14
  "type": "module",
15
15
  "keywords": [
16
16
  "e2e",
17
+ "e2e-testing",
18
+ "react-native",
19
+ "expo",
17
20
  "ios-simulator",
18
21
  "android-emulator",
22
+ "mobile-testing",
19
23
  "bun",
20
24
  "testing"
21
25
  ],
@@ -37,7 +41,7 @@
37
41
  "LICENSE"
38
42
  ],
39
43
  "peerDependencies": {
40
- "@delacour/warden": "0.8.0"
44
+ "@delacour/warden": "0.10.0"
41
45
  },
42
46
  "dependencies": {
43
47
  "zod": "^4.4.3"
package/preload.mjs CHANGED
@@ -109,7 +109,7 @@ import {
109
109
  onlyWasSeen,
110
110
  WORKSPACE_VERSION,
111
111
  WARDEN_E2E_VERSION2
112
- } from "./chunk-vs5npy59.mjs";
112
+ } from "./chunk-p7618aj5.mjs";
113
113
 
114
114
  // ../../packages/e2e/src/preload.ts
115
115
  import { afterAll, setDefaultTimeout } from "bun:test";
@@ -8272,7 +8272,7 @@ function deviceTypeTextBudgetMs(text) {
8272
8272
  var DEFAULT_QUIET_MS = 250;
8273
8273
  var DEFAULT_SETTLE_TIMEOUT_MS2 = 5000;
8274
8274
  var SETTLE_MARGIN_MS = 2000;
8275
- var REBIND_TIMEOUT_MS = 3000;
8275
+ var REBIND_TIMEOUT_MS = 1e4;
8276
8276
  var GESTURE_MARGIN_MS = 5000;
8277
8277
  var FRONTMOST_TIMEOUT_MS = 3000;
8278
8278
  var LAUNCH_TIMEOUT_MS = 30000;
@@ -8331,6 +8331,37 @@ function nativeDetail(data) {
8331
8331
  noteSpanDetail("frontmostPid", frontmostPid);
8332
8332
  return detail;
8333
8333
  }
8334
+ function noteSnapshotError(detail) {
8335
+ if (typeof detail !== "object" || detail === null)
8336
+ return;
8337
+ const fields = {
8338
+ stage: "axStage",
8339
+ reason: "axReason",
8340
+ request: "axRequest",
8341
+ bridgeError: "bridgeError",
8342
+ axError: "axError"
8343
+ };
8344
+ for (const [from, to] of Object.entries(fields)) {
8345
+ const value = detail[from];
8346
+ if (typeof value === "string")
8347
+ noteSpanDetail(to, value);
8348
+ }
8349
+ }
8350
+ function noteHelperHealth(health) {
8351
+ noteSpanDetail("bridge", health.ax.bridge);
8352
+ if (health.ax.lastError)
8353
+ noteSpanDetail("bridgeLastError", health.ax.lastError.message);
8354
+ if (health.ax.error)
8355
+ noteSpanDetail("bridgeLastError", health.ax.error);
8356
+ if (health.xcode)
8357
+ noteSpanDetail("hostXcode", health.xcode);
8358
+ if (health.builtWith?.xcode)
8359
+ noteSpanDetail("helperXcode", health.builtWith.xcode);
8360
+ if (health.coreSimulatorVersion)
8361
+ noteSpanDetail("coreSimulator", health.coreSimulatorVersion);
8362
+ if (health.frontmost)
8363
+ noteSpanDetail("frontmostUnresolvedAgoMs", health.frontmost.unresolvedAgoMs);
8364
+ }
8334
8365
  function noteRebind(data) {
8335
8366
  noteSpanDetail("rebind", data.bound ? "bound" : data.reason ?? "unbound");
8336
8367
  noteSpanDetail("rebindMs", data.waitedMs);
@@ -8495,13 +8526,30 @@ function createIosDriver(swap, simctl, opts) {
8495
8526
  note(viaHelper.data);
8496
8527
  return okVoid2;
8497
8528
  }
8529
+ let failureDiagnosed = false;
8498
8530
  const fetchSnapshot = async (o) => {
8499
8531
  const result = await request("snapshot", params({ interactiveOnly: o?.interactiveOnly, backend: o?.backend }));
8500
- if (!result.success)
8532
+ if (!result.success) {
8533
+ noteSnapshotError(result.error.detail);
8534
+ if (!failureDiagnosed) {
8535
+ failureDiagnosed = true;
8536
+ const health = await request("health", {});
8537
+ if (health.success)
8538
+ noteHelperHealth(health.data);
8539
+ }
8501
8540
  return result;
8502
- const { fallback } = result.data;
8503
- if (fallback)
8541
+ }
8542
+ failureDiagnosed = false;
8543
+ const { fallback, target } = result.data;
8544
+ noteSpanDetail("backend", result.data.backend);
8545
+ if (fallback) {
8504
8546
  opts.log?.(`[ios] snapshot fell back ${fallback.from} -> ${fallback.to}: ${fallback.reason}`);
8547
+ noteSpanDetail("fallback", fallback.reason);
8548
+ }
8549
+ if (target) {
8550
+ noteSpanDetail("targetPid", target.pid);
8551
+ noteSpanDetail("targetSource", target.source);
8552
+ }
8505
8553
  return { success: true, data: toSnapshot(result.data, now()) };
8506
8554
  };
8507
8555
  async function snapshot(o) {
@@ -72,3 +72,9 @@ export declare function resolveKind(project: Project, kind: BuildKind, device?:
72
72
  * `device` target the project builds for a physical iPhone: the signed `xcodebuild` command, the device bundle id.
73
73
  */
74
74
  export declare function projectForKind(project: Project, kind: BuildKind, device?: DeviceTarget): Project;
75
+ /**
76
+ * The kind-less build of `project` on `platform` is the `dev` kind's build: same command, Debug, no JS in the key, no
77
+ * variant, kind env or device target. Then both are one build, cached once under the dev kind (`kindHash`), and a
78
+ * kind-less row of the same fingerprint (written before they were unified) is that build too.
79
+ */
80
+ export declare function kindlessIsDev(project: Project, platform: Platform): boolean;
@@ -16,6 +16,7 @@ import { type SwappableClient } from "./ios-session";
16
16
  import { type IosSettings, type StagedSettings } from "./ios-settings";
17
17
  import { type Simctl } from "./simctl";
18
18
  import { type SimdClient } from "./simd-client";
19
+ import type { HealthData } from "./simd-protocol";
19
20
  import type { SimdSpawn } from "./simd-transport";
20
21
  /**
21
22
  * The iOS `Driver`: input, AX and app launch / terminate / openUrl through `warden-simd` (socket when
@@ -83,6 +84,10 @@ export type OpenIosDriverOptions = {
83
84
  };
84
85
  /** USB HID keyboard-page usage ids for the keys `Driver.key` offers. */
85
86
  export declare const KEY_USAGE: Readonly<Record<KeyName, number>>;
87
+ /** The fields of a failed snapshot's `detail` the helper sets (which reader, why, both readers' errors), on its span. */
88
+ export declare function noteSnapshotError(detail: unknown): void;
89
+ /** What the helper says about itself after a failed read: bridge state, host vs build Xcode, CoreSimulator. */
90
+ export declare function noteHelperHealth(health: HealthData): void;
86
91
  export declare function createIosDriver(swap: SwappableClient, simctl: Simctl, opts: {
87
92
  udid: string;
88
93
  now: () => number;
@@ -183,6 +183,15 @@ export declare const healthDataSchema: z.ZodObject<{
183
183
  }, z.core.$strip>>;
184
184
  idb: z.ZodOptional<z.ZodString>;
185
185
  xcode: z.ZodOptional<z.ZodString>;
186
+ builtWith: z.ZodOptional<z.ZodObject<{
187
+ xcode: z.ZodOptional<z.ZodString>;
188
+ idb: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strip>>;
190
+ coreSimulatorVersion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
191
+ frontmost: z.ZodOptional<z.ZodObject<{
192
+ unresolvedAgoMs: z.ZodNumber;
193
+ method: z.ZodString;
194
+ }, z.core.$strip>>;
186
195
  state: z.ZodOptional<z.ZodString>;
187
196
  uptimeMs: z.ZodOptional<z.ZodNumber>;
188
197
  }, z.core.$loose>;
@@ -206,6 +215,10 @@ export declare const snapshotDataSchema: z.ZodObject<{
206
215
  to: z.ZodString;
207
216
  reason: z.ZodString;
208
217
  }, z.core.$strip>>;
218
+ target: z.ZodOptional<z.ZodObject<{
219
+ pid: z.ZodNumber;
220
+ source: z.ZodString;
221
+ }, z.core.$strip>>;
209
222
  readMs: z.ZodOptional<z.ZodNumber>;
210
223
  nodes: z.ZodOptional<z.ZodNumber>;
211
224
  }, z.core.$loose>;
@@ -340,6 +353,15 @@ export declare const opSchemas: {
340
353
  }, z.core.$strip>>;
341
354
  idb: z.ZodOptional<z.ZodString>;
342
355
  xcode: z.ZodOptional<z.ZodString>;
356
+ builtWith: z.ZodOptional<z.ZodObject<{
357
+ xcode: z.ZodOptional<z.ZodString>;
358
+ idb: z.ZodOptional<z.ZodString>;
359
+ }, z.core.$strip>>;
360
+ coreSimulatorVersion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
361
+ frontmost: z.ZodOptional<z.ZodObject<{
362
+ unresolvedAgoMs: z.ZodNumber;
363
+ method: z.ZodString;
364
+ }, z.core.$strip>>;
343
365
  state: z.ZodOptional<z.ZodString>;
344
366
  uptimeMs: z.ZodOptional<z.ZodNumber>;
345
367
  }, z.core.$loose>;
@@ -362,6 +384,10 @@ export declare const opSchemas: {
362
384
  to: z.ZodString;
363
385
  reason: z.ZodString;
364
386
  }, z.core.$strip>>;
387
+ target: z.ZodOptional<z.ZodObject<{
388
+ pid: z.ZodNumber;
389
+ source: z.ZodString;
390
+ }, z.core.$strip>>;
365
391
  readMs: z.ZodOptional<z.ZodNumber>;
366
392
  nodes: z.ZodOptional<z.ZodNumber>;
367
393
  }, z.core.$loose>;