doc-detective 4.21.0 → 4.22.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/dist/common/src/schemas/schemas.json +264 -264
- package/dist/common/src/types/generated/config_v3.d.ts +4 -4
- package/dist/common/src/types/generated/context_v3.d.ts +4 -4
- package/dist/common/src/types/generated/report_v3.d.ts +4 -4
- package/dist/common/src/types/generated/resolvedTests_v3.d.ts +8 -8
- package/dist/common/src/types/generated/spec_v3.d.ts +4 -4
- package/dist/common/src/types/generated/startSurface_v3.d.ts +7 -7
- package/dist/common/src/types/generated/step_v3.d.ts +7 -7
- package/dist/common/src/types/generated/test_v3.d.ts +18 -18
- package/dist/core/tests/androidEmulator.d.ts +2 -12
- package/dist/core/tests/androidEmulator.d.ts.map +1 -1
- package/dist/core/tests/androidEmulator.js +5 -17
- package/dist/core/tests/androidEmulator.js.map +1 -1
- package/dist/core/tests/appSurface.d.ts +35 -1
- package/dist/core/tests/appSurface.d.ts.map +1 -1
- package/dist/core/tests/appSurface.js +162 -20
- package/dist/core/tests/appSurface.js.map +1 -1
- package/dist/core/tests/iosSimulator.d.ts +89 -0
- package/dist/core/tests/iosSimulator.d.ts.map +1 -0
- package/dist/core/tests/iosSimulator.js +453 -0
- package/dist/core/tests/iosSimulator.js.map +1 -0
- package/dist/core/tests/mobileDevice.d.ts +15 -0
- package/dist/core/tests/mobileDevice.d.ts.map +1 -0
- package/dist/core/tests/mobileDevice.js +24 -0
- package/dist/core/tests/mobileDevice.js.map +1 -0
- package/dist/core/tests/mobilePlatform.d.ts +1 -2
- package/dist/core/tests/mobilePlatform.d.ts.map +1 -1
- package/dist/core/tests/mobilePlatform.js +15 -14
- package/dist/core/tests/mobilePlatform.js.map +1 -1
- package/dist/core/tests.d.ts.map +1 -1
- package/dist/core/tests.js +152 -45
- package/dist/core/tests.js.map +1 -1
- package/dist/index.cjs +845 -331
- package/dist/runtime/heavyDeps.d.ts +1 -1
- package/dist/runtime/heavyDeps.d.ts.map +1 -1
- package/dist/runtime/heavyDeps.js +1 -0
- package/dist/runtime/heavyDeps.js.map +1 -1
- package/dist/runtime/installCommand.d.ts +1 -1
- package/dist/runtime/installCommand.d.ts.map +1 -1
- package/dist/runtime/installCommand.js +21 -4
- package/dist/runtime/installCommand.js.map +1 -1
- package/dist/runtime/iosInstaller.d.ts +23 -0
- package/dist/runtime/iosInstaller.d.ts.map +1 -0
- package/dist/runtime/iosInstaller.js +104 -0
- package/dist/runtime/iosInstaller.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { normalizeDeviceDescriptor } from "./mobileDevice.js";
|
|
2
|
+
import type { DeviceDescriptor } from "./mobileDevice.js";
|
|
3
|
+
export { parseSimctlDevices, parseSimctlRuntimes, parseSimctlDeviceTypes, compareVersions, newestRuntime, productFamilyForDeviceType, newestDeviceType, planSimulatorAcquisition, createSimulatorRegistry, acquireSimulator, teardownSimulatorRegistry, normalizeDeviceDescriptor, buildAcquireSimulatorDeps, };
|
|
4
|
+
export type { DeviceDescriptor, SimDevice, SimRuntime, SimDeviceType, SimulatorRegistry, SimulatorEntry, SimulatorAcquisition, };
|
|
5
|
+
interface SimDevice {
|
|
6
|
+
udid: string;
|
|
7
|
+
name: string;
|
|
8
|
+
state: string;
|
|
9
|
+
runtime: string;
|
|
10
|
+
isAvailable?: boolean;
|
|
11
|
+
deviceTypeIdentifier?: string;
|
|
12
|
+
}
|
|
13
|
+
interface SimRuntime {
|
|
14
|
+
identifier: string;
|
|
15
|
+
version: string;
|
|
16
|
+
name: string;
|
|
17
|
+
isAvailable: boolean;
|
|
18
|
+
platform?: string;
|
|
19
|
+
}
|
|
20
|
+
interface SimDeviceType {
|
|
21
|
+
identifier: string;
|
|
22
|
+
name: string;
|
|
23
|
+
productFamily?: string;
|
|
24
|
+
}
|
|
25
|
+
declare function parseSimctlDevices(text: string): SimDevice[];
|
|
26
|
+
declare function parseSimctlRuntimes(text: string): SimRuntime[];
|
|
27
|
+
declare function parseSimctlDeviceTypes(text: string): SimDeviceType[];
|
|
28
|
+
declare function compareVersions(a: string, b: string): number;
|
|
29
|
+
declare function newestRuntime(runtimes: SimRuntime[]): SimRuntime | null;
|
|
30
|
+
declare function productFamilyForDeviceType(deviceType?: string): "iPhone" | "iPad";
|
|
31
|
+
declare function newestDeviceType(deviceTypes: SimDeviceType[], family: "iPhone" | "iPad"): SimDeviceType | null;
|
|
32
|
+
type SimulatorAcquisition = {
|
|
33
|
+
action: "reuse-booted";
|
|
34
|
+
name: string;
|
|
35
|
+
udid: string;
|
|
36
|
+
} | {
|
|
37
|
+
action: "boot";
|
|
38
|
+
name: string;
|
|
39
|
+
udid: string;
|
|
40
|
+
} | {
|
|
41
|
+
action: "create-boot";
|
|
42
|
+
name: string;
|
|
43
|
+
deviceTypeId: string;
|
|
44
|
+
runtimeId: string;
|
|
45
|
+
} | {
|
|
46
|
+
action: "skip";
|
|
47
|
+
reason: string;
|
|
48
|
+
};
|
|
49
|
+
declare function planSimulatorAcquisition(desc: DeviceDescriptor, { devices, runtimes, deviceTypes, }: {
|
|
50
|
+
devices: SimDevice[];
|
|
51
|
+
runtimes: SimRuntime[];
|
|
52
|
+
deviceTypes: SimDeviceType[];
|
|
53
|
+
}): SimulatorAcquisition;
|
|
54
|
+
interface SimulatorEntry {
|
|
55
|
+
name: string;
|
|
56
|
+
udid: string;
|
|
57
|
+
bootedByUs: boolean;
|
|
58
|
+
ready?: Promise<SimulatorEntry>;
|
|
59
|
+
}
|
|
60
|
+
type SimulatorRegistry = Map<string, SimulatorEntry>;
|
|
61
|
+
declare function createSimulatorRegistry(): SimulatorRegistry;
|
|
62
|
+
interface AcquireSimulatorDeps {
|
|
63
|
+
listDevices: () => Promise<SimDevice[]>;
|
|
64
|
+
listRuntimes: () => Promise<SimRuntime[]>;
|
|
65
|
+
listDeviceTypes: () => Promise<SimDeviceType[]>;
|
|
66
|
+
create: (args: {
|
|
67
|
+
name: string;
|
|
68
|
+
deviceTypeId: string;
|
|
69
|
+
runtimeId: string;
|
|
70
|
+
}) => Promise<{
|
|
71
|
+
udid: string;
|
|
72
|
+
}>;
|
|
73
|
+
boot: (udid: string) => Promise<void>;
|
|
74
|
+
log?: (message: string) => void;
|
|
75
|
+
}
|
|
76
|
+
declare function acquireSimulator({ desc, registry, deps, }: {
|
|
77
|
+
desc: DeviceDescriptor;
|
|
78
|
+
registry: SimulatorRegistry;
|
|
79
|
+
deps: AcquireSimulatorDeps;
|
|
80
|
+
}): Promise<{
|
|
81
|
+
entry: SimulatorEntry;
|
|
82
|
+
} | {
|
|
83
|
+
skip: string;
|
|
84
|
+
}>;
|
|
85
|
+
declare function teardownSimulatorRegistry(registry: SimulatorRegistry, shutdown: (entry: SimulatorEntry) => Promise<void>): Promise<void>;
|
|
86
|
+
declare function buildAcquireSimulatorDeps(log?: (m: string) => void): AcquireSimulatorDeps & {
|
|
87
|
+
shutdown: (entry: SimulatorEntry) => Promise<void>;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=iosSimulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iosSimulator.d.ts","sourceRoot":"","sources":["../../../src/core/tests/iosSimulator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
// Native app surfaces phase A4: the managed iOS simulator layer, the simctl
|
|
2
|
+
// analogue of androidEmulator.ts. The top half is pure — `simctl … --json`
|
|
3
|
+
// parsers, runtime/device-type selection, and the reuse-or-create decision —
|
|
4
|
+
// so it's unit-testable without Xcode. The bottom half is the effectful
|
|
5
|
+
// registry and `acquireSimulator`, whose effects (simctl spawns, boot polling)
|
|
6
|
+
// are all injected so the orchestration is testable with fakes.
|
|
7
|
+
//
|
|
8
|
+
// Unlike Android emulators (addressed by an even console port → `emulator-5554`
|
|
9
|
+
// serial), simulators are addressed by their UDID, and the XCUITest driver
|
|
10
|
+
// attaches to whichever simulator we boot via `appium:udid`. simctl owns the
|
|
11
|
+
// heavy lifting (boot/create), so this layer just decides WHICH simulator and
|
|
12
|
+
// tracks launch-ownership for the run-end sweep.
|
|
13
|
+
import { execFile } from "node:child_process";
|
|
14
|
+
import { normalizeDeviceDescriptor } from "./mobileDevice.js";
|
|
15
|
+
export { parseSimctlDevices, parseSimctlRuntimes, parseSimctlDeviceTypes, compareVersions, newestRuntime, productFamilyForDeviceType, newestDeviceType, planSimulatorAcquisition, createSimulatorRegistry, acquireSimulator, teardownSimulatorRegistry, normalizeDeviceDescriptor,
|
|
16
|
+
// Effectful helpers + the deps builder that wires them.
|
|
17
|
+
buildAcquireSimulatorDeps, };
|
|
18
|
+
// --- Output parsers (pure) ---
|
|
19
|
+
// Parse `xcrun simctl list devices --json`. The `devices` object is keyed by
|
|
20
|
+
// runtime identifier; each value is an array of devices under that runtime. We
|
|
21
|
+
// flatten it, stamping each device with its runtime, and (defensively) keep
|
|
22
|
+
// only entries that carry a udid + name.
|
|
23
|
+
function parseSimctlDevices(text) {
|
|
24
|
+
let data;
|
|
25
|
+
try {
|
|
26
|
+
data = JSON.parse(String(text));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const byRuntime = data?.devices;
|
|
32
|
+
if (!byRuntime || typeof byRuntime !== "object")
|
|
33
|
+
return [];
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const [runtime, list] of Object.entries(byRuntime)) {
|
|
36
|
+
if (!Array.isArray(list))
|
|
37
|
+
continue;
|
|
38
|
+
for (const d of list) {
|
|
39
|
+
if (!d || typeof d.udid !== "string" || typeof d.name !== "string")
|
|
40
|
+
continue;
|
|
41
|
+
out.push({
|
|
42
|
+
udid: d.udid,
|
|
43
|
+
name: d.name,
|
|
44
|
+
state: typeof d.state === "string" ? d.state : "Unknown",
|
|
45
|
+
runtime,
|
|
46
|
+
isAvailable: d.isAvailable !== false,
|
|
47
|
+
deviceTypeIdentifier: typeof d.deviceTypeIdentifier === "string"
|
|
48
|
+
? d.deviceTypeIdentifier
|
|
49
|
+
: undefined,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
// Parse `xcrun simctl list runtimes --json`.
|
|
56
|
+
function parseSimctlRuntimes(text) {
|
|
57
|
+
let data;
|
|
58
|
+
try {
|
|
59
|
+
data = JSON.parse(String(text));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
const list = data?.runtimes;
|
|
65
|
+
if (!Array.isArray(list))
|
|
66
|
+
return [];
|
|
67
|
+
const out = [];
|
|
68
|
+
for (const r of list) {
|
|
69
|
+
if (!r || typeof r.identifier !== "string")
|
|
70
|
+
continue;
|
|
71
|
+
out.push({
|
|
72
|
+
identifier: r.identifier,
|
|
73
|
+
version: typeof r.version === "string" ? r.version : "",
|
|
74
|
+
name: typeof r.name === "string" ? r.name : r.identifier,
|
|
75
|
+
isAvailable: r.isAvailable !== false,
|
|
76
|
+
platform: typeof r.platform === "string" ? r.platform : undefined,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
// Parse `xcrun simctl list devicetypes --json`.
|
|
82
|
+
function parseSimctlDeviceTypes(text) {
|
|
83
|
+
let data;
|
|
84
|
+
try {
|
|
85
|
+
data = JSON.parse(String(text));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const list = data?.devicetypes;
|
|
91
|
+
if (!Array.isArray(list))
|
|
92
|
+
return [];
|
|
93
|
+
const out = [];
|
|
94
|
+
for (const t of list) {
|
|
95
|
+
if (!t || typeof t.identifier !== "string" || typeof t.name !== "string")
|
|
96
|
+
continue;
|
|
97
|
+
out.push({
|
|
98
|
+
identifier: t.identifier,
|
|
99
|
+
name: t.name,
|
|
100
|
+
productFamily: typeof t.productFamily === "string" ? t.productFamily : undefined,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
// --- Runtime / device-type selection (pure) ---
|
|
106
|
+
// Compare dotted version strings numerically ("17.5" < "18.0", "17.10" >
|
|
107
|
+
// "17.9"). Missing components read as 0. Returns negative/0/positive like a
|
|
108
|
+
// comparator.
|
|
109
|
+
function compareVersions(a, b) {
|
|
110
|
+
const pa = String(a).split(".").map((n) => parseInt(n, 10) || 0);
|
|
111
|
+
const pb = String(b).split(".").map((n) => parseInt(n, 10) || 0);
|
|
112
|
+
const len = Math.max(pa.length, pb.length);
|
|
113
|
+
for (let i = 0; i < len; i++) {
|
|
114
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
115
|
+
if (d !== 0)
|
|
116
|
+
return d;
|
|
117
|
+
}
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
// Whether a runtime is an iOS runtime (vs. watchOS/tvOS/visionOS). Prefers the
|
|
121
|
+
// `platform` field; a runtime with no platform is treated as iOS only when its
|
|
122
|
+
// identifier/name names iOS — hosted images sometimes omit the field. This is
|
|
123
|
+
// load-bearing: the hosted runners ship visionOS/watchOS/tvOS runtimes and
|
|
124
|
+
// devices too, and booting an Apple Vision Pro for an `ios` context builds a
|
|
125
|
+
// (different, slow-to-fail) WebDriverAgent — so every device/runtime selection
|
|
126
|
+
// gates on this.
|
|
127
|
+
function isIosRuntime(r) {
|
|
128
|
+
if (r.platform)
|
|
129
|
+
return r.platform === "iOS";
|
|
130
|
+
return /\.iOS-/i.test(r.identifier) || /^iOS\b/i.test(r.name);
|
|
131
|
+
}
|
|
132
|
+
// The newest available iOS runtime (highest version). Returns null when none is
|
|
133
|
+
// installed/available.
|
|
134
|
+
function newestRuntime(runtimes) {
|
|
135
|
+
const ios = runtimes.filter((r) => r.isAvailable && isIosRuntime(r));
|
|
136
|
+
if (!ios.length)
|
|
137
|
+
return null;
|
|
138
|
+
return ios.reduce((best, r) => compareVersions(r.version, best.version) > 0 ? r : best);
|
|
139
|
+
}
|
|
140
|
+
// The product family a device descriptor's `deviceType` maps to: "tablet" →
|
|
141
|
+
// iPad, everything else (incl. the default "phone") → iPhone.
|
|
142
|
+
function productFamilyForDeviceType(deviceType) {
|
|
143
|
+
return deviceType === "tablet" ? "iPad" : "iPhone";
|
|
144
|
+
}
|
|
145
|
+
// Extract a device type's leading model number for ordering ("iPhone 15 Pro" →
|
|
146
|
+
// 15, "iPad Pro 11-inch" → 11). Names without a number sort lowest.
|
|
147
|
+
function deviceTypeModelNumber(name) {
|
|
148
|
+
const match = /\b(\d+)\b/.exec(name);
|
|
149
|
+
return match ? parseInt(match[1], 10) : -1;
|
|
150
|
+
}
|
|
151
|
+
// The newest device type of a product family (highest model number; within a
|
|
152
|
+
// model, tier tie-breaks "Pro Max" > "Pro" > "Plus" > plain, so the pick is
|
|
153
|
+
// deterministic when several variants of one model exist). Returns null when
|
|
154
|
+
// the family has no device types. Used only for the create path — booting an
|
|
155
|
+
// existing simulator never needs it.
|
|
156
|
+
function newestDeviceType(deviceTypes, family) {
|
|
157
|
+
const rank = (name) => {
|
|
158
|
+
if (/pro max/i.test(name))
|
|
159
|
+
return 3;
|
|
160
|
+
if (/\bpro\b/i.test(name))
|
|
161
|
+
return 2;
|
|
162
|
+
if (/\bplus\b/i.test(name))
|
|
163
|
+
return 1;
|
|
164
|
+
return 0;
|
|
165
|
+
};
|
|
166
|
+
const candidates = deviceTypes.filter((t) => (t.productFamily ?? "").toLowerCase() === family.toLowerCase());
|
|
167
|
+
if (!candidates.length)
|
|
168
|
+
return null;
|
|
169
|
+
return candidates.reduce((best, t) => {
|
|
170
|
+
const dn = deviceTypeModelNumber(t.name) - deviceTypeModelNumber(best.name);
|
|
171
|
+
if (dn !== 0)
|
|
172
|
+
return dn > 0 ? t : best;
|
|
173
|
+
return rank(t.name) > rank(best.name) ? t : best;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// Filter devices to the iPhone/iPad family the descriptor asks for, restricted
|
|
177
|
+
// to devices living on an AVAILABLE iOS runtime (so a visionOS Apple Vision Pro,
|
|
178
|
+
// a watchOS watch, or a tvOS box is never a candidate for an `ios` context), and
|
|
179
|
+
// honoring an explicit `osVersion` (matched against the runtime version). Family
|
|
180
|
+
// is matched on the device type identifier, falling back to the device name.
|
|
181
|
+
function candidateDevices(desc, devices, runtimes) {
|
|
182
|
+
const family = productFamilyForDeviceType(desc.deviceType);
|
|
183
|
+
const iosRuntimes = new Set(runtimes.filter((r) => r.isAvailable && isIosRuntime(r)).map((r) => r.identifier));
|
|
184
|
+
const versionOf = (runtimeId) => runtimes.find((r) => r.identifier === runtimeId)?.version ?? "";
|
|
185
|
+
const familyRe = family === "iPad" ? /iPad/i : /iPhone|iPod/i;
|
|
186
|
+
return devices
|
|
187
|
+
.filter((d) => d.isAvailable !== false)
|
|
188
|
+
.filter((d) => iosRuntimes.has(d.runtime))
|
|
189
|
+
.filter((d) => {
|
|
190
|
+
if (!desc.osVersion)
|
|
191
|
+
return true;
|
|
192
|
+
return versionOf(d.runtime) === desc.osVersion;
|
|
193
|
+
})
|
|
194
|
+
.filter((d) => familyRe.test(d.deviceTypeIdentifier ?? "") || familyRe.test(d.name));
|
|
195
|
+
}
|
|
196
|
+
// Decide how to obtain the simulator described by `desc`. A NAMED device
|
|
197
|
+
// reuses a booted match → boots an existing shutdown match → creates+boots
|
|
198
|
+
// under that name. The DEFAULT (unnamed) device reuses any booted candidate →
|
|
199
|
+
// boots the newest-runtime candidate → creates+boots the newest iPhone. SKIPs
|
|
200
|
+
// with an actionable reason when nothing is bootable (no runtime installed).
|
|
201
|
+
function planSimulatorAcquisition(desc, { devices, runtimes, deviceTypes, }) {
|
|
202
|
+
const versionOf = (runtimeId) => runtimes.find((r) => r.identifier === runtimeId)?.version ?? "";
|
|
203
|
+
const newestOf = (list) => list.length
|
|
204
|
+
? list.reduce((best, d) => compareVersions(versionOf(d.runtime), versionOf(best.runtime)) > 0
|
|
205
|
+
? d
|
|
206
|
+
: best)
|
|
207
|
+
: null;
|
|
208
|
+
const isBooted = (d) => /^booted$/i.test(d.state);
|
|
209
|
+
const iosRuntimeIds = new Set(runtimes.filter((r) => r.isAvailable && isIosRuntime(r)).map((r) => r.identifier));
|
|
210
|
+
if (desc.name) {
|
|
211
|
+
// Match the name ONLY among available iOS-runtime devices — a watchOS /
|
|
212
|
+
// tvOS / visionOS device that happens to share the name must never be
|
|
213
|
+
// reused or booted for an `ios` context. If nothing iOS-side matches, fall
|
|
214
|
+
// through to create an iOS device under the requested name.
|
|
215
|
+
const named = devices.filter((d) => d.name === desc.name &&
|
|
216
|
+
d.isAvailable !== false &&
|
|
217
|
+
iosRuntimeIds.has(d.runtime));
|
|
218
|
+
const booted = named.find(isBooted);
|
|
219
|
+
if (booted)
|
|
220
|
+
return { action: "reuse-booted", name: desc.name, udid: booted.udid };
|
|
221
|
+
const existing = newestOf(named);
|
|
222
|
+
if (existing)
|
|
223
|
+
return { action: "boot", name: desc.name, udid: existing.udid };
|
|
224
|
+
// Create it under the requested name.
|
|
225
|
+
return planCreate(desc, runtimes, deviceTypes, devices, desc.name);
|
|
226
|
+
}
|
|
227
|
+
// Default device: reuse any booted candidate, else boot the newest existing
|
|
228
|
+
// candidate, else create the newest iPhone.
|
|
229
|
+
const candidates = candidateDevices(desc, devices, runtimes);
|
|
230
|
+
const booted = candidates.find(isBooted);
|
|
231
|
+
if (booted)
|
|
232
|
+
return { action: "reuse-booted", name: booted.name, udid: booted.udid };
|
|
233
|
+
const existing = newestOf(candidates);
|
|
234
|
+
if (existing)
|
|
235
|
+
return { action: "boot", name: existing.name, udid: existing.udid };
|
|
236
|
+
return planCreate(desc, runtimes, deviceTypes, devices, defaultSimulatorName(desc));
|
|
237
|
+
}
|
|
238
|
+
// The registry name for a created default simulator: stable so a second
|
|
239
|
+
// acquire in the same run reuses it rather than creating a duplicate.
|
|
240
|
+
function defaultSimulatorName(desc) {
|
|
241
|
+
return desc.deviceType === "tablet"
|
|
242
|
+
? "doc-detective-ipad"
|
|
243
|
+
: "doc-detective-iphone";
|
|
244
|
+
}
|
|
245
|
+
// Resolve the create-boot plan (or a skip) for a device that must be created:
|
|
246
|
+
// needs an available iOS runtime (honoring osVersion) and a device type of the
|
|
247
|
+
// requested family. When no osVersion is pinned, prefer the newest runtime that
|
|
248
|
+
// ALREADY has simulators (a proven-usable runtime) over the absolute-newest —
|
|
249
|
+
// a freshly-downloaded/partial newest runtime can have a very slow or unusable
|
|
250
|
+
// first boot + WebDriverAgent build, whereas a runtime that already carries
|
|
251
|
+
// devices is known good. Fall back to the newest available runtime when none
|
|
252
|
+
// has devices yet.
|
|
253
|
+
function planCreate(desc, runtimes, deviceTypes, devices, name) {
|
|
254
|
+
const family = productFamilyForDeviceType(desc.deviceType);
|
|
255
|
+
const available = runtimes.filter((r) => r.isAvailable && isIosRuntime(r));
|
|
256
|
+
let runtime;
|
|
257
|
+
if (desc.osVersion) {
|
|
258
|
+
runtime = available.find((r) => r.version === desc.osVersion);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
const warmedIds = new Set(devices.filter((d) => d.isAvailable !== false).map((d) => d.runtime));
|
|
262
|
+
const warmed = available.filter((r) => warmedIds.has(r.identifier));
|
|
263
|
+
runtime = (warmed.length ? newestRuntime(warmed) : null) ?? newestRuntime(available);
|
|
264
|
+
}
|
|
265
|
+
if (!runtime) {
|
|
266
|
+
return {
|
|
267
|
+
action: "skip",
|
|
268
|
+
reason: desc.osVersion
|
|
269
|
+
? `Skipping context on 'ios': no installed iOS ${desc.osVersion} simulator runtime to create the "${name}" simulator. Install one via Xcode → Settings → Components (or \`xcodebuild -downloadPlatform iOS\`).`
|
|
270
|
+
: `Skipping context on 'ios': no installed iOS simulator runtime is available. Open Xcode once (or run \`xcodebuild -downloadPlatform iOS\`) to install a simulator runtime, then rerun.`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const deviceType = newestDeviceType(deviceTypes, family);
|
|
274
|
+
if (!deviceType) {
|
|
275
|
+
return {
|
|
276
|
+
action: "skip",
|
|
277
|
+
reason: `Skipping context on 'ios': no ${family} simulator device type is available to create the "${name}" simulator. Install the iOS platform components in Xcode and rerun.`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
action: "create-boot",
|
|
282
|
+
name,
|
|
283
|
+
deviceTypeId: deviceType.identifier,
|
|
284
|
+
runtimeId: runtime.identifier,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function createSimulatorRegistry() {
|
|
288
|
+
return new Map();
|
|
289
|
+
}
|
|
290
|
+
// Obtain the simulator for a descriptor, booting/creating as planned and
|
|
291
|
+
// registering it (keyed by resolved name, shared across the run). A registry
|
|
292
|
+
// hit returns immediately. Returns the entry, or a skip-shaped object the
|
|
293
|
+
// caller turns into SKIPPED. Mirrors androidEmulator.acquireDevice.
|
|
294
|
+
async function acquireSimulator({ desc, registry, deps, }) {
|
|
295
|
+
// Fast reuse for a NAMED device already acquired this run, without enumerating
|
|
296
|
+
// runtimes/device types (the boot/create-only probes).
|
|
297
|
+
if (desc.name) {
|
|
298
|
+
const registered = registry.get(desc.name);
|
|
299
|
+
if (registered) {
|
|
300
|
+
const entry = registered.ready ? await registered.ready : registered;
|
|
301
|
+
return { entry };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const [devices, runtimes, deviceTypes] = await Promise.all([
|
|
305
|
+
deps.listDevices(),
|
|
306
|
+
deps.listRuntimes(),
|
|
307
|
+
deps.listDeviceTypes(),
|
|
308
|
+
]);
|
|
309
|
+
const plan = planSimulatorAcquisition(desc, {
|
|
310
|
+
devices,
|
|
311
|
+
runtimes,
|
|
312
|
+
deviceTypes,
|
|
313
|
+
});
|
|
314
|
+
if (plan.action === "skip")
|
|
315
|
+
return { skip: plan.reason };
|
|
316
|
+
// Registry hit (same resolved name already acquired this run) — reuse,
|
|
317
|
+
// awaiting any in-flight boot so concurrent callers converge on one device.
|
|
318
|
+
const existing = registry.get(plan.name);
|
|
319
|
+
if (existing) {
|
|
320
|
+
const entry = existing.ready ? await existing.ready : existing;
|
|
321
|
+
return { entry };
|
|
322
|
+
}
|
|
323
|
+
if (plan.action === "reuse-booted") {
|
|
324
|
+
const entry = {
|
|
325
|
+
name: plan.name,
|
|
326
|
+
udid: plan.udid,
|
|
327
|
+
bootedByUs: false,
|
|
328
|
+
};
|
|
329
|
+
registry.set(plan.name, entry);
|
|
330
|
+
return { entry };
|
|
331
|
+
}
|
|
332
|
+
// boot / create-boot: register a placeholder carrying the in-flight boot
|
|
333
|
+
// promise BEFORE awaiting, so a concurrent acquirer shares it.
|
|
334
|
+
const placeholder = {
|
|
335
|
+
name: plan.name,
|
|
336
|
+
udid: plan.action === "boot" ? plan.udid : "",
|
|
337
|
+
bootedByUs: true,
|
|
338
|
+
};
|
|
339
|
+
const readyPromise = (async () => {
|
|
340
|
+
if (plan.action === "create-boot") {
|
|
341
|
+
deps.log?.(`Creating simulator "${plan.name}" (${plan.deviceTypeId} on ${plan.runtimeId}).`);
|
|
342
|
+
const created = await deps.create({
|
|
343
|
+
name: plan.name,
|
|
344
|
+
deviceTypeId: plan.deviceTypeId,
|
|
345
|
+
runtimeId: plan.runtimeId,
|
|
346
|
+
});
|
|
347
|
+
placeholder.udid = created.udid;
|
|
348
|
+
}
|
|
349
|
+
deps.log?.(`Booting simulator "${plan.name}" (${placeholder.udid}).`);
|
|
350
|
+
await deps.boot(placeholder.udid);
|
|
351
|
+
return placeholder;
|
|
352
|
+
})();
|
|
353
|
+
placeholder.ready = readyPromise;
|
|
354
|
+
registry.set(plan.name, placeholder);
|
|
355
|
+
try {
|
|
356
|
+
await readyPromise;
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
// A failed create/boot must not leave a broken placeholder wedging every
|
|
360
|
+
// later acquire of this device — drop it so a retry can start fresh.
|
|
361
|
+
if (registry.get(plan.name) === placeholder)
|
|
362
|
+
registry.delete(plan.name);
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
365
|
+
return { entry: placeholder };
|
|
366
|
+
}
|
|
367
|
+
// Run-end sweep: shut down only simulators Doc Detective booted (launch-
|
|
368
|
+
// ownership), leaving pre-existing booted simulators running. Effects injected.
|
|
369
|
+
async function teardownSimulatorRegistry(registry, shutdown) {
|
|
370
|
+
for (const entry of registry.values()) {
|
|
371
|
+
if (!entry.bootedByUs)
|
|
372
|
+
continue;
|
|
373
|
+
try {
|
|
374
|
+
await shutdown(entry);
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// best-effort; a stuck simulator shouldn't fail the run's teardown
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
registry.clear();
|
|
381
|
+
}
|
|
382
|
+
// --- Real effects (c8-ignored: exercised on the macOS fixture legs and dev
|
|
383
|
+
// boxes, not the unit suite, which injects all of these). ---
|
|
384
|
+
/* c8 ignore start */
|
|
385
|
+
function runSimctl(args, timeout = 60000) {
|
|
386
|
+
return new Promise((resolve) => {
|
|
387
|
+
execFile("xcrun", ["simctl", ...args], { timeout, maxBuffer: 32 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
388
|
+
resolve({
|
|
389
|
+
// A timeout or spawn error sets no numeric `code` (it's null) — treat
|
|
390
|
+
// that as a failure, not success, so a hung `simctl` doesn't look like
|
|
391
|
+
// an empty-but-ok result to the boot/create callers.
|
|
392
|
+
code: error ? (typeof error.code === "number" ? error.code : 1) : 0,
|
|
393
|
+
stdout: String(stdout ?? ""),
|
|
394
|
+
stderr: String(stderr ?? ""),
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
// Boot a simulator and block until it finishes booting. `simctl boot` returns
|
|
400
|
+
// immediately; `simctl bootstatus -b` waits for the boot to complete (and is a
|
|
401
|
+
// no-op if it's already booted).
|
|
402
|
+
async function realBootSimulator(udid, timeout = 300000) {
|
|
403
|
+
const boot = await runSimctl(["boot", udid], 60000);
|
|
404
|
+
// "Unable to boot device in current state: Booted" is fine — already booted.
|
|
405
|
+
if (boot.code !== 0 && !/current state: Booted/i.test(boot.stderr)) {
|
|
406
|
+
throw new Error(`simctl boot ${udid} failed (code ${boot.code}): ${boot.stderr.trim()}`);
|
|
407
|
+
}
|
|
408
|
+
// `bootstatus -b` waits for the boot to finish, but it's a best-effort
|
|
409
|
+
// readiness optimization, NOT a gate: a cold simulator can take longer than
|
|
410
|
+
// this to settle, and the XCUITest driver waits for the device during session
|
|
411
|
+
// creation regardless (appium:wdaLaunchTimeout). So a bootstatus timeout or
|
|
412
|
+
// error is not fatal — proceed and let the driver do the final wait.
|
|
413
|
+
await runSimctl(["bootstatus", udid, "-b"], timeout);
|
|
414
|
+
}
|
|
415
|
+
async function realCreateSimulator({ name, deviceTypeId, runtimeId, }) {
|
|
416
|
+
const created = await runSimctl(["create", name, deviceTypeId, runtimeId]);
|
|
417
|
+
if (created.code !== 0) {
|
|
418
|
+
throw new Error(`simctl create "${name}" failed (code ${created.code}): ${created.stderr.trim()}`);
|
|
419
|
+
}
|
|
420
|
+
const udid = created.stdout.trim().split(/\r?\n/).pop()?.trim() ?? "";
|
|
421
|
+
if (!udid) {
|
|
422
|
+
throw new Error(`simctl create "${name}" returned no udid.`);
|
|
423
|
+
}
|
|
424
|
+
return { udid };
|
|
425
|
+
}
|
|
426
|
+
async function realShutdownSimulator(udid) {
|
|
427
|
+
await runSimctl(["shutdown", udid], 30000);
|
|
428
|
+
}
|
|
429
|
+
// Assemble the injected effect bundle for acquireSimulator, plus the `shutdown`
|
|
430
|
+
// effect the run-end teardown sweep uses. runContext calls this; unit tests
|
|
431
|
+
// pass their own bundle instead. Mirrors androidEmulator.buildAcquireDeviceDeps.
|
|
432
|
+
function buildAcquireSimulatorDeps(log) {
|
|
433
|
+
return {
|
|
434
|
+
listDevices: async () => {
|
|
435
|
+
const { stdout } = await runSimctl(["list", "devices", "--json"], 60000);
|
|
436
|
+
return parseSimctlDevices(stdout);
|
|
437
|
+
},
|
|
438
|
+
listRuntimes: async () => {
|
|
439
|
+
const { stdout } = await runSimctl(["list", "runtimes", "--json"], 60000);
|
|
440
|
+
return parseSimctlRuntimes(stdout);
|
|
441
|
+
},
|
|
442
|
+
listDeviceTypes: async () => {
|
|
443
|
+
const { stdout } = await runSimctl(["list", "devicetypes", "--json"], 60000);
|
|
444
|
+
return parseSimctlDeviceTypes(stdout);
|
|
445
|
+
},
|
|
446
|
+
create: realCreateSimulator,
|
|
447
|
+
boot: realBootSimulator,
|
|
448
|
+
shutdown: (entry) => realShutdownSimulator(entry.udid),
|
|
449
|
+
log,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
/* c8 ignore stop */
|
|
453
|
+
//# sourceMappingURL=iosSimulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iosSimulator.js","sourceRoot":"","sources":["../../../src/core/tests/iosSimulator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { normalizeDeviceDescriptor };
|
|
2
|
+
export type { DeviceDescriptor };
|
|
3
|
+
interface DeviceDescriptor {
|
|
4
|
+
name?: string;
|
|
5
|
+
deviceType?: string;
|
|
6
|
+
osVersion?: string;
|
|
7
|
+
headless?: boolean;
|
|
8
|
+
platform?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function normalizeDeviceDescriptor({ contextDevice, stepDevice, platform, }: {
|
|
11
|
+
contextDevice?: DeviceDescriptor | string;
|
|
12
|
+
stepDevice?: DeviceDescriptor | string;
|
|
13
|
+
platform?: string;
|
|
14
|
+
}): DeviceDescriptor;
|
|
15
|
+
//# sourceMappingURL=mobileDevice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobileDevice.d.ts","sourceRoot":"","sources":["../../../src/core/tests/mobileDevice.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,CAAC;AACrC,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,iBAAS,yBAAyB,CAAC,EACjC,aAAa,EACb,UAAU,EACV,QAAQ,GACT,EAAE;IACD,aAAa,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IAC1C,UAAU,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,gBAAgB,CAYnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Native app surfaces: the shared mobile-device descriptor, used by both the
|
|
2
|
+
// Android emulator layer (androidEmulator.ts) and the iOS simulator layer
|
|
3
|
+
// (iosSimulator.ts). A descriptor names a managed device by identity and
|
|
4
|
+
// refines how it is created; the per-platform acquisition modules turn it into
|
|
5
|
+
// a booted emulator/simulator. Kept pure so it's unit-testable without either
|
|
6
|
+
// toolchain.
|
|
7
|
+
export { normalizeDeviceDescriptor };
|
|
8
|
+
// Normalize a context default device merged with a step-level device override.
|
|
9
|
+
// A string is shorthand for `{ name }`. The step wins field-by-field; platform
|
|
10
|
+
// comes from whichever supplies it (the mobile context, normally).
|
|
11
|
+
function normalizeDeviceDescriptor({ contextDevice, stepDevice, platform, }) {
|
|
12
|
+
const asObj = (d) => typeof d === "string" ? { name: d.trim() } : d ? { ...d } : {};
|
|
13
|
+
const ctx = asObj(contextDevice);
|
|
14
|
+
const step = asObj(stepDevice);
|
|
15
|
+
const merged = { ...ctx, ...step };
|
|
16
|
+
// Drop undefined step keys so they don't clobber context values.
|
|
17
|
+
for (const k of Object.keys(step)) {
|
|
18
|
+
if (step[k] === undefined && ctx[k] !== undefined)
|
|
19
|
+
merged[k] = ctx[k];
|
|
20
|
+
}
|
|
21
|
+
merged.platform = step.platform ?? ctx.platform ?? platform;
|
|
22
|
+
return merged;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=mobileDevice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobileDevice.js","sourceRoot":"","sources":["../../../src/core/tests/mobileDevice.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,+EAA+E;AAC/E,8EAA8E;AAC9E,aAAa;AAEb,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAWrC,+EAA+E;AAC/E,+EAA+E;AAC/E,mEAAmE;AACnE,SAAS,yBAAyB,CAAC,EACjC,aAAa,EACb,UAAU,EACV,QAAQ,GAKT;IACC,MAAM,KAAK,GAAG,CAAC,CAA6B,EAAoB,EAAE,CAChE,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAqB,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;IACrD,iEAAiE;IACjE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAA+B,EAAE,CAAC;QAChE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS;YAAG,MAAc,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC5D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export { isMobileTargetPlatform, mobileContextSkipReason };
|
|
2
2
|
type MobileTarget = "android" | "ios";
|
|
3
3
|
declare function isMobileTargetPlatform(platform: unknown): MobileTarget | null;
|
|
4
|
-
declare function mobileContextSkipReason({ platform,
|
|
4
|
+
declare function mobileContextSkipReason({ platform, }: {
|
|
5
5
|
platform: MobileTarget;
|
|
6
|
-
hasBrowserStep?: boolean;
|
|
7
6
|
}): {
|
|
8
7
|
level: "warning" | "info";
|
|
9
8
|
reason: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobilePlatform.d.ts","sourceRoot":"","sources":["../../../src/core/tests/mobilePlatform.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,CAAC;AAE3D,KAAK,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAGtC,iBAAS,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAGtE;
|
|
1
|
+
{"version":3,"file":"mobilePlatform.d.ts","sourceRoot":"","sources":["../../../src/core/tests/mobilePlatform.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,CAAC;AAE3D,KAAK,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAGtC,iBAAS,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAGtE;AASD,iBAAS,uBAAuB,CAAC,EAC/B,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,YAAY,CAAC;CACxB,GAAG;IAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAahD"}
|