playwright-locator-healer 0.1.3

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 (137) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/LICENSE +21 -0
  3. package/README.md +338 -0
  4. package/USAGE.md +217 -0
  5. package/dist/healing/audit-log.d.ts +9 -0
  6. package/dist/healing/audit-log.d.ts.map +1 -0
  7. package/dist/healing/audit-log.js +22 -0
  8. package/dist/healing/audit-log.js.map +1 -0
  9. package/dist/healing/auto-fixture.d.ts +14 -0
  10. package/dist/healing/auto-fixture.d.ts.map +1 -0
  11. package/dist/healing/auto-fixture.js +430 -0
  12. package/dist/healing/auto-fixture.js.map +1 -0
  13. package/dist/healing/cache.d.ts +11 -0
  14. package/dist/healing/cache.d.ts.map +1 -0
  15. package/dist/healing/cache.js +128 -0
  16. package/dist/healing/cache.js.map +1 -0
  17. package/dist/healing/circuit-breaker.d.ts +11 -0
  18. package/dist/healing/circuit-breaker.d.ts.map +1 -0
  19. package/dist/healing/circuit-breaker.js +34 -0
  20. package/dist/healing/circuit-breaker.js.map +1 -0
  21. package/dist/healing/cost-tracker.d.ts +30 -0
  22. package/dist/healing/cost-tracker.d.ts.map +1 -0
  23. package/dist/healing/cost-tracker.js +101 -0
  24. package/dist/healing/cost-tracker.js.map +1 -0
  25. package/dist/healing/dom-extractor.d.ts +9 -0
  26. package/dist/healing/dom-extractor.d.ts.map +1 -0
  27. package/dist/healing/dom-extractor.js +268 -0
  28. package/dist/healing/dom-extractor.js.map +1 -0
  29. package/dist/healing/errors.d.ts +33 -0
  30. package/dist/healing/errors.d.ts.map +1 -0
  31. package/dist/healing/errors.js +40 -0
  32. package/dist/healing/errors.js.map +1 -0
  33. package/dist/healing/heal/caller-context.d.ts +8 -0
  34. package/dist/healing/heal/caller-context.d.ts.map +1 -0
  35. package/dist/healing/heal/caller-context.js +46 -0
  36. package/dist/healing/heal/caller-context.js.map +1 -0
  37. package/dist/healing/heal/orchestrator-helpers.d.ts +84 -0
  38. package/dist/healing/heal/orchestrator-helpers.d.ts.map +1 -0
  39. package/dist/healing/heal/orchestrator-helpers.js +117 -0
  40. package/dist/healing/heal/orchestrator-helpers.js.map +1 -0
  41. package/dist/healing/heal/orchestrator.d.ts +47 -0
  42. package/dist/healing/heal/orchestrator.d.ts.map +1 -0
  43. package/dist/healing/heal/orchestrator.js +644 -0
  44. package/dist/healing/heal/orchestrator.js.map +1 -0
  45. package/dist/healing/heal/playwright-code.d.ts +26 -0
  46. package/dist/healing/heal/playwright-code.d.ts.map +1 -0
  47. package/dist/healing/heal/playwright-code.js +134 -0
  48. package/dist/healing/heal/playwright-code.js.map +1 -0
  49. package/dist/healing/heal/preflight.d.ts +8 -0
  50. package/dist/healing/heal/preflight.d.ts.map +1 -0
  51. package/dist/healing/heal/preflight.js +77 -0
  52. package/dist/healing/heal/preflight.js.map +1 -0
  53. package/dist/healing/heal/prompt.d.ts +9 -0
  54. package/dist/healing/heal/prompt.d.ts.map +1 -0
  55. package/dist/healing/heal/prompt.js +22 -0
  56. package/dist/healing/heal/prompt.js.map +1 -0
  57. package/dist/healing/heal/report.d.ts +11 -0
  58. package/dist/healing/heal/report.d.ts.map +1 -0
  59. package/dist/healing/heal/report.js +28 -0
  60. package/dist/healing/heal/report.js.map +1 -0
  61. package/dist/healing/heal/source-trace.d.ts +17 -0
  62. package/dist/healing/heal/source-trace.d.ts.map +1 -0
  63. package/dist/healing/heal/source-trace.js +59 -0
  64. package/dist/healing/heal/source-trace.js.map +1 -0
  65. package/dist/healing/index.d.ts +6 -0
  66. package/dist/healing/index.d.ts.map +1 -0
  67. package/dist/healing/index.js +3 -0
  68. package/dist/healing/index.js.map +1 -0
  69. package/dist/healing/llm-client.d.ts +58 -0
  70. package/dist/healing/llm-client.d.ts.map +1 -0
  71. package/dist/healing/llm-client.js +258 -0
  72. package/dist/healing/llm-client.js.map +1 -0
  73. package/dist/healing/logger.d.ts +18 -0
  74. package/dist/healing/logger.d.ts.map +1 -0
  75. package/dist/healing/logger.js +38 -0
  76. package/dist/healing/logger.js.map +1 -0
  77. package/dist/healing/models.d.ts +26 -0
  78. package/dist/healing/models.d.ts.map +1 -0
  79. package/dist/healing/models.js +109 -0
  80. package/dist/healing/models.js.map +1 -0
  81. package/dist/healing/overlay/bridge.d.ts +46 -0
  82. package/dist/healing/overlay/bridge.d.ts.map +1 -0
  83. package/dist/healing/overlay/bridge.js +2 -0
  84. package/dist/healing/overlay/bridge.js.map +1 -0
  85. package/dist/healing/overlay/dock.css.d.ts +2 -0
  86. package/dist/healing/overlay/dock.css.d.ts.map +1 -0
  87. package/dist/healing/overlay/dock.css.js +448 -0
  88. package/dist/healing/overlay/dock.css.js.map +1 -0
  89. package/dist/healing/overlay/dock.html.d.ts +46 -0
  90. package/dist/healing/overlay/dock.html.d.ts.map +1 -0
  91. package/dist/healing/overlay/dock.html.js +248 -0
  92. package/dist/healing/overlay/dock.html.js.map +1 -0
  93. package/dist/healing/overlay/drag.d.ts +17 -0
  94. package/dist/healing/overlay/drag.d.ts.map +1 -0
  95. package/dist/healing/overlay/drag.js +68 -0
  96. package/dist/healing/overlay/drag.js.map +1 -0
  97. package/dist/healing/overlay/inject.d.ts +41 -0
  98. package/dist/healing/overlay/inject.d.ts.map +1 -0
  99. package/dist/healing/overlay/inject.js +277 -0
  100. package/dist/healing/overlay/inject.js.map +1 -0
  101. package/dist/healing/overlay/keybinds.d.ts +33 -0
  102. package/dist/healing/overlay/keybinds.d.ts.map +1 -0
  103. package/dist/healing/overlay/keybinds.js +105 -0
  104. package/dist/healing/overlay/keybinds.js.map +1 -0
  105. package/dist/healing/prompts/heal-v21.d.ts +8 -0
  106. package/dist/healing/prompts/heal-v21.d.ts.map +1 -0
  107. package/dist/healing/prompts/heal-v21.js +204 -0
  108. package/dist/healing/prompts/heal-v21.js.map +1 -0
  109. package/dist/healing/retry-policy.d.ts +37 -0
  110. package/dist/healing/retry-policy.d.ts.map +1 -0
  111. package/dist/healing/retry-policy.js +46 -0
  112. package/dist/healing/retry-policy.js.map +1 -0
  113. package/dist/healing/session-cost.d.ts +44 -0
  114. package/dist/healing/session-cost.d.ts.map +1 -0
  115. package/dist/healing/session-cost.js +95 -0
  116. package/dist/healing/session-cost.js.map +1 -0
  117. package/dist/healing/test-fixture.d.ts +9 -0
  118. package/dist/healing/test-fixture.d.ts.map +1 -0
  119. package/dist/healing/test-fixture.js +37 -0
  120. package/dist/healing/test-fixture.js.map +1 -0
  121. package/dist/healing/types.d.ts +399 -0
  122. package/dist/healing/types.d.ts.map +1 -0
  123. package/dist/healing/types.js +162 -0
  124. package/dist/healing/types.js.map +1 -0
  125. package/dist/healing/validator.d.ts +64 -0
  126. package/dist/healing/validator.d.ts.map +1 -0
  127. package/dist/healing/validator.js +286 -0
  128. package/dist/healing/validator.js.map +1 -0
  129. package/dist/scripts/heal-report.d.ts +23 -0
  130. package/dist/scripts/heal-report.d.ts.map +1 -0
  131. package/dist/scripts/heal-report.js +106 -0
  132. package/dist/scripts/heal-report.js.map +1 -0
  133. package/dist/scripts/init.d.ts +3 -0
  134. package/dist/scripts/init.d.ts.map +1 -0
  135. package/dist/scripts/init.js +132 -0
  136. package/dist/scripts/init.js.map +1 -0
  137. package/package.json +84 -0
@@ -0,0 +1,399 @@
1
+ import { z } from 'zod';
2
+ import type { Locator, TestInfo } from '@playwright/test';
3
+ export declare const CandidateSchema: z.ZodObject<{
4
+ tag: z.ZodString;
5
+ id: z.ZodOptional<z.ZodString>;
6
+ classes: z.ZodArray<z.ZodString, "many">;
7
+ text: z.ZodString;
8
+ ariaLabel: z.ZodOptional<z.ZodString>;
9
+ role: z.ZodOptional<z.ZodString>;
10
+ placeholder: z.ZodOptional<z.ZodString>;
11
+ name: z.ZodOptional<z.ZodString>;
12
+ type: z.ZodOptional<z.ZodString>;
13
+ href: z.ZodOptional<z.ZodString>;
14
+ title: z.ZodOptional<z.ZodString>;
15
+ dataAttrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
16
+ position: z.ZodEnum<["above-fold", "below-fold"]>;
17
+ associatedLabel: z.ZodOptional<z.ZodString>;
18
+ parentRole: z.ZodOptional<z.ZodString>;
19
+ siblingsSameTag: z.ZodOptional<z.ZodNumber>;
20
+ outerHTMLSnippet: z.ZodOptional<z.ZodString>;
21
+ }, "strip", z.ZodTypeAny, {
22
+ tag: string;
23
+ classes: string[];
24
+ text: string;
25
+ position: "above-fold" | "below-fold";
26
+ id?: string | undefined;
27
+ type?: string | undefined;
28
+ ariaLabel?: string | undefined;
29
+ role?: string | undefined;
30
+ placeholder?: string | undefined;
31
+ name?: string | undefined;
32
+ href?: string | undefined;
33
+ title?: string | undefined;
34
+ dataAttrs?: Record<string, string> | undefined;
35
+ associatedLabel?: string | undefined;
36
+ parentRole?: string | undefined;
37
+ siblingsSameTag?: number | undefined;
38
+ outerHTMLSnippet?: string | undefined;
39
+ }, {
40
+ tag: string;
41
+ classes: string[];
42
+ text: string;
43
+ position: "above-fold" | "below-fold";
44
+ id?: string | undefined;
45
+ type?: string | undefined;
46
+ ariaLabel?: string | undefined;
47
+ role?: string | undefined;
48
+ placeholder?: string | undefined;
49
+ name?: string | undefined;
50
+ href?: string | undefined;
51
+ title?: string | undefined;
52
+ dataAttrs?: Record<string, string> | undefined;
53
+ associatedLabel?: string | undefined;
54
+ parentRole?: string | undefined;
55
+ siblingsSameTag?: number | undefined;
56
+ outerHTMLSnippet?: string | undefined;
57
+ }>;
58
+ export declare const LocatorSuggestionSchema: z.ZodObject<{
59
+ selectorType: z.ZodEnum<["role", "text", "label", "testid", "css", "xpath", "filter-chain", "js"]>;
60
+ selector: z.ZodString;
61
+ rationale: z.ZodString;
62
+ tier: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
65
+ selector: string;
66
+ rationale: string;
67
+ tier?: number | null | undefined;
68
+ }, {
69
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
70
+ selector: string;
71
+ rationale: string;
72
+ tier?: number | null | undefined;
73
+ }>;
74
+ export declare const LocatorSuggestionsResponseSchema: z.ZodObject<{
75
+ suggestions: z.ZodArray<z.ZodObject<{
76
+ selectorType: z.ZodEnum<["role", "text", "label", "testid", "css", "xpath", "filter-chain", "js"]>;
77
+ selector: z.ZodString;
78
+ rationale: z.ZodString;
79
+ tier: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
80
+ }, "strip", z.ZodTypeAny, {
81
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
82
+ selector: string;
83
+ rationale: string;
84
+ tier?: number | null | undefined;
85
+ }, {
86
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
87
+ selector: string;
88
+ rationale: string;
89
+ tier?: number | null | undefined;
90
+ }>, "many">;
91
+ }, "strip", z.ZodTypeAny, {
92
+ suggestions: {
93
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
94
+ selector: string;
95
+ rationale: string;
96
+ tier?: number | null | undefined;
97
+ }[];
98
+ }, {
99
+ suggestions: {
100
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain" | "js";
101
+ selector: string;
102
+ rationale: string;
103
+ tier?: number | null | undefined;
104
+ }[];
105
+ }>;
106
+ export declare const CacheEntrySchema: z.ZodObject<{
107
+ healedSelector: z.ZodString;
108
+ selectorType: z.ZodString;
109
+ description: z.ZodString;
110
+ lastUsed: z.ZodString;
111
+ successCount: z.ZodNumber;
112
+ }, "strip", z.ZodTypeAny, {
113
+ selectorType: string;
114
+ healedSelector: string;
115
+ description: string;
116
+ lastUsed: string;
117
+ successCount: number;
118
+ }, {
119
+ selectorType: string;
120
+ healedSelector: string;
121
+ description: string;
122
+ lastUsed: string;
123
+ successCount: number;
124
+ }>;
125
+ export declare const AuditLogEntrySchema: z.ZodObject<{
126
+ timestamp: z.ZodString;
127
+ testFile: z.ZodString;
128
+ originalSelector: z.ZodString;
129
+ stage: z.ZodEnum<["cache", "llm", "visual", "terminal", "failed", "verify-failed", "wrong-element"]>;
130
+ healedSelector: z.ZodOptional<z.ZodString>;
131
+ selectorType: z.ZodString;
132
+ description: z.ZodString;
133
+ error: z.ZodOptional<z.ZodString>;
134
+ }, "strip", z.ZodTypeAny, {
135
+ selectorType: string;
136
+ description: string;
137
+ timestamp: string;
138
+ testFile: string;
139
+ originalSelector: string;
140
+ stage: "cache" | "llm" | "visual" | "terminal" | "failed" | "verify-failed" | "wrong-element";
141
+ healedSelector?: string | undefined;
142
+ error?: string | undefined;
143
+ }, {
144
+ selectorType: string;
145
+ description: string;
146
+ timestamp: string;
147
+ testFile: string;
148
+ originalSelector: string;
149
+ stage: "cache" | "llm" | "visual" | "terminal" | "failed" | "verify-failed" | "wrong-element";
150
+ healedSelector?: string | undefined;
151
+ error?: string | undefined;
152
+ }>;
153
+ export declare const HealOptionsSchema: z.ZodObject<{
154
+ initialTimeout: z.ZodOptional<z.ZodNumber>;
155
+ timeouts: z.ZodOptional<z.ZodObject<{
156
+ cacheValidate: z.ZodOptional<z.ZodNumber>;
157
+ domExtract: z.ZodOptional<z.ZodNumber>;
158
+ llmCall: z.ZodOptional<z.ZodNumber>;
159
+ candidateValidate: z.ZodOptional<z.ZodNumber>;
160
+ visualSelect: z.ZodOptional<z.ZodNumber>;
161
+ terminalSelect: z.ZodOptional<z.ZodNumber>;
162
+ }, "strip", z.ZodTypeAny, {
163
+ cacheValidate?: number | undefined;
164
+ domExtract?: number | undefined;
165
+ llmCall?: number | undefined;
166
+ candidateValidate?: number | undefined;
167
+ visualSelect?: number | undefined;
168
+ terminalSelect?: number | undefined;
169
+ }, {
170
+ cacheValidate?: number | undefined;
171
+ domExtract?: number | undefined;
172
+ llmCall?: number | undefined;
173
+ candidateValidate?: number | undefined;
174
+ visualSelect?: number | undefined;
175
+ terminalSelect?: number | undefined;
176
+ }>>;
177
+ scope: z.ZodOptional<z.ZodType<Locator, z.ZodTypeDef, Locator>>;
178
+ skipCache: z.ZodOptional<z.ZodBoolean>;
179
+ skipVisual: z.ZodOptional<z.ZodBoolean>;
180
+ testInfo: z.ZodOptional<z.ZodType<TestInfo, z.ZodTypeDef, TestInfo>>;
181
+ verify: z.ZodOptional<z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodPromise<z.ZodVoid>>>;
182
+ }, "strip", z.ZodTypeAny, {
183
+ initialTimeout?: number | undefined;
184
+ timeouts?: {
185
+ cacheValidate?: number | undefined;
186
+ domExtract?: number | undefined;
187
+ llmCall?: number | undefined;
188
+ candidateValidate?: number | undefined;
189
+ visualSelect?: number | undefined;
190
+ terminalSelect?: number | undefined;
191
+ } | undefined;
192
+ scope?: Locator | undefined;
193
+ skipCache?: boolean | undefined;
194
+ skipVisual?: boolean | undefined;
195
+ testInfo?: TestInfo | undefined;
196
+ verify?: ((...args: unknown[]) => Promise<void>) | undefined;
197
+ }, {
198
+ initialTimeout?: number | undefined;
199
+ timeouts?: {
200
+ cacheValidate?: number | undefined;
201
+ domExtract?: number | undefined;
202
+ llmCall?: number | undefined;
203
+ candidateValidate?: number | undefined;
204
+ visualSelect?: number | undefined;
205
+ terminalSelect?: number | undefined;
206
+ } | undefined;
207
+ scope?: Locator | undefined;
208
+ skipCache?: boolean | undefined;
209
+ skipVisual?: boolean | undefined;
210
+ testInfo?: TestInfo | undefined;
211
+ verify?: ((...args: unknown[]) => Promise<void>) | undefined;
212
+ }>;
213
+ export type Candidate = z.infer<typeof CandidateSchema>;
214
+ export type LocatorSuggestion = z.infer<typeof LocatorSuggestionSchema>;
215
+ export type LocatorSuggestionsResponse = z.infer<typeof LocatorSuggestionsResponseSchema>;
216
+ export type CacheEntry = z.infer<typeof CacheEntrySchema>;
217
+ export type AuditLogEntry = z.infer<typeof AuditLogEntrySchema>;
218
+ export type HealOptions = z.infer<typeof HealOptionsSchema>;
219
+ export interface CostLogEntry {
220
+ timestamp: string;
221
+ testFile: string;
222
+ originalSelector: string;
223
+ callType: 'llm' | 'pick-ai';
224
+ prompt_tokens: number;
225
+ completion_tokens: number;
226
+ cost_usd: number;
227
+ }
228
+ export declare const HealEntryFingerprintSchema: z.ZodObject<{
229
+ tag: z.ZodString;
230
+ role: z.ZodOptional<z.ZodString>;
231
+ accessibleName: z.ZodOptional<z.ZodString>;
232
+ text: z.ZodOptional<z.ZodString>;
233
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
234
+ }, "strip", z.ZodTypeAny, {
235
+ tag: string;
236
+ text?: string | undefined;
237
+ role?: string | undefined;
238
+ accessibleName?: string | undefined;
239
+ attrs?: Record<string, string> | undefined;
240
+ }, {
241
+ tag: string;
242
+ text?: string | undefined;
243
+ role?: string | undefined;
244
+ accessibleName?: string | undefined;
245
+ attrs?: Record<string, string> | undefined;
246
+ }>;
247
+ export type HealEntryFingerprint = z.infer<typeof HealEntryFingerprintSchema>;
248
+ export declare const HealEntryV2Schema: z.ZodObject<{
249
+ originalSelector: z.ZodString;
250
+ action: z.ZodString;
251
+ healedSelector: z.ZodString;
252
+ selectorType: z.ZodEnum<["role", "text", "label", "testid", "css", "xpath", "filter-chain"]>;
253
+ tier: z.ZodOptional<z.ZodNumber>;
254
+ intent: z.ZodString;
255
+ callSite: z.ZodString;
256
+ pomFrame: z.ZodString;
257
+ healedAt: z.ZodString;
258
+ fingerprint: z.ZodOptional<z.ZodObject<{
259
+ tag: z.ZodString;
260
+ role: z.ZodOptional<z.ZodString>;
261
+ accessibleName: z.ZodOptional<z.ZodString>;
262
+ text: z.ZodOptional<z.ZodString>;
263
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
264
+ }, "strip", z.ZodTypeAny, {
265
+ tag: string;
266
+ text?: string | undefined;
267
+ role?: string | undefined;
268
+ accessibleName?: string | undefined;
269
+ attrs?: Record<string, string> | undefined;
270
+ }, {
271
+ tag: string;
272
+ text?: string | undefined;
273
+ role?: string | undefined;
274
+ accessibleName?: string | undefined;
275
+ attrs?: Record<string, string> | undefined;
276
+ }>>;
277
+ }, "strip", z.ZodTypeAny, {
278
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain";
279
+ healedSelector: string;
280
+ originalSelector: string;
281
+ action: string;
282
+ intent: string;
283
+ callSite: string;
284
+ pomFrame: string;
285
+ healedAt: string;
286
+ tier?: number | undefined;
287
+ fingerprint?: {
288
+ tag: string;
289
+ text?: string | undefined;
290
+ role?: string | undefined;
291
+ accessibleName?: string | undefined;
292
+ attrs?: Record<string, string> | undefined;
293
+ } | undefined;
294
+ }, {
295
+ selectorType: "text" | "role" | "label" | "testid" | "css" | "xpath" | "filter-chain";
296
+ healedSelector: string;
297
+ originalSelector: string;
298
+ action: string;
299
+ intent: string;
300
+ callSite: string;
301
+ pomFrame: string;
302
+ healedAt: string;
303
+ tier?: number | undefined;
304
+ fingerprint?: {
305
+ tag: string;
306
+ text?: string | undefined;
307
+ role?: string | undefined;
308
+ accessibleName?: string | undefined;
309
+ attrs?: Record<string, string> | undefined;
310
+ } | undefined;
311
+ }>;
312
+ export type HealEntryV2 = z.infer<typeof HealEntryV2Schema>;
313
+ export interface CacheFileV2 {
314
+ version: 2;
315
+ entries: Record<string, HealEntryV2>;
316
+ }
317
+ export declare const FailedAttemptSchema: z.ZodObject<{
318
+ selectorType: z.ZodString;
319
+ selector: z.ZodString;
320
+ tier: z.ZodNumber;
321
+ reason: z.ZodEnum<["count-zero", "count-many", "strict-mode-violation", "invalid-selector", "js-eval-error"]>;
322
+ matchedCount: z.ZodOptional<z.ZodNumber>;
323
+ }, "strip", z.ZodTypeAny, {
324
+ selectorType: string;
325
+ selector: string;
326
+ tier: number;
327
+ reason: "count-zero" | "count-many" | "strict-mode-violation" | "invalid-selector" | "js-eval-error";
328
+ matchedCount?: number | undefined;
329
+ }, {
330
+ selectorType: string;
331
+ selector: string;
332
+ tier: number;
333
+ reason: "count-zero" | "count-many" | "strict-mode-violation" | "invalid-selector" | "js-eval-error";
334
+ matchedCount?: number | undefined;
335
+ }>;
336
+ export type FailedAttempt = z.infer<typeof FailedAttemptSchema>;
337
+ export declare const ScopedCandidateSchema: z.ZodObject<{
338
+ tag: z.ZodString;
339
+ id: z.ZodOptional<z.ZodString>;
340
+ classes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
341
+ text: z.ZodOptional<z.ZodString>;
342
+ ariaLabel: z.ZodOptional<z.ZodString>;
343
+ role: z.ZodOptional<z.ZodString>;
344
+ accessibleName: z.ZodOptional<z.ZodString>;
345
+ dataTestId: z.ZodOptional<z.ZodString>;
346
+ dataAttrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
347
+ name: z.ZodOptional<z.ZodString>;
348
+ type: z.ZodOptional<z.ZodString>;
349
+ placeholder: z.ZodOptional<z.ZodString>;
350
+ href: z.ZodOptional<z.ZodString>;
351
+ associatedLabel: z.ZodOptional<z.ZodString>;
352
+ parentRole: z.ZodOptional<z.ZodString>;
353
+ siblingsSameTag: z.ZodOptional<z.ZodNumber>;
354
+ neighborText: z.ZodOptional<z.ZodString>;
355
+ xpathRelative: z.ZodString;
356
+ outerHTMLSnippet: z.ZodOptional<z.ZodString>;
357
+ }, "strip", z.ZodTypeAny, {
358
+ tag: string;
359
+ xpathRelative: string;
360
+ id?: string | undefined;
361
+ type?: string | undefined;
362
+ classes?: string[] | undefined;
363
+ text?: string | undefined;
364
+ ariaLabel?: string | undefined;
365
+ role?: string | undefined;
366
+ placeholder?: string | undefined;
367
+ name?: string | undefined;
368
+ href?: string | undefined;
369
+ dataAttrs?: Record<string, string> | undefined;
370
+ associatedLabel?: string | undefined;
371
+ parentRole?: string | undefined;
372
+ siblingsSameTag?: number | undefined;
373
+ outerHTMLSnippet?: string | undefined;
374
+ accessibleName?: string | undefined;
375
+ dataTestId?: string | undefined;
376
+ neighborText?: string | undefined;
377
+ }, {
378
+ tag: string;
379
+ xpathRelative: string;
380
+ id?: string | undefined;
381
+ type?: string | undefined;
382
+ classes?: string[] | undefined;
383
+ text?: string | undefined;
384
+ ariaLabel?: string | undefined;
385
+ role?: string | undefined;
386
+ placeholder?: string | undefined;
387
+ name?: string | undefined;
388
+ href?: string | undefined;
389
+ dataAttrs?: Record<string, string> | undefined;
390
+ associatedLabel?: string | undefined;
391
+ parentRole?: string | undefined;
392
+ siblingsSameTag?: number | undefined;
393
+ outerHTMLSnippet?: string | undefined;
394
+ accessibleName?: string | undefined;
395
+ dataTestId?: string | undefined;
396
+ neighborText?: string | undefined;
397
+ }>;
398
+ export type ScopedCandidate = z.infer<typeof ScopedCandidateSchema>;
399
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../healing/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK1D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B1B,CAAC;AAKH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;EAOlC,CAAC;AAKH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE3C,CAAC;AAKH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;EAM3B,CAAC;AAKH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB9B,CAAC;AAKH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe5B,CAAC;AAKH,MAAM,MAAM,SAAS,GAAoB,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACzE,MAAM,MAAM,iBAAiB,GAAY,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACjF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC1F,MAAM,MAAM,UAAU,GAAmB,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1E,MAAM,MAAM,aAAa,GAAgB,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAC7E,MAAM,MAAM,WAAW,GAAkB,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAK3E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAS,MAAM,CAAC;IACzB,QAAQ,EAAU,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAU,KAAK,GAAG,SAAS,CAAC;IACpC,aAAa,EAAK,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAU,MAAM,CAAC;CAC1B;AAQD,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;EAMrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC;AAKD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAM9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,162 @@
1
+ import { z } from 'zod';
2
+ // ---------------------------------------------------------------------------
3
+ // CandidateSchema — shape of a single DOM candidate from dom-extractor.ts
4
+ // ---------------------------------------------------------------------------
5
+ export const CandidateSchema = z.object({
6
+ tag: z.string(),
7
+ id: z.string().optional(),
8
+ classes: z.array(z.string()).max(5),
9
+ text: z.string().max(100),
10
+ ariaLabel: z.string().optional(),
11
+ role: z.string().optional(),
12
+ placeholder: z.string().optional(),
13
+ name: z.string().optional(),
14
+ type: z.string().optional(),
15
+ href: z.string().optional(),
16
+ title: z.string().optional(),
17
+ dataAttrs: z.record(z.string()).optional(),
18
+ position: z.enum(['above-fold', 'below-fold']),
19
+ // ── Enrichments for one-shot heal reliability ──────────────────────────
20
+ // <label for=id> text OR wrapping <label> text. Solves the very common
21
+ // case where role=textbox[name='X'] fails because the form has no proper
22
+ // label association — the LLM still sees the visible label here.
23
+ associatedLabel: z.string().optional(),
24
+ // Closest landmark ancestor role ('navigation', 'main', 'dialog', 'aside')
25
+ // — lets the LLM scope ambiguous matches by region in the first call.
26
+ parentRole: z.string().optional(),
27
+ // Count of same-tag siblings under the candidate's parent. >1 signals
28
+ // upfront that bare text/role= will probably be multi-match.
29
+ siblingsSameTag: z.number().optional(),
30
+ // 200-char outerHTML slice for deeply-nested / composite widgets
31
+ // (span-inside-button, react-select). Lets the LLM see the clickable
32
+ // ancestor it should target rather than the inner span.
33
+ outerHTMLSnippet: z.string().optional(),
34
+ });
35
+ // ---------------------------------------------------------------------------
36
+ // LocatorSuggestionSchema — a single LLM suggestion
37
+ // ---------------------------------------------------------------------------
38
+ export const LocatorSuggestionSchema = z.object({
39
+ selectorType: z.enum(['role', 'text', 'label', 'testid', 'css', 'xpath', 'filter-chain', 'js']),
40
+ selector: z.string().min(1),
41
+ rationale: z.string(),
42
+ // OpenAI structured-output requires nullable+optional, not just optional.
43
+ // Future SDK versions error on plain .optional() when a key may be absent.
44
+ tier: z.number().int().min(1).max(9).nullable().optional(),
45
+ });
46
+ // ---------------------------------------------------------------------------
47
+ // LocatorSuggestionsResponseSchema — top-level LLM response (3–5 suggestions)
48
+ // ---------------------------------------------------------------------------
49
+ export const LocatorSuggestionsResponseSchema = z.object({
50
+ suggestions: z.array(LocatorSuggestionSchema).min(3).max(5),
51
+ });
52
+ // ---------------------------------------------------------------------------
53
+ // CacheEntrySchema — one healed locator record persisted to disk
54
+ // ---------------------------------------------------------------------------
55
+ export const CacheEntrySchema = z.object({
56
+ healedSelector: z.string(),
57
+ selectorType: z.string(),
58
+ description: z.string(),
59
+ lastUsed: z.string().datetime(),
60
+ successCount: z.number().int().nonnegative(),
61
+ });
62
+ // ---------------------------------------------------------------------------
63
+ // AuditLogEntrySchema — one NDJSON line appended to audit.log
64
+ // ---------------------------------------------------------------------------
65
+ export const AuditLogEntrySchema = z.object({
66
+ timestamp: z.string().datetime(),
67
+ testFile: z.string(),
68
+ originalSelector: z.string(),
69
+ stage: z.enum([
70
+ 'cache',
71
+ 'llm',
72
+ 'visual',
73
+ 'terminal',
74
+ 'failed',
75
+ 'verify-failed',
76
+ 'wrong-element',
77
+ ]),
78
+ healedSelector: z.string().optional(),
79
+ selectorType: z.string(), // z.string() — accepts "visual" from the visual stage
80
+ description: z.string(),
81
+ error: z.string().optional(),
82
+ });
83
+ // ---------------------------------------------------------------------------
84
+ // HealOptionsSchema — options accepted by healAction
85
+ // ---------------------------------------------------------------------------
86
+ export const HealOptionsSchema = z.object({
87
+ initialTimeout: z.number().positive().optional(),
88
+ timeouts: z.object({
89
+ cacheValidate: z.number().positive(),
90
+ domExtract: z.number().positive(),
91
+ llmCall: z.number().positive(),
92
+ candidateValidate: z.number().positive(),
93
+ visualSelect: z.number().positive(),
94
+ terminalSelect: z.number().positive(),
95
+ }).partial().optional(),
96
+ scope: z.custom().optional(),
97
+ skipCache: z.boolean().optional(),
98
+ skipVisual: z.boolean().optional(),
99
+ testInfo: z.custom().optional(),
100
+ verify: z.function().returns(z.promise(z.void())).optional(),
101
+ });
102
+ // ---------------------------------------------------------------------------
103
+ // HealEntryV2Schema — v2 schema with action key + source trace fields
104
+ // ---------------------------------------------------------------------------
105
+ // HealEntryFingerprint — drift detector. Captured at heal time, recomputed
106
+ // on cache hit. Divergence past threshold marks the cache entry stale and
107
+ // triggers re-heal. Optional for backward compat with v0.1.0 entries.
108
+ export const HealEntryFingerprintSchema = z.object({
109
+ tag: z.string(),
110
+ role: z.string().optional(),
111
+ accessibleName: z.string().optional(),
112
+ text: z.string().optional(), // first 80 chars textContent
113
+ attrs: z.record(z.string()).optional(), // id, name, data-testid, aria-label if present
114
+ });
115
+ export const HealEntryV2Schema = z.object({
116
+ originalSelector: z.string(),
117
+ action: z.string(),
118
+ healedSelector: z.string(),
119
+ selectorType: z.enum(['role', 'text', 'label', 'testid', 'css', 'xpath', 'filter-chain']),
120
+ tier: z.number().int().min(1).max(8).optional(), // cached entries from v2 default to tier 6 in code
121
+ intent: z.string(),
122
+ callSite: z.string(),
123
+ pomFrame: z.string(),
124
+ healedAt: z.string().datetime(),
125
+ fingerprint: HealEntryFingerprintSchema.optional(),
126
+ });
127
+ // ---------------------------------------------------------------------------
128
+ // FailedAttempt — for CH-3 retry: tells the next LLM round what already failed
129
+ // ---------------------------------------------------------------------------
130
+ export const FailedAttemptSchema = z.object({
131
+ selectorType: z.string(),
132
+ selector: z.string(),
133
+ tier: z.number(),
134
+ reason: z.enum(['count-zero', 'count-many', 'strict-mode-violation', 'invalid-selector', 'js-eval-error']),
135
+ matchedCount: z.number().optional(),
136
+ });
137
+ // ---------------------------------------------------------------------------
138
+ // ScopedCandidate — used by the progressive-scope LLM rounds. Adds
139
+ // neighborText (Nass 2024) and parentRole-chain for chained-locator hints.
140
+ // ---------------------------------------------------------------------------
141
+ export const ScopedCandidateSchema = z.object({
142
+ tag: z.string(),
143
+ id: z.string().optional(),
144
+ classes: z.array(z.string()).max(5).optional(),
145
+ text: z.string().max(80).optional(),
146
+ ariaLabel: z.string().optional(),
147
+ role: z.string().optional(),
148
+ accessibleName: z.string().optional(),
149
+ dataTestId: z.string().optional(),
150
+ dataAttrs: z.record(z.string()).optional(),
151
+ name: z.string().optional(),
152
+ type: z.string().optional(),
153
+ placeholder: z.string().optional(),
154
+ href: z.string().optional(),
155
+ associatedLabel: z.string().optional(),
156
+ parentRole: z.string().optional(),
157
+ siblingsSameTag: z.number().optional(),
158
+ neighborText: z.string().max(240).optional(),
159
+ xpathRelative: z.string(),
160
+ outerHTMLSnippet: z.string().max(200).optional(),
161
+ });
162
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../healing/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { Page, Locator, ElementHandle } from '@playwright/test';
2
+ import type { LocatorSuggestion, HealEntryFingerprint } from './types.js';
3
+ /**
4
+ * Capture a stable fingerprint of a DOM element for cache-drift detection.
5
+ * Recomputed on cache hit; entries whose fingerprint has drifted are
6
+ * treated as stale and re-healed instead of trusted blindly.
7
+ *
8
+ * @param handle - Element handle, usually the operator's picked node.
9
+ * @returns Fingerprint (tag + role + name + text + key attrs).
10
+ */
11
+ export declare function captureFingerprint(handle: ElementHandle): Promise<HealEntryFingerprint>;
12
+ /**
13
+ * Compare two fingerprints. Returns true if they match within a tolerance
14
+ * suitable for "same logical element after a minor DOM change".
15
+ *
16
+ * - tag must match exactly
17
+ * - role, accessibleName, text compared via Levenshtein distance ≤ 30%
18
+ * - any matching stable attr (id, testid, aria-label) short-circuits to match
19
+ *
20
+ * @param a - Cached fingerprint.
21
+ * @param b - Live recomputed fingerprint.
22
+ */
23
+ export declare function fingerprintMatches(a: HealEntryFingerprint, b: HealEntryFingerprint): boolean;
24
+ export type { LocatorSuggestion };
25
+ /**
26
+ * If a role suggestion's exact `name="X"` returns no matches, produce a
27
+ * relaxed variant using a case-insensitive regex match. Accessible names
28
+ * commonly carry leading/trailing whitespace introduced by adjacent icons
29
+ * (`<button><i>icon</i> Login</button>` → accessibleName=` Login`), and
30
+ * exact-string matches fail in that case.
31
+ *
32
+ * Returns the relaxed suggestion (new selector string) or null if the input
33
+ * isn't a role+name selector.
34
+ *
35
+ * @param suggestion - Original LLM suggestion.
36
+ * @returns Relaxed suggestion with regex name, or null.
37
+ */
38
+ export declare function relaxRoleNameMatch(suggestion: LocatorSuggestion): LocatorSuggestion | null;
39
+ export declare function buildLocator(page: Page, suggestion: LocatorSuggestion): Locator;
40
+ export declare function validateLocator(page: Page, suggestion: LocatorSuggestion, timeoutMs?: number): Promise<boolean>;
41
+ export interface ValidateResult {
42
+ ok: boolean;
43
+ count: number;
44
+ reason?: string;
45
+ }
46
+ export declare function validateProposedSelector(page: Page, selector: string, picked: ElementHandle): Promise<ValidateResult>;
47
+ export declare function validateProposedLocator(locator: Locator, picked: ElementHandle | null): Promise<ValidateResult>;
48
+ /**
49
+ * Verify a candidate locator is actionable for the requested action BEFORE
50
+ * writing it to cache. Without this check the healer can cache a selector
51
+ * that resolves count===1 + visible but isn't actually clickable (overlay,
52
+ * pointer-events:none, disabled). Cache then poisons every subsequent run.
53
+ *
54
+ * Uses Playwright's trial mode for mutating actions: the action is fully
55
+ * simulated (visibility, stability, enabledness, no overlap) but not
56
+ * performed. For read-only actions a lighter check suffices.
57
+ *
58
+ * @param locator - Built locator under validation.
59
+ * @param action - Method name the test will invoke on success (`click`, `fill`...).
60
+ * @param timeoutMs - Budget per probe.
61
+ * @returns `{ ok }` plus a `reason` describing the first failing check.
62
+ */
63
+ export declare function verifyActionable(locator: Locator, action: string, timeoutMs?: number): Promise<ValidateResult>;
64
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../healing/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAG1E;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoB7F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAkB5F;AAsBD,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAUlC;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,IAAI,CAQ1F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CA6C/E;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,iBAAiB,EAC7B,SAAS,SAAO,GACf,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAClD,OAAO,CAAC,cAAc,CAAC,CAczB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,GAC7C,OAAO,CAAC,cAAc,CAAC,CA+BzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,SAAO,GACf,OAAO,CAAC,cAAc,CAAC,CA6BzB"}