@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/dist/index.mjs CHANGED
@@ -202,9 +202,10 @@ function planAndroid(input) {
202
202
  }
203
203
  }
204
204
  });
205
- const launchCommand = launchCommandFor(android, serial);
206
- push(launchStep("android.launch-1", android, serial));
207
- push(hermesStep("android.hermes-1", android, metro, resolved, hermesDeviceName, launchCommand));
205
+ const launch1Command = launchCommandFor(android, resolved, serial, { forceStopBefore: true });
206
+ const launch2Command = launchCommandFor(android, resolved, serial, { forceStopBefore: false });
207
+ push(launchStep("android.launch-1", android, launch1Command));
208
+ push(hermesStep("android.hermes-1", android, metro, resolved, hermesDeviceName, launch1Command));
208
209
  push({
209
210
  id: "android.forward-clean",
210
211
  stage: "companion",
@@ -261,8 +262,8 @@ function planAndroid(input) {
261
262
  }
262
263
  }
263
264
  });
264
- push(launchStep("android.launch-2", android, serial));
265
- push(hermesStep("android.hermes-2", android, metro, resolved, hermesDeviceName, launchCommand));
265
+ push(launchStep("android.launch-2", android, launch2Command));
266
+ push(hermesStep("android.hermes-2", android, metro, resolved, hermesDeviceName, launch2Command));
266
267
  const cleanup = [
267
268
  {
268
269
  type: "kill-process",
@@ -317,22 +318,34 @@ function planAndroid(input) {
317
318
  playwright: playwrightCommand(playwright, specs, passthrough)
318
319
  };
319
320
  }
320
- function launchCommandFor(android, serial) {
321
- return adb(serial, [
322
- "shell",
323
- "am",
324
- "start",
325
- "-W",
326
- "-n",
327
- `${android.packageName}/${android.activity}`
328
- ]);
321
+ function launchCommandFor(android, resolved, serial, opts) {
322
+ if (android.launch.kind === "plain") {
323
+ return adb(serial, [
324
+ "shell",
325
+ "am",
326
+ "start",
327
+ "-W",
328
+ "-n",
329
+ `${android.packageName}/${android.activity}`
330
+ ]);
331
+ }
332
+ if (!android.scheme) {
333
+ throw new Error('android.scheme is required when android.launch.kind is "expo-dev-client"');
334
+ }
335
+ const launchScript = `am start -a android.intent.action.VIEW -d ${shellSingleQuote(
336
+ devClientUrl(android.scheme, resolved.initialUrl)
337
+ )}`;
338
+ return adbShellScript(
339
+ serial,
340
+ opts.forceStopBefore ? `am force-stop ${android.packageName} && ${launchScript}` : launchScript
341
+ );
329
342
  }
330
- function launchStep(id, android, serial) {
343
+ function launchStep(id, android, command) {
331
344
  return {
332
345
  id,
333
346
  stage: "app-launch",
334
347
  description: `Launch ${android.packageName}/${android.activity}`,
335
- action: { type: "command", command: launchCommandFor(android, serial) }
348
+ action: { type: "command", command }
336
349
  };
337
350
  }
338
351
  function hermesStep(id, android, metro, resolved, deviceNameMatch, launchCommand) {
@@ -366,6 +379,12 @@ function debugHostXml(host) {
366
379
  function adb(serial, args) {
367
380
  return { command: "adb", args: ["-s", serial, ...args] };
368
381
  }
382
+ function devClientUrl(scheme, initialUrl) {
383
+ return `${scheme}://expo-development-client/?url=${initialUrl}`;
384
+ }
385
+ function shellSingleQuote(value) {
386
+ return `'${value.replaceAll("'", "'\\''")}'`;
387
+ }
369
388
  function adbShellScript(serial, remote) {
370
389
  return { command: "adb", args: ["-s", serial, "shell", remote] };
371
390
  }
@@ -411,8 +430,7 @@ function planIos(input) {
411
430
  // Pass the resolved UI-test scheme so a custom `ios.uitestScheme` scaffolds
412
431
  // the SAME target that companion startup later builds (default is
413
432
  // `${appScheme}UITests`).
414
- command: npx([
415
- "rn-driver-xctest-scaffold",
433
+ command: cmd("node_modules/.bin/rn-driver-xctest-scaffold", [
416
434
  "--ios-dir",
417
435
  "ios",
418
436
  "--project-name",
@@ -706,7 +724,7 @@ function placeholderIos(ios, metro) {
706
724
  initialUrl: ios.launch.initialUrl ?? metro.url
707
725
  };
708
726
  }
709
- function placeholderAndroid(android, _metro) {
727
+ function placeholderAndroid(android, metro) {
710
728
  return {
711
729
  serial: "<android-serial>",
712
730
  touchPort: android.companion?.port ?? DEFAULTS.companionPort,
@@ -714,7 +732,8 @@ function placeholderAndroid(android, _metro) {
714
732
  hermesTimeoutMs: DEFAULTS.hermesTargetTimeoutMs,
715
733
  tokenFile: SECRET_PLACEHOLDER,
716
734
  deviceTokenFileName: DEFAULTS.androidTokenFileName,
717
- instrumentationTarget: instrumentationTarget(android)
735
+ instrumentationTarget: instrumentationTarget(android),
736
+ initialUrl: android.launch.initialUrl ?? metro.url
718
737
  };
719
738
  }
720
739
 
@@ -741,7 +760,7 @@ function buildDryRunPlan(config, platform, opts = {}) {
741
760
  return planAndroid({
742
761
  android,
743
762
  metro,
744
- resolved: placeholderAndroid(android),
763
+ resolved: placeholderAndroid(android, metro),
745
764
  playwright: config.playwright,
746
765
  timeoutMs: config.timeoutMs,
747
766
  specs,
@@ -850,6 +869,7 @@ var IOS_KEYS = /* @__PURE__ */ new Set([
850
869
  var ANDROID_KEYS = /* @__PURE__ */ new Set([
851
870
  "packageName",
852
871
  "activity",
872
+ "scheme",
853
873
  "gradleTasks",
854
874
  "appApkPath",
855
875
  "testApkPath",
@@ -951,6 +971,8 @@ function validateAndroid(android, errors) {
951
971
  reportUnknownKeys("config.android", android, ANDROID_KEYS, errors);
952
972
  requireAndroidPackage("config.android.packageName", android.packageName, errors);
953
973
  requireAndroidActivity("config.android.activity", android.activity, errors);
974
+ if (android.scheme !== void 0)
975
+ requireAppScheme("config.android.scheme", android.scheme, errors);
954
976
  optionalString("config.android.appApkPath", android.appApkPath, errors);
955
977
  optionalString("config.android.testApkPath", android.testApkPath, errors);
956
978
  if (android.instrumentationTarget !== void 0)
@@ -963,7 +985,10 @@ function validateAndroid(android, errors) {
963
985
  errors.push("config.android.gradleTasks: expected an array of strings");
964
986
  }
965
987
  validateCompanion("config.android.companion", android.companion, errors);
966
- validateLaunch("config.android.launch", android.launch, errors);
988
+ const launch = validateLaunch("config.android.launch", android.launch, errors);
989
+ if (launch?.kind === "expo-dev-client" && android.scheme === void 0) {
990
+ errors.push('config.android.scheme: required when android.launch.kind is "expo-dev-client"');
991
+ }
967
992
  }
968
993
  function validateCompanion(path, companion, errors) {
969
994
  if (companion === void 0) return;
@@ -1009,6 +1034,7 @@ function requireString(path, value, errors) {
1009
1034
  }
1010
1035
  var ANDROID_PACKAGE_RE = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)+$/;
1011
1036
  var ANDROID_ACTIVITY_RE = /^\.?[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)*$/;
1037
+ var APP_SCHEME_RE = /^[a-z][a-z0-9+.-]*$/;
1012
1038
  function requireAndroidPackage(path, value, errors) {
1013
1039
  if (typeof value !== "string" || value.trim() === "") {
1014
1040
  errors.push(`${path}: required non-empty string`);
@@ -1025,6 +1051,17 @@ function requireAndroidActivity(path, value, errors) {
1025
1051
  if (!ANDROID_ACTIVITY_RE.test(value))
1026
1052
  errors.push(`${path}: expected an activity name (e.g. .MainActivity)`);
1027
1053
  }
1054
+ function requireAppScheme(path, value, errors) {
1055
+ if (typeof value !== "string" || value.trim() === "") {
1056
+ errors.push(`${path}: required non-empty string`);
1057
+ return;
1058
+ }
1059
+ if (!APP_SCHEME_RE.test(value)) {
1060
+ errors.push(
1061
+ `${path}: expected a valid URL scheme (lowercase letter, then lowercase letters, digits, +, ., or -)`
1062
+ );
1063
+ }
1064
+ }
1028
1065
  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_]*)*$/;
1029
1066
  function requireInstrumentationTarget(path, value, errors) {
1030
1067
  if (typeof value !== "string" || value.trim() === "") {