prowl-tools 0.1.7 → 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 +56 -7
- package/dist/{chunk-R7NUH44M.js → chunk-2RNOK64Y.js} +314 -399
- package/dist/chunk-2RNOK64Y.js.map +1 -0
- package/dist/{chunk-O3OUTZ2P.js → chunk-JFJQNJSJ.js} +394 -2
- package/dist/chunk-JFJQNJSJ.js.map +1 -0
- package/dist/index.cjs +1564 -692
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +597 -40
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +650 -346
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +95 -17
- package/dist/lib.d.ts +95 -17
- package/dist/lib.js +3 -3
- package/dist/{loader-X37URHUV.js → loader-JTHA4BYG.js} +2 -2
- package/examples/hunts/form.yml +53 -0
- package/examples/hunts/macos-hello.yml +49 -0
- package/package.json +1 -1
- package/dist/chunk-O3OUTZ2P.js.map +0 -1
- package/dist/chunk-R7NUH44M.js.map +0 -1
- /package/dist/{loader-X37URHUV.js.map → loader-JTHA4BYG.js.map} +0 -0
package/dist/lib.d.cts
CHANGED
|
@@ -444,6 +444,8 @@ interface SessionDriver {
|
|
|
444
444
|
goto(url: string, options?: NavigateOptions): Promise<void>;
|
|
445
445
|
currentUrl(): string;
|
|
446
446
|
count(selector: string): Promise<number>;
|
|
447
|
+
/** Count only elements the driver considers visibly present, when it can distinguish visibility from existence. */
|
|
448
|
+
visibleCount?(selector: string): Promise<number>;
|
|
447
449
|
textContent(selector: string): Promise<string | null>;
|
|
448
450
|
click(selector: string): Promise<void>;
|
|
449
451
|
clickFirst(selector: string): Promise<void>;
|
|
@@ -453,6 +455,12 @@ interface SessionDriver {
|
|
|
453
455
|
selectOption(selector: string, value: string): Promise<void>;
|
|
454
456
|
selectOptionFirst(selector: string, value: string): Promise<void>;
|
|
455
457
|
hover(selector: string): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Scroll the viewport in `direction` by `amount` (engine-defined units: CSS
|
|
460
|
+
* pixels on web, a synthesized swipe distance on mobile). Native targets that
|
|
461
|
+
* have no scroll gesture (macOS) reject this.
|
|
462
|
+
*/
|
|
463
|
+
scroll(direction: "up" | "down" | "left" | "right", amount?: number): Promise<void>;
|
|
456
464
|
scrollIntoView(selector: string): Promise<void>;
|
|
457
465
|
setInputFiles(selector: string, files: string | string[]): Promise<void>;
|
|
458
466
|
countByRole(role: string, name: string): Promise<number>;
|
|
@@ -597,15 +605,38 @@ type ResolveHelperOptions = {
|
|
|
597
605
|
declare function resolveHelperBinary(env?: NodeJS.ProcessEnv, options?: ResolveHelperOptions): string;
|
|
598
606
|
/** Default per-request deadline for the helper transport. */
|
|
599
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
|
+
};
|
|
600
617
|
type SpawnMacHelperOptions = {
|
|
601
618
|
/** Per-request deadline; a request that gets no response by then rejects. */
|
|
602
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;
|
|
603
632
|
};
|
|
604
633
|
/** A {@link MacHelperClient} backed by a spawned `prowl-macdriver serve` process. */
|
|
605
634
|
declare class SpawnMacHelperClient implements MacHelperClient {
|
|
606
635
|
private readonly child;
|
|
607
636
|
private readonly pending;
|
|
608
637
|
private readonly requestTimeoutMs;
|
|
638
|
+
private readonly onEvent?;
|
|
639
|
+
private readonly onEventError;
|
|
609
640
|
private stdoutBuffer;
|
|
610
641
|
private stderrBuffer;
|
|
611
642
|
private nextId;
|
|
@@ -614,6 +645,7 @@ declare class SpawnMacHelperClient implements MacHelperClient {
|
|
|
614
645
|
constructor(binaryPath: string, options?: SpawnMacHelperOptions);
|
|
615
646
|
private onStdout;
|
|
616
647
|
private dispatch;
|
|
648
|
+
private handleEvent;
|
|
617
649
|
private failAll;
|
|
618
650
|
private recordTerminalFailure;
|
|
619
651
|
/** Number of in-flight requests awaiting a response (for teardown/tests). */
|
|
@@ -751,6 +783,38 @@ declare function collectMacdriverStatus(options?: StatusOptions): Promise<Macdri
|
|
|
751
783
|
/** Static TCC-permission guidance printed after install / in status. */
|
|
752
784
|
declare function tccGuidance(): string;
|
|
753
785
|
|
|
786
|
+
/** Screen dimensions in device points, as reported by the agent. */
|
|
787
|
+
interface ScreenSize {
|
|
788
|
+
width: number;
|
|
789
|
+
height: number;
|
|
790
|
+
}
|
|
791
|
+
/** One item in a W3C `pointer` action sequence. */
|
|
792
|
+
type PointerActionItem = {
|
|
793
|
+
type: "pointerMove";
|
|
794
|
+
duration: number;
|
|
795
|
+
x: number;
|
|
796
|
+
y: number;
|
|
797
|
+
origin?: "viewport";
|
|
798
|
+
} | {
|
|
799
|
+
type: "pointerDown";
|
|
800
|
+
button: number;
|
|
801
|
+
} | {
|
|
802
|
+
type: "pointerUp";
|
|
803
|
+
button: number;
|
|
804
|
+
} | {
|
|
805
|
+
type: "pause";
|
|
806
|
+
duration: number;
|
|
807
|
+
};
|
|
808
|
+
/** A single `touch` pointer input source and its ordered actions. */
|
|
809
|
+
interface PointerActionSequence {
|
|
810
|
+
type: "pointer";
|
|
811
|
+
id: string;
|
|
812
|
+
parameters: {
|
|
813
|
+
pointerType: "touch";
|
|
814
|
+
};
|
|
815
|
+
actions: PointerActionItem[];
|
|
816
|
+
}
|
|
817
|
+
|
|
754
818
|
/** The selector kinds the native dialect understands. */
|
|
755
819
|
type NativeSelectorKind = "id" | "label" | "text" | "role" | "focused";
|
|
756
820
|
/**
|
|
@@ -968,6 +1032,10 @@ interface AndroidAgentClient {
|
|
|
968
1032
|
getText(elementId: string): Promise<string | null>;
|
|
969
1033
|
/** Dispatch a global key event by Android key code (goes to the focused view). */
|
|
970
1034
|
pressKeyCode(keyCode: number): Promise<void>;
|
|
1035
|
+
/** Current screen size in pixels (uiautomator2 `/window/current/size`), for gestures. */
|
|
1036
|
+
windowSize(): Promise<ScreenSize>;
|
|
1037
|
+
/** Perform a W3C pointer action sequence (`POST /session/:id/actions`). */
|
|
1038
|
+
performActions(actions: PointerActionSequence): Promise<void>;
|
|
971
1039
|
/** Capture the current screen as PNG bytes. */
|
|
972
1040
|
screenshotPng(): Promise<Buffer>;
|
|
973
1041
|
/**
|
|
@@ -1211,10 +1279,16 @@ interface IosAgentClient {
|
|
|
1211
1279
|
/** Replace an element's text (W3C `element/value`). */
|
|
1212
1280
|
setValue(elementId: string, text: string): Promise<void>;
|
|
1213
1281
|
getText(elementId: string): Promise<string | null>;
|
|
1282
|
+
/** True only when WDA reports the element is displayed in the current viewport. */
|
|
1283
|
+
isDisplayed(elementId: string): Promise<boolean>;
|
|
1214
1284
|
/** Send raw key sequences to the focused element (WDA `/wda/keys`). */
|
|
1215
1285
|
sendKeys(keys: string[]): Promise<void>;
|
|
1216
1286
|
/** Return to the springboard home screen (WDA `/wda/homescreen`). */
|
|
1217
1287
|
homescreen(): Promise<void>;
|
|
1288
|
+
/** Current screen size in points (WDA `/window/size`), for gesture geometry. */
|
|
1289
|
+
windowSize(): Promise<ScreenSize>;
|
|
1290
|
+
/** Perform a W3C pointer action sequence (WDA `POST /session/:id/actions`). */
|
|
1291
|
+
performActions(actions: PointerActionSequence): Promise<void>;
|
|
1218
1292
|
/**
|
|
1219
1293
|
* Return the current UI hierarchy as WebDriverAgent `/source` XML. Present on
|
|
1220
1294
|
* live clients and consumed by the analyzer (PROWL-061); optional so lighter
|
|
@@ -1516,7 +1590,9 @@ declare function createWdaAgentClient(transport: WdaTransport, sessionId: string
|
|
|
1516
1590
|
* Step types that only make sense on the web target. Everything else
|
|
1517
1591
|
* (`click`, `fill`, `type`, `press`, `wait`, `assert visible/notVisible`,
|
|
1518
1592
|
* `screenshot`, `assertScreenshot`, `repeat`, `runHunt`, `if`, `copyText`,
|
|
1519
|
-
* `hover`, `scrollTo`, `waitForSelector`) is portable across targets.
|
|
1593
|
+
* `hover`, `scrollTo`, `waitForSelector`) is portable across targets. The
|
|
1594
|
+
* directional `scroll` step is the one per-target exception — see
|
|
1595
|
+
* {@link MACOS_UNSUPPORTED_STEP_TYPES}.
|
|
1520
1596
|
*/
|
|
1521
1597
|
declare const WEB_ONLY_STEP_TYPES: ReadonlySet<string>;
|
|
1522
1598
|
/** The web-only reason a step is unsupported on a non-web target, or null if portable. */
|
|
@@ -1524,8 +1600,10 @@ declare function webOnlyReason(step: Step): string | null;
|
|
|
1524
1600
|
/**
|
|
1525
1601
|
* Throw if any step in `steps` (recursing into `if`/`repeat` bodies) is not
|
|
1526
1602
|
* supported by `target`. `runHunt` references are validated when the referenced
|
|
1527
|
-
* hunt itself runs. No-op for the web target; every native target
|
|
1528
|
-
*
|
|
1603
|
+
* hunt itself runs. No-op for the web target; every native target rejects the
|
|
1604
|
+
* same web-only step vocabulary, and macOS additionally rejects the directional
|
|
1605
|
+
* `scroll` swipe (no AX equivalent) — but NOT `scrollTo`, which macOS maps to
|
|
1606
|
+
* AXScrollToVisible just as iOS/Android map it to a swipe loop.
|
|
1529
1607
|
*/
|
|
1530
1608
|
declare function assertStepsSupportedByTarget(steps: Step[], target: Target["type"]): void;
|
|
1531
1609
|
/** Read the bundle id from an iOS `.app` (root `Info.plist`), or null. */
|
|
@@ -1862,24 +1940,24 @@ declare const configSchema: z.ZodObject<{
|
|
|
1862
1940
|
}>]>>;
|
|
1863
1941
|
}, "strip", z.ZodTypeAny, {
|
|
1864
1942
|
timeout?: number | undefined;
|
|
1865
|
-
headless?: boolean | undefined;
|
|
1866
|
-
slowMo?: number | undefined;
|
|
1867
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1868
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1869
1943
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
1870
1944
|
width: number;
|
|
1871
1945
|
height: number;
|
|
1872
1946
|
} | undefined;
|
|
1873
|
-
}, {
|
|
1874
|
-
timeout?: number | undefined;
|
|
1875
1947
|
headless?: boolean | undefined;
|
|
1876
1948
|
slowMo?: number | undefined;
|
|
1877
1949
|
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1878
1950
|
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1951
|
+
}, {
|
|
1952
|
+
timeout?: number | undefined;
|
|
1879
1953
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
1880
1954
|
width: number;
|
|
1881
1955
|
height: number;
|
|
1882
1956
|
} | undefined;
|
|
1957
|
+
headless?: boolean | undefined;
|
|
1958
|
+
slowMo?: number | undefined;
|
|
1959
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1960
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1883
1961
|
}>>;
|
|
1884
1962
|
artifacts: z.ZodOptional<z.ZodObject<{
|
|
1885
1963
|
screenshots: z.ZodOptional<z.ZodEnum<["on-failure", "all"]>>;
|
|
@@ -1993,14 +2071,14 @@ declare const configSchema: z.ZodObject<{
|
|
|
1993
2071
|
};
|
|
1994
2072
|
browser?: {
|
|
1995
2073
|
timeout?: number | undefined;
|
|
1996
|
-
headless?: boolean | undefined;
|
|
1997
|
-
slowMo?: number | undefined;
|
|
1998
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1999
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2000
2074
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
2001
2075
|
width: number;
|
|
2002
2076
|
height: number;
|
|
2003
2077
|
} | undefined;
|
|
2078
|
+
headless?: boolean | undefined;
|
|
2079
|
+
slowMo?: number | undefined;
|
|
2080
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2081
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2004
2082
|
} | undefined;
|
|
2005
2083
|
artifacts?: {
|
|
2006
2084
|
screenshots?: "on-failure" | "all" | undefined;
|
|
@@ -2058,14 +2136,14 @@ declare const configSchema: z.ZodObject<{
|
|
|
2058
2136
|
};
|
|
2059
2137
|
browser?: {
|
|
2060
2138
|
timeout?: number | undefined;
|
|
2061
|
-
headless?: boolean | undefined;
|
|
2062
|
-
slowMo?: number | undefined;
|
|
2063
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2064
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2065
2139
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
2066
2140
|
width: number;
|
|
2067
2141
|
height: number;
|
|
2068
2142
|
} | undefined;
|
|
2143
|
+
headless?: boolean | undefined;
|
|
2144
|
+
slowMo?: number | undefined;
|
|
2145
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2146
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2069
2147
|
} | undefined;
|
|
2070
2148
|
artifacts?: {
|
|
2071
2149
|
screenshots?: "on-failure" | "all" | undefined;
|
package/dist/lib.d.ts
CHANGED
|
@@ -444,6 +444,8 @@ interface SessionDriver {
|
|
|
444
444
|
goto(url: string, options?: NavigateOptions): Promise<void>;
|
|
445
445
|
currentUrl(): string;
|
|
446
446
|
count(selector: string): Promise<number>;
|
|
447
|
+
/** Count only elements the driver considers visibly present, when it can distinguish visibility from existence. */
|
|
448
|
+
visibleCount?(selector: string): Promise<number>;
|
|
447
449
|
textContent(selector: string): Promise<string | null>;
|
|
448
450
|
click(selector: string): Promise<void>;
|
|
449
451
|
clickFirst(selector: string): Promise<void>;
|
|
@@ -453,6 +455,12 @@ interface SessionDriver {
|
|
|
453
455
|
selectOption(selector: string, value: string): Promise<void>;
|
|
454
456
|
selectOptionFirst(selector: string, value: string): Promise<void>;
|
|
455
457
|
hover(selector: string): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Scroll the viewport in `direction` by `amount` (engine-defined units: CSS
|
|
460
|
+
* pixels on web, a synthesized swipe distance on mobile). Native targets that
|
|
461
|
+
* have no scroll gesture (macOS) reject this.
|
|
462
|
+
*/
|
|
463
|
+
scroll(direction: "up" | "down" | "left" | "right", amount?: number): Promise<void>;
|
|
456
464
|
scrollIntoView(selector: string): Promise<void>;
|
|
457
465
|
setInputFiles(selector: string, files: string | string[]): Promise<void>;
|
|
458
466
|
countByRole(role: string, name: string): Promise<number>;
|
|
@@ -597,15 +605,38 @@ type ResolveHelperOptions = {
|
|
|
597
605
|
declare function resolveHelperBinary(env?: NodeJS.ProcessEnv, options?: ResolveHelperOptions): string;
|
|
598
606
|
/** Default per-request deadline for the helper transport. */
|
|
599
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
|
+
};
|
|
600
617
|
type SpawnMacHelperOptions = {
|
|
601
618
|
/** Per-request deadline; a request that gets no response by then rejects. */
|
|
602
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;
|
|
603
632
|
};
|
|
604
633
|
/** A {@link MacHelperClient} backed by a spawned `prowl-macdriver serve` process. */
|
|
605
634
|
declare class SpawnMacHelperClient implements MacHelperClient {
|
|
606
635
|
private readonly child;
|
|
607
636
|
private readonly pending;
|
|
608
637
|
private readonly requestTimeoutMs;
|
|
638
|
+
private readonly onEvent?;
|
|
639
|
+
private readonly onEventError;
|
|
609
640
|
private stdoutBuffer;
|
|
610
641
|
private stderrBuffer;
|
|
611
642
|
private nextId;
|
|
@@ -614,6 +645,7 @@ declare class SpawnMacHelperClient implements MacHelperClient {
|
|
|
614
645
|
constructor(binaryPath: string, options?: SpawnMacHelperOptions);
|
|
615
646
|
private onStdout;
|
|
616
647
|
private dispatch;
|
|
648
|
+
private handleEvent;
|
|
617
649
|
private failAll;
|
|
618
650
|
private recordTerminalFailure;
|
|
619
651
|
/** Number of in-flight requests awaiting a response (for teardown/tests). */
|
|
@@ -751,6 +783,38 @@ declare function collectMacdriverStatus(options?: StatusOptions): Promise<Macdri
|
|
|
751
783
|
/** Static TCC-permission guidance printed after install / in status. */
|
|
752
784
|
declare function tccGuidance(): string;
|
|
753
785
|
|
|
786
|
+
/** Screen dimensions in device points, as reported by the agent. */
|
|
787
|
+
interface ScreenSize {
|
|
788
|
+
width: number;
|
|
789
|
+
height: number;
|
|
790
|
+
}
|
|
791
|
+
/** One item in a W3C `pointer` action sequence. */
|
|
792
|
+
type PointerActionItem = {
|
|
793
|
+
type: "pointerMove";
|
|
794
|
+
duration: number;
|
|
795
|
+
x: number;
|
|
796
|
+
y: number;
|
|
797
|
+
origin?: "viewport";
|
|
798
|
+
} | {
|
|
799
|
+
type: "pointerDown";
|
|
800
|
+
button: number;
|
|
801
|
+
} | {
|
|
802
|
+
type: "pointerUp";
|
|
803
|
+
button: number;
|
|
804
|
+
} | {
|
|
805
|
+
type: "pause";
|
|
806
|
+
duration: number;
|
|
807
|
+
};
|
|
808
|
+
/** A single `touch` pointer input source and its ordered actions. */
|
|
809
|
+
interface PointerActionSequence {
|
|
810
|
+
type: "pointer";
|
|
811
|
+
id: string;
|
|
812
|
+
parameters: {
|
|
813
|
+
pointerType: "touch";
|
|
814
|
+
};
|
|
815
|
+
actions: PointerActionItem[];
|
|
816
|
+
}
|
|
817
|
+
|
|
754
818
|
/** The selector kinds the native dialect understands. */
|
|
755
819
|
type NativeSelectorKind = "id" | "label" | "text" | "role" | "focused";
|
|
756
820
|
/**
|
|
@@ -968,6 +1032,10 @@ interface AndroidAgentClient {
|
|
|
968
1032
|
getText(elementId: string): Promise<string | null>;
|
|
969
1033
|
/** Dispatch a global key event by Android key code (goes to the focused view). */
|
|
970
1034
|
pressKeyCode(keyCode: number): Promise<void>;
|
|
1035
|
+
/** Current screen size in pixels (uiautomator2 `/window/current/size`), for gestures. */
|
|
1036
|
+
windowSize(): Promise<ScreenSize>;
|
|
1037
|
+
/** Perform a W3C pointer action sequence (`POST /session/:id/actions`). */
|
|
1038
|
+
performActions(actions: PointerActionSequence): Promise<void>;
|
|
971
1039
|
/** Capture the current screen as PNG bytes. */
|
|
972
1040
|
screenshotPng(): Promise<Buffer>;
|
|
973
1041
|
/**
|
|
@@ -1211,10 +1279,16 @@ interface IosAgentClient {
|
|
|
1211
1279
|
/** Replace an element's text (W3C `element/value`). */
|
|
1212
1280
|
setValue(elementId: string, text: string): Promise<void>;
|
|
1213
1281
|
getText(elementId: string): Promise<string | null>;
|
|
1282
|
+
/** True only when WDA reports the element is displayed in the current viewport. */
|
|
1283
|
+
isDisplayed(elementId: string): Promise<boolean>;
|
|
1214
1284
|
/** Send raw key sequences to the focused element (WDA `/wda/keys`). */
|
|
1215
1285
|
sendKeys(keys: string[]): Promise<void>;
|
|
1216
1286
|
/** Return to the springboard home screen (WDA `/wda/homescreen`). */
|
|
1217
1287
|
homescreen(): Promise<void>;
|
|
1288
|
+
/** Current screen size in points (WDA `/window/size`), for gesture geometry. */
|
|
1289
|
+
windowSize(): Promise<ScreenSize>;
|
|
1290
|
+
/** Perform a W3C pointer action sequence (WDA `POST /session/:id/actions`). */
|
|
1291
|
+
performActions(actions: PointerActionSequence): Promise<void>;
|
|
1218
1292
|
/**
|
|
1219
1293
|
* Return the current UI hierarchy as WebDriverAgent `/source` XML. Present on
|
|
1220
1294
|
* live clients and consumed by the analyzer (PROWL-061); optional so lighter
|
|
@@ -1516,7 +1590,9 @@ declare function createWdaAgentClient(transport: WdaTransport, sessionId: string
|
|
|
1516
1590
|
* Step types that only make sense on the web target. Everything else
|
|
1517
1591
|
* (`click`, `fill`, `type`, `press`, `wait`, `assert visible/notVisible`,
|
|
1518
1592
|
* `screenshot`, `assertScreenshot`, `repeat`, `runHunt`, `if`, `copyText`,
|
|
1519
|
-
* `hover`, `scrollTo`, `waitForSelector`) is portable across targets.
|
|
1593
|
+
* `hover`, `scrollTo`, `waitForSelector`) is portable across targets. The
|
|
1594
|
+
* directional `scroll` step is the one per-target exception — see
|
|
1595
|
+
* {@link MACOS_UNSUPPORTED_STEP_TYPES}.
|
|
1520
1596
|
*/
|
|
1521
1597
|
declare const WEB_ONLY_STEP_TYPES: ReadonlySet<string>;
|
|
1522
1598
|
/** The web-only reason a step is unsupported on a non-web target, or null if portable. */
|
|
@@ -1524,8 +1600,10 @@ declare function webOnlyReason(step: Step): string | null;
|
|
|
1524
1600
|
/**
|
|
1525
1601
|
* Throw if any step in `steps` (recursing into `if`/`repeat` bodies) is not
|
|
1526
1602
|
* supported by `target`. `runHunt` references are validated when the referenced
|
|
1527
|
-
* hunt itself runs. No-op for the web target; every native target
|
|
1528
|
-
*
|
|
1603
|
+
* hunt itself runs. No-op for the web target; every native target rejects the
|
|
1604
|
+
* same web-only step vocabulary, and macOS additionally rejects the directional
|
|
1605
|
+
* `scroll` swipe (no AX equivalent) — but NOT `scrollTo`, which macOS maps to
|
|
1606
|
+
* AXScrollToVisible just as iOS/Android map it to a swipe loop.
|
|
1529
1607
|
*/
|
|
1530
1608
|
declare function assertStepsSupportedByTarget(steps: Step[], target: Target["type"]): void;
|
|
1531
1609
|
/** Read the bundle id from an iOS `.app` (root `Info.plist`), or null. */
|
|
@@ -1862,24 +1940,24 @@ declare const configSchema: z.ZodObject<{
|
|
|
1862
1940
|
}>]>>;
|
|
1863
1941
|
}, "strip", z.ZodTypeAny, {
|
|
1864
1942
|
timeout?: number | undefined;
|
|
1865
|
-
headless?: boolean | undefined;
|
|
1866
|
-
slowMo?: number | undefined;
|
|
1867
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1868
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1869
1943
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
1870
1944
|
width: number;
|
|
1871
1945
|
height: number;
|
|
1872
1946
|
} | undefined;
|
|
1873
|
-
}, {
|
|
1874
|
-
timeout?: number | undefined;
|
|
1875
1947
|
headless?: boolean | undefined;
|
|
1876
1948
|
slowMo?: number | undefined;
|
|
1877
1949
|
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1878
1950
|
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1951
|
+
}, {
|
|
1952
|
+
timeout?: number | undefined;
|
|
1879
1953
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
1880
1954
|
width: number;
|
|
1881
1955
|
height: number;
|
|
1882
1956
|
} | undefined;
|
|
1957
|
+
headless?: boolean | undefined;
|
|
1958
|
+
slowMo?: number | undefined;
|
|
1959
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1960
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
1883
1961
|
}>>;
|
|
1884
1962
|
artifacts: z.ZodOptional<z.ZodObject<{
|
|
1885
1963
|
screenshots: z.ZodOptional<z.ZodEnum<["on-failure", "all"]>>;
|
|
@@ -1993,14 +2071,14 @@ declare const configSchema: z.ZodObject<{
|
|
|
1993
2071
|
};
|
|
1994
2072
|
browser?: {
|
|
1995
2073
|
timeout?: number | undefined;
|
|
1996
|
-
headless?: boolean | undefined;
|
|
1997
|
-
slowMo?: number | undefined;
|
|
1998
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
1999
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2000
2074
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
2001
2075
|
width: number;
|
|
2002
2076
|
height: number;
|
|
2003
2077
|
} | undefined;
|
|
2078
|
+
headless?: boolean | undefined;
|
|
2079
|
+
slowMo?: number | undefined;
|
|
2080
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2081
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2004
2082
|
} | undefined;
|
|
2005
2083
|
artifacts?: {
|
|
2006
2084
|
screenshots?: "on-failure" | "all" | undefined;
|
|
@@ -2058,14 +2136,14 @@ declare const configSchema: z.ZodObject<{
|
|
|
2058
2136
|
};
|
|
2059
2137
|
browser?: {
|
|
2060
2138
|
timeout?: number | undefined;
|
|
2061
|
-
headless?: boolean | undefined;
|
|
2062
|
-
slowMo?: number | undefined;
|
|
2063
|
-
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2064
|
-
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2065
2139
|
viewport?: "mobile" | "tablet" | "desktop" | {
|
|
2066
2140
|
width: number;
|
|
2067
2141
|
height: number;
|
|
2068
2142
|
} | undefined;
|
|
2143
|
+
headless?: boolean | undefined;
|
|
2144
|
+
slowMo?: number | undefined;
|
|
2145
|
+
engine?: "chromium" | "firefox" | "webkit" | undefined;
|
|
2146
|
+
channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
|
|
2069
2147
|
} | undefined;
|
|
2070
2148
|
artifacts?: {
|
|
2071
2149
|
screenshots?: "on-failure" | "all" | undefined;
|
package/dist/lib.js
CHANGED
|
@@ -74,7 +74,6 @@ import {
|
|
|
74
74
|
healSelector,
|
|
75
75
|
injectUsePortIntoXctestrun,
|
|
76
76
|
installMacdriver,
|
|
77
|
-
interpolateHunt,
|
|
78
77
|
iosAppAllowedIdentities,
|
|
79
78
|
iosNodeToNative,
|
|
80
79
|
iosQueryToLocator,
|
|
@@ -150,17 +149,18 @@ import {
|
|
|
150
149
|
wdaTestRunArgs,
|
|
151
150
|
webOnlyReason,
|
|
152
151
|
zipinfoArchiveLister
|
|
153
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-2RNOK64Y.js";
|
|
154
153
|
import {
|
|
155
154
|
configSchema,
|
|
156
155
|
huntSchema,
|
|
156
|
+
interpolateHunt,
|
|
157
157
|
listHunts,
|
|
158
158
|
loadConfig,
|
|
159
159
|
loadHunt,
|
|
160
160
|
loadHuntMeta,
|
|
161
161
|
loadHuntTags,
|
|
162
162
|
stepSchema
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-JFJQNJSJ.js";
|
|
164
164
|
export {
|
|
165
165
|
ANDROID_INTERACTIVE_CLASSES,
|
|
166
166
|
ANDROID_KEYCODES,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadHuntTags,
|
|
11
11
|
resolveViewport,
|
|
12
12
|
warnLegacyConfigDir
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-JFJQNJSJ.js";
|
|
14
14
|
export {
|
|
15
15
|
CONFIG_DIR,
|
|
16
16
|
LEGACY_CONFIG_DIR,
|
|
@@ -24,4 +24,4 @@ export {
|
|
|
24
24
|
resolveViewport,
|
|
25
25
|
warnLegacyConfigDir
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=loader-
|
|
27
|
+
//# sourceMappingURL=loader-JTHA4BYG.js.map
|
|
@@ -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!"
|