@houwert/conductor 0.9.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.
@@ -35,6 +35,7 @@ exports.uninstallDriver = uninstallDriver;
35
35
  const child_process_1 = require("child_process");
36
36
  const crypto_1 = __importDefault(require("crypto"));
37
37
  const http_1 = __importDefault(require("http"));
38
+ const https_1 = __importDefault(require("https"));
38
39
  const net_1 = __importDefault(require("net"));
39
40
  const os_1 = __importDefault(require("os"));
40
41
  const fs_1 = __importDefault(require("fs"));
@@ -161,40 +162,195 @@ async function getDriverPort(platform, deviceId) {
161
162
  return port;
162
163
  });
163
164
  }
164
- // ── Bundled driver paths ───────────────────────────────────────────────────────
165
+ // ── Driver paths (bundled dev fallback + runtime download cache) ──────────────
165
166
  /**
166
- * Root of the bundled drivers directory (packages/cli/drivers/).
167
- *
168
167
  * Walk up from __dirname to find the package root (the directory containing
169
- * package.json). This handles both the normal build (dist/drivers/bootstrap.js)
170
- * and the test build (dist-tests/src/drivers/bootstrap.js) where __dirname has
171
- * an extra src/ level, making a fixed relative path incorrect.
168
+ * package.json). Handles both the normal build (dist/drivers/bootstrap.js)
169
+ * and the test build (dist-tests/src/drivers/bootstrap.js) where __dirname
170
+ * has an extra src/ level.
172
171
  */
173
- function findBundledDriversDir() {
172
+ function findPackageRoot() {
174
173
  let dir = __dirname;
175
174
  while (true) {
176
175
  if (fs_1.default.existsSync(path_1.default.join(dir, 'package.json'))) {
177
- return path_1.default.join(dir, 'drivers');
176
+ return dir;
178
177
  }
179
178
  const parent = path_1.default.dirname(dir);
180
179
  if (parent === dir)
181
180
  break;
182
181
  dir = parent;
183
182
  }
184
- // Fallback to original relative path
185
- return path_1.default.join(__dirname, '..', '..', 'drivers');
183
+ return path_1.default.join(__dirname, '..', '..');
184
+ }
185
+ const DRIVERS_CACHE_ROOT = path_1.default.join(os_1.default.homedir(), '.conductor', 'drivers');
186
+ const DRIVERS_DOWNLOAD_BASE = 'https://github.com/DouweBos/conductor/releases/download';
187
+ const DRIVERS_LOCK_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes (download can be slow)
188
+ const DRIVERS_LOCK_POLL_MS = 500;
189
+ let _driversDirPromise = null;
190
+ /**
191
+ * Resolve the directory containing the platform driver artifacts
192
+ * (`<dir>/{android,ios,tvos}/...`).
193
+ *
194
+ * Lookup order:
195
+ * 1. Legacy bundled drivers at `<pkg-root>/drivers/` — populated by
196
+ * `make build` for local development.
197
+ * 2. Runtime cache at `~/.conductor/drivers/<version>/` — downloaded
198
+ * on first use from the matching GitHub Release.
199
+ */
200
+ async function getDriversDir() {
201
+ if (_driversDirPromise)
202
+ return _driversDirPromise;
203
+ _driversDirPromise = (async () => {
204
+ const pkgRoot = findPackageRoot();
205
+ const legacyDir = path_1.default.join(pkgRoot, 'drivers');
206
+ if (fs_1.default.existsSync(legacyDir))
207
+ return legacyDir;
208
+ return await ensureDriversCache(pkgRoot);
209
+ })().catch((err) => {
210
+ _driversDirPromise = null;
211
+ throw err;
212
+ });
213
+ return _driversDirPromise;
214
+ }
215
+ async function ensureDriversCache(pkgRoot) {
216
+ const pkgJsonPath = path_1.default.join(pkgRoot, 'package.json');
217
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, 'utf-8'));
218
+ const version = pkg.version;
219
+ const cacheDir = path_1.default.join(DRIVERS_CACHE_ROOT, version);
220
+ const completeMarker = path_1.default.join(cacheDir, '.complete');
221
+ if (fs_1.default.existsSync(completeMarker))
222
+ return cacheDir;
223
+ fs_1.default.mkdirSync(DRIVERS_CACHE_ROOT, { recursive: true });
224
+ const lockFile = path_1.default.join(DRIVERS_CACHE_ROOT, `${version}.lock`);
225
+ await acquireDriversLock(lockFile);
226
+ try {
227
+ // Re-check after acquiring lock — another process may have finished.
228
+ if (fs_1.default.existsSync(completeMarker))
229
+ return cacheDir;
230
+ const tmpDir = path_1.default.join(DRIVERS_CACHE_ROOT, `.tmp-${version}-${process.pid}-${Date.now()}`);
231
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
232
+ fs_1.default.mkdirSync(tmpDir, { recursive: true });
233
+ const tarball = path_1.default.join(tmpDir, 'drivers.tar.gz');
234
+ const url = `${DRIVERS_DOWNLOAD_BASE}/v${version}/drivers.tar.gz`;
235
+ (0, verbose_js_1.log)(`Downloading conductor drivers v${version} from ${url}...`);
236
+ try {
237
+ await downloadToFile(url, tarball);
238
+ (0, child_process_1.execFileSync)('tar', ['-xzf', tarball, '-C', tmpDir], { stdio: 'ignore' });
239
+ fs_1.default.unlinkSync(tarball);
240
+ if (fs_1.default.existsSync(cacheDir)) {
241
+ fs_1.default.rmSync(cacheDir, { recursive: true, force: true });
242
+ }
243
+ fs_1.default.renameSync(tmpDir, cacheDir);
244
+ fs_1.default.writeFileSync(completeMarker, version);
245
+ (0, verbose_js_1.log)(`Conductor drivers v${version} ready at ${cacheDir}`);
246
+ pruneOldDriverCaches(version);
247
+ return cacheDir;
248
+ }
249
+ catch (err) {
250
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
251
+ throw new Error(`Failed to download conductor drivers v${version} from ${url}: ${err.message}`);
252
+ }
253
+ }
254
+ finally {
255
+ try {
256
+ fs_1.default.unlinkSync(lockFile);
257
+ }
258
+ catch {
259
+ /* ok */
260
+ }
261
+ }
262
+ }
263
+ /**
264
+ * Remove cached driver versions other than the current one. Old CLI builds
265
+ * would just re-download on demand, so there's no reason to keep them.
266
+ * Errors are swallowed — pruning is best-effort and must never block startup.
267
+ */
268
+ function pruneOldDriverCaches(currentVersion) {
269
+ try {
270
+ for (const entry of fs_1.default.readdirSync(DRIVERS_CACHE_ROOT, { withFileTypes: true })) {
271
+ if (!entry.isDirectory())
272
+ continue;
273
+ if (entry.name === currentVersion)
274
+ continue;
275
+ if (entry.name.startsWith('.tmp-'))
276
+ continue; // active concurrent extraction
277
+ const stale = path_1.default.join(DRIVERS_CACHE_ROOT, entry.name);
278
+ try {
279
+ fs_1.default.rmSync(stale, { recursive: true, force: true });
280
+ (0, verbose_js_1.log)(`Pruned stale driver cache ${stale}`);
281
+ }
282
+ catch {
283
+ /* ok — another process may be using it */
284
+ }
285
+ }
286
+ }
287
+ catch {
288
+ /* ok */
289
+ }
290
+ }
291
+ async function acquireDriversLock(lockFile) {
292
+ const deadline = Date.now() + DRIVERS_LOCK_TIMEOUT_MS;
293
+ while (Date.now() < deadline) {
294
+ try {
295
+ const fd = fs_1.default.openSync(lockFile, 'wx');
296
+ fs_1.default.closeSync(fd);
297
+ return;
298
+ }
299
+ catch {
300
+ await (0, utils_js_1.sleep)(DRIVERS_LOCK_POLL_MS);
301
+ }
302
+ }
303
+ throw new Error(`Could not acquire drivers cache lock (${lockFile})`);
304
+ }
305
+ function downloadToFile(url, dest, maxRedirects = 5) {
306
+ return new Promise((resolve, reject) => {
307
+ const fetch = (u, remaining) => {
308
+ const req = https_1.default.get(u, (res) => {
309
+ const status = res.statusCode ?? 0;
310
+ if ((status === 301 ||
311
+ status === 302 ||
312
+ status === 303 ||
313
+ status === 307 ||
314
+ status === 308) &&
315
+ res.headers.location) {
316
+ res.resume();
317
+ if (remaining <= 0) {
318
+ reject(new Error(`Too many redirects fetching ${url}`));
319
+ return;
320
+ }
321
+ const next = new URL(res.headers.location, u).toString();
322
+ fetch(next, remaining - 1);
323
+ return;
324
+ }
325
+ if (status !== 200) {
326
+ res.resume();
327
+ reject(new Error(`HTTP ${status} for ${u}`));
328
+ return;
329
+ }
330
+ const file = fs_1.default.createWriteStream(dest);
331
+ res.pipe(file);
332
+ file.on('finish', () => file.close((err) => (err ? reject(err) : resolve())));
333
+ file.on('error', (err) => {
334
+ fs_1.default.rmSync(dest, { force: true });
335
+ reject(err);
336
+ });
337
+ });
338
+ req.on('error', reject);
339
+ };
340
+ fetch(url, maxRedirects);
341
+ });
186
342
  }
187
- const BUNDLED_DRIVERS_DIR = findBundledDriversDir();
188
343
  /**
189
344
  * Install the Conductor Android driver APKs on the device.
190
345
  * Reads pre-built APKs directly from the bundled drivers directory.
191
346
  */
192
347
  async function installDriver(deviceId) {
193
348
  (0, verbose_js_1.log)(`installDriver: installing Android driver on ${deviceId}`);
194
- const appApk = path_1.default.join(BUNDLED_DRIVERS_DIR, 'android', 'conductor-app.apk');
195
- const serverApk = path_1.default.join(BUNDLED_DRIVERS_DIR, 'android', 'conductor-server.apk');
349
+ const driversDir = await getDriversDir();
350
+ const appApk = path_1.default.join(driversDir, 'android', 'conductor-app.apk');
351
+ const serverApk = path_1.default.join(driversDir, 'android', 'conductor-server.apk');
196
352
  if (!fs_1.default.existsSync(appApk) || !fs_1.default.existsSync(serverApk)) {
197
- throw new Error(`Conductor driver APKs not found at ${path_1.default.join(BUNDLED_DRIVERS_DIR, 'android')}.\n` +
353
+ throw new Error(`Conductor driver APKs not found at ${path_1.default.join(driversDir, 'android')}.\n` +
198
354
  `Run 'make package-cli' from the repo root to build and bundle the drivers.`);
199
355
  }
200
356
  await spawnAndWait('adb', ['-s', deviceId, 'install', '-r', '-t', '-g', appApk]);
@@ -214,13 +370,14 @@ const IOS_DRIVER_CACHE = path_1.default.join(os_1.default.homedir(), '.conductor
214
370
  * dir. Re-extracts only when the bundled xctestrun has changed (tracked by mtime).
215
371
  */
216
372
  async function setupIOSDriverCache() {
217
- const bundledXctestrun = path_1.default.join(BUNDLED_DRIVERS_DIR, 'ios', 'conductor-driver-ios-config.xctestrun');
218
- const bundledDriverZip = path_1.default.join(BUNDLED_DRIVERS_DIR, 'ios', 'conductor-driver-ios.zip');
219
- const bundledRunnerZip = path_1.default.join(BUNDLED_DRIVERS_DIR, 'ios', 'conductor-driver-iosUITests-Runner.zip');
373
+ const driversDir = await getDriversDir();
374
+ const bundledXctestrun = path_1.default.join(driversDir, 'ios', 'conductor-driver-ios-config.xctestrun');
375
+ const bundledDriverZip = path_1.default.join(driversDir, 'ios', 'conductor-driver-ios.zip');
376
+ const bundledRunnerZip = path_1.default.join(driversDir, 'ios', 'conductor-driver-iosUITests-Runner.zip');
220
377
  if (!fs_1.default.existsSync(bundledXctestrun) ||
221
378
  !fs_1.default.existsSync(bundledDriverZip) ||
222
379
  !fs_1.default.existsSync(bundledRunnerZip)) {
223
- throw new Error(`Conductor iOS driver files not found at ${path_1.default.join(BUNDLED_DRIVERS_DIR, 'ios')}.\n` +
380
+ throw new Error(`Conductor iOS driver files not found at ${path_1.default.join(driversDir, 'ios')}.\n` +
224
381
  `Run 'make package-cli' from the repo root to build and bundle the drivers.`);
225
382
  }
226
383
  const versionFile = path_1.default.join(IOS_DRIVER_CACHE, '.version');
@@ -335,13 +492,14 @@ const TVOS_DRIVER_CACHE = path_1.default.join(os_1.default.homedir(), '.conducto
335
492
  * dir. Re-extracts only when the bundled xctestrun has changed (tracked by mtime).
336
493
  */
337
494
  async function setupTvOSDriverCache() {
338
- const bundledXctestrun = path_1.default.join(BUNDLED_DRIVERS_DIR, 'tvos', 'conductor-driver-tvos-config.xctestrun');
339
- const bundledDriverZip = path_1.default.join(BUNDLED_DRIVERS_DIR, 'tvos', 'conductor-driver-tvos.zip');
340
- const bundledRunnerZip = path_1.default.join(BUNDLED_DRIVERS_DIR, 'tvos', 'conductor-driver-tvosUITests-Runner.zip');
495
+ const driversDir = await getDriversDir();
496
+ const bundledXctestrun = path_1.default.join(driversDir, 'tvos', 'conductor-driver-tvos-config.xctestrun');
497
+ const bundledDriverZip = path_1.default.join(driversDir, 'tvos', 'conductor-driver-tvos.zip');
498
+ const bundledRunnerZip = path_1.default.join(driversDir, 'tvos', 'conductor-driver-tvosUITests-Runner.zip');
341
499
  if (!fs_1.default.existsSync(bundledXctestrun) ||
342
500
  !fs_1.default.existsSync(bundledDriverZip) ||
343
501
  !fs_1.default.existsSync(bundledRunnerZip)) {
344
- throw new Error(`Conductor tvOS driver files not found at ${path_1.default.join(BUNDLED_DRIVERS_DIR, 'tvos')}.\n` +
502
+ throw new Error(`Conductor tvOS driver files not found at ${path_1.default.join(driversDir, 'tvos')}.\n` +
345
503
  `Run 'make package-cli' from the repo root to build and bundle the drivers.`);
346
504
  }
347
505
  const versionFile = path_1.default.join(TVOS_DRIVER_CACHE, '.version');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@houwert/conductor",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "CLI tool for mobile app interactions — optimized for AI agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,7 +17,6 @@
17
17
  "main": "./dist/index.js",
18
18
  "files": [
19
19
  "dist/",
20
- "drivers/",
21
20
  "skills/",
22
21
  "proto/",
23
22
  ".claude-plugin/"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: conductor
3
- version: 0.9.0
3
+ version: 0.10.0
4
4
  description: "Token-efficient CLI for mobile UI testing (iOS simulator + Android emulator), designed for AI agents"
5
5
  metadata.openclaw:
6
6
  category: service
@@ -3,6 +3,6 @@ skills:
3
3
  path: conductor/SKILL.md
4
4
  description: "Token-efficient CLI for mobile UI testing, designed for AI agents"
5
5
  category: service
6
- version: 0.9.0
6
+ version: 0.10.0
7
7
  requires:
8
8
  bins: [conductor]
Binary file
@@ -1,126 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>__xctestrun_metadata__</key>
6
- <dict>
7
- <key>ContainerInfo</key>
8
- <dict>
9
- <key>ContainerName</key>
10
- <string>conductor-driver-ios</string>
11
- <key>SchemeName</key>
12
- <string>conductor-driver-ios</string>
13
- </dict>
14
- <key>FormatVersion</key>
15
- <integer>1</integer>
16
- </dict>
17
- <key>conductor-driver-iosUITests</key>
18
- <dict>
19
- <key>BlueprintName</key>
20
- <string>conductor-driver-iosUITests</string>
21
- <key>BlueprintProviderName</key>
22
- <string>conductor-driver-ios</string>
23
- <key>BlueprintProviderRelativePath</key>
24
- <string>conductor-driver-ios.xcodeproj</string>
25
- <key>BundleIdentifiersForCrashReportEmphasis</key>
26
- <array>
27
- <string>dev.houwert.ConductorDriverLib</string>
28
- <string>dev.houwert.conductor-driver-ios</string>
29
- <string>dev.houwert.conductor-driver-iosUITests</string>
30
- </array>
31
- <key>CommandLineArguments</key>
32
- <array/>
33
- <key>DefaultTestExecutionTimeAllowance</key>
34
- <integer>600</integer>
35
- <key>DependentProductPaths</key>
36
- <array>
37
- <string>__TESTROOT__/Debug-iphonesimulator/ConductorDriverLib.framework</string>
38
- <string>__TESTROOT__/Debug-iphonesimulator/conductor-driver-ios.app</string>
39
- <string>__TESTROOT__/Debug-iphonesimulator/conductor-driver-iosUITests-Runner.app</string>
40
- <string>__TESTROOT__/Debug-iphonesimulator/conductor-driver-iosUITests-Runner.app/PlugIns/conductor-driver-iosUITests.xctest</string>
41
- </array>
42
- <key>DiagnosticCollectionPolicy</key>
43
- <integer>1</integer>
44
- <key>EnvironmentVariables</key>
45
- <dict>
46
- <key>APP_DISTRIBUTOR_ID_OVERRIDE</key>
47
- <string>com.apple.AppStore</string>
48
- <key>OS_ACTIVITY_DT_MODE</key>
49
- <string>YES</string>
50
- <key>SQLITE_ENABLE_THREAD_ASSERTIONS</key>
51
- <string>1</string>
52
- <key>TERM</key>
53
- <string>dumb</string>
54
- </dict>
55
- <key>IsUITestBundle</key>
56
- <true/>
57
- <key>IsXCTRunnerHostedTestBundle</key>
58
- <true/>
59
- <key>PreferredScreenCaptureFormat</key>
60
- <string>screenRecording</string>
61
- <key>ProductModuleName</key>
62
- <string>conductor_driver_iosUITests</string>
63
- <key>RunOrder</key>
64
- <integer>0</integer>
65
- <key>SkipTestIdentifiers</key>
66
- <array>
67
- <string>ViewHierarchyHandlerTests</string>
68
- <string>ViewHierarchyHandlerTests/testViewHierarchyHandlerReturnsNonEmptyHierarchy()</string>
69
- </array>
70
- <key>SystemAttachmentLifetime</key>
71
- <string>deleteOnSuccess</string>
72
- <key>TestBundlePath</key>
73
- <string>__TESTHOST__/PlugIns/conductor-driver-iosUITests.xctest</string>
74
- <key>TestHostBundleIdentifier</key>
75
- <string>dev.houwert.conductor-driver-iosUITests.xctrunner</string>
76
- <key>TestHostPath</key>
77
- <string>__TESTROOT__/Debug-iphonesimulator/conductor-driver-iosUITests-Runner.app</string>
78
- <key>TestLanguage</key>
79
- <string></string>
80
- <key>TestRegion</key>
81
- <string></string>
82
- <key>TestTimeoutsEnabled</key>
83
- <false/>
84
- <key>TestingEnvironmentVariables</key>
85
- <dict>
86
- <key>DYLD_FRAMEWORK_PATH</key>
87
- <string>__TESTROOT__/Debug-iphonesimulator:__TESTROOT__/Debug-iphonesimulator/PackageFrameworks:__PLATFORMS__/iPhoneSimulator.platform/Developer/Library/Frameworks</string>
88
- <key>DYLD_LIBRARY_PATH</key>
89
- <string>__TESTROOT__/Debug-iphonesimulator:__PLATFORMS__/iPhoneSimulator.platform/Developer/usr/lib</string>
90
- <key>XCODE_SCHEME_NAME</key>
91
- <string>conductor-driver-ios</string>
92
- <key>__XCODE_BUILT_PRODUCTS_DIR_PATHS</key>
93
- <string>__TESTROOT__/Debug-iphonesimulator</string>
94
- <key>__XPC_DYLD_FRAMEWORK_PATH</key>
95
- <string>__TESTROOT__/Debug-iphonesimulator</string>
96
- <key>__XPC_DYLD_LIBRARY_PATH</key>
97
- <string>__TESTROOT__/Debug-iphonesimulator</string>
98
- </dict>
99
- <key>ToolchainsSettingValue</key>
100
- <array/>
101
- <key>UITargetAppCommandLineArguments</key>
102
- <array/>
103
- <key>UITargetAppEnvironmentVariables</key>
104
- <dict>
105
- <key>APP_DISTRIBUTOR_ID_OVERRIDE</key>
106
- <string>com.apple.AppStore</string>
107
- <key>DYLD_FRAMEWORK_PATH</key>
108
- <string>__TESTROOT__/Debug-iphonesimulator:__TESTROOT__/Debug-iphonesimulator/PackageFrameworks</string>
109
- <key>DYLD_LIBRARY_PATH</key>
110
- <string>__TESTROOT__/Debug-iphonesimulator</string>
111
- <key>XCODE_SCHEME_NAME</key>
112
- <string>conductor-driver-ios</string>
113
- <key>__XCODE_BUILT_PRODUCTS_DIR_PATHS</key>
114
- <string>__TESTROOT__/Debug-iphonesimulator</string>
115
- <key>__XPC_DYLD_FRAMEWORK_PATH</key>
116
- <string>__TESTROOT__/Debug-iphonesimulator</string>
117
- <key>__XPC_DYLD_LIBRARY_PATH</key>
118
- <string>__TESTROOT__/Debug-iphonesimulator</string>
119
- </dict>
120
- <key>UITargetAppPath</key>
121
- <string>__TESTROOT__/Debug-iphonesimulator/conductor-driver-ios.app</string>
122
- <key>UserAttachmentLifetime</key>
123
- <string>deleteOnSuccess</string>
124
- </dict>
125
- </dict>
126
- </plist>
@@ -1,121 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>__xctestrun_metadata__</key>
6
- <dict>
7
- <key>ContainerInfo</key>
8
- <dict>
9
- <key>ContainerName</key>
10
- <string>conductor-driver-ios</string>
11
- <key>SchemeName</key>
12
- <string>conductor-driver-tvos</string>
13
- </dict>
14
- <key>FormatVersion</key>
15
- <integer>1</integer>
16
- </dict>
17
- <key>conductor-driver-tvosUITests</key>
18
- <dict>
19
- <key>BlueprintName</key>
20
- <string>conductor-driver-tvosUITests</string>
21
- <key>BlueprintProviderName</key>
22
- <string>conductor-driver-ios</string>
23
- <key>BlueprintProviderRelativePath</key>
24
- <string>conductor-driver-ios.xcodeproj</string>
25
- <key>BundleIdentifiersForCrashReportEmphasis</key>
26
- <array>
27
- <string>dev.houwert.ConductorDriverLib</string>
28
- <string>dev.houwert.conductor-driver-tvos</string>
29
- <string>dev.houwert.conductor-driver-tvosUITests</string>
30
- </array>
31
- <key>CommandLineArguments</key>
32
- <array/>
33
- <key>DefaultTestExecutionTimeAllowance</key>
34
- <integer>600</integer>
35
- <key>DependentProductPaths</key>
36
- <array>
37
- <string>__TESTROOT__/Debug-appletvsimulator/ConductorDriverLib.framework</string>
38
- <string>__TESTROOT__/Debug-appletvsimulator/conductor-driver-tvos.app</string>
39
- <string>__TESTROOT__/Debug-appletvsimulator/conductor-driver-tvosUITests-Runner.app</string>
40
- <string>__TESTROOT__/Debug-appletvsimulator/conductor-driver-tvosUITests-Runner.app/PlugIns/conductor-driver-tvosUITests.xctest</string>
41
- </array>
42
- <key>DiagnosticCollectionPolicy</key>
43
- <integer>1</integer>
44
- <key>EnvironmentVariables</key>
45
- <dict>
46
- <key>APP_DISTRIBUTOR_ID_OVERRIDE</key>
47
- <string>com.apple.AppStore</string>
48
- <key>OS_ACTIVITY_DT_MODE</key>
49
- <string>YES</string>
50
- <key>SQLITE_ENABLE_THREAD_ASSERTIONS</key>
51
- <string>1</string>
52
- <key>TERM</key>
53
- <string>dumb</string>
54
- </dict>
55
- <key>IsUITestBundle</key>
56
- <true/>
57
- <key>IsXCTRunnerHostedTestBundle</key>
58
- <true/>
59
- <key>PreferredScreenCaptureFormat</key>
60
- <string>screenRecording</string>
61
- <key>ProductModuleName</key>
62
- <string>conductor_driver_tvosUITests</string>
63
- <key>RunOrder</key>
64
- <integer>0</integer>
65
- <key>SystemAttachmentLifetime</key>
66
- <string>deleteOnSuccess</string>
67
- <key>TestBundlePath</key>
68
- <string>__TESTHOST__/PlugIns/conductor-driver-tvosUITests.xctest</string>
69
- <key>TestHostBundleIdentifier</key>
70
- <string>dev.houwert.conductor-driver-tvosUITests.xctrunner</string>
71
- <key>TestHostPath</key>
72
- <string>__TESTROOT__/Debug-appletvsimulator/conductor-driver-tvosUITests-Runner.app</string>
73
- <key>TestLanguage</key>
74
- <string></string>
75
- <key>TestRegion</key>
76
- <string></string>
77
- <key>TestTimeoutsEnabled</key>
78
- <false/>
79
- <key>TestingEnvironmentVariables</key>
80
- <dict>
81
- <key>DYLD_FRAMEWORK_PATH</key>
82
- <string>__TESTROOT__/Debug-appletvsimulator:__TESTROOT__/Debug-appletvsimulator/PackageFrameworks:__PLATFORMS__/AppleTVSimulator.platform/Developer/Library/Frameworks</string>
83
- <key>DYLD_LIBRARY_PATH</key>
84
- <string>__TESTROOT__/Debug-appletvsimulator:__PLATFORMS__/AppleTVSimulator.platform/Developer/usr/lib</string>
85
- <key>XCODE_SCHEME_NAME</key>
86
- <string>conductor-driver-tvos</string>
87
- <key>__XCODE_BUILT_PRODUCTS_DIR_PATHS</key>
88
- <string>__TESTROOT__/Debug-appletvsimulator</string>
89
- <key>__XPC_DYLD_FRAMEWORK_PATH</key>
90
- <string>__TESTROOT__/Debug-appletvsimulator</string>
91
- <key>__XPC_DYLD_LIBRARY_PATH</key>
92
- <string>__TESTROOT__/Debug-appletvsimulator</string>
93
- </dict>
94
- <key>ToolchainsSettingValue</key>
95
- <array/>
96
- <key>UITargetAppCommandLineArguments</key>
97
- <array/>
98
- <key>UITargetAppEnvironmentVariables</key>
99
- <dict>
100
- <key>APP_DISTRIBUTOR_ID_OVERRIDE</key>
101
- <string>com.apple.AppStore</string>
102
- <key>DYLD_FRAMEWORK_PATH</key>
103
- <string>__TESTROOT__/Debug-appletvsimulator:__TESTROOT__/Debug-appletvsimulator/PackageFrameworks</string>
104
- <key>DYLD_LIBRARY_PATH</key>
105
- <string>__TESTROOT__/Debug-appletvsimulator</string>
106
- <key>XCODE_SCHEME_NAME</key>
107
- <string>conductor-driver-tvos</string>
108
- <key>__XCODE_BUILT_PRODUCTS_DIR_PATHS</key>
109
- <string>__TESTROOT__/Debug-appletvsimulator</string>
110
- <key>__XPC_DYLD_FRAMEWORK_PATH</key>
111
- <string>__TESTROOT__/Debug-appletvsimulator</string>
112
- <key>__XPC_DYLD_LIBRARY_PATH</key>
113
- <string>__TESTROOT__/Debug-appletvsimulator</string>
114
- </dict>
115
- <key>UITargetAppPath</key>
116
- <string>__TESTROOT__/Debug-appletvsimulator/conductor-driver-tvos.app</string>
117
- <key>UserAttachmentLifetime</key>
118
- <string>deleteOnSuccess</string>
119
- </dict>
120
- </dict>
121
- </plist>