prompttest-mobile 1.5.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.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +80 -0
  2. package/LICENSE +42 -0
  3. package/LICENSES.md +81 -0
  4. package/README.md +526 -0
  5. package/SECURITY.md +56 -0
  6. package/TERMS.md +138 -0
  7. package/dist/bin/prompttest.d.ts +2 -0
  8. package/dist/bin/prompttest.js +1418 -0
  9. package/dist/bin/server.d.ts +1 -0
  10. package/dist/constants/commands.d.ts +125 -0
  11. package/dist/engine.bundle.js +1039 -0
  12. package/dist/index.d.ts +143 -0
  13. package/dist/index.js +1039 -0
  14. package/dist/lib/adaptive-timing.d.ts +55 -0
  15. package/dist/lib/adb-provisioner.d.ts +55 -0
  16. package/dist/lib/adb.d.ts +448 -0
  17. package/dist/lib/ai/heuristic-resolver.d.ts +19 -0
  18. package/dist/lib/ai/index.d.ts +16 -0
  19. package/dist/lib/ai/llm-provider.d.ts +40 -0
  20. package/dist/lib/ai/types.d.ts +64 -0
  21. package/dist/lib/baseline.d.ts +159 -0
  22. package/dist/lib/benchmark.d.ts +100 -0
  23. package/dist/lib/checkpoint.d.ts +61 -0
  24. package/dist/lib/ci.d.ts +49 -0
  25. package/dist/lib/config-loader.d.ts +87 -0
  26. package/dist/lib/config.d.ts +136 -0
  27. package/dist/lib/crawler.d.ts +335 -0
  28. package/dist/lib/data-loader.d.ts +53 -0
  29. package/dist/lib/dfs-engine.d.ts +149 -0
  30. package/dist/lib/dictionary.d.ts +41 -0
  31. package/dist/lib/doctor.d.ts +45 -0
  32. package/dist/lib/driver-interface.d.ts +50 -0
  33. package/dist/lib/enterprise.d.ts +71 -0
  34. package/dist/lib/errors.d.ts +68 -0
  35. package/dist/lib/explorer.d.ts +165 -0
  36. package/dist/lib/feedback.d.ts +35 -0
  37. package/dist/lib/form-filler.d.ts +101 -0
  38. package/dist/lib/ios-driver.d.ts +38 -0
  39. package/dist/lib/jail-guard.d.ts +59 -0
  40. package/dist/lib/license.d.ts +51 -0
  41. package/dist/lib/live-server.d.ts +52 -0
  42. package/dist/lib/lock.d.ts +30 -0
  43. package/dist/lib/logger.d.ts +68 -0
  44. package/dist/lib/memory.d.ts +259 -0
  45. package/dist/lib/patterns.d.ts +202 -0
  46. package/dist/lib/profiler.d.ts +75 -0
  47. package/dist/lib/prompt-runner.d.ts +101 -0
  48. package/dist/lib/quiescence.d.ts +44 -0
  49. package/dist/lib/recorder.d.ts +155 -0
  50. package/dist/lib/repl.d.ts +29 -0
  51. package/dist/lib/reporter.d.ts +269 -0
  52. package/dist/lib/runner-utils.d.ts +316 -0
  53. package/dist/lib/scaffold.d.ts +53 -0
  54. package/dist/lib/step-handlers.d.ts +390 -0
  55. package/dist/lib/triage.d.ts +50 -0
  56. package/dist/lib/wizard.d.ts +42 -0
  57. package/dist/lib/zip-util.d.ts +36 -0
  58. package/docs/ARCHITECTURE.md +154 -0
  59. package/docs/CLI_CONTRACT.md +131 -0
  60. package/docs/CLI_STUDIO_CONTRACT.md +123 -0
  61. package/docs/PERFORMANCE_BASELINE.md +71 -0
  62. package/docs/PRODUCT_STATUS.md +56 -0
  63. package/docs/USER_MANUAL.md +764 -0
  64. package/package.json +66 -0
@@ -0,0 +1,390 @@
1
+ /**
2
+ * @module step-handlers
3
+ * @description
4
+ * StepHandler pattern (A-04) implementation for PromptTest.
5
+ *
6
+ * This module implements the Command/Strategy architectural pattern where each action
7
+ * type (e.g., TAP, SWIPE, VERIFY) is encapsulated in its own independent handler class.
8
+ * By isolating step execution logic into discrete classes, the PromptRunner becomes a
9
+ * thin dispatcher relying on an O(1) map lookup (see STEP_HANDLER_REGISTRY).
10
+ *
11
+ * Adding a new step type requires only implementing a new StepHandler class and
12
+ * registering it, ensuring the core execution engine remains untouched and adhering
13
+ * to the Open/Closed Principle.
14
+ */
15
+ import { AndroidDriver } from './adb.js';
16
+ import { MemoryEngine } from './memory.js';
17
+ import { UiNode } from './crawler.js';
18
+ import { PromptStep } from './prompt-runner.js';
19
+ /**
20
+ * ExecutionContext provides shared resources and utility methods to StepHandlers.
21
+ * It encapsulates the driver instance, state cache, and common UI interaction logic.
22
+ */
23
+ export interface ExecutionContext {
24
+ /** Target application package name under test (used for jail guard containment). */
25
+ targetPackage?: string;
26
+ /** The ADB-based Android UI driver used to interact with the device. */
27
+ driver: AndroidDriver;
28
+ /** Memory engine used to record and learn resilient locators over time. */
29
+ memory: MemoryEngine;
30
+ /** Optional device serial number for targeting specific devices via ADB. */
31
+ serial?: string;
32
+ /** Device screen dimensions used for coordinate calculations. */
33
+ screenDimensions: {
34
+ width: number;
35
+ height: number;
36
+ };
37
+ /** Height of the navigation bar, used to prevent interacting with system overlays. */
38
+ navBarHeight: number;
39
+ /** Cached snapshot of the last known UI hierarchy to accelerate operations. */
40
+ lastHierarchy: {
41
+ xml: string;
42
+ flat: UiNode[];
43
+ timestamp: number;
44
+ hash?: string;
45
+ } | null;
46
+ /** Caches the provided hierarchy snapshot for subsequent steps. */
47
+ setLastHierarchy(h: {
48
+ xml: string;
49
+ flat: UiNode[];
50
+ timestamp: number;
51
+ hash?: string;
52
+ } | null): void;
53
+ /** Fetches a fresh UI hierarchy directly from the device. */
54
+ getCleanHierarchy(serial?: string): Promise<{
55
+ xml: string;
56
+ flat: UiNode[];
57
+ }>;
58
+ /** Polls for a specific target node until it appears or times out. */
59
+ waitForTarget(target: string, serial?: string, timeoutMs?: number, step?: PromptStep): Promise<{
60
+ flat: UiNode[];
61
+ matched: UiNode[];
62
+ }>;
63
+ /** Evaluates nodes against a natural language query or semantic pattern. */
64
+ matchNodes(nodes: UiNode[], query: string, step?: PromptStep): UiNode[];
65
+ /** Checks if a node is visible, scrolling the viewport if necessary. */
66
+ ensureInViewport(node: UiNode, serial?: string): Promise<boolean>;
67
+ /** Generates rich, contextual errors when a step fails. */
68
+ buildDiagnosticError(target: string, flat: UiNode[], context: string): Error;
69
+ /** Specialized locator for finding form inputs, prioritizing matching hints or labels. */
70
+ findTargetInputField(nodes: UiNode[], target: string, value?: string): UiNode | null;
71
+ /** Future steps in the current script, used for fast-forward lookahead optimizations. */
72
+ upcomingSteps?: PromptStep[];
73
+ /** Live mutable variables map for storing and interpolating $var values across steps. */
74
+ variables: Map<string, string>;
75
+ /** Stack tracking nested loop executions to prevent infinite recursion. */
76
+ loopStack: Array<{
77
+ current: number;
78
+ total: number;
79
+ variable?: string;
80
+ }>;
81
+ /** Callback to execute a sequence of child steps (e.g. inside IF or LOOP). */
82
+ executeChildSteps?(steps: PromptStep[], ctx: ExecutionContext): Promise<void>;
83
+ }
84
+ /**
85
+ * Represents the outcome of a StepHandler's execution.
86
+ */
87
+ export interface StepResult {
88
+ /** Indicates if the step was bypassed because its desired state was already met. */
89
+ fastForwarded?: boolean;
90
+ /** Explanation for why the step was fast-forwarded or altered. */
91
+ reason?: string;
92
+ /** Number of upcoming steps to skip if fast-forwarded over multiple actions. */
93
+ skipCount?: number;
94
+ }
95
+ /**
96
+ * The base interface for all action handlers.
97
+ * Enforces a strict contract for dispatching PromptStep instructions.
98
+ */
99
+ export interface StepHandler {
100
+ /** The specific PromptStep type this handler is responsible for (e.g., 'TAP'). */
101
+ readonly type: PromptStep['type'];
102
+ /**
103
+ * Executes the step using the provided context.
104
+ *
105
+ * @param step - The parsed step instruction to execute.
106
+ * @param ctx - The execution context providing driver and utility access.
107
+ * @returns A promise resolving to a StepResult, or void if standard execution completes.
108
+ * @throws Will throw if the step cannot be completed (e.g., element not found).
109
+ */
110
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<StepResult | void>;
111
+ }
112
+ /**
113
+ * Handles TAP actions by finding the target element and simulating a single touch event.
114
+ * Incorporates fast-forwarding and auto-scrolling optimizations.
115
+ */
116
+ export declare class TapHandler implements StepHandler {
117
+ readonly type: "TAP";
118
+ /**
119
+ * Executes the TAP step.
120
+ * @param step - The step instruction.
121
+ * @param ctx - The execution context.
122
+ */
123
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<StepResult | void>;
124
+ }
125
+ /**
126
+ * Handles LONG_PRESS actions by pressing and holding on a target element.
127
+ */
128
+ export declare class LongPressHandler implements StepHandler {
129
+ readonly type: "LONG_PRESS";
130
+ /**
131
+ * Executes the LONG_PRESS step.
132
+ * @param step - The step instruction.
133
+ * @param ctx - The execution context.
134
+ */
135
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
136
+ }
137
+ /**
138
+ * Handles TYPE actions to input text into form fields.
139
+ * Manages focus, clearing existing text, and keyboard interactions.
140
+ */
141
+ export declare class TypeHandler implements StepHandler {
142
+ readonly type: "TYPE";
143
+ /**
144
+ * Executes the TYPE step.
145
+ * @param step - The step instruction.
146
+ * @param ctx - The execution context.
147
+ */
148
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<StepResult | void>;
149
+ }
150
+ /**
151
+ * Handles CLEAR actions to empty an input field.
152
+ * Locates the target input, taps to focus, and clears its contents.
153
+ */
154
+ export declare class ClearHandler implements StepHandler {
155
+ readonly type: "CLEAR";
156
+ /**
157
+ * Executes the CLEAR step.
158
+ * @param step - The step instruction.
159
+ * @param ctx - The execution context.
160
+ */
161
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
162
+ }
163
+ /**
164
+ * Handles VERIFY actions to assert the presence or state of elements on the screen.
165
+ */
166
+ export declare class VerifyHandler implements StepHandler {
167
+ readonly type: "VERIFY";
168
+ /**
169
+ * Executes the VERIFY step.
170
+ * @param step - The step instruction.
171
+ * @param ctx - The execution context.
172
+ */
173
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<StepResult | void>;
174
+ }
175
+ /**
176
+ * Handles BACK actions by simulating a hardware back button press.
177
+ */
178
+ export declare class BackHandler implements StepHandler {
179
+ readonly type: "BACK";
180
+ /**
181
+ * Executes the BACK step.
182
+ * @param step - The step instruction.
183
+ * @param ctx - The execution context.
184
+ */
185
+ execute(_step: PromptStep, ctx: ExecutionContext): Promise<void>;
186
+ }
187
+ /**
188
+ * Handles SCROLL actions to navigate through lists or pages.
189
+ */
190
+ export declare class ScrollHandler implements StepHandler {
191
+ readonly type: "SCROLL";
192
+ /**
193
+ * Executes the SCROLL step.
194
+ * @param step - The step instruction.
195
+ * @param ctx - The execution context.
196
+ */
197
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
198
+ }
199
+ /**
200
+ * Handles SWIPE actions to perform directional swipe gestures on the screen or specific elements.
201
+ */
202
+ export declare class SwipeHandler implements StepHandler {
203
+ readonly type: "SWIPE";
204
+ /**
205
+ * Executes the SWIPE step.
206
+ * @param step - The step instruction.
207
+ * @param ctx - The execution context.
208
+ */
209
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
210
+ }
211
+ /**
212
+ * Handles TOGGLE actions for checkboxes and switches, ensuring the element reaches the desired state.
213
+ */
214
+ export declare class ToggleHandler implements StepHandler {
215
+ readonly type: "TOGGLE";
216
+ /**
217
+ * Executes the TOGGLE step.
218
+ * @param step - The step instruction.
219
+ * @param ctx - The execution context.
220
+ */
221
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
222
+ }
223
+ /**
224
+ * Handles SELECT actions to choose an option from a dropdown or picker modal.
225
+ */
226
+ export declare class SelectHandler implements StepHandler {
227
+ readonly type: "SELECT";
228
+ /**
229
+ * Executes the SELECT step.
230
+ * @param step - The step instruction.
231
+ * @param ctx - The execution context.
232
+ */
233
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
234
+ }
235
+ /**
236
+ * Handles LAUNCH_APP actions by starting the application via its package name.
237
+ */
238
+ export declare class LaunchAppHandler implements StepHandler {
239
+ readonly type: "LAUNCH_APP";
240
+ /**
241
+ * Executes the LAUNCH_APP step.
242
+ * @param step - The step instruction.
243
+ * @param ctx - The execution context.
244
+ */
245
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
246
+ }
247
+ /**
248
+ * Handles RESTART_APP actions by forcefully stopping and then relaunching the app.
249
+ */
250
+ export declare class RestartAppHandler implements StepHandler {
251
+ readonly type: "RESTART_APP";
252
+ /**
253
+ * Executes the RESTART_APP step.
254
+ * @param step - The step instruction.
255
+ * @param ctx - The execution context.
256
+ */
257
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
258
+ }
259
+ /**
260
+ * Handles TERMINATE_APP actions by forcefully stopping the application.
261
+ */
262
+ export declare class TerminateAppHandler implements StepHandler {
263
+ readonly type: "TERMINATE_APP";
264
+ /**
265
+ * Executes the TERMINATE_APP step.
266
+ * @param step - The step instruction.
267
+ * @param ctx - The execution context.
268
+ */
269
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
270
+ }
271
+ /**
272
+ * Handles CLEAR_DATA actions by wiping the application's local data and cache.
273
+ */
274
+ export declare class ClearDataHandler implements StepHandler {
275
+ readonly type: "CLEAR_DATA";
276
+ /**
277
+ * Executes the CLEAR_DATA step.
278
+ * @param step - The step instruction.
279
+ * @param ctx - The execution context.
280
+ */
281
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
282
+ }
283
+ /**
284
+ * Handles GRANT_PERMISSION actions to grant specific runtime permissions to the app.
285
+ */
286
+ export declare class GrantPermissionHandler implements StepHandler {
287
+ readonly type: "GRANT_PERMISSION";
288
+ /**
289
+ * Executes the GRANT_PERMISSION step.
290
+ * @param step - The step instruction.
291
+ * @param ctx - The execution context.
292
+ */
293
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
294
+ }
295
+ /**
296
+ * Handles DEEP_LINK actions by opening a URI scheme or Intent.
297
+ */
298
+ export declare class DeepLinkHandler implements StepHandler {
299
+ readonly type: "DEEP_LINK";
300
+ /**
301
+ * Executes the DEEP_LINK step.
302
+ * @param step - The step instruction.
303
+ * @param ctx - The execution context.
304
+ */
305
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
306
+ }
307
+ /**
308
+ * Handles WAIT actions by pausing execution for a specified duration.
309
+ */
310
+ export declare class WaitHandler implements StepHandler {
311
+ readonly type: "WAIT";
312
+ /**
313
+ * Executes the WAIT step.
314
+ * @param step - The step instruction.
315
+ * @param _ctx - The execution context.
316
+ */
317
+ execute(step: PromptStep, _ctx: ExecutionContext): Promise<void>;
318
+ }
319
+ /**
320
+ * Handles conditional branching based on UI element presence.
321
+ * Executes thenSteps if visible, or elseSteps if present and element not found.
322
+ */
323
+ export declare class ConditionalHandler implements StepHandler {
324
+ readonly type: "IF_VISIBLE";
325
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
326
+ }
327
+ /**
328
+ * Handles iterative execution of child steps with loop bound protections.
329
+ */
330
+ export declare class LoopHandler implements StepHandler {
331
+ readonly type: "LOOP";
332
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
333
+ }
334
+ /**
335
+ * Polls for an element to appear or become enabled without failing immediately.
336
+ */
337
+ export declare class WaitUntilHandler implements StepHandler {
338
+ readonly type: "WAIT_UNTIL";
339
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
340
+ }
341
+ /**
342
+ * Sets dynamic variables in the execution context for interpolation into subsequent steps.
343
+ */
344
+ export declare class SetVariableHandler implements StepHandler {
345
+ readonly type: "SET_VARIABLE";
346
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
347
+ }
348
+ /**
349
+ * Executes hardware and connectivity controls (Wi-Fi, Airplane mode, Orientation, Notifications).
350
+ */
351
+ export declare class DeviceStateHandler implements StepHandler {
352
+ readonly type: "DEVICE_STATE";
353
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
354
+ }
355
+ /**
356
+ * Executes a sandboxed JavaScript snippet for runtime calculations or variable manipulation.
357
+ */
358
+ export declare class RunJsHandler implements StepHandler {
359
+ readonly type: "RUN_JS";
360
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
361
+ }
362
+ /**
363
+ * Handles automatic capture and input of One-Time Passwords (OTP) and 2FA codes.
364
+ * Reads codes from mock environment variables or live ADB logcat streams.
365
+ */
366
+ export declare class OtpHandler implements StepHandler {
367
+ readonly type: "ENTER_OTP";
368
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<StepResult | void>;
369
+ }
370
+ /**
371
+ * Handles HTTP requests and API assertions within a test flow.
372
+ * Capable of extracting JSON response fields into runtime $variables.
373
+ */
374
+ export declare class ApiHandler implements StepHandler {
375
+ readonly type: "API_REQUEST";
376
+ execute(step: PromptStep, ctx: ExecutionContext): Promise<void>;
377
+ private resolveJsonPath;
378
+ }
379
+ /**
380
+ * Handles assertions on transactional emails delivered to users during testing.
381
+ */
382
+ export declare class EmailHandler implements StepHandler {
383
+ readonly type: "EMAIL_ASSERT";
384
+ execute(step: PromptStep, _ctx: ExecutionContext): Promise<void>;
385
+ }
386
+ /**
387
+ * STEP_HANDLER_REGISTRY maps step types to their concrete handler implementations.
388
+ * Provides an O(1) lookup for dispatching steps in the PromptRunner.
389
+ */
390
+ export declare const STEP_HANDLER_REGISTRY: Map<import("./runner-utils.js").PromptStepType, StepHandler>;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @module triage
3
+ * @description
4
+ * Auto-crash triage and privacy-safe GitHub bug report link generator for PromptTest.
5
+ * Provides passive, zero-telemetry 1-click issue reporting when unexpected
6
+ * internal framework crashes or unhandled exceptions occur.
7
+ */
8
+ export interface TriageOptions {
9
+ errorMessage: string;
10
+ stack?: string;
11
+ command?: string;
12
+ exitCode?: number;
13
+ repoUrl?: string;
14
+ }
15
+ export interface TriageContext {
16
+ command?: string;
17
+ exitCode?: number;
18
+ }
19
+ /**
20
+ * Sanitizes stack traces and error messages by stripping personal user directories
21
+ * (e.g. C:\Users\username\... or /Users/username/...) to protect developer privacy.
22
+ *
23
+ * @param trace - The raw stack trace or log string.
24
+ * @returns Sanitized string with user home directories replaced by '~'.
25
+ */
26
+ export declare function sanitizeStackTrace(trace?: string): string;
27
+ /**
28
+ * Distinguishes whether an error is an expected test failure (e.g., assertion failed,
29
+ * element not found timeout) or an unexpected internal framework/runtime crash
30
+ * (TypeError, process panic, unhandled exception).
31
+ *
32
+ * @param error - The caught error or rejection reason.
33
+ * @returns true if the error represents an unexpected framework crash.
34
+ */
35
+ export declare function isFrameworkCrash(error: unknown): boolean;
36
+ /**
37
+ * Builds a sanitized, length-bounded pre-filled GitHub issue URL matching
38
+ * the 1_bug_report.yml template in prompttest-community.
39
+ *
40
+ * @param options - Error context and command details.
41
+ * @returns The fully-encoded GitHub issue URL.
42
+ */
43
+ export declare function buildIssueUrl(options: TriageOptions): string;
44
+ /**
45
+ * Renders a polite, non-intrusive diagnostic crash triage box in the console.
46
+ *
47
+ * @param error - The caught crash error.
48
+ * @param context - Additional execution context (e.g. command run, exit code).
49
+ */
50
+ export declare function displayCrashTriage(error: unknown, context?: TriageContext): void;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @module wizard
3
+ * @description
4
+ * Interactive guided CLI wizard for PromptTest.
5
+ * Auto-detects connected devices, identifies foreground apps, discovers existing
6
+ * test specifications, and guides developers through autonomous exploration,
7
+ * test recording, spec execution, and diagnostics with zero required CLI arguments.
8
+ */
9
+ import { AndroidDriver, AndroidDevice } from './adb.js';
10
+ import { PromptRunner } from './prompt-runner.js';
11
+ export interface EnvironmentInfo {
12
+ device?: AndroidDevice;
13
+ serial?: string;
14
+ activePackage?: string;
15
+ isOnline: boolean;
16
+ }
17
+ export interface WizardOptions {
18
+ input?: NodeJS.ReadableStream;
19
+ output?: NodeJS.WritableStream;
20
+ driver?: AndroidDriver;
21
+ runner?: PromptRunner;
22
+ }
23
+ /**
24
+ * Automatically inspects ADB to detect online devices and active foreground application.
25
+ *
26
+ * @param driver - AndroidDriver instance to query.
27
+ * @returns Detected environment state.
28
+ */
29
+ export declare function detectActiveEnvironment(driver?: AndroidDriver): Promise<EnvironmentInfo>;
30
+ /**
31
+ * Scans the current workspace for existing plain-English test specs (*.txt, *.spec).
32
+ *
33
+ * @param baseDir - Root directory to search (defaults to process.cwd()).
34
+ * @returns Array of discovered relative spec paths.
35
+ */
36
+ export declare function findExistingSpecs(baseDir?: string): string[];
37
+ /**
38
+ * Starts the interactive guided CLI wizard.
39
+ *
40
+ * @param options - Configuration options for input/output streams and drivers.
41
+ */
42
+ export declare function startInteractiveWizard(options?: WizardOptions): Promise<void>;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @module zip-util
3
+ * @description
4
+ * Lightweight, zero-dependency ZIP archive generator built using Node.js native zlib.
5
+ * Generates standard PKZIP archives containing files with deflation compression.
6
+ */
7
+ export interface ZipEntry {
8
+ name: string;
9
+ data: Buffer;
10
+ date?: Date;
11
+ }
12
+ /**
13
+ * Calculates a standard CRC32 checksum for a buffer.
14
+ */
15
+ export declare function crc32(buf: Buffer): number;
16
+ /**
17
+ * Converts a JS Date into standard MS-DOS format (16-bit time, 16-bit date).
18
+ */
19
+ export declare function dosDateTime(d?: Date): {
20
+ time: number;
21
+ date: number;
22
+ };
23
+ /**
24
+ * Packs an array of ZipEntry files into a standard PKZIP buffer using Deflate compression.
25
+ *
26
+ * @param entries - Array of file entries with names and data buffers.
27
+ * @returns A Buffer containing the valid ZIP archive.
28
+ */
29
+ export declare function createZipArchive(entries: ZipEntry[]): Buffer;
30
+ /**
31
+ * Saves a list of entries as a ZIP file to disk.
32
+ *
33
+ * @param filePath - Target file path on disk.
34
+ * @param entries - Array of zip entries.
35
+ */
36
+ export declare function writeZipFile(filePath: string, entries: ZipEntry[]): Promise<void>;
@@ -0,0 +1,154 @@
1
+ # PromptTest Architecture & System Design
2
+
3
+ PromptTest is a zero-code, AI-assisted Android test automation and visual QA framework. It drives native Android devices over ADB without requiring app instrumentation, agent binaries, or server daemons.
4
+
5
+ ---
6
+
7
+ ## 1. High-Level Architecture Overview
8
+
9
+ PromptTest operates on a modular layered architecture where test scripts written in natural language or AST-driven directives are compiled, bound to live or synthetic data, executed against connected devices via an isolated locking layer, and reported with visual diffs and interactive HTML reports. Current release boundaries are tracked in [PRODUCT_STATUS.md](PRODUCT_STATUS.md).
10
+
11
+ ```
12
+ ┌───────────────────────────────────────────────────────────┐
13
+ │ CLI & Runner Interface │
14
+ │ (bin/prompttest.ts, index.ts) │
15
+ └─────────────────────────────┬─────────────────────────────┘
16
+ │
17
+ ┌─────────────────────────────▼─────────────────────────────┐
18
+ │ Compilation & Parsing │
19
+ │ lib/runner-utils.ts (AST, Parser, Includes) │
20
+ │ lib/data-loader.ts (Dynamic generators, CSV/JSON) │
21
+ └─────────────────────────────┬─────────────────────────────┘
22
+ │
23
+ ┌─────────────────────────────▼─────────────────────────────┐
24
+ │ PromptRunner Orchestrator │
25
+ │ (lib/prompt-runner.ts) │
26
+ └──────┬──────────────────────┬──────────────────────┬──────┘
27
+ │ │ │
28
+ ┌──────▼──────────────┐┌──────▼──────────────┐┌──────▼──────────────┐
29
+ │ Modular Handlers ││ Self-Healing & AI ││ Device & Locking │
30
+ │ lib/step-handlers.ts││ lib/memory.ts ││ lib/lock.ts │
31
+ │ (Wait, Tap, Type, ││ lib/patterns.ts ││ lib/adb.ts │
32
+ │ Cond, Loop, API, ││ lib/ai/ ││ lib/ios-driver.ts │
33
+ │ OTP, Email, Check) ││ (LLM & Vision) ││ │
34
+ └─────────────────────┘└─────────────────────┘└─────────────────────┘
35
+ │ │ │
36
+ ┌──────▼──────────────────────▼──────────────────────▼──────┐
37
+ │ Visual Testing & Diagnostics │
38
+ │ lib/baseline.ts (pixelmatch / PNG Diff) │
39
+ │ lib/explorer.ts (Autonomous Crawler) │
40
+ └─────────────────────────────┬─────────────────────────────┘
41
+ │
42
+ ┌─────────────────────────────▼─────────────────────────────┐
43
+ │ Reporting & Observability │
44
+ │ lib/reporter.ts (HTML, JSON, JUnit XML, Markdown) │
45
+ │ lib/live-server.ts (HTTP / SSE Live Monitor) │
46
+ └───────────────────────────────────────────────────────────┘
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 2. Core Modules & Responsibilities
52
+
53
+ ### 2.1 PromptRunner Orchestrator (`lib/prompt-runner.ts`)
54
+
55
+ The `PromptRunner` class coordinates the full lifecycle of test execution:
56
+
57
+ - **Device Provisioning & Locking**: Acquires exclusive locks (`lib/lock.ts`) from device pools or the default ADB device.
58
+ - **Spec Resolution**: Loads script files, resolves data-driven iterations (`#!data`, `--iterations`, `--only-row`), expands modular includes (`#include <spec>`), and tokenizes AST step blocks.
59
+ - **Step Execution Loop**: Delegates individual step execution to registered step handlers (`lib/step-handlers.ts`) while handling error collection, retry policies, screenshot capture, and timeout budgets.
60
+ - **Reporting Hook Dispatch**: Triggers lifecycle callbacks (`onStep`, `onComplete`, `onError`) across reporters and live monitors.
61
+
62
+ ### 2.2 Runner Utilities & Parser (`lib/runner-utils.ts`)
63
+
64
+ Extracted from the monolithic runner to ensure clean separation of concerns and maintainability:
65
+
66
+ - `parsePrompt(prompt)`: Tokenizes raw natural language statements into typed `PromptStep` AST definitions with action, target, value, timeout, and regex parameters.
67
+ - `assembleAstBlocks(lines)`: Assembles structured nested blocks (conditionals `IF...ELSE...ENDIF`, loops `LOOP...ENDLOOP`, wait-untils `WAIT_UNTIL...ENDWAIT`) into hierarchical AST trees.
68
+ - `expandSpecIncludes(specPath, visited)`: Recursively resolves and flattens `#include <subspec.txt>` directives with circular dependency detection.
69
+ - `buildDiagnosticError(...)`: Enriches execution failures with element dumps, screenshot paths, and suggested locator fixes.
70
+ - `findTargetInputField(tree, label)` & `matchNodes(tree, query)`: Spatial and attribute-based UI hierarchy matching algorithms.
71
+
72
+ ### 2.3 Modular Step Handlers (`lib/step-handlers.ts`)
73
+
74
+ Instead of an unwieldy switch-case statement, execution is delegated to decoupled, single-responsibility handlers:
75
+
76
+ - **Primitive Action Handlers**: `WaitHandler`, `TapHandler`, `TypeHandler`, `VerifyHandler`, `SwipeHandler`, `KeyEventHandler`.
77
+ - **Flow Control Handlers**: `ConditionalHandler` (boolean element visibility checks), `LoopHandler` (fixed or dynamic iteration loops), `WaitUntilHandler` (polling with timeout), `SetVariableHandler`, `RunJsHandler` (sandboxed JavaScript expressions via `node:vm`).
78
+ - **Integration Handlers**:
79
+ - `OtpHandler`: Extracts verification codes from local mock stores, environment variables, or live SMS/email inboxes.
80
+ - `ApiHandler`: Dispatches synchronous REST/HTTP assertions (`status`, `jsonPath`, `headers`) directly within the test pipeline.
81
+ - `EmailHandler`: Asserts transactional email delivery and body content against test stores.
82
+ - **State & Checkpoint Handlers**: `DeviceActionHandler` (network, airplane mode, orientation, notifications), `CheckpointHandler` (named state saves and rollback).
83
+
84
+ ### 2.4 Data-Driven Engine (`lib/data-loader.ts` & `lib/form-filler.ts`)
85
+
86
+ - **Iterative Testing**: Loads parameter matrices from CSV, JSON, or inline `#!data` tables.
87
+ - **Dynamic Generators**: In-line variable expansion for synthetic data generation:
88
+ - `$random.firstName`, `$random.lastName`, `$random.email`, `$random.phone`
89
+ - `$random.string(len)`, `$random.number(min, max)`
90
+ - `$uuid` (v4 UUID)
91
+ - `$seq.id` (monotonically incrementing sequence)
92
+ - `$date.now`, `$date.iso`, `$date.format(...)`
93
+ - `$calc(expression)`: Runtime arithmetic evaluation.
94
+
95
+ ### 2.5 Hardware & Device Layer (`lib/adb.ts`, `lib/lock.ts`, `lib/ios-driver.ts`)
96
+
97
+ - `lib/adb.ts`: Wraps Android Debug Bridge commands (`shell input`, `uiautomator dump`, `screencap`, `install`, `forward`, Wi-Fi, airplane mode, orientation).
98
+ - `lib/lock.ts`: File-locking (`flock`/lockfile) mechanism enabling parallel worker execution across multi-device test farms (`--device-pool dev1,dev2`) without device collision.
99
+ - `lib/ios-driver.ts`: Implements `DriverInterface` for Apple iOS physical devices and Simulators via `idb` and `xcrun simctl`.
100
+
101
+ ### 2.6 Visual Baselines & Computer Vision (`lib/baseline.ts`, `lib/explorer.ts`)
102
+
103
+ - Pixel-level image diffing using `pixelmatch` and PNG decoding via `pngjs`.
104
+ - Configurable failure thresholds (e.g. `diffThreshold: 0.02` for 2% variance).
105
+ - Automatic bounding box masking for dynamic regions (e.g. status bar clocks, live feeds) to eliminate false positives in visual regression testing.
106
+
107
+ ### 2.7 Self-Healing & Memory (`lib/memory.ts`, `lib/ai/`)
108
+
109
+ - Persistent memory storage (`.prompttest/memory.json`) mapping natural language queries to confirmed UI element identifiers (`resource-id`, `content-desc`, text).
110
+ - Autonomous self-healing: When an element locator shifts or fails, PromptTest queries the memory cache and fuzzy synonym dictionary (`lib/dictionary.ts`), falling back to optional LLM/Vision providers (`lib/ai/llm-provider.ts`) to repair the locator automatically.
111
+
112
+ ### 2.8 Observability & Reporting (`lib/reporter.ts`, `lib/live-server.ts`)
113
+
114
+ - Multi-format report generation: Interactive standalone HTML dashboards with embedded base64 screenshots, JSON execution summaries, JUnit XML (for CI/CD pipelines like GitHub Actions and GitLab CI), and Markdown summaries.
115
+ - Real-time event streaming (`lib/live-server.ts`) for browser dashboards and CI progress logs.
116
+
117
+ ---
118
+
119
+ ## 3. Execution Data Flow
120
+
121
+ ```
122
+ [Spec File (.txt)]
123
+ │
124
+ ▼
125
+ [expandSpecIncludes] ─── Flat Raw Prompt
126
+ │
127
+ ▼
128
+ [DataLoader / Generators] ─── Bound Row Variables ($var)
129
+ │
130
+ ▼
131
+ [assembleAstBlocks] ─── Hierarchical AST (PromptStep[])
132
+ │
133
+ ▼
134
+ [PromptRunner.runStep] ─── Iterates AST nodes
135
+ │
136
+ ├─► [Acquire Device Lock]
137
+ ├─► [Capture Screen & Dump Hierarchy]
138
+ ├─► [Resolve Element via Memory / Crawler / AI]
139
+ ├─► [Dispatch to Handler (lib/step-handlers.ts)]
140
+ ├─► [Evaluate Baseline Diff if visual step]
141
+ └─► [Emit Events & Record Step Result]
142
+ │
143
+ ▼
144
+ [Reporter.generateReport] ─── Output HTML / JSON / XML
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 4. Design Principles & Non-Functional Guarantees
150
+
151
+ 1. **Zero Client Instrumentation**: Target mobile applications require no modified build flavors, no test SDKs, and no debugging permissions beyond standard ADB authorization.
152
+ 2. **Deterministic Flow Control**: Programmatic constructs (`IF`, `LOOP`, `WAIT_UNTIL`) execute with predictable time bounds and clear exit conditions.
153
+ 3. **Fail-Fast vs. Resilient Execution**: Controlled via CLI flags (`--fail-fast` vs. `--continue-on-failure`), allowing rapid iteration in development or broad test suite discovery in nightly CI runs.
154
+ 4. **Strict Modular Decoupling**: File sizes are capped (<1100 lines for core orchestrator), types are strictly enforced without `any` escapes, and modules communicate via well-typed TypeScript interfaces.