prompttest 1.3.0
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/CONTRIBUTING.md +80 -0
- package/LICENSE +36 -0
- package/LICENSES.md +81 -0
- package/README.md +402 -0
- package/SECURITY.md +56 -0
- package/dist/bin/prompttest.d.ts +2 -0
- package/dist/bin/prompttest.js +1020 -0
- package/dist/constants/commands.d.ts +125 -0
- package/dist/index.d.ts +140 -0
- package/dist/index.js +862 -0
- package/dist/lib/adb.d.ts +394 -0
- package/dist/lib/ai/heuristic-resolver.d.ts +19 -0
- package/dist/lib/ai/index.d.ts +16 -0
- package/dist/lib/ai/llm-provider.d.ts +40 -0
- package/dist/lib/ai/types.d.ts +64 -0
- package/dist/lib/baseline.d.ts +111 -0
- package/dist/lib/benchmark.d.ts +100 -0
- package/dist/lib/checkpoint.d.ts +61 -0
- package/dist/lib/config-loader.d.ts +87 -0
- package/dist/lib/config.d.ts +136 -0
- package/dist/lib/crawler.d.ts +335 -0
- package/dist/lib/data-loader.d.ts +53 -0
- package/dist/lib/dfs-engine.d.ts +106 -0
- package/dist/lib/dictionary.d.ts +41 -0
- package/dist/lib/doctor.d.ts +45 -0
- package/dist/lib/driver-interface.d.ts +50 -0
- package/dist/lib/enterprise.d.ts +71 -0
- package/dist/lib/errors.d.ts +68 -0
- package/dist/lib/explorer.d.ts +121 -0
- package/dist/lib/form-filler.d.ts +101 -0
- package/dist/lib/ios-driver.d.ts +38 -0
- package/dist/lib/live-server.d.ts +47 -0
- package/dist/lib/lock.d.ts +30 -0
- package/dist/lib/logger.d.ts +68 -0
- package/dist/lib/memory.d.ts +259 -0
- package/dist/lib/patterns.d.ts +202 -0
- package/dist/lib/prompt-runner.d.ts +100 -0
- package/dist/lib/recorder.d.ts +115 -0
- package/dist/lib/repl.d.ts +29 -0
- package/dist/lib/reporter.d.ts +253 -0
- package/dist/lib/runner-utils.d.ts +290 -0
- package/dist/lib/step-handlers.d.ts +388 -0
- package/docs/ARCHITECTURE.md +154 -0
- package/docs/USER_MANUAL.md +765 -0
- package/package.json +90 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Crawler
|
|
3
|
+
* Parses Android uiautomator XML hierarchy dumps into structured node trees
|
|
4
|
+
* and provides element filtering, detection functions, and visual defect scanning.
|
|
5
|
+
* This module is crucial for interpreting the device screen state.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Represents the rectangular bounds of a UI element on the screen.
|
|
9
|
+
*/
|
|
10
|
+
export interface ElementBounds {
|
|
11
|
+
/** The x-coordinate of the left edge */
|
|
12
|
+
x1: number;
|
|
13
|
+
/** The y-coordinate of the top edge */
|
|
14
|
+
y1: number;
|
|
15
|
+
/** The x-coordinate of the right edge */
|
|
16
|
+
x2: number;
|
|
17
|
+
/** The y-coordinate of the bottom edge */
|
|
18
|
+
y2: number;
|
|
19
|
+
/** The width of the element */
|
|
20
|
+
width: number;
|
|
21
|
+
/** The height of the element */
|
|
22
|
+
height: number;
|
|
23
|
+
/** The x-coordinate of the center point */
|
|
24
|
+
centerX: number;
|
|
25
|
+
/** The y-coordinate of the center point */
|
|
26
|
+
centerY: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Represents a parsed node from the uiautomator XML hierarchy.
|
|
30
|
+
*/
|
|
31
|
+
export interface UiNode {
|
|
32
|
+
/** The index of the node among its siblings */
|
|
33
|
+
index: number;
|
|
34
|
+
/** The text content of the element */
|
|
35
|
+
text: string;
|
|
36
|
+
/** The Android resource ID of the element */
|
|
37
|
+
resourceId: string;
|
|
38
|
+
/** The Android class name of the element (e.g., android.widget.TextView) */
|
|
39
|
+
className: string;
|
|
40
|
+
/** The package name of the app the element belongs to */
|
|
41
|
+
packageName: string;
|
|
42
|
+
/** The content description (accessibility text) of the element */
|
|
43
|
+
contentDesc: string;
|
|
44
|
+
/** The physical bounds of the element on screen */
|
|
45
|
+
bounds: ElementBounds;
|
|
46
|
+
/** Whether the element can be clicked */
|
|
47
|
+
clickable: boolean;
|
|
48
|
+
/** Whether the element is currently enabled */
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
/** Whether the element currently has input focus */
|
|
51
|
+
focused: boolean;
|
|
52
|
+
/** Whether the element can be scrolled */
|
|
53
|
+
scrollable: boolean;
|
|
54
|
+
/** Whether the element is a password field */
|
|
55
|
+
password: boolean;
|
|
56
|
+
/** Whether the element is selected */
|
|
57
|
+
selected: boolean;
|
|
58
|
+
/** Whether the element is currently checked (if applicable) */
|
|
59
|
+
checked?: boolean;
|
|
60
|
+
/** Whether the element can be checked */
|
|
61
|
+
checkable?: boolean;
|
|
62
|
+
/** The child nodes nested within this element */
|
|
63
|
+
children: UiNode[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Criteria for filtering and selecting specific UI nodes.
|
|
67
|
+
*/
|
|
68
|
+
export interface ElementSelector {
|
|
69
|
+
/** Exact text or regular expression to match element text */
|
|
70
|
+
text?: string | RegExp;
|
|
71
|
+
/** Exact string or regular expression to match resource ID */
|
|
72
|
+
resourceId?: string | RegExp;
|
|
73
|
+
/** Exact string or regular expression to match content description */
|
|
74
|
+
contentDesc?: string | RegExp;
|
|
75
|
+
/** Substring to match within the class name */
|
|
76
|
+
className?: string;
|
|
77
|
+
/** Require the element to be clickable (true) or not clickable (false) */
|
|
78
|
+
clickable?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parses a raw bounds string (e.g., "[0,0][1080,2400]") into an ElementBounds object.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} raw - The bounds string from the XML attribute.
|
|
84
|
+
* @returns {ElementBounds} The parsed bounding box and center coordinates.
|
|
85
|
+
*/
|
|
86
|
+
export declare function parseBounds(raw: string): ElementBounds;
|
|
87
|
+
/**
|
|
88
|
+
* Parses raw uiautomator XML dump into a tree of structured UI nodes.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} xmlContent - The raw XML string from the device.
|
|
91
|
+
* @returns {{ root: UiNode[]; flat: UiNode[] }} An object containing the root nodes and a flattened list of all nodes.
|
|
92
|
+
/**
|
|
93
|
+
* Regex-based tag stack machine parsing uiautomator XML.
|
|
94
|
+
* Simulates an XML parser using a regex loop to build the tree manually.
|
|
95
|
+
*
|
|
96
|
+
* @param xmlContent The raw XML string from the device.
|
|
97
|
+
* @returns Object containing root nodes and a flattened list of all nodes.
|
|
98
|
+
*/
|
|
99
|
+
export declare function parseHierarchyXmlRegex(xmlContent: string): {
|
|
100
|
+
root: UiNode[];
|
|
101
|
+
flat: UiNode[];
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Streaming SAX-style parser for uiautomator XML dumps (SP-05).
|
|
105
|
+
* Tokenizes character-by-character so attribute values containing '>' or '<'
|
|
106
|
+
* cannot corrupt tag parsing or tree structure.
|
|
107
|
+
*
|
|
108
|
+
* @param xmlContent The raw XML string.
|
|
109
|
+
* @returns Object containing root nodes and a flattened list of all nodes.
|
|
110
|
+
*/
|
|
111
|
+
export declare function parseHierarchyXmlStreaming(xmlContent: string): {
|
|
112
|
+
root: UiNode[];
|
|
113
|
+
flat: UiNode[];
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Parses raw uiautomator XML dump into a tree of structured UI nodes.
|
|
117
|
+
* Supports configurable parser mode ('regex' | 'streaming') (SP-05).
|
|
118
|
+
*
|
|
119
|
+
* @param xmlContent The raw XML string from the device.
|
|
120
|
+
* @param mode Optional parser mode override ('regex' | 'streaming'). Defaults to CONFIG.parser.mode.
|
|
121
|
+
* @returns An object containing the root nodes and a flattened list of all nodes.
|
|
122
|
+
*/
|
|
123
|
+
export declare function parseHierarchyXml(xmlContent: string, mode?: 'regex' | 'streaming'): {
|
|
124
|
+
root: UiNode[];
|
|
125
|
+
flat: UiNode[];
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Filters a list of UI nodes based on the given element selector criteria.
|
|
129
|
+
*
|
|
130
|
+
* @param {UiNode[]} nodes - The array of UI nodes to filter.
|
|
131
|
+
* @param {ElementSelector} selector - The criteria to apply for filtering.
|
|
132
|
+
* @returns {UiNode[]} An array of nodes that match the selector criteria.
|
|
133
|
+
*/
|
|
134
|
+
export declare function findNodes(nodes: UiNode[], selector: ElementSelector): UiNode[];
|
|
135
|
+
/**
|
|
136
|
+
* Patterns identifying development error, warning, info consoles, toasts, and stack traces.
|
|
137
|
+
*/
|
|
138
|
+
export declare const LOGBOX_PATTERNS: readonly RegExp[];
|
|
139
|
+
/**
|
|
140
|
+
* Evaluates whether a UI element belongs to a development overlay, LogBox console, or stack trace.
|
|
141
|
+
*
|
|
142
|
+
* @param node - UI element node to inspect.
|
|
143
|
+
* @returns True if element is part of a development console or overlay.
|
|
144
|
+
*/
|
|
145
|
+
export declare function isLogBoxNode(node: UiNode): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Finds text input fields (EditText / TextInput) on screen.
|
|
148
|
+
*
|
|
149
|
+
* @param {UiNode[]} nodes - The array of UI nodes to search within.
|
|
150
|
+
* @returns {UiNode[]} A list of input field nodes.
|
|
151
|
+
*/
|
|
152
|
+
export declare function findInputFields(nodes: UiNode[]): UiNode[];
|
|
153
|
+
/**
|
|
154
|
+
* Detects items inside scrollable lists / RecyclerViews / ListViews.
|
|
155
|
+
*
|
|
156
|
+
* @param {UiNode[]} nodes - The array of UI nodes to search within.
|
|
157
|
+
* @param {{ width: number; height: number }} [screenDims] - Optional screen dimensions to scale heuristics against.
|
|
158
|
+
* @returns {UiNode[]} A list of nodes that represent individual items in a list.
|
|
159
|
+
*/
|
|
160
|
+
export declare function findListItems(nodes: UiNode[], screenDims?: {
|
|
161
|
+
width: number;
|
|
162
|
+
height: number;
|
|
163
|
+
}): UiNode[];
|
|
164
|
+
/**
|
|
165
|
+
* Finds interactive action buttons on screen (e.g. Save, Submit, Like, Favorite, Add, Sign In).
|
|
166
|
+
*
|
|
167
|
+
* @param {UiNode[]} nodes - The array of UI nodes to search within.
|
|
168
|
+
* @returns {UiNode[]} A list of action button nodes.
|
|
169
|
+
*/
|
|
170
|
+
export declare function findActionButtons(nodes: UiNode[]): UiNode[];
|
|
171
|
+
/**
|
|
172
|
+
* Finds bottom navigation tabs or tab layout items.
|
|
173
|
+
*
|
|
174
|
+
* @param {UiNode[]} nodes - The array of UI nodes to search within.
|
|
175
|
+
* @param {number} [screenHeight=CONFIG.screen.fallbackHeight] - The height of the screen to calculate the bottom threshold.
|
|
176
|
+
* @returns {UiNode[]} A list of navigation tab nodes.
|
|
177
|
+
*/
|
|
178
|
+
export declare function findNavigationTabs(nodes: UiNode[], screenHeight?: number, targetPackage?: string): UiNode[];
|
|
179
|
+
/**
|
|
180
|
+
* Checks for visible crash messages, error dialogs, or ANRs.
|
|
181
|
+
*
|
|
182
|
+
* @param {UiNode[]} nodes - The array of UI nodes to search within.
|
|
183
|
+
* @returns {UiNode[]} A list of nodes that appear to be part of an error or crash dialog.
|
|
184
|
+
*/
|
|
185
|
+
export declare function findErrorDialogs(nodes: UiNode[]): UiNode[];
|
|
186
|
+
/**
|
|
187
|
+
* Patterns that indicate potentially irreversible or high-risk destructive actions.
|
|
188
|
+
* Autonomous exploration must never tap elements matching these patterns in strict mode.
|
|
189
|
+
*/
|
|
190
|
+
export declare const DESTRUCTIVE_ACTION_PATTERNS: readonly RegExp[];
|
|
191
|
+
/**
|
|
192
|
+
* Moderate safety patterns shielding solely authentication and catastrophic account loss,
|
|
193
|
+
* while permitting localized in-app modifications and draft/item deletions.
|
|
194
|
+
*/
|
|
195
|
+
export declare const MODERATE_DESTRUCTIVE_PATTERNS: readonly RegExp[];
|
|
196
|
+
/**
|
|
197
|
+
* Patterns identifying external app triggers, deep links, or web views (AX-11).
|
|
198
|
+
* Autonomous crawlers skip these in-app to prevent escaping into Chrome, Play Store, or external apps.
|
|
199
|
+
*/
|
|
200
|
+
export declare const EXTERNAL_INTENT_PATTERNS: readonly RegExp[];
|
|
201
|
+
/**
|
|
202
|
+
* Supported safety enforcement policies (AX-10).
|
|
203
|
+
*/
|
|
204
|
+
export type SafetyMode = 'strict' | 'moderate' | 'interactive' | 'disabled';
|
|
205
|
+
/**
|
|
206
|
+
* Evaluates whether a UI element represents a destructive or high-risk action (AX-09, AX-10).
|
|
207
|
+
*
|
|
208
|
+
* @param node - UI element node to inspect.
|
|
209
|
+
* @param customBlacklist - Optional user-defined keywords or regular expressions.
|
|
210
|
+
* @param mode - Safety enforcement mode ('strict', 'moderate', 'interactive', 'disabled').
|
|
211
|
+
* @returns True if the element matches destructive patterns under the active safety policy.
|
|
212
|
+
*/
|
|
213
|
+
export declare function isDestructiveAction(node: UiNode, customBlacklist?: readonly (string | RegExp)[], mode?: SafetyMode): boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Evaluates whether a UI element represents an external app intent or web link (AX-11).
|
|
216
|
+
*
|
|
217
|
+
* @param node - UI element node to inspect.
|
|
218
|
+
* @returns True if element matches external intent patterns.
|
|
219
|
+
*/
|
|
220
|
+
export declare function isExternalIntentAction(node: UiNode): boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Information describing a detected development console or modal overlay (AX-13).
|
|
223
|
+
*/
|
|
224
|
+
/**
|
|
225
|
+
* Information describing a detected development console or modal overlay (AX-13).
|
|
226
|
+
*/
|
|
227
|
+
export interface DevOverlayMatch {
|
|
228
|
+
type: 'logbox' | 'anr';
|
|
229
|
+
severity: 'error' | 'warning' | 'info';
|
|
230
|
+
node: UiNode;
|
|
231
|
+
errorText: string;
|
|
232
|
+
sourceLocation?: string;
|
|
233
|
+
stackTrace?: string[];
|
|
234
|
+
dismissButton?: UiNode;
|
|
235
|
+
isToast?: boolean;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Scans UI hierarchy nodes to detect development error consoles, LogBox overlays, warnings, info toasts, or ANRs (AX-13).
|
|
239
|
+
*
|
|
240
|
+
* @param nodes - Array of UI nodes on the current screen.
|
|
241
|
+
* @returns Match metadata if an overlay is detected, otherwise null.
|
|
242
|
+
*/
|
|
243
|
+
export declare function findDevOverlay(nodes: UiNode[]): DevOverlayMatch | null;
|
|
244
|
+
/**
|
|
245
|
+
* Identifies toggleable controls such as checkboxes, switches, and radio buttons.
|
|
246
|
+
*
|
|
247
|
+
* @param nodes - Array of UI nodes.
|
|
248
|
+
* @returns Array of checkable or switch UI nodes.
|
|
249
|
+
*/
|
|
250
|
+
export declare function findCheckableControls(nodes: UiNode[]): UiNode[];
|
|
251
|
+
/**
|
|
252
|
+
* Detects side-drawer or hamburger navigation buttons (AX-03).
|
|
253
|
+
*
|
|
254
|
+
* @param nodes - Array of UI nodes on the current screen.
|
|
255
|
+
* @param screenHeight - Screen height used to bound top navigation bar area.
|
|
256
|
+
* @returns The drawer button node, or null if none is present.
|
|
257
|
+
*/
|
|
258
|
+
export declare function findDrawerButton(nodes: UiNode[], screenHeight?: number, screenWidth?: number): UiNode | null;
|
|
259
|
+
/**
|
|
260
|
+
* Finds top-right header action buttons (e.g. Notification bell, Search, Settings, More options).
|
|
261
|
+
*/
|
|
262
|
+
export declare function findHeaderActionButtons(nodes: UiNode[], screenHeight?: number, screenWidth?: number): UiNode[];
|
|
263
|
+
/**
|
|
264
|
+
* Identifies vertically scrollable containers on screen (AX-04).
|
|
265
|
+
* (e.g. ScrollView, RecyclerView, ListView, or nodes with scrollable: true).
|
|
266
|
+
*
|
|
267
|
+
* @param nodes - Array of UI nodes.
|
|
268
|
+
* @returns Array of scrollable container nodes.
|
|
269
|
+
*/
|
|
270
|
+
export declare function findScrollableContainers(nodes: UiNode[]): UiNode[];
|
|
271
|
+
/**
|
|
272
|
+
* Represents a detected visual defect on the screen, such as overflows or overlapping text.
|
|
273
|
+
*/
|
|
274
|
+
export interface VisualDefect {
|
|
275
|
+
/** The type or category of the visual defect */
|
|
276
|
+
type: 'OVERLAP' | 'OVERFLOW' | 'STALLED_LOADER';
|
|
277
|
+
/** The severity level of the defect */
|
|
278
|
+
severity: 'WARN' | 'ERROR';
|
|
279
|
+
/** A human-readable description of what is wrong */
|
|
280
|
+
description: string;
|
|
281
|
+
/** The identifiers of the UI elements involved in the defect */
|
|
282
|
+
elements: string[];
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Inspects parsed UI hierarchy to detect visual bugs, broken layouts,
|
|
286
|
+
* clipped elements, and unintended overlapping text nodes.
|
|
287
|
+
*
|
|
288
|
+
* @param {UiNode[]} nodes - The array of structured UI nodes representing the current screen.
|
|
289
|
+
* @param {number} [screenWidth=1080] - The physical width of the device screen.
|
|
290
|
+
* @param {number} [screenHeight=2400] - The physical height of the device screen.
|
|
291
|
+
* @returns {VisualDefect[]} A list of any detected visual anomalies or bugs.
|
|
292
|
+
*/
|
|
293
|
+
export declare function detectVisualDefects(nodes: UiNode[], screenWidth?: number, screenHeight?: number, overlapRatio?: number): VisualDefect[];
|
|
294
|
+
/**
|
|
295
|
+
* Navigation paradigm detected for an application.
|
|
296
|
+
*/
|
|
297
|
+
export type NavigationParadigm = 'bottom_tabs' | 'top_tabs' | 'drawer' | 'single_hub';
|
|
298
|
+
/**
|
|
299
|
+
* Result of detecting the top-level navigation structure.
|
|
300
|
+
*/
|
|
301
|
+
export interface NavigationParadigmResult {
|
|
302
|
+
paradigm: NavigationParadigm;
|
|
303
|
+
roots: UiNode[];
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Detects the root navigation paradigm of an application (Universal Navigation).
|
|
307
|
+
*
|
|
308
|
+
* @param nodes - Array of UI nodes on the screen.
|
|
309
|
+
* @param screenDims - Physical screen width and height.
|
|
310
|
+
* @param targetPackage - Optional package name filter.
|
|
311
|
+
* @returns Detected paradigm and list of root interactive elements.
|
|
312
|
+
*/
|
|
313
|
+
export declare function detectNavigationParadigm(nodes: UiNode[], screenDims?: {
|
|
314
|
+
width: number;
|
|
315
|
+
height: number;
|
|
316
|
+
}, targetPackage?: string): NavigationParadigmResult;
|
|
317
|
+
/**
|
|
318
|
+
* Partitions repeated sibling cards/list items into equivalence classes,
|
|
319
|
+
* keeping at most maxPerCluster representative items per family (Universal List Guard).
|
|
320
|
+
*
|
|
321
|
+
* @param nodes - Array of candidate list items.
|
|
322
|
+
* @param maxPerCluster - Maximum items to keep per sibling group (default: 2).
|
|
323
|
+
* @returns Pruned list with representative items.
|
|
324
|
+
*/
|
|
325
|
+
export declare function clusterSiblingElements(nodes: UiNode[], maxPerCluster?: number): UiNode[];
|
|
326
|
+
/**
|
|
327
|
+
* Locates an in-app Back, Close, or Cancel button in the upper screen area (Universal Backtracking).
|
|
328
|
+
*
|
|
329
|
+
* @param nodes - Array of UI nodes on the current screen.
|
|
330
|
+
* @param screenHeight - Screen height used to bound top bar area.
|
|
331
|
+
* @param screenWidth - Screen width used to bound top-left area.
|
|
332
|
+
* @param isChildScreen - Whether we are currently in an inner/child screen where top-left icon is a back button.
|
|
333
|
+
* @returns The in-app back button node, or null if none found.
|
|
334
|
+
*/
|
|
335
|
+
export declare function findInAppBackButton(nodes: UiNode[], screenHeight?: number, screenWidth?: number, isChildScreen?: boolean): UiNode | null;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module data-loader
|
|
3
|
+
* @description Data-driven test provider for PromptTest.
|
|
4
|
+
* Parses external CSV/JSON files and inline data directives (#!data),
|
|
5
|
+
* providing parameter rows for multi-iteration test execution.
|
|
6
|
+
*/
|
|
7
|
+
export interface DataFilterOptions {
|
|
8
|
+
onlyRow?: number;
|
|
9
|
+
iterations?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ParsedDataDirective {
|
|
12
|
+
/** Raw directive string found in spec header. */
|
|
13
|
+
directive: string;
|
|
14
|
+
/** File path referenced in #!data directive, or 'inline'. */
|
|
15
|
+
source: string;
|
|
16
|
+
/** Cleaned spec text with data directives removed. */
|
|
17
|
+
cleanedSpec: string;
|
|
18
|
+
/** Parsed data rows. */
|
|
19
|
+
rows: Record<string, string>[];
|
|
20
|
+
}
|
|
21
|
+
export declare class DataSpecLoader {
|
|
22
|
+
/**
|
|
23
|
+
* Discovers and parses `#!data` directive in spec content.
|
|
24
|
+
*
|
|
25
|
+
* @param specContent - Raw spec content.
|
|
26
|
+
* @param baseDir - Directory of the spec file to resolve relative paths.
|
|
27
|
+
* @returns Parsed directive details and rows, or null if no #!data directive exists.
|
|
28
|
+
*/
|
|
29
|
+
static extractDataDirective(specContent: string, baseDir?: string): ParsedDataDirective | null;
|
|
30
|
+
/**
|
|
31
|
+
* Loads data rows from an external CSV or JSON file.
|
|
32
|
+
*
|
|
33
|
+
* @param filePath - Path to CSV or JSON data file.
|
|
34
|
+
* @returns Array of key-value data records.
|
|
35
|
+
*/
|
|
36
|
+
static loadFromFile(filePath: string): Record<string, string>[];
|
|
37
|
+
/**
|
|
38
|
+
* Parses JSON string into an array of string-mapped records.
|
|
39
|
+
*/
|
|
40
|
+
static parseJson(jsonString: string): Record<string, string>[];
|
|
41
|
+
/**
|
|
42
|
+
* Robust RFC-4180 compliant CSV parser supporting quotes, commas within fields,
|
|
43
|
+
* escaped quotes (""), and varied newline formats.
|
|
44
|
+
*/
|
|
45
|
+
static parseCsv(csvString: string): Record<string, string>[];
|
|
46
|
+
/**
|
|
47
|
+
* Filters and bounds rows according to CLI / execution flags (e.g. onlyRow, iterations).
|
|
48
|
+
*/
|
|
49
|
+
static filterRows(rows: Record<string, string>[], options?: DataFilterOptions): Record<string, string>[];
|
|
50
|
+
private static parseCsvRow;
|
|
51
|
+
private static splitCsvLines;
|
|
52
|
+
private static stringifyObject;
|
|
53
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { UiNode } from './crawler.js';
|
|
2
|
+
import { type SafetyMode } from './crawler.js';
|
|
3
|
+
import { AndroidDriver } from './adb.js';
|
|
4
|
+
import { QaReporter } from './reporter.js';
|
|
5
|
+
import { MemoryEngine } from './memory.js';
|
|
6
|
+
export interface DfsElementAction {
|
|
7
|
+
node: UiNode;
|
|
8
|
+
type: 'input' | 'toggle' | 'overlay' | 'transition';
|
|
9
|
+
label: string;
|
|
10
|
+
tested: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface ScreenNode {
|
|
13
|
+
hash: string;
|
|
14
|
+
semanticHash: string;
|
|
15
|
+
title: string;
|
|
16
|
+
elements: DfsElementAction[];
|
|
17
|
+
status: 'DISCOVERED' | 'IN_PROGRESS' | 'FULLY_EXPLORED';
|
|
18
|
+
depth: number;
|
|
19
|
+
interactionCount: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NavigationFrame {
|
|
22
|
+
screenHash: string;
|
|
23
|
+
semanticHash: string;
|
|
24
|
+
title: string;
|
|
25
|
+
actionTaken?: string;
|
|
26
|
+
timestamp: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DfsEngineOptions {
|
|
29
|
+
packageName: string;
|
|
30
|
+
serial?: string;
|
|
31
|
+
maxScreens?: number;
|
|
32
|
+
maxDepth?: number;
|
|
33
|
+
stepBudget?: number;
|
|
34
|
+
maxInteractionsPerScreen?: number;
|
|
35
|
+
safetyMode?: SafetyMode;
|
|
36
|
+
safetyBlacklist?: readonly (string | RegExp)[];
|
|
37
|
+
screenshotPolicy?: 'all' | 'state-change' | 'failure-only';
|
|
38
|
+
skipAlreadyCrawled?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Universal Hierarchical State-Graph DFS Engine (Universal Exploration Engine).
|
|
42
|
+
* Explores mobile applications systematically by root navigation domains,
|
|
43
|
+
* maintaining a call stack with cycle detection, multi-strategy backtracking,
|
|
44
|
+
* in-place prioritization, and canonical semantic state hashing.
|
|
45
|
+
*/
|
|
46
|
+
export declare class HierarchicalDfsEngine {
|
|
47
|
+
private driver;
|
|
48
|
+
private reporter;
|
|
49
|
+
private memory;
|
|
50
|
+
private formFiller;
|
|
51
|
+
screenLedger: Map<string, ScreenNode>;
|
|
52
|
+
callStack: NavigationFrame[];
|
|
53
|
+
executedStepCount: number;
|
|
54
|
+
visitedScreenHashes: Set<string>;
|
|
55
|
+
devDefectsList: string[];
|
|
56
|
+
safetyHitList: string[];
|
|
57
|
+
externalSkippedList: string[];
|
|
58
|
+
constructor(driver?: AndroidDriver, reporter?: QaReporter, memory?: MemoryEngine);
|
|
59
|
+
/**
|
|
60
|
+
* Captures UI hierarchy globally, intercepting and triaging any development error consoles,
|
|
61
|
+
* LogBox overlays, warnings, info toasts, or ANRs before returning a clean app hierarchy.
|
|
62
|
+
*/
|
|
63
|
+
getCleanUiHierarchy(packageName: string, serial?: string, maxTriageAttempts?: number): Promise<{
|
|
64
|
+
xml: string;
|
|
65
|
+
flat: UiNode[];
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Automatically lowers the on-screen soft keyboard after typing.
|
|
69
|
+
*/
|
|
70
|
+
dismissSoftKeyboard(serial?: string): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Verifies app is running in foreground; recovers if it escaped into third-party apps.
|
|
73
|
+
*/
|
|
74
|
+
packageJailGuard(packageName: string, serial?: string): Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* Detects and dismisses system app choosers ("Open with" / ResolverActivity)
|
|
77
|
+
* to ensure playback remains strictly in-app.
|
|
78
|
+
*/
|
|
79
|
+
handleExternalMediaChooser(packageName: string, serial?: string): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Catalogs all interactive elements on a screen and classifies them into:
|
|
82
|
+
* 1. In-place input/search fields
|
|
83
|
+
* 2. In-place toggle/checkbox controls
|
|
84
|
+
* 3. Ephemeral modals/pickers
|
|
85
|
+
* 4. Deep navigational transitions (action buttons, list cards)
|
|
86
|
+
*/
|
|
87
|
+
catalogScreen(nodes: UiNode[], screenDims: {
|
|
88
|
+
width: number;
|
|
89
|
+
height: number;
|
|
90
|
+
}, rootNodes?: UiNode[]): DfsElementAction[];
|
|
91
|
+
/**
|
|
92
|
+
* Multi-strategy universal backtracking:
|
|
93
|
+
* 1. Try explicit in-app back/close button in upper screen
|
|
94
|
+
* 2. Try hardware KEYCODE_BACK
|
|
95
|
+
* 3. Verify parent restoration
|
|
96
|
+
*/
|
|
97
|
+
safeBacktrack(expectedSemanticHash: string, packageName: string, serial?: string, rootNode?: UiNode, allowHardwareBack?: boolean): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Executes universal Hierarchical State-Graph DFS exploration.
|
|
100
|
+
*/
|
|
101
|
+
explore(options: DfsEngineOptions): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Recursive/Stack-based DFS node explorer for a given screen.
|
|
104
|
+
*/
|
|
105
|
+
private exploreDfsNode;
|
|
106
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curated Universal Mobile UI Seed Dictionary.
|
|
3
|
+
* Maps canonical English concepts to standard mobile synonyms, icon glyphs,
|
|
4
|
+
* accessibility labels, and component naming conventions.
|
|
5
|
+
*
|
|
6
|
+
* Schema: Record<CanonicalTerm, Array<Synonym>>
|
|
7
|
+
* Usage: Used to pre-populate the memory engine and enhance naive semantic
|
|
8
|
+
* string matching during UI hierarchy traversal.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Curated Universal Mobile UI Seed Dictionary Packs per Locale.
|
|
12
|
+
* Maps canonical concepts to standard mobile synonyms, icon glyphs,
|
|
13
|
+
* accessibility labels, and component naming conventions.
|
|
14
|
+
*/
|
|
15
|
+
export declare const LOCALE_PACKS: Record<string, Record<string, string[]>>;
|
|
16
|
+
/**
|
|
17
|
+
* Backward compatibility export: Canonical English mobile taxonomy.
|
|
18
|
+
*/
|
|
19
|
+
export declare const GLOBAL_SEED_DICTIONARY: Record<string, string[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Registers or extends a custom locale pack at runtime.
|
|
22
|
+
*
|
|
23
|
+
* @param locale Two-letter or language code (e.g. 'fr', 'de', 'ja').
|
|
24
|
+
* @param pack Record mapping canonical concepts to synonyms.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerLocalePack(locale: string, pack: Record<string, string[]>): void;
|
|
27
|
+
/**
|
|
28
|
+
* Returns list of all registered locale identifiers.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getSupportedLocales(): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Returns canonical synonyms for a given term from the locale seed dictionary in O(1) time.
|
|
33
|
+
* Falls back to English if term is not found in specified locale.
|
|
34
|
+
*
|
|
35
|
+
* @param term The word or phrase to look up.
|
|
36
|
+
* @param locale Optional locale code. Defaults to 'en'.
|
|
37
|
+
* @returns An array of normalized synonyms, including the original term itself.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getSeedSynonyms(term: string, locale?: string): string[];
|
|
40
|
+
/** Alias for getSeedSynonyms */
|
|
41
|
+
export declare const getSynonyms: typeof getSeedSynonyms;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module doctor
|
|
3
|
+
* @description
|
|
4
|
+
* Diagnostic health check utility for PromptTest.
|
|
5
|
+
* Validates the local developer environment, Node.js version, ADB installation,
|
|
6
|
+
* device connectivity, authorization, filesystem permissions, and target package availability.
|
|
7
|
+
*/
|
|
8
|
+
import { AndroidDriver } from './adb.js';
|
|
9
|
+
export interface DoctorCheck {
|
|
10
|
+
name: string;
|
|
11
|
+
passed: boolean;
|
|
12
|
+
message: string;
|
|
13
|
+
hint?: string;
|
|
14
|
+
details?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface DoctorReport {
|
|
17
|
+
timestamp: string;
|
|
18
|
+
allPassed: boolean;
|
|
19
|
+
checks: DoctorCheck[];
|
|
20
|
+
summary: {
|
|
21
|
+
passed: number;
|
|
22
|
+
failed: number;
|
|
23
|
+
warnings: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface DoctorOptions {
|
|
27
|
+
packageName?: string;
|
|
28
|
+
serial?: string;
|
|
29
|
+
json?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Runs a complete diagnostic scan of the PromptTest environment.
|
|
33
|
+
*
|
|
34
|
+
* @param driver - The AndroidDriver instance to query.
|
|
35
|
+
* @param options - Diagnostic scan configuration options.
|
|
36
|
+
* @returns Complete DoctorReport.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runDoctor(driver?: AndroidDriver, options?: DoctorOptions): Promise<DoctorReport>;
|
|
39
|
+
/**
|
|
40
|
+
* Formats a DoctorReport into user-friendly CLI terminal output with icons and remediation hints.
|
|
41
|
+
*
|
|
42
|
+
* @param report - The DoctorReport to format.
|
|
43
|
+
* @returns Multi-line formatted terminal string.
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatDoctorReport(report: DoctorReport): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module driver-interface
|
|
3
|
+
* @description
|
|
4
|
+
* Universal mobile device driver interface and common types for PromptTest.
|
|
5
|
+
* Decouples the test runner and autonomous crawler from platform-specific APIs
|
|
6
|
+
* (Android ADB vs. iOS XCUITest / simctl / idb).
|
|
7
|
+
*/
|
|
8
|
+
export interface MobileDeviceInfo {
|
|
9
|
+
serial: string;
|
|
10
|
+
state: 'device' | 'simulator' | 'offline' | 'unauthorized';
|
|
11
|
+
model?: string;
|
|
12
|
+
platform: 'android' | 'ios';
|
|
13
|
+
}
|
|
14
|
+
export interface ScreenDimensions {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Common device driver contract implemented by AndroidDriver and IosDriver.
|
|
20
|
+
*/
|
|
21
|
+
export interface DeviceDriver {
|
|
22
|
+
/** Returns the primary target device serial or identifier. */
|
|
23
|
+
getDefaultDevice(): string | undefined;
|
|
24
|
+
/** Resolves or validates the active device identifier. */
|
|
25
|
+
ensureDefaultDevice(serial?: string): Promise<string>;
|
|
26
|
+
/** Lists all connected physical devices and emulators/simulators. */
|
|
27
|
+
getConnectedDevices(): Promise<MobileDeviceInfo[]>;
|
|
28
|
+
/** Retrieves the screen resolution in physical pixels. */
|
|
29
|
+
getScreenDimensions(serial?: string): Promise<ScreenDimensions>;
|
|
30
|
+
/** Captures the current display buffer as a PNG image. */
|
|
31
|
+
captureScreenshot(serial?: string): Promise<Buffer>;
|
|
32
|
+
/** Dumps the active window accessibility UI hierarchy XML. */
|
|
33
|
+
getUiHierarchy(serial?: string): Promise<string>;
|
|
34
|
+
/** Simulates a touch tap gesture at coordinates (x, y). */
|
|
35
|
+
tap(x: number, y: number, serial?: string): Promise<void>;
|
|
36
|
+
/** Simulates typing text into the currently focused input field. */
|
|
37
|
+
inputText(text: string, serial?: string): Promise<void>;
|
|
38
|
+
/** Sends a key event or hardware keycode. */
|
|
39
|
+
pressKey(key: string, serial?: string): Promise<void>;
|
|
40
|
+
/** Performs a touch drag or swipe gesture between two points. */
|
|
41
|
+
swipe(x1: number, y1: number, x2: number, y2: number, durationMs?: number, serial?: string): Promise<void>;
|
|
42
|
+
/** Launches an application by package name (Android) or bundle ID (iOS). */
|
|
43
|
+
launchApp(appId: string, serial?: string): Promise<void>;
|
|
44
|
+
/** Forcefully terminates a running application. */
|
|
45
|
+
forceStop(appId: string, serial?: string): Promise<void>;
|
|
46
|
+
/** Checks if the application is installed on the target device. */
|
|
47
|
+
isAppInstalled(appId: string, serial?: string): Promise<boolean>;
|
|
48
|
+
/** Retrieves the foreground active package name or bundle ID. */
|
|
49
|
+
getForegroundPackage(serial?: string): Promise<string | null>;
|
|
50
|
+
}
|