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,68 @@
1
+ /**
2
+ * Defines the available log severity levels.
3
+ * Priority increases from DEBUG to SILENT.
4
+ */
5
+ export type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'SILENT';
6
+ /**
7
+ * A utility class for handling formatted, level-filtered console output.
8
+ */
9
+ export declare class Logger {
10
+ private currentLevel;
11
+ /**
12
+ * Initializes a new Logger instance.
13
+ * If an initialLevel is not provided, it falls back to the LOG_LEVEL environment variable,
14
+ * or defaults to 'INFO'.
15
+ *
16
+ * @param initialLevel An optional initial log level to override the default.
17
+ */
18
+ constructor(initialLevel?: LogLevel);
19
+ /**
20
+ * Updates the current log level threshold.
21
+ *
22
+ * @param level The new log level to apply.
23
+ */
24
+ setLevel(level: LogLevel): void;
25
+ /**
26
+ * Gets the current log level threshold.
27
+ *
28
+ * @returns The currently active LogLevel.
29
+ */
30
+ getLevel(): LogLevel;
31
+ /**
32
+ * Determines if a specific log level is currently enabled based on the threshold.
33
+ *
34
+ * @param level The log level to check.
35
+ * @returns true if messages of this level should be output, false otherwise.
36
+ */
37
+ isLevelEnabled(level: LogLevel): boolean;
38
+ private isJsonMode;
39
+ private emitJson;
40
+ /**
41
+ * Logs a debug message to stdout. Formatted in gray or structured JSON.
42
+ *
43
+ * @param args The message or variables to log.
44
+ */
45
+ debug(...args: unknown[]): void;
46
+ /**
47
+ * Logs an informational message to stdout. No special formatting applied or structured JSON.
48
+ *
49
+ * @param args The message or variables to log.
50
+ */
51
+ info(...args: unknown[]): void;
52
+ /**
53
+ * Logs a warning message to stderr. Formatted in yellow or structured JSON.
54
+ *
55
+ * @param args The message or variables to log.
56
+ */
57
+ warn(...args: unknown[]): void;
58
+ /**
59
+ * Logs an error message to stderr. Formatted in red or structured JSON.
60
+ *
61
+ * @param args The message or variables to log.
62
+ */
63
+ error(...args: unknown[]): void;
64
+ }
65
+ /**
66
+ * A globally accessible singleton instance of Logger for use throughout the PromptTest codebase.
67
+ */
68
+ export declare const logger: Logger;
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Represents a stored association between a test action and a specific on-screen element.
3
+ */
4
+ export interface LearnedMapping {
5
+ /** The normalized natural language intent string that led to this mapping */
6
+ canonicalIntent: string;
7
+ /** The action type being performed */
8
+ action: 'TAP' | 'TYPE' | 'VERIFY';
9
+ /** The literal text, content descriptor, or resource ID of the matched element */
10
+ matchedIdentifier: string;
11
+ /** How the matched identifier is exposed on the Android element */
12
+ matchType: 'text' | 'contentDesc' | 'resourceId';
13
+ /** Probability score [0.0 - 1.0] of this mapping being correct */
14
+ confidence: number;
15
+ /** Number of consecutive times this mapping succeeded */
16
+ successCount: number;
17
+ /** Number of consecutive times this mapping failed */
18
+ failCount: number;
19
+ /** Total lifetime successful interactions with this mapping */
20
+ totalSuccesses: number;
21
+ /** Sliding window of recent interaction outcomes ('PASS' | 'FAIL') */
22
+ recentOutcomes: ('PASS' | 'FAIL')[];
23
+ /** ISO 8601 timestamp of the last time this mapping was updated or used */
24
+ lastUpdated: string;
25
+ /** ISO 8601 timestamp when this element was last observed on screen */
26
+ lastSeenTs: string;
27
+ /** Originating locator this element was healed from during autonomous self-healing */
28
+ healedFrom?: string;
29
+ }
30
+ /**
31
+ * Represents a stored screen state fingerprint with elements, crawl status, and safe actions (LN-01, AX-07).
32
+ */
33
+ export interface ScreenMemoryEntry {
34
+ lastSeenTs: string;
35
+ elements: string[];
36
+ crawled?: boolean;
37
+ crawledAt?: string;
38
+ safeActions?: string[];
39
+ }
40
+ /**
41
+ * Represents a cached natural language intent expansion into actionable PromptTest steps (LN-03).
42
+ */
43
+ export interface IntentExpansionEntry {
44
+ intent: string;
45
+ steps: string[];
46
+ learnedAt: string;
47
+ usageCount: number;
48
+ }
49
+ /**
50
+ * Persisted JSON schema for storing memory data per Android package.
51
+ */
52
+ export interface AppMemoryData {
53
+ /** The Android application package name (or "global") */
54
+ packageName: string;
55
+ /** Schema version for migration handling */
56
+ version: number;
57
+ /** ISO 8601 timestamp of the last update to this package's memory */
58
+ lastUpdated: string;
59
+ /** Dictionary of composite keys to learned mappings */
60
+ mappings: Record<string, LearnedMapping>;
61
+ /** Optional screen-hash index mapping screen fingerprints to element keys and crawl status (LN-01, AX-07) */
62
+ screens?: Record<string, ScreenMemoryEntry>;
63
+ /** Optional macro intent expansion cache (LN-03) */
64
+ intents?: Record<string, IntentExpansionEntry>;
65
+ }
66
+ /**
67
+ * The MemoryEngine handles loading, resolving, recording, and persisting
68
+ * learned test actions to improve performance and reliability.
69
+ */
70
+ export declare class MemoryEngine {
71
+ private memoryDir;
72
+ private currentPackage;
73
+ private mappings;
74
+ private screens;
75
+ private intents;
76
+ private dirty;
77
+ private locale;
78
+ /**
79
+ * Sets the active locale for taxonomy lookup.
80
+ */
81
+ setLocale(locale: string): void;
82
+ /**
83
+ * Gets the active locale.
84
+ */
85
+ getLocale(): string;
86
+ /**
87
+ * Initializes the memory engine.
88
+ * @param customMemoryDir Optional directory path to store memory files. Defaults to a standard memory directory.
89
+ */
90
+ constructor(customMemoryDir?: string);
91
+ private cleanPackageName;
92
+ private static readonly SCHEMA_VERSION;
93
+ /**
94
+ * Initializes memory for a specific Android package, loading its existing mappings from disk.
95
+ * @param packageName The Android package name to load.
96
+ * @returns A promise that resolves when initialization is complete.
97
+ */
98
+ init(packageName: string): Promise<void>;
99
+ /**
100
+ * Resolves a deterministic canonical query for synonymous terms (LN-02).
101
+ */
102
+ getCanonicalQuery(query: string): string;
103
+ private buildKey;
104
+ /**
105
+ * Resolves a learned mapping for a specific action and query intent.
106
+ * Supports synonym-canonical resolution so equivalent phrasings resolve to the same mapping (LN-02).
107
+ * @param action The action type (e.g., 'TAP', 'TYPE').
108
+ * @param query The natural language query intent.
109
+ * @returns The learned mapping if found, otherwise undefined.
110
+ */
111
+ resolve(action: string, query: string): LearnedMapping | undefined;
112
+ /**
113
+ * Returns an ordered list of search candidates:
114
+ * 0. Screen-specific learned element identifier (if screenHash provided & verified) (LN-01)
115
+ * 1. The learned element identifier (if verified memory exists) (LN-02)
116
+ * 2. The literal query itself
117
+ * 3. Seed dictionary synonyms
118
+ *
119
+ * @param action The action being performed.
120
+ * @param query The natural language query to match.
121
+ * @param locale Optional locale override. Defaults to engine active locale.
122
+ * @param screenHash Optional screen hash fingerprint for whole-screen lookup.
123
+ * @returns Array of candidate strings to search for on screen.
124
+ */
125
+ getAllCandidates(action: string, query: string, locale?: string, screenHash?: string): string[];
126
+ /**
127
+ * Records a successful element interaction into persistent memory.
128
+ *
129
+ * @param action The action performed.
130
+ * @param query The initial query intent.
131
+ * @param matchedIdentifier The actual identifier matched on screen.
132
+ * @param matchType The type of match (text, contentDesc, resourceId).
133
+ * @param confidence Initial confidence score for the new mapping.
134
+ */
135
+ recordSuccess(action: string, query: string, matchedIdentifier: string, matchType: 'text' | 'contentDesc' | 'resourceId', confidence?: number, healedFrom?: string, screenHash?: string): void;
136
+ /**
137
+ * Associates a learned element mapping key with a screen hash fingerprint (LN-01).
138
+ * @param screenHash The unique hash fingerprint of the UI screen.
139
+ * @param elementKey The memory key of the learned mapping.
140
+ */
141
+ associateScreenElement(screenHash: string, elementKey: string): void;
142
+ /**
143
+ * Retrieves all learned elements associated with a specific screen hash (LN-01).
144
+ * Enables whole-screen fast-forwarding on recognized screens.
145
+ * @param screenHash The unique hash fingerprint of the screen.
146
+ * @returns Array of LearnedMapping objects known to exist on this screen.
147
+ */
148
+ getScreenElements(screenHash: string): LearnedMapping[];
149
+ /**
150
+ * Retrieves raw screen index data for reporting and inspection.
151
+ */
152
+ getScreenIndex(): Record<string, ScreenMemoryEntry>;
153
+ /**
154
+ * Marks a screen hash fingerprint as crawled and records verified safe actions (AX-07).
155
+ * @param screenHash The unique hash fingerprint of the screen.
156
+ * @param safeActions Optional array of action labels verified safe on this screen.
157
+ */
158
+ markScreenCrawled(screenHash: string, safeActions?: string[]): void;
159
+ /**
160
+ * Queries whether a screen fingerprint was previously crawled offline (AX-07).
161
+ * @param screenHash The unique hash fingerprint of the screen.
162
+ * @returns true if the screen was previously explored and marked crawled.
163
+ */
164
+ isScreenCrawled(screenHash: string): boolean;
165
+ /**
166
+ * Retrieves screen memory entry for a specific screen hash.
167
+ */
168
+ getScreenMemory(screenHash: string): ScreenMemoryEntry | undefined;
169
+ /**
170
+ * Retrieves the number of unique screens marked as crawled (AX-07).
171
+ */
172
+ getCrawledScreensCount(): number;
173
+ /**
174
+ * Caches a resolved natural language macro intent expansion into actionable PromptTest steps (LN-03).
175
+ * @param intent The natural language intent text (e.g. "log in with default credentials").
176
+ * @param steps Array of actionable PromptTest step strings.
177
+ */
178
+ recordIntentExpansion(intent: string, steps: string[]): void;
179
+ /**
180
+ * Retrieves a cached natural language intent expansion if available (LN-03).
181
+ * Increments usage count upon cache hit.
182
+ * @param intent The natural language intent text.
183
+ * @returns Array of step strings or undefined if not cached.
184
+ */
185
+ getIntentExpansion(intent: string): string[] | undefined;
186
+ /**
187
+ * Checks whether a macro intent expansion exists in persistent memory (LN-03).
188
+ */
189
+ hasIntentExpansion(intent: string): boolean;
190
+ /**
191
+ * Retrieves total count of cached macro intent expansions (LN-03).
192
+ */
193
+ getIntentExpansionsCount(): number;
194
+ /**
195
+ * Records an interaction failure for a learned mapping.
196
+ * Employs sliding-window decay over the last 5 interactions.
197
+ * A mapping is pruned only if 3 or more recent interactions failed or confidence drops below 0.20.
198
+ *
199
+ * @param action The action that failed.
200
+ * @param query The natural language query intent that failed.
201
+ */
202
+ recordFailure(action: string, query: string): void;
203
+ /**
204
+ * Applies stale-mapping decay for elements not observed recently (LN-05).
205
+ * Reduces confidence of mappings whose lastSeenTs is older than thresholdDays.
206
+ * Does NOT delete them outright, preserving knowledge with demoted confidence.
207
+ *
208
+ * @param thresholdDays Number of days of inactivity before decaying (defaults to CONFIG.memory.staleThresholdDays).
209
+ * @returns Number of mappings decayed.
210
+ */
211
+ decayStaleMappings(thresholdDays?: number): number;
212
+ /**
213
+ * Asynchronously commits learned knowledge to disk.
214
+ * @returns A promise that resolves when the save operation completes.
215
+ */
216
+ save(): Promise<void>;
217
+ /**
218
+ * Exports learned mappings to a designated JSON file for sharing across CI or developers.
219
+ * @param destFilePath Optional destination file path. Defaults to memory/<package>-export.json
220
+ * @returns The resolved destination file path.
221
+ */
222
+ exportMemory(destFilePath?: string): Promise<string>;
223
+ /**
224
+ * Imports learned mappings from a JSON export file into the current knowledge base.
225
+ * Merges imported mappings with existing knowledge, retaining higher-confidence entries.
226
+ * @param sourceFilePath Path to the JSON file to import.
227
+ * @returns Number of mappings successfully imported or merged.
228
+ */
229
+ importMemory(sourceFilePath: string): Promise<number>;
230
+ /**
231
+ * Retrieves all learned mappings for the current package.
232
+ * @returns An array of all learned mappings.
233
+ */
234
+ getMappingsList(): LearnedMapping[];
235
+ /**
236
+ * Gets memory statistics for the current package.
237
+ * @returns An object containing total mappings, package name, lifetime successes, and average confidence.
238
+ */
239
+ getStats(): {
240
+ totalMappings: number;
241
+ totalScreens: number;
242
+ crawledScreens: number;
243
+ totalIntents: number;
244
+ package: string;
245
+ totalSuccesses: number;
246
+ averageConfidence: number;
247
+ };
248
+ /**
249
+ * Clears the memory mappings for a specific package, deleting the associated file.
250
+ * @param packageName Optional package name to clear. Defaults to current package.
251
+ * @returns A promise resolving to true if a file was deleted, false otherwise.
252
+ */
253
+ clear(packageName?: string): Promise<boolean>;
254
+ }
255
+ /**
256
+ * Global singleton instance of the MemoryEngine.
257
+ * Used throughout the framework to access the persistent knowledge base.
258
+ */
259
+ export declare const memoryEngine: MemoryEngine;
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Centralized Regex & Matching Patterns for PromptTest
3
+ *
4
+ * Provides unified, reusable regular expressions and string extraction helpers
5
+ * for prompt instruction parsing, XML hierarchy parsing, and UI element matching.
6
+ * This file serves as the central pattern repository for all text normalization,
7
+ * variable interpolation, and string similarity operations across the framework.
8
+ */
9
+ /**
10
+ * Removes leading step numbers, bullets e.g. "1. ", "10. ", "- ", "* "
11
+ * @type {RegExp}
12
+ */
13
+ export declare const STEP_PREFIX_REGEX: RegExp;
14
+ /**
15
+ * Robust extraction of text wrapped in either double quotes ("..."), single quotes ('...'),
16
+ * or bare tokens.
17
+ * Correctly handles apostrophes inside double quotes (e.g. "Today's Schedule")
18
+ * and double quotes inside single quotes (e.g. 'Press "OK"').
19
+ *
20
+ * @param {string} text - The input text from which to extract the quoted token.
21
+ * @returns {string} The extracted text without the wrapping quotes, or trimmed text if unquoted.
22
+ */
23
+ export declare function extractQuotedText(text: string): string;
24
+ /**
25
+ * Helper to get value from a captured token match (checking group indices)
26
+ *
27
+ * @param {(string | undefined)[]} groups - Array of captured regex groups to check.
28
+ * @returns {string} The first non-empty, defined capture group string.
29
+ */
30
+ export declare function resolveTokenMatch(groups: (string | undefined)[]): string;
31
+ /**
32
+ * Dynamic variable interpolation helper
33
+ *
34
+ * @param {string} text - The raw text containing variable placeholders to interpolate.
35
+ * @param {Record<string, string>} [customVars] - Optional map of custom variables to inject.
36
+ * @returns {string} The text with all variables resolved and interpolated.
37
+ */
38
+ export declare function interpolateVariables(text: string, customVars?: Record<string, string>): string;
39
+ /**
40
+ * Collection of regular expressions used to parse natural language prompt instructions
41
+ * into actionable test steps.
42
+ * @type {Record<string, RegExp>}
43
+ */
44
+ export declare const PROMPT_ACTION_PATTERNS: {
45
+ /** TAP / CLICK: e.g. Tap 'Sign In', Click "Today's Schedule", Tap on 'rajesh.verma', Press button 'Submit' */
46
+ TAP: RegExp;
47
+ /** ORDINAL TAP: e.g. Tap 1st 'View', Click 2nd "Export", Tap last 'Delete' */
48
+ ORDINAL_TAP: RegExp;
49
+ /** RELATIVE PROXIMITY TAP: e.g. Tap 'Delete' next to 'Rohan Gupta', Click 'Edit' near 'Batch 1' */
50
+ PROXIMITY_TAP: RegExp;
51
+ /** CLEAR INPUT: e.g. Clear 'Email', Empty field 'Enter your password', Clear text in 'Search' */
52
+ CLEAR: RegExp;
53
+ /** LONG PRESS: e.g. Long press 'Mid-Term Examination Schedule', Press and hold 'Message' */
54
+ LONG_PRESS: RegExp;
55
+ /** TYPE / ENTER: e.g. Type 'ramesh@coachconnect.app' into 'Email' */
56
+ TYPE: RegExp;
57
+ /** VERIFY / ASSERT: e.g. Verify 'Apex Coaching Academy' is visible, Verify error message "Email is required" is not visible */
58
+ VERIFY: RegExp;
59
+ /** BACK: e.g. Press back, Go back, Navigate back, Back */
60
+ BACK: RegExp;
61
+ /** SCROLL TO: e.g. Scroll to 'Apex Coaching Academy', Scroll down to 'Submit', Swipe up to 'Top' */
62
+ SCROLL_TO: RegExp;
63
+ /** SCROLL / SWIPE: e.g. Scroll down, Swipe up, Swipe left on 'Card' */
64
+ SCROLL: RegExp;
65
+ /** DIRECTIONAL SWIPE: e.g. Swipe left, Swipe right, Swipe left on 'Carousel' */
66
+ DIRECTIONAL_SWIPE: RegExp;
67
+ /** TOGGLE / CHECK / UNCHECK: e.g. Toggle 'Remember Me', Check 'I agree', Turn on 'Notifications' */
68
+ TOGGLE: RegExp;
69
+ /** SELECT DROPDOWN / PICKER: e.g. Select 'Grade 10' from 'Class Dropdown' */
70
+ SELECT_DROPDOWN: RegExp;
71
+ /** APP LIFECYCLE: Launch / Open */
72
+ LAUNCH_APP: RegExp;
73
+ /** APP LIFECYCLE: Restart / Relaunch */
74
+ RESTART_APP: RegExp;
75
+ /** APP LIFECYCLE: Terminate / Close / Force Stop */
76
+ TERMINATE_APP: RegExp;
77
+ /** APP LIFECYCLE: Clear App Data */
78
+ CLEAR_DATA: RegExp;
79
+ /** APP LIFECYCLE: Grant Permission */
80
+ GRANT_PERMISSION: RegExp;
81
+ /** DEEP LINK: e.g. Open deep link 'myapp://batches/10' */
82
+ DEEP_LINK: RegExp;
83
+ /** WAIT: e.g. Wait 3s, Wait 5 seconds, Wait 2 */
84
+ WAIT: RegExp;
85
+ /** WAIT UNTIL: e.g. Wait until 'Welcome' is visible, Wait for "Submit" is enabled up to 10s */
86
+ WAIT_UNTIL: RegExp;
87
+ /** CONDITIONAL IF: e.g. If 'Allow' is visible, If 'Skip' is present */
88
+ IF_VISIBLE: RegExp;
89
+ /** CONDITIONAL ELSE */
90
+ ELSE: RegExp;
91
+ /** BLOCK TERMINATOR: End, End if, End loop, fi, done */
92
+ END: RegExp;
93
+ /** LOOP: e.g. Loop 5 times, Repeat 3 */
94
+ LOOP: RegExp;
95
+ /** FOR EACH: e.g. For each item in 'Settings List', For each 'Order Card' */
96
+ FOR_EACH: RegExp;
97
+ /** VARIABLE ASSIGNMENT: e.g. Set $username = 'admin', Set $email = $RANDOM_EMAIL */
98
+ SET_VARIABLE: RegExp;
99
+ /** DEVICE STATE: Wi-Fi on/off */
100
+ DEVICE_WIFI: RegExp;
101
+ /** DEVICE STATE: Airplane mode on/off */
102
+ DEVICE_AIRPLANE: RegExp;
103
+ /** DEVICE STATE: Orientation portrait/landscape */
104
+ DEVICE_ORIENTATION: RegExp;
105
+ /** DEVICE STATE: Notification shade */
106
+ DEVICE_NOTIFICATIONS: RegExp;
107
+ /** SPEC MODULARITY: Include / Run subflow */
108
+ INCLUDE_SPEC: RegExp;
109
+ /** JS HOOK: e.g. Run JS: vars.counter = 5 */
110
+ RUN_JS: RegExp;
111
+ /** OTP / 2FA CAPTURE: e.g. Enter verification code just sent, Enter OTP into 'Code Field' */
112
+ ENTER_OTP: RegExp;
113
+ /** API REQUEST: e.g. API GET 'https://api.example.com/status' assert status 200 */
114
+ API_REQUEST: RegExp;
115
+ /** EMAIL ASSERT: e.g. Assert email to 'user@test.com' with subject 'Welcome' contains 'Verify' */
116
+ EMAIL_ASSERT: RegExp;
117
+ /** OPTIONAL SUFFIX CHECK: (optional) or (if present) */
118
+ OPTIONAL_SUFFIX: RegExp;
119
+ /** Fallback TAP with any quotes */
120
+ FALLBACK_QUOTED_TAP: RegExp;
121
+ };
122
+ /**
123
+ * Collection of regular expressions used for parsing Android UI Automator XML hierarchies.
124
+ * @type {Record<string, RegExp>}
125
+ */
126
+ export declare const XML_HIERARCHY_PATTERNS: {
127
+ /** Outer <hierarchy> ... </hierarchy> wrapper */
128
+ HIERARCHY_ROOT: RegExp;
129
+ /** Individual XML node tag opening / self-closing / closing */
130
+ NODE_TAG: RegExp;
131
+ /** XML attribute key-value pairs (key="value") */
132
+ ATTR_KEY_VALUE: RegExp;
133
+ /** Android element bounds string: [x1,y1][x2,y2] */
134
+ BOUNDS_RECT: RegExp;
135
+ };
136
+ /**
137
+ * Unescapes standard XML and numeric character entities (e.g. &#128680; -> 🚨)
138
+ * present in Android UI Automator hierarchy dumps.
139
+ *
140
+ * @param {string} text - The XML text to unescape.
141
+ * @returns {string} The unescaped string with standard characters.
142
+ */
143
+ export declare function unescapeXml(text: string): string;
144
+ /**
145
+ * Normalizes text for resilient matching:
146
+ * - Unescapes XML entities (&amp; -> &)
147
+ * - Trims whitespace
148
+ * - Converts to lower case
149
+ * - Normalizes curly single/double quotes to straight quotes
150
+ *
151
+ * @param {string} str - The string to normalize.
152
+ * @returns {string} The normalized, stripped string.
153
+ */
154
+ export declare function normalizeText(str: string): string;
155
+ /**
156
+ * Flexible text containment check that is resilient to case, icon prefixes,
157
+ * XML entity escaping (&amp; vs &), and punctuation differences.
158
+ *
159
+ * @param {string} needle - The expected text or subset to look for.
160
+ * @param {string} haystack - The full text to search within.
161
+ * @returns {boolean} True if the haystack contains the needle.
162
+ */
163
+ export declare function matchesText(needle: string, haystack: string): boolean;
164
+ /**
165
+ * Common keywords used to identify form submission buttons or actions.
166
+ * @type {string[]}
167
+ */
168
+ export declare const SUBMIT_KEYWORDS: string[];
169
+ /**
170
+ * Semantic keywords indicating primary user actions or interactive elements.
171
+ * @type {string[]}
172
+ */
173
+ export declare const ACTION_KEYWORDS: string[];
174
+ /**
175
+ * Computes the Levenshtein distance between two strings.
176
+ *
177
+ * @param {string} s1 - The first string to compare.
178
+ * @param {string} s2 - The second string to compare.
179
+ * @returns {number} The edit distance between the two strings.
180
+ */
181
+ export declare function levenshteinDistance(s1: string, s2: string): number;
182
+ /**
183
+ * Computes a normalized similarity score between 0.0 (completely different) and 1.0 (identical).
184
+ *
185
+ * @param {string} s1 - The first string to compare.
186
+ * @param {string} s2 - The second string to compare.
187
+ * @returns {number} A score representing the similarity of the strings.
188
+ */
189
+ export declare function stringSimilarity(s1: string, s2: string): number;
190
+ /**
191
+ * Searches a list of candidates and returns the top closest matches above a given similarity threshold.
192
+ *
193
+ * @param {string} query - The target string to search for.
194
+ * @param {string[]} candidates - The array of candidate strings to search against.
195
+ * @param {number} [limit=3] - The maximum number of matches to return.
196
+ * @param {number} [threshold=0.35] - The minimum similarity score required to be considered a match.
197
+ * @returns {{ text: string; score: number }[]} An array of objects containing matching text and their scores.
198
+ */
199
+ export declare function findClosestMatches(query: string, candidates: string[], limit?: number, threshold?: number): {
200
+ text: string;
201
+ score: number;
202
+ }[];
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @module profiler
3
+ * @description
4
+ * Real-Time Mobile Performance & FPS Profiler (PF-01).
5
+ * Samples `dumpsys gfxinfo <pkg>` and `dumpsys meminfo <pkg>` during test execution,
6
+ * computes frame rendering statistics, jank percentages, and memory growth.
7
+ */
8
+ import { AndroidDriver } from './adb.js';
9
+ export interface FrameStats {
10
+ totalFrames: number;
11
+ jankyFrames: number;
12
+ jankPercentage: number;
13
+ p50Ms?: number;
14
+ p90Ms?: number;
15
+ p95Ms?: number;
16
+ p99Ms?: number;
17
+ missedVsync?: number;
18
+ slowUiThread?: number;
19
+ }
20
+ export interface MemorySample {
21
+ timestamp: number;
22
+ stepIndex?: number;
23
+ stepName?: string;
24
+ totalPssKb: number;
25
+ nativeHeapKb?: number;
26
+ javaHeapKb?: number;
27
+ }
28
+ export interface PerformanceReport {
29
+ packageName: string;
30
+ durationMs: number;
31
+ fpsCompliance: 'PASS' | 'WARN' | 'FAIL';
32
+ frames: FrameStats;
33
+ memory: {
34
+ startPssKb: number;
35
+ peakPssKb: number;
36
+ endPssKb: number;
37
+ deltaPssKb: number;
38
+ samples: MemorySample[];
39
+ };
40
+ }
41
+ /**
42
+ * Parses dumpsys gfxinfo stdout to extract frame counts, jank percentage, and percentile latencies.
43
+ */
44
+ export declare function parseGfxInfo(stdout: string): FrameStats;
45
+ /**
46
+ * Parses dumpsys meminfo stdout to extract Total PSS, Native Heap, and Java Heap values in KB.
47
+ */
48
+ export declare function parseMemInfo(stdout: string): {
49
+ totalPssKb: number;
50
+ nativeHeapKb?: number;
51
+ javaHeapKb?: number;
52
+ };
53
+ /**
54
+ * PerformanceProfiler tracks real-time frame times, jank metrics, and memory growth.
55
+ */
56
+ export declare class PerformanceProfiler {
57
+ private driver;
58
+ private serial?;
59
+ private packageName;
60
+ private startTime;
61
+ private memorySamples;
62
+ constructor(driver?: AndroidDriver, serial?: string);
63
+ /**
64
+ * Starts tracking performance for the target package.
65
+ */
66
+ start(packageName: string): Promise<void>;
67
+ /**
68
+ * Captures a discrete memory sample at a step transition.
69
+ */
70
+ sample(stepIndex: number, stepName: string): Promise<void>;
71
+ /**
72
+ * Finalizes tracking and returns the performance report.
73
+ */
74
+ stop(): Promise<PerformanceReport>;
75
+ }