prowl-tools 0.1.6 → 0.1.7

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.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  DEFAULT_FLAKY_THRESHOLD,
4
+ MACDRIVER_VERSION,
4
5
  analyzeAndroidApp,
5
6
  analyzeIosApp,
6
7
  analyzeMacApp,
@@ -9,12 +10,15 @@ import {
9
10
  assertIosAppAllowed,
10
11
  assertTargetAppAllowed,
11
12
  closeBrowser,
13
+ collectMacdriverStatus,
12
14
  createPlaywrightDriver,
13
15
  generateHunt,
16
+ installMacdriver,
14
17
  launchAndroidSession,
15
18
  launchBrowser,
16
19
  launchIosSession,
17
20
  launchMacSession,
21
+ macdriverReleaseTag,
18
22
  parseBrowserEngine,
19
23
  printCiSummary,
20
24
  rankFlaky,
@@ -22,8 +26,9 @@ import {
22
26
  runHunt,
23
27
  runSuite,
24
28
  saveStorageState,
29
+ tccGuidance,
25
30
  updateBacklogFromSuite
26
- } from "./chunk-5KQR3IR3.js";
31
+ } from "./chunk-R7NUH44M.js";
27
32
  import {
28
33
  CONFIG_DIR,
29
34
  findConfigPath,
@@ -31,17 +36,18 @@ import {
31
36
  loadConfig,
32
37
  loadHuntMeta,
33
38
  loadHuntTags,
39
+ normalizeHuntName,
34
40
  resolveViewport
35
- } from "./chunk-WHAMB4TY.js";
41
+ } from "./chunk-O3OUTZ2P.js";
36
42
 
37
43
  // src/cli/program.ts
38
- import { Command as Command13 } from "commander";
44
+ import { Command as Command14 } from "commander";
39
45
 
40
46
  // package.json
41
47
  var package_default = {
42
48
  name: "prowl-tools",
43
- version: "0.1.6",
44
- description: "CLI-first QA testing tool for deterministic Playwright flows.",
49
+ version: "0.1.7",
50
+ description: "E2E testing for native macOS apps and web apps from declarative YAML hunts.",
45
51
  type: "module",
46
52
  license: "Apache-2.0",
47
53
  author: "Prowl Tools",
@@ -56,9 +62,12 @@ var package_default = {
56
62
  keywords: [
57
63
  "testing",
58
64
  "qa",
65
+ "e2e",
66
+ "macos",
67
+ "desktop-testing",
68
+ "accessibility",
59
69
  "playwright",
60
70
  "yaml",
61
- "e2e",
62
71
  "browser-testing",
63
72
  "automation",
64
73
  "web-testing",
@@ -274,7 +283,11 @@ ${bot}`);
274
283
 
275
284
  // src/cli/commands/run.ts
276
285
  function buildRunCommand() {
277
- const command = new Command("run").argument("<hunt-name>", "Hunt name or path (e.g. homepage or admin/users-crud)").option("--url <target>", "Override target URL").option("--headed", "Show browser window").option("--slow-mo <ms>", "Slow down Playwright actions", (value) => Number(value)).option("--trace", "Capture Playwright trace").option("--browser <engine>", "Browser engine: chromium, firefox, or webkit").option("--channel <name>", "Browser channel: chrome, msedge, chrome-beta, etc.").option("--viewport <size>", "Viewport size: WxH (e.g. 1920x1080) or preset (mobile, tablet, desktop)").option("--include-tags <tags>", "Only run hunts matching these tags (comma-separated)").option("--exclude-tags <tags>", "Skip hunts matching these tags (comma-separated)").option("--junit", "Generate JUnit XML report").option("--config <path>", "Custom config path").option("--json", "Output results as JSON").action(async (huntName, options) => {
286
+ const command = new Command("run").argument(
287
+ "<hunt-name>",
288
+ "Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)"
289
+ ).option("--url <target>", "Override target URL").option("--headed", "Show browser window").option("--slow-mo <ms>", "Slow down Playwright actions", (value) => Number(value)).option("--trace", "Capture Playwright trace").option("--browser <engine>", "Browser engine: chromium, firefox, or webkit").option("--channel <name>", "Browser channel: chrome, msedge, chrome-beta, etc.").option("--viewport <size>", "Viewport size: WxH (e.g. 1920x1080) or preset (mobile, tablet, desktop)").option("--include-tags <tags>", "Only run hunts matching these tags (comma-separated)").option("--exclude-tags <tags>", "Skip hunts matching these tags (comma-separated)").option("--junit", "Generate JUnit XML report").option("--config <path>", "Custom config path").option("--json", "Output results as JSON").action(async (huntArg, options) => {
290
+ const huntName = normalizeHuntName(huntArg);
278
291
  try {
279
292
  if (options.includeTags || options.excludeTags) {
280
293
  const { configDir } = loadConfig(options.config);
@@ -409,7 +422,7 @@ function buildInitCommand() {
409
422
  console.log(welcomeBanner());
410
423
  console.log(chalk4.green(` Initialized ${CONFIG_DIR} directory.`));
411
424
  console.log(chalk4.gray(" Run ") + chalk4.bold("prowl run hello") + chalk4.gray(" to get started."));
412
- console.log(chalk4.gray(" Browse hunt templates at ") + chalk4.cyan("https://hub.prowl.tools") + "\n");
425
+ console.log(chalk4.gray(" See ") + chalk4.cyan(`${CONFIG_DIR}/hunts/login-flow.yml`) + chalk4.gray(" for a fuller example.") + "\n");
413
426
  });
414
427
  return command;
415
428
  }
@@ -546,7 +559,11 @@ function createDebouncer(delayMs, fn) {
546
559
 
547
560
  // src/cli/commands/watch.ts
548
561
  function buildWatchCommand() {
549
- const command = new Command5("watch").argument("<hunt-name>", "Hunt name or path (e.g. homepage or admin/users-crud)").option("--url <target>", "Override target URL").option("--headed", "Show browser window").option("--slow-mo <ms>", "Slow down Playwright actions", (value) => Number(value)).option("--trace", "Capture Playwright trace").option("--config <path>", "Custom config path").action(async (huntName, options) => {
562
+ const command = new Command5("watch").argument(
563
+ "<hunt-name>",
564
+ "Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)"
565
+ ).option("--url <target>", "Override target URL").option("--headed", "Show browser window").option("--slow-mo <ms>", "Slow down Playwright actions", (value) => Number(value)).option("--trace", "Capture Playwright trace").option("--config <path>", "Custom config path").action(async (huntArg, options) => {
566
+ const huntName = normalizeHuntName(huntArg);
550
567
  const { configDir } = loadConfig(options.config);
551
568
  const watchTargets = getWatchTargets(configDir, huntName);
552
569
  let running = false;
@@ -1177,7 +1194,7 @@ function buildGenerateCommand() {
1177
1194
  } else if (options.output) {
1178
1195
  let configDir;
1179
1196
  try {
1180
- const { loadConfig: loadConfig2 } = await import("./loader-PBBYV3U7.js");
1197
+ const { loadConfig: loadConfig2 } = await import("./loader-X37URHUV.js");
1181
1198
  const result = loadConfig2(options.config);
1182
1199
  configDir = result.configDir;
1183
1200
  } catch {
@@ -1211,13 +1228,17 @@ function buildGenerateCommand() {
1211
1228
  import { Command as Command10 } from "commander";
1212
1229
  import chalk12 from "chalk";
1213
1230
  function buildHistoryCommand() {
1214
- const command = new Command10("history").argument("<hunt-name>", "Hunt name or path (e.g. homepage or admin/users-crud)").description("Show run history for a hunt").option("--config <path>", "Custom config path").option("--limit <n>", "Show the last N runs (default: 20)", (value) => {
1231
+ const command = new Command10("history").argument(
1232
+ "<hunt-name>",
1233
+ "Hunt name or path (e.g. homepage, admin/users-crud, or .prowl/hunts/homepage.yml)"
1234
+ ).description("Show run history for a hunt").option("--config <path>", "Custom config path").option("--limit <n>", "Show the last N runs (default: 20)", (value) => {
1215
1235
  const n = Number(value);
1216
1236
  if (!Number.isInteger(n) || n < 1) {
1217
1237
  throw new Error("--limit must be a positive integer");
1218
1238
  }
1219
1239
  return n;
1220
- }).option("--json", "Output as JSON").action((huntName, options) => {
1240
+ }).option("--json", "Output as JSON").action((huntArg, options) => {
1241
+ const huntName = normalizeHuntName(huntArg);
1221
1242
  try {
1222
1243
  const { configDir } = loadConfig(options.config);
1223
1244
  const entries = readHuntHistory(configDir, huntName);
@@ -1605,10 +1626,83 @@ function buildMcpCommand() {
1605
1626
  });
1606
1627
  }
1607
1628
 
1629
+ // src/cli/commands/macdriver.ts
1630
+ import chalk14 from "chalk";
1631
+ import { Command as Command13 } from "commander";
1632
+ function buildInstallCommand() {
1633
+ return new Command13("install").description("Download and install the prebuilt, signed prowl-macdriver helper").option("--force", "Reinstall even if the pinned version is already present").action(async (options) => {
1634
+ try {
1635
+ console.log(
1636
+ chalk14.cyan(
1637
+ `Installing prowl-macdriver ${MACDRIVER_VERSION} (${macdriverReleaseTag(MACDRIVER_VERSION)})\u2026`
1638
+ )
1639
+ );
1640
+ const result = await installMacdriver({ force: options.force });
1641
+ if (result.alreadyInstalled) {
1642
+ console.log(
1643
+ chalk14.green(`Already installed at ${result.binaryPath}`) + chalk14.dim(" (use --force to reinstall)")
1644
+ );
1645
+ } else {
1646
+ console.log(chalk14.green(`Installed prowl-macdriver ${result.version} \u2192 ${result.binaryPath}`));
1647
+ }
1648
+ console.log("");
1649
+ console.log(tccGuidance());
1650
+ } catch (error) {
1651
+ const message = error instanceof Error ? error.message : "Install failed";
1652
+ console.error(chalk14.red(`Error: ${message}`));
1653
+ process.exitCode = 1;
1654
+ }
1655
+ });
1656
+ }
1657
+ function buildStatusCommand() {
1658
+ return new Command13("status").description("Report the resolved prowl-macdriver binary, installed versions, and permissions guidance").action(async () => {
1659
+ try {
1660
+ const status = await collectMacdriverStatus();
1661
+ console.log(chalk14.bold("prowl-macdriver status"));
1662
+ console.log(` pinned version: ${status.pinnedVersion}`);
1663
+ if (status.resolved) {
1664
+ const label = status.resolved.source === "env" ? "PROWL_MACDRIVER_BIN override" : status.resolved.source === "user-install" ? "user install (~/.prowl/macdriver)" : "repo source build (macdriver/.build)";
1665
+ console.log(` resolved binary: ${status.resolved.path}`);
1666
+ console.log(` resolved via: ${label}`);
1667
+ console.log(
1668
+ ` runs: ${status.probedVersion ? chalk14.green(`yes (reports ${status.probedVersion})`) : chalk14.yellow("no (binary did not respond to `version`)")}`
1669
+ );
1670
+ } else {
1671
+ console.log(` resolved binary: ${chalk14.yellow("none")}`);
1672
+ console.log(chalk14.dim(" search order: PROWL_MACDRIVER_BIN \u2192 ~/.prowl/macdriver \u2192 macdriver/.build"));
1673
+ console.log(chalk14.cyan(" Run `prowl macdriver install` to install the prebuilt helper."));
1674
+ }
1675
+ if (status.installed.length > 0) {
1676
+ console.log(" installed versions:");
1677
+ for (const entry of status.installed) {
1678
+ const marker = entry.version === status.pinnedVersion ? chalk14.green(" (pinned)") : "";
1679
+ console.log(` - ${entry.version}${marker} ${chalk14.dim(entry.binaryPath)}`);
1680
+ }
1681
+ } else {
1682
+ console.log(" installed versions: none");
1683
+ }
1684
+ console.log("");
1685
+ console.log(tccGuidance());
1686
+ } catch (error) {
1687
+ const message = error instanceof Error ? error.message : "Status failed";
1688
+ console.error(chalk14.red(`Error: ${message}`));
1689
+ process.exitCode = 1;
1690
+ }
1691
+ });
1692
+ }
1693
+ function buildMacdriverCommand() {
1694
+ const command = new Command13("macdriver").description(
1695
+ "Manage the macOS helper binary (prowl-macdriver) for the macOS target"
1696
+ );
1697
+ command.addCommand(buildInstallCommand());
1698
+ command.addCommand(buildStatusCommand());
1699
+ return command;
1700
+ }
1701
+
1608
1702
  // src/cli/program.ts
1609
1703
  var CLI_VERSION = package_default.version;
1610
1704
  function buildProgram() {
1611
- const program2 = new Command13();
1705
+ const program2 = new Command14();
1612
1706
  program2.name("prowl").description("CLI-first QA testing tool for deterministic Playwright flows").version(CLI_VERSION);
1613
1707
  program2.addCommand(buildRunCommand());
1614
1708
  program2.addCommand(buildCiCommand());
@@ -1622,6 +1716,7 @@ function buildProgram() {
1622
1716
  program2.addCommand(buildHistoryCommand());
1623
1717
  program2.addCommand(buildFlakyCommand());
1624
1718
  program2.addCommand(buildMcpCommand());
1719
+ program2.addCommand(buildMacdriverCommand());
1625
1720
  return program2;
1626
1721
  }
1627
1722