prowl-tools 0.1.8 → 0.1.9
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/README.md +42 -6
- package/dist/{chunk-CWLRDV5P.js → chunk-2RNOK64Y.js} +25 -1
- package/dist/chunk-2RNOK64Y.js.map +1 -0
- package/dist/index.cjs +637 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +595 -38
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +24 -0
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +24 -0
- package/dist/lib.d.ts +24 -0
- package/dist/lib.js +1 -1
- package/examples/hunts/form.yml +53 -0
- package/examples/hunts/macos-hello.yml +49 -0
- package/package.json +1 -1
- package/dist/chunk-CWLRDV5P.js.map +0 -1
package/dist/lib.d.cts
CHANGED
|
@@ -605,15 +605,38 @@ type ResolveHelperOptions = {
|
|
|
605
605
|
declare function resolveHelperBinary(env?: NodeJS.ProcessEnv, options?: ResolveHelperOptions): string;
|
|
606
606
|
/** Default per-request deadline for the helper transport. */
|
|
607
607
|
declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
608
|
+
/**
|
|
609
|
+
* A server-initiated event line from the helper (ARCH-008): a JSON object with
|
|
610
|
+
* an `event` discriminant and **no** `id`, so it is unambiguously distinct from
|
|
611
|
+
* an id-matched command response. Emitted, for example, when an AXObserver
|
|
612
|
+
* notification fires during a `waitFor`/`openMenu` wait.
|
|
613
|
+
*/
|
|
614
|
+
type MacHelperEvent = Record<string, unknown> & {
|
|
615
|
+
event: string;
|
|
616
|
+
};
|
|
608
617
|
type SpawnMacHelperOptions = {
|
|
609
618
|
/** Per-request deadline; a request that gets no response by then rejects. */
|
|
610
619
|
requestTimeoutMs?: number;
|
|
620
|
+
/**
|
|
621
|
+
* Optional sink for server-initiated event lines. Events are informational —
|
|
622
|
+
* waits are resolved helper-side by the id-matched response — so they are
|
|
623
|
+
* forwarded here (if provided) and otherwise dropped, never touching the
|
|
624
|
+
* pending-request map.
|
|
625
|
+
*/
|
|
626
|
+
onEvent?: (event: MacHelperEvent) => void;
|
|
627
|
+
/**
|
|
628
|
+
* Optional diagnostic sink for event handler failures. Defaults to stderr so a
|
|
629
|
+
* bad sink is visible without allowing it to break helper transport.
|
|
630
|
+
*/
|
|
631
|
+
onEventError?: (message: string) => void;
|
|
611
632
|
};
|
|
612
633
|
/** A {@link MacHelperClient} backed by a spawned `prowl-macdriver serve` process. */
|
|
613
634
|
declare class SpawnMacHelperClient implements MacHelperClient {
|
|
614
635
|
private readonly child;
|
|
615
636
|
private readonly pending;
|
|
616
637
|
private readonly requestTimeoutMs;
|
|
638
|
+
private readonly onEvent?;
|
|
639
|
+
private readonly onEventError;
|
|
617
640
|
private stdoutBuffer;
|
|
618
641
|
private stderrBuffer;
|
|
619
642
|
private nextId;
|
|
@@ -622,6 +645,7 @@ declare class SpawnMacHelperClient implements MacHelperClient {
|
|
|
622
645
|
constructor(binaryPath: string, options?: SpawnMacHelperOptions);
|
|
623
646
|
private onStdout;
|
|
624
647
|
private dispatch;
|
|
648
|
+
private handleEvent;
|
|
625
649
|
private failAll;
|
|
626
650
|
private recordTerminalFailure;
|
|
627
651
|
/** Number of in-flight requests awaiting a response (for teardown/tests). */
|
package/dist/lib.d.ts
CHANGED
|
@@ -605,15 +605,38 @@ type ResolveHelperOptions = {
|
|
|
605
605
|
declare function resolveHelperBinary(env?: NodeJS.ProcessEnv, options?: ResolveHelperOptions): string;
|
|
606
606
|
/** Default per-request deadline for the helper transport. */
|
|
607
607
|
declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
608
|
+
/**
|
|
609
|
+
* A server-initiated event line from the helper (ARCH-008): a JSON object with
|
|
610
|
+
* an `event` discriminant and **no** `id`, so it is unambiguously distinct from
|
|
611
|
+
* an id-matched command response. Emitted, for example, when an AXObserver
|
|
612
|
+
* notification fires during a `waitFor`/`openMenu` wait.
|
|
613
|
+
*/
|
|
614
|
+
type MacHelperEvent = Record<string, unknown> & {
|
|
615
|
+
event: string;
|
|
616
|
+
};
|
|
608
617
|
type SpawnMacHelperOptions = {
|
|
609
618
|
/** Per-request deadline; a request that gets no response by then rejects. */
|
|
610
619
|
requestTimeoutMs?: number;
|
|
620
|
+
/**
|
|
621
|
+
* Optional sink for server-initiated event lines. Events are informational —
|
|
622
|
+
* waits are resolved helper-side by the id-matched response — so they are
|
|
623
|
+
* forwarded here (if provided) and otherwise dropped, never touching the
|
|
624
|
+
* pending-request map.
|
|
625
|
+
*/
|
|
626
|
+
onEvent?: (event: MacHelperEvent) => void;
|
|
627
|
+
/**
|
|
628
|
+
* Optional diagnostic sink for event handler failures. Defaults to stderr so a
|
|
629
|
+
* bad sink is visible without allowing it to break helper transport.
|
|
630
|
+
*/
|
|
631
|
+
onEventError?: (message: string) => void;
|
|
611
632
|
};
|
|
612
633
|
/** A {@link MacHelperClient} backed by a spawned `prowl-macdriver serve` process. */
|
|
613
634
|
declare class SpawnMacHelperClient implements MacHelperClient {
|
|
614
635
|
private readonly child;
|
|
615
636
|
private readonly pending;
|
|
616
637
|
private readonly requestTimeoutMs;
|
|
638
|
+
private readonly onEvent?;
|
|
639
|
+
private readonly onEventError;
|
|
617
640
|
private stdoutBuffer;
|
|
618
641
|
private stderrBuffer;
|
|
619
642
|
private nextId;
|
|
@@ -622,6 +645,7 @@ declare class SpawnMacHelperClient implements MacHelperClient {
|
|
|
622
645
|
constructor(binaryPath: string, options?: SpawnMacHelperOptions);
|
|
623
646
|
private onStdout;
|
|
624
647
|
private dispatch;
|
|
648
|
+
private handleEvent;
|
|
625
649
|
private failAll;
|
|
626
650
|
private recordTerminalFailure;
|
|
627
651
|
/** Number of in-flight requests awaiting a response (for teardown/tests). */
|
package/dist/lib.js
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Form Submission
|
|
2
|
+
# ---
|
|
3
|
+
# Pattern: Forms — fill text fields, pick a dropdown option, submit, verify result.
|
|
4
|
+
# What it tests: Complete a form and confirm the success state renders.
|
|
5
|
+
# Customize:
|
|
6
|
+
# - Point `navigate` at your form's path
|
|
7
|
+
# - Update the field labels, the dropdown label/option, and the button text
|
|
8
|
+
# to match your form
|
|
9
|
+
#
|
|
10
|
+
# Tip: Prefer stable selectors — an accessible label or a data-testid — over
|
|
11
|
+
# brittle CSS. Run `prowl analyze` to dump ranked selector candidates for a page.
|
|
12
|
+
|
|
13
|
+
name: form
|
|
14
|
+
description: Fill and submit a form, verify the success message
|
|
15
|
+
|
|
16
|
+
tags:
|
|
17
|
+
- forms
|
|
18
|
+
- input
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- navigate: "/signup"
|
|
22
|
+
|
|
23
|
+
# Shorthand fill — Prowl finds the input by its label or placeholder text.
|
|
24
|
+
# Equivalent explicit form:
|
|
25
|
+
# fill:
|
|
26
|
+
# selector: "input[name='name']"
|
|
27
|
+
# value: "Ada Lovelace"
|
|
28
|
+
- fill:
|
|
29
|
+
"Full name": "Ada Lovelace"
|
|
30
|
+
|
|
31
|
+
- fill:
|
|
32
|
+
"Email": "ada@example.com"
|
|
33
|
+
|
|
34
|
+
# Shorthand select — finds the <select> by its label and picks the option by
|
|
35
|
+
# its visible text. Equivalent explicit form:
|
|
36
|
+
# selectOption:
|
|
37
|
+
# selector: "select[name='plan']"
|
|
38
|
+
# value: "Pro"
|
|
39
|
+
- select:
|
|
40
|
+
"Plan": "Pro"
|
|
41
|
+
|
|
42
|
+
# Shorthand click — Prowl finds a checkbox or button by its text content.
|
|
43
|
+
- click: "I agree to the terms"
|
|
44
|
+
|
|
45
|
+
- click: "Create account"
|
|
46
|
+
|
|
47
|
+
# Mid-flow assertion — verify the success state rendered.
|
|
48
|
+
- assert:
|
|
49
|
+
visible: "Welcome, Ada"
|
|
50
|
+
|
|
51
|
+
assertions:
|
|
52
|
+
- urlIncludes: "/welcome"
|
|
53
|
+
- noConsoleErrors: true
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# macOS Hello — Your First Desktop Hunt (Experimental)
|
|
2
|
+
# ---
|
|
3
|
+
# Prowl drives native macOS apps through Apple's Accessibility API, from the same
|
|
4
|
+
# YAML as web hunts. This starter targets TextEdit — present on every Mac — so you
|
|
5
|
+
# can try the desktop target without wiring up your own app first.
|
|
6
|
+
#
|
|
7
|
+
# ── Before this hunt will run ───────────────────────────────────────────────
|
|
8
|
+
# 1. Install the helper: prowl macdriver install
|
|
9
|
+
# Until the first signed release ships, `install` returns a 404 — build from
|
|
10
|
+
# source instead (needs the Swift toolchain / Xcode CLT):
|
|
11
|
+
# cd macdriver && swift build -c release
|
|
12
|
+
# 2. Grant Accessibility permission to the app hosting your terminal (Terminal,
|
|
13
|
+
# iTerm, VS Code, …): System Settings → Privacy & Security → Accessibility.
|
|
14
|
+
# `prowl macdriver status` prints the resolved binary and this guidance.
|
|
15
|
+
# 3. Point .prowl/config.yml at a macOS target — init's default config targets
|
|
16
|
+
# the web. Replace its `target:` block, and scope the app under guardrails:
|
|
17
|
+
#
|
|
18
|
+
# target:
|
|
19
|
+
# type: macos
|
|
20
|
+
# app: "com.apple.TextEdit" # bundle id, or an absolute /path/to/App.app
|
|
21
|
+
# guardrails:
|
|
22
|
+
# allowedApps:
|
|
23
|
+
# - "com.apple.TextEdit"
|
|
24
|
+
#
|
|
25
|
+
# The macOS target is EXPERIMENTAL — the selector dialect and step coverage may
|
|
26
|
+
# still change. `navigate`, `waitForUrl`, and other web-only steps are rejected
|
|
27
|
+
# on it; the portable steps below (`type`, `assert: visible`) run on both targets.
|
|
28
|
+
#
|
|
29
|
+
# ── Finding selectors ───────────────────────────────────────────────────────
|
|
30
|
+
# Don't guess selectors — dump them: prowl analyze --app com.apple.TextEdit
|
|
31
|
+
# It walks the Accessibility tree and prints every element with ranked selector
|
|
32
|
+
# candidates (prefer `id=` — the native analog of data-testid). TextEdit's
|
|
33
|
+
# controls aren't ours, so treat the steps below as a starting point and adjust
|
|
34
|
+
# to what `analyze` reports on your macOS version.
|
|
35
|
+
|
|
36
|
+
name: macos-hello
|
|
37
|
+
description: Type into TextEdit and verify the text appears (experimental macOS target)
|
|
38
|
+
|
|
39
|
+
tags:
|
|
40
|
+
- macos
|
|
41
|
+
- smoke
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
# `type` sends keystrokes to the focused element — a fresh TextEdit document.
|
|
45
|
+
- type: "Hello from Prowl!"
|
|
46
|
+
|
|
47
|
+
# Portable assertion — the document's text should now contain what we typed.
|
|
48
|
+
- assert:
|
|
49
|
+
visible: "Hello from Prowl!"
|