@unrulysystems/rn-playwright-driver-runner 0.1.0 → 0.1.1
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/CHANGELOG.md +11 -0
- package/README.md +79 -6
- package/bin/rn-driver.mjs +9 -0
- package/dist/cli.js +63 -25
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +63 -25
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +59 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -3
- package/bin/rn-driver.ts +0 -17
package/dist/cli.mjs
CHANGED
|
@@ -209,9 +209,10 @@ function planAndroid(input) {
|
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
});
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
push(
|
|
212
|
+
const launch1Command = launchCommandFor(android, resolved, serial, { forceStopBefore: true });
|
|
213
|
+
const launch2Command = launchCommandFor(android, resolved, serial, { forceStopBefore: false });
|
|
214
|
+
push(launchStep("android.launch-1", android, launch1Command));
|
|
215
|
+
push(hermesStep("android.hermes-1", android, metro, resolved, hermesDeviceName, launch1Command));
|
|
215
216
|
push({
|
|
216
217
|
id: "android.forward-clean",
|
|
217
218
|
stage: "companion",
|
|
@@ -268,8 +269,8 @@ function planAndroid(input) {
|
|
|
268
269
|
}
|
|
269
270
|
}
|
|
270
271
|
});
|
|
271
|
-
push(launchStep("android.launch-2", android,
|
|
272
|
-
push(hermesStep("android.hermes-2", android, metro, resolved, hermesDeviceName,
|
|
272
|
+
push(launchStep("android.launch-2", android, launch2Command));
|
|
273
|
+
push(hermesStep("android.hermes-2", android, metro, resolved, hermesDeviceName, launch2Command));
|
|
273
274
|
const cleanup = [
|
|
274
275
|
{
|
|
275
276
|
type: "kill-process",
|
|
@@ -324,22 +325,34 @@ function planAndroid(input) {
|
|
|
324
325
|
playwright: playwrightCommand(playwright, specs, passthrough)
|
|
325
326
|
};
|
|
326
327
|
}
|
|
327
|
-
function launchCommandFor(android, serial) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
328
|
+
function launchCommandFor(android, resolved, serial, opts) {
|
|
329
|
+
if (android.launch.kind === "plain") {
|
|
330
|
+
return adb(serial, [
|
|
331
|
+
"shell",
|
|
332
|
+
"am",
|
|
333
|
+
"start",
|
|
334
|
+
"-W",
|
|
335
|
+
"-n",
|
|
336
|
+
`${android.packageName}/${android.activity}`
|
|
337
|
+
]);
|
|
338
|
+
}
|
|
339
|
+
if (!android.scheme) {
|
|
340
|
+
throw new Error('android.scheme is required when android.launch.kind is "expo-dev-client"');
|
|
341
|
+
}
|
|
342
|
+
const launchScript = `am start -a android.intent.action.VIEW -d ${shellSingleQuote(
|
|
343
|
+
devClientUrl(android.scheme, resolved.initialUrl)
|
|
344
|
+
)}`;
|
|
345
|
+
return adbShellScript(
|
|
346
|
+
serial,
|
|
347
|
+
opts.forceStopBefore ? `am force-stop ${android.packageName} && ${launchScript}` : launchScript
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
function launchStep(id, android, command) {
|
|
338
351
|
return {
|
|
339
352
|
id,
|
|
340
353
|
stage: "app-launch",
|
|
341
354
|
description: `Launch ${android.packageName}/${android.activity}`,
|
|
342
|
-
action: { type: "command", command
|
|
355
|
+
action: { type: "command", command }
|
|
343
356
|
};
|
|
344
357
|
}
|
|
345
358
|
function hermesStep(id, android, metro, resolved, deviceNameMatch, launchCommand) {
|
|
@@ -373,6 +386,12 @@ function debugHostXml(host) {
|
|
|
373
386
|
function adb(serial, args) {
|
|
374
387
|
return { command: "adb", args: ["-s", serial, ...args] };
|
|
375
388
|
}
|
|
389
|
+
function devClientUrl(scheme, initialUrl) {
|
|
390
|
+
return `${scheme}://expo-development-client/?url=${initialUrl}`;
|
|
391
|
+
}
|
|
392
|
+
function shellSingleQuote(value) {
|
|
393
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
394
|
+
}
|
|
376
395
|
function adbShellScript(serial, remote) {
|
|
377
396
|
return { command: "adb", args: ["-s", serial, "shell", remote] };
|
|
378
397
|
}
|
|
@@ -418,8 +437,7 @@ function planIos(input) {
|
|
|
418
437
|
// Pass the resolved UI-test scheme so a custom `ios.uitestScheme` scaffolds
|
|
419
438
|
// the SAME target that companion startup later builds (default is
|
|
420
439
|
// `${appScheme}UITests`).
|
|
421
|
-
command:
|
|
422
|
-
"rn-driver-xctest-scaffold",
|
|
440
|
+
command: cmd("node_modules/.bin/rn-driver-xctest-scaffold", [
|
|
423
441
|
"--ios-dir",
|
|
424
442
|
"ios",
|
|
425
443
|
"--project-name",
|
|
@@ -713,7 +731,7 @@ function placeholderIos(ios, metro) {
|
|
|
713
731
|
initialUrl: ios.launch.initialUrl ?? metro.url
|
|
714
732
|
};
|
|
715
733
|
}
|
|
716
|
-
function placeholderAndroid(android,
|
|
734
|
+
function placeholderAndroid(android, metro) {
|
|
717
735
|
return {
|
|
718
736
|
serial: "<android-serial>",
|
|
719
737
|
touchPort: android.companion?.port ?? DEFAULTS.companionPort,
|
|
@@ -721,7 +739,8 @@ function placeholderAndroid(android, _metro) {
|
|
|
721
739
|
hermesTimeoutMs: DEFAULTS.hermesTargetTimeoutMs,
|
|
722
740
|
tokenFile: SECRET_PLACEHOLDER,
|
|
723
741
|
deviceTokenFileName: DEFAULTS.androidTokenFileName,
|
|
724
|
-
instrumentationTarget: instrumentationTarget(android)
|
|
742
|
+
instrumentationTarget: instrumentationTarget(android),
|
|
743
|
+
initialUrl: android.launch.initialUrl ?? metro.url
|
|
725
744
|
};
|
|
726
745
|
}
|
|
727
746
|
|
|
@@ -748,7 +767,7 @@ function buildDryRunPlan(config, platform, opts = {}) {
|
|
|
748
767
|
return planAndroid({
|
|
749
768
|
android,
|
|
750
769
|
metro,
|
|
751
|
-
resolved: placeholderAndroid(android),
|
|
770
|
+
resolved: placeholderAndroid(android, metro),
|
|
752
771
|
playwright: config.playwright,
|
|
753
772
|
timeoutMs: config.timeoutMs,
|
|
754
773
|
specs,
|
|
@@ -1288,7 +1307,7 @@ async function resolveIosTarget(ios, metro, opts) {
|
|
|
1288
1307
|
initialUrl: ios.launch.initialUrl ?? metro.url
|
|
1289
1308
|
};
|
|
1290
1309
|
}
|
|
1291
|
-
async function resolveAndroidTarget(android,
|
|
1310
|
+
async function resolveAndroidTarget(android, metro, opts) {
|
|
1292
1311
|
const serial = await selectSerial(opts.device);
|
|
1293
1312
|
await requireBooted(serial);
|
|
1294
1313
|
const deviceName = (await capture("adb", ["-s", serial, "shell", "getprop", "ro.product.model"])).trim();
|
|
@@ -1301,7 +1320,8 @@ async function resolveAndroidTarget(android, _metro, opts) {
|
|
|
1301
1320
|
hermesTimeoutMs: DEFAULTS.hermesTargetTimeoutMs,
|
|
1302
1321
|
tokenFile,
|
|
1303
1322
|
deviceTokenFileName: DEFAULTS.androidTokenFileName,
|
|
1304
|
-
instrumentationTarget: instrumentationTarget(android)
|
|
1323
|
+
instrumentationTarget: instrumentationTarget(android),
|
|
1324
|
+
initialUrl: android.launch.initialUrl ?? metro.url
|
|
1305
1325
|
},
|
|
1306
1326
|
deviceName
|
|
1307
1327
|
};
|
|
@@ -1406,6 +1426,7 @@ var IOS_KEYS = /* @__PURE__ */ new Set([
|
|
|
1406
1426
|
var ANDROID_KEYS = /* @__PURE__ */ new Set([
|
|
1407
1427
|
"packageName",
|
|
1408
1428
|
"activity",
|
|
1429
|
+
"scheme",
|
|
1409
1430
|
"gradleTasks",
|
|
1410
1431
|
"appApkPath",
|
|
1411
1432
|
"testApkPath",
|
|
@@ -1507,6 +1528,8 @@ function validateAndroid(android, errors) {
|
|
|
1507
1528
|
reportUnknownKeys("config.android", android, ANDROID_KEYS, errors);
|
|
1508
1529
|
requireAndroidPackage("config.android.packageName", android.packageName, errors);
|
|
1509
1530
|
requireAndroidActivity("config.android.activity", android.activity, errors);
|
|
1531
|
+
if (android.scheme !== void 0)
|
|
1532
|
+
requireAppScheme("config.android.scheme", android.scheme, errors);
|
|
1510
1533
|
optionalString("config.android.appApkPath", android.appApkPath, errors);
|
|
1511
1534
|
optionalString("config.android.testApkPath", android.testApkPath, errors);
|
|
1512
1535
|
if (android.instrumentationTarget !== void 0)
|
|
@@ -1519,7 +1542,10 @@ function validateAndroid(android, errors) {
|
|
|
1519
1542
|
errors.push("config.android.gradleTasks: expected an array of strings");
|
|
1520
1543
|
}
|
|
1521
1544
|
validateCompanion("config.android.companion", android.companion, errors);
|
|
1522
|
-
validateLaunch("config.android.launch", android.launch, errors);
|
|
1545
|
+
const launch = validateLaunch("config.android.launch", android.launch, errors);
|
|
1546
|
+
if (launch?.kind === "expo-dev-client" && android.scheme === void 0) {
|
|
1547
|
+
errors.push('config.android.scheme: required when android.launch.kind is "expo-dev-client"');
|
|
1548
|
+
}
|
|
1523
1549
|
}
|
|
1524
1550
|
function validateCompanion(path4, companion, errors) {
|
|
1525
1551
|
if (companion === void 0) return;
|
|
@@ -1565,6 +1591,7 @@ function requireString(path4, value, errors) {
|
|
|
1565
1591
|
}
|
|
1566
1592
|
var ANDROID_PACKAGE_RE = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)+$/;
|
|
1567
1593
|
var ANDROID_ACTIVITY_RE = /^\.?[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)*$/;
|
|
1594
|
+
var APP_SCHEME_RE = /^[a-z][a-z0-9+.-]*$/;
|
|
1568
1595
|
function requireAndroidPackage(path4, value, errors) {
|
|
1569
1596
|
if (typeof value !== "string" || value.trim() === "") {
|
|
1570
1597
|
errors.push(`${path4}: required non-empty string`);
|
|
@@ -1581,6 +1608,17 @@ function requireAndroidActivity(path4, value, errors) {
|
|
|
1581
1608
|
if (!ANDROID_ACTIVITY_RE.test(value))
|
|
1582
1609
|
errors.push(`${path4}: expected an activity name (e.g. .MainActivity)`);
|
|
1583
1610
|
}
|
|
1611
|
+
function requireAppScheme(path4, value, errors) {
|
|
1612
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
1613
|
+
errors.push(`${path4}: required non-empty string`);
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
if (!APP_SCHEME_RE.test(value)) {
|
|
1617
|
+
errors.push(
|
|
1618
|
+
`${path4}: expected a valid URL scheme (lowercase letter, then lowercase letters, digits, +, ., or -)`
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1584
1622
|
var ANDROID_INSTRUMENTATION_RE = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)*\/[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)*$/;
|
|
1585
1623
|
function requireInstrumentationTarget(path4, value, errors) {
|
|
1586
1624
|
if (typeof value !== "string" || value.trim() === "") {
|