prowl-tools 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.
package/dist/lib.d.ts ADDED
@@ -0,0 +1,935 @@
1
+ import { Page } from 'playwright';
2
+ import { z } from 'zod';
3
+
4
+ type BrowserEngine = "chromium" | "firefox" | "webkit";
5
+ type BrowserChannel = "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev";
6
+ type Viewport = {
7
+ width: number;
8
+ height: number;
9
+ };
10
+ type Config = {
11
+ target: {
12
+ url: string;
13
+ };
14
+ browser: {
15
+ headless: boolean;
16
+ slowMo: number;
17
+ timeout: number;
18
+ engine: BrowserEngine;
19
+ channel?: BrowserChannel;
20
+ viewport: Viewport;
21
+ };
22
+ artifacts: {
23
+ screenshots: "on-failure" | "all";
24
+ networkHar: boolean;
25
+ console: boolean;
26
+ junit: boolean;
27
+ };
28
+ assertions: {
29
+ noConsoleErrors: boolean;
30
+ noNetworkErrors: boolean;
31
+ maxTotalTimeMs: number;
32
+ networkIgnorePatterns: string[];
33
+ };
34
+ guardrails: {
35
+ maxSteps: number;
36
+ allowedDomains: string[];
37
+ forbiddenSelectors: string[];
38
+ selfHealing: boolean;
39
+ };
40
+ auth: {
41
+ storageStatePath?: string;
42
+ };
43
+ history: {
44
+ maxRuns: number;
45
+ };
46
+ bugLog?: BugLogConfig;
47
+ tracing?: TracingConfig;
48
+ reliability?: ReliabilityConfig;
49
+ };
50
+ type ReliabilityConfig = {
51
+ /** Flake score (0-1) at or above which a hunt is flagged flaky (default 0.3). */
52
+ flakyThreshold?: number;
53
+ };
54
+ type TracingConfig = {
55
+ /** Response header carrying the distributed-trace id (default "traceparent"). */
56
+ header?: string;
57
+ };
58
+ type BugLogConfig = {
59
+ enabled?: boolean;
60
+ backlogPath?: string;
61
+ resolvedPath?: string;
62
+ };
63
+ type HistoryEntry = {
64
+ hunt: string;
65
+ status: "pass" | "fail";
66
+ durationMs: number;
67
+ startedAt: string;
68
+ runDir?: string;
69
+ };
70
+ type HistoryFile = {
71
+ entries: HistoryEntry[];
72
+ };
73
+ type Hunt = {
74
+ name?: string;
75
+ description?: string;
76
+ tags?: string[];
77
+ vars?: Record<string, string>;
78
+ steps: Step[];
79
+ assertions?: Assertion[];
80
+ retry?: {
81
+ maxRetries: number;
82
+ delay?: number;
83
+ };
84
+ };
85
+ type NavigateStep = {
86
+ navigate: string;
87
+ };
88
+ type ClickStep = {
89
+ click: {
90
+ selector: string;
91
+ } | string;
92
+ };
93
+ type FillStep = {
94
+ fill: {
95
+ selector: string;
96
+ value: string;
97
+ } | Record<string, string>;
98
+ };
99
+ type TypeStep = {
100
+ type: string;
101
+ };
102
+ type PressStep = {
103
+ press: {
104
+ selector: string;
105
+ key: string;
106
+ };
107
+ };
108
+ type WaitForSelectorStep = {
109
+ waitForSelector: {
110
+ selector: string;
111
+ timeout?: number;
112
+ };
113
+ };
114
+ type WaitStep = {
115
+ wait: string | {
116
+ for: string;
117
+ timeout?: number;
118
+ };
119
+ };
120
+ type WaitForUrlStep = {
121
+ waitForUrl: {
122
+ value: string;
123
+ timeout?: number;
124
+ };
125
+ };
126
+ type WaitForNetworkIdleStep = {
127
+ waitForNetworkIdle: {
128
+ timeout?: number;
129
+ };
130
+ };
131
+ type SelectOptionStep = {
132
+ selectOption: {
133
+ selector: string;
134
+ value: string;
135
+ };
136
+ };
137
+ type SelectStep = {
138
+ select: Record<string, string>;
139
+ };
140
+ type OnDialogStep = {
141
+ onDialog: {
142
+ action: "accept" | "dismiss";
143
+ };
144
+ };
145
+ type SetInputFilesStep = {
146
+ setInputFiles: {
147
+ selector: string;
148
+ files: string | string[];
149
+ };
150
+ };
151
+ type InlineAssertStep = {
152
+ assert: {
153
+ visible?: string;
154
+ notVisible?: string;
155
+ urlIncludes?: string;
156
+ urlEquals?: string;
157
+ };
158
+ };
159
+ type RunHuntStep = {
160
+ runHunt: string | {
161
+ name: string;
162
+ vars?: Record<string, string>;
163
+ };
164
+ };
165
+ type HoverStep = {
166
+ hover: {
167
+ selector: string;
168
+ };
169
+ };
170
+ type ScrollStep = {
171
+ scroll: {
172
+ direction: "up" | "down" | "left" | "right";
173
+ amount?: number;
174
+ };
175
+ };
176
+ type ScrollToStep = {
177
+ scrollTo: {
178
+ selector: string;
179
+ };
180
+ };
181
+ type ScreenshotStep = {
182
+ screenshot: {
183
+ name?: string;
184
+ };
185
+ };
186
+ type IfStep = {
187
+ if: {
188
+ visible?: string;
189
+ notVisible?: string;
190
+ then: Step[];
191
+ else?: Step[];
192
+ };
193
+ };
194
+ type RepeatStep = {
195
+ repeat: {
196
+ times?: number;
197
+ while?: {
198
+ visible?: string;
199
+ notVisible?: string;
200
+ };
201
+ maxIterations?: number;
202
+ steps: Step[];
203
+ };
204
+ };
205
+ type MockRouteStep = {
206
+ mockRoute: {
207
+ url: string;
208
+ response: {
209
+ status: number;
210
+ contentType?: string;
211
+ body?: string;
212
+ file?: string;
213
+ };
214
+ };
215
+ };
216
+ type UnmockRouteStep = {
217
+ unmockRoute: string | {
218
+ url: string;
219
+ };
220
+ };
221
+ type EvalScriptStep = {
222
+ evalScript: string | {
223
+ expression: string;
224
+ as?: string;
225
+ };
226
+ };
227
+ type RunScriptStep = {
228
+ runScript: {
229
+ file: string;
230
+ };
231
+ };
232
+ type CopyTextStep = {
233
+ copyText: {
234
+ selector: string;
235
+ as: string;
236
+ };
237
+ };
238
+ type WaitForDownloadStep = {
239
+ waitForDownload: {
240
+ filename?: string;
241
+ timeout?: number;
242
+ } | null;
243
+ };
244
+ type AssertScreenshotStep = {
245
+ assertScreenshot: {
246
+ name: string;
247
+ threshold?: number;
248
+ };
249
+ };
250
+ type Step = NavigateStep | ClickStep | FillStep | TypeStep | PressStep | WaitStep | SelectOptionStep | SelectStep | OnDialogStep | SetInputFilesStep | InlineAssertStep | RunHuntStep | WaitForSelectorStep | WaitForUrlStep | WaitForNetworkIdleStep | HoverStep | ScrollStep | ScrollToStep | ScreenshotStep | IfStep | RepeatStep | MockRouteStep | UnmockRouteStep | EvalScriptStep | RunScriptStep | AssertScreenshotStep | CopyTextStep | WaitForDownloadStep;
251
+ type Assertion = {
252
+ selectorExists: string;
253
+ } | {
254
+ selectorNotExists: string;
255
+ } | {
256
+ urlIncludes: string;
257
+ } | {
258
+ urlEquals: string;
259
+ } | {
260
+ noConsoleErrors: boolean;
261
+ } | {
262
+ noNetworkErrors: boolean;
263
+ };
264
+ type StepResult = {
265
+ type: string;
266
+ status: "pass" | "fail";
267
+ durationMs: number;
268
+ selector?: string;
269
+ value?: string;
270
+ error?: string;
271
+ screenshot?: string;
272
+ /** Original selector when the step was completed via a self-healed selector. */
273
+ healedFrom?: string;
274
+ };
275
+ type AssertionResult = {
276
+ type: string;
277
+ value?: string | boolean;
278
+ status: "pass" | "fail";
279
+ error?: string;
280
+ };
281
+ type RunArtifacts = {
282
+ summary?: string;
283
+ screenshots?: string[];
284
+ console?: string;
285
+ trace?: string;
286
+ networkHar?: string;
287
+ junit?: string;
288
+ };
289
+ type TraceCorrelation = {
290
+ url: string;
291
+ status: number;
292
+ traceId: string;
293
+ header: string;
294
+ };
295
+ type RunResult = {
296
+ status: "pass" | "fail";
297
+ exitCode: 0 | 1;
298
+ startedAt: string;
299
+ durationMs: number;
300
+ hunt: string;
301
+ targetUrl: string;
302
+ steps: StepResult[];
303
+ assertions: AssertionResult[];
304
+ artifacts: RunArtifacts;
305
+ traceCorrelations?: TraceCorrelation[];
306
+ };
307
+ type CiHuntResult = {
308
+ hunt: string;
309
+ status: "pass" | "fail" | "skipped";
310
+ durationMs: number;
311
+ runDir?: string;
312
+ error?: string;
313
+ };
314
+ type CiStatus = "pass" | "fail" | "no-hunts" | "all-skipped";
315
+ type CiFlakyHunt = {
316
+ hunt: string;
317
+ score: number;
318
+ };
319
+ type CiFailureCluster = {
320
+ cause: string;
321
+ stepType?: string;
322
+ selector?: string;
323
+ error: string;
324
+ count: number;
325
+ hunts: string[];
326
+ };
327
+ type CiResult = {
328
+ status: CiStatus;
329
+ startedAt: string;
330
+ durationMs: number;
331
+ totalHunts: number;
332
+ passed: number;
333
+ failed: number;
334
+ skipped: number;
335
+ hunts: CiHuntResult[];
336
+ /** Hunts whose flake score is at/above the configured threshold (omitted when none). */
337
+ flaky?: CiFlakyHunt[];
338
+ /** Groups of failed hunts sharing a common cause (omitted when none). */
339
+ clusters?: CiFailureCluster[];
340
+ };
341
+
342
+ type StepCallback = (result: StepResult, step: Step, index: number) => void;
343
+
344
+ type RunOptions = {
345
+ huntName: string;
346
+ urlOverride?: string;
347
+ headed?: boolean;
348
+ slowMo?: number;
349
+ trace?: boolean;
350
+ configPath?: string;
351
+ onStep?: StepCallback;
352
+ browser?: "chromium" | "firefox" | "webkit";
353
+ channel?: BrowserChannel;
354
+ viewport?: string;
355
+ junit?: boolean;
356
+ };
357
+ declare function runHunt(options: RunOptions): Promise<{
358
+ result: RunResult;
359
+ runDir: string;
360
+ steps: Step[];
361
+ }>;
362
+
363
+ type SkipReason = "include" | "exclude";
364
+ type SuiteHookResult = void | Promise<void>;
365
+ interface RunSuiteHooks {
366
+ onHuntStart?: (huntName: string) => SuiteHookResult;
367
+ onStep?: RunOptions["onStep"];
368
+ onHuntSuccess?: (huntName: string, result: RunResult, runDir: string) => SuiteHookResult;
369
+ onHuntFailure?: (huntName: string, message: string) => SuiteHookResult;
370
+ onHuntSkipped?: (huntName: string, reason: SkipReason) => SuiteHookResult;
371
+ }
372
+ interface RunSuiteOptions {
373
+ configPath?: string;
374
+ urlOverride?: string;
375
+ headed?: boolean;
376
+ slowMo?: number;
377
+ trace?: boolean;
378
+ browser?: RunOptions["browser"];
379
+ channel?: RunOptions["channel"];
380
+ viewport?: string;
381
+ junit?: boolean;
382
+ includeTags?: string[];
383
+ excludeTags?: string[];
384
+ parallel?: number;
385
+ hooks?: RunSuiteHooks;
386
+ }
387
+ interface RunSuiteResult {
388
+ result: CiResult;
389
+ /** Path to the written ci-result.json, or null when there were no hunts to run. */
390
+ resultPath: string | null;
391
+ }
392
+ /**
393
+ * Runs every hunt in the project and aggregates a CiResult. Side-effect-free with
394
+ * respect to the console and process exit — callers provide hooks for presentation
395
+ * and inspect the returned status for exit codes.
396
+ */
397
+ declare function runSuite(options?: RunSuiteOptions): Promise<RunSuiteResult>;
398
+
399
+ /**
400
+ * A single failure worth logging as a bug: a specific hunt failing at a specific
401
+ * spot. `stepType`/`selector`/`stepIndex` are absent when the hunt threw before
402
+ * producing step results (e.g. a missing hunt file).
403
+ */
404
+ interface BugFailure {
405
+ hunt: string;
406
+ stepIndex?: number;
407
+ stepType?: string;
408
+ selector?: string;
409
+ error: string;
410
+ runDir?: string;
411
+ }
412
+
413
+ interface UpdateBacklogOptions {
414
+ /** Project root containing docs/. Defaults to process.cwd(). */
415
+ projectRoot?: string;
416
+ /** Overrides the backlog path (default: <projectRoot>/docs/backlog.md). */
417
+ backlogPath?: string;
418
+ /** Overrides the resolved path (default: <projectRoot>/docs/resolved.md). */
419
+ resolvedPath?: string;
420
+ /** Date stamp for new tickets (default: today, YYYY-MM-DD). */
421
+ date?: string;
422
+ }
423
+ interface BugLogSummary {
424
+ /** QA-NNN ids created for brand-new failures. */
425
+ created: string[];
426
+ /** QA-NNN ids created for failures that recurred after being resolved. */
427
+ regressions: string[];
428
+ /** QA-NNN ids of already-open tickets that were left untouched. */
429
+ skipped: string[];
430
+ backlogPath: string;
431
+ }
432
+ /** Extract one BugFailure per failed hunt from a completed suite run. */
433
+ declare function extractFailures(suiteResult: RunSuiteResult): BugFailure[];
434
+ /**
435
+ * Logs failures from a completed suite run as deduplicated bug tickets in the
436
+ * target project's backlog. New failures get a fresh QA-NNN ticket; failures that
437
+ * already have an open ticket are skipped; failures matching a resolved ticket are
438
+ * logged as regressions that reference the old id. Idempotent across runs.
439
+ */
440
+ declare function updateBacklogFromSuite(suiteResult: RunSuiteResult, options?: UpdateBacklogOptions): BugLogSummary;
441
+
442
+ declare function readHistory(configDir: string): HistoryFile;
443
+ declare function readHuntHistory(configDir: string, huntName: string): HistoryEntry[];
444
+
445
+ declare const DEFAULT_FLAKY_THRESHOLD = 0.3;
446
+ type FlakyScore = {
447
+ hunt: string;
448
+ /** Oscillation rate in [0,1]: share of consecutive run pairs whose status changed. */
449
+ score: number;
450
+ runs: number;
451
+ flaky: boolean;
452
+ };
453
+ /**
454
+ * Flake score for a single hunt's run history (oldest→newest): the fraction of
455
+ * consecutive run pairs where the status flipped (pass↔fail). 0 = perfectly
456
+ * stable, 1 = flips every run. Needs at least 2 runs; fewer returns 0.
457
+ */
458
+ declare function computeFlakeScore(entries: HistoryEntry[], lastN?: number): number;
459
+ type RankFlakyOptions = {
460
+ /** Only score the most recent N runs per hunt. */
461
+ lastN?: number;
462
+ /** Score at/above this is flagged flaky. Defaults to DEFAULT_FLAKY_THRESHOLD. */
463
+ threshold?: number;
464
+ };
465
+ /**
466
+ * Rank every hunt in the project's history by flake score, highest first.
467
+ * Hunts are tie-broken by run count (more runs first) then name for stable output.
468
+ */
469
+ declare function rankFlaky(configDir: string, options?: RankFlakyOptions): FlakyScore[];
470
+
471
+ /**
472
+ * Self-healing selectors (PROWL-023). When an explicit selector matches nothing,
473
+ * derive the human "intent" from the selector and try alternative strategies —
474
+ * fuzzy text, ARIA label, and structural (interactive element + text) — healing
475
+ * ONLY to a candidate that resolves to exactly one element. Opt-in via
476
+ * `guardrails.selfHealing`; never guesses among multiple matches.
477
+ */
478
+ type HealResult = {
479
+ /** The candidate selector that uniquely matched. */
480
+ selector: string;
481
+ /** The original selector that failed. */
482
+ healedFrom: string;
483
+ /** Which strategy produced the match (for reporting). */
484
+ strategy: "text" | "aria" | "structural";
485
+ };
486
+ /**
487
+ * Pull human-meaningful words out of a raw selector. Reads id (`#submit-btn`),
488
+ * class tokens (`.login-form`), and attribute values (`[data-testid="sign-in"]`,
489
+ * `[aria-label='Close']`), splitting on separators and camelCase. Returns the
490
+ * lowercased words (de-duped, in order) and a space-joined label. Mapping is
491
+ * intentionally literal/predictable — no noise-word filtering.
492
+ */
493
+ declare function extractSelectorIntent(selector: string): {
494
+ words: string[];
495
+ label: string;
496
+ };
497
+ /**
498
+ * Build candidate Playwright selectors for a derived intent, in AC priority order:
499
+ * (1) fuzzy text, (2) ARIA label, (3) structural (interactive element + text).
500
+ * Returns [] when the selector carried no usable words.
501
+ */
502
+ declare function buildHealCandidates(selector: string): Array<{
503
+ selector: string;
504
+ strategy: HealResult["strategy"];
505
+ }>;
506
+ /**
507
+ * Attempt to heal a failed selector. Returns a HealResult only when a candidate
508
+ * resolves to exactly one element; otherwise null. Counting is delegated so this
509
+ * is unit-testable with a fake page.
510
+ */
511
+ declare function healSelector(page: Pick<Page, "locator">, selector: string, options: {
512
+ enabled: boolean;
513
+ }): Promise<HealResult | null>;
514
+
515
+ /**
516
+ * Failure clustering (PROWL-034). Groups failures that share a common cause —
517
+ * the same normalized error on the same step type and selector — so a single
518
+ * root cause (e.g. one renamed selector breaking 5 hunts) surfaces as one
519
+ * cluster instead of N independent failures.
520
+ */
521
+ type FailureCluster = CiFailureCluster;
522
+ /**
523
+ * Group failures by shared cause. Returns clusters sorted by size (largest first),
524
+ * then by cause for stable output. Every failure lands in a cluster — single-hunt
525
+ * clusters are included so the full picture is preserved; callers can filter to
526
+ * `count > 1` to show only shared root causes.
527
+ */
528
+ declare function clusterFailures(failures: BugFailure[]): FailureCluster[];
529
+
530
+ declare function loadConfig(configPath?: string): {
531
+ config: Config;
532
+ configPath: string;
533
+ configDir: string;
534
+ };
535
+ declare function loadHunt(huntName: string, configDir: string): Hunt;
536
+ declare function loadHuntTags(huntName: string, configDir: string): string[];
537
+ declare function loadHuntMeta(huntName: string, configDir: string): {
538
+ description?: string;
539
+ tags: string[];
540
+ };
541
+ declare function listHunts(configDir: string): string[];
542
+
543
+ declare const configSchema: z.ZodObject<{
544
+ target: z.ZodObject<{
545
+ url: z.ZodString;
546
+ }, "strip", z.ZodTypeAny, {
547
+ url: string;
548
+ }, {
549
+ url: string;
550
+ }>;
551
+ browser: z.ZodOptional<z.ZodObject<{
552
+ headless: z.ZodOptional<z.ZodBoolean>;
553
+ slowMo: z.ZodOptional<z.ZodNumber>;
554
+ timeout: z.ZodOptional<z.ZodNumber>;
555
+ engine: z.ZodOptional<z.ZodEnum<["chromium", "firefox", "webkit"]>>;
556
+ channel: z.ZodOptional<z.ZodEnum<["chromium", "chrome", "chrome-beta", "chrome-canary", "chrome-dev", "msedge", "msedge-beta", "msedge-canary", "msedge-dev"]>>;
557
+ viewport: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["mobile", "tablet", "desktop"]>, z.ZodObject<{
558
+ width: z.ZodNumber;
559
+ height: z.ZodNumber;
560
+ }, "strict", z.ZodTypeAny, {
561
+ width: number;
562
+ height: number;
563
+ }, {
564
+ width: number;
565
+ height: number;
566
+ }>]>>;
567
+ }, "strip", z.ZodTypeAny, {
568
+ headless?: boolean | undefined;
569
+ slowMo?: number | undefined;
570
+ timeout?: number | undefined;
571
+ engine?: "chromium" | "firefox" | "webkit" | undefined;
572
+ channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
573
+ viewport?: "mobile" | "tablet" | "desktop" | {
574
+ width: number;
575
+ height: number;
576
+ } | undefined;
577
+ }, {
578
+ headless?: boolean | undefined;
579
+ slowMo?: number | undefined;
580
+ timeout?: number | undefined;
581
+ engine?: "chromium" | "firefox" | "webkit" | undefined;
582
+ channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
583
+ viewport?: "mobile" | "tablet" | "desktop" | {
584
+ width: number;
585
+ height: number;
586
+ } | undefined;
587
+ }>>;
588
+ artifacts: z.ZodOptional<z.ZodObject<{
589
+ screenshots: z.ZodOptional<z.ZodEnum<["on-failure", "all"]>>;
590
+ networkHar: z.ZodOptional<z.ZodBoolean>;
591
+ console: z.ZodOptional<z.ZodBoolean>;
592
+ junit: z.ZodOptional<z.ZodBoolean>;
593
+ }, "strip", z.ZodTypeAny, {
594
+ screenshots?: "on-failure" | "all" | undefined;
595
+ networkHar?: boolean | undefined;
596
+ console?: boolean | undefined;
597
+ junit?: boolean | undefined;
598
+ }, {
599
+ screenshots?: "on-failure" | "all" | undefined;
600
+ networkHar?: boolean | undefined;
601
+ console?: boolean | undefined;
602
+ junit?: boolean | undefined;
603
+ }>>;
604
+ assertions: z.ZodOptional<z.ZodObject<{
605
+ noConsoleErrors: z.ZodOptional<z.ZodBoolean>;
606
+ noNetworkErrors: z.ZodOptional<z.ZodBoolean>;
607
+ maxTotalTimeMs: z.ZodOptional<z.ZodNumber>;
608
+ networkIgnorePatterns: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
609
+ }, "strip", z.ZodTypeAny, {
610
+ noConsoleErrors?: boolean | undefined;
611
+ noNetworkErrors?: boolean | undefined;
612
+ maxTotalTimeMs?: number | undefined;
613
+ networkIgnorePatterns?: string[] | undefined;
614
+ }, {
615
+ noConsoleErrors?: boolean | undefined;
616
+ noNetworkErrors?: boolean | undefined;
617
+ maxTotalTimeMs?: number | undefined;
618
+ networkIgnorePatterns?: string[] | undefined;
619
+ }>>;
620
+ guardrails: z.ZodOptional<z.ZodObject<{
621
+ maxSteps: z.ZodOptional<z.ZodNumber>;
622
+ allowedDomains: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
623
+ forbiddenSelectors: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
624
+ selfHealing: z.ZodOptional<z.ZodBoolean>;
625
+ }, "strip", z.ZodTypeAny, {
626
+ maxSteps?: number | undefined;
627
+ allowedDomains?: string[] | undefined;
628
+ forbiddenSelectors?: string[] | undefined;
629
+ selfHealing?: boolean | undefined;
630
+ }, {
631
+ maxSteps?: number | undefined;
632
+ allowedDomains?: string[] | undefined;
633
+ forbiddenSelectors?: string[] | undefined;
634
+ selfHealing?: boolean | undefined;
635
+ }>>;
636
+ auth: z.ZodOptional<z.ZodObject<{
637
+ storageStatePath: z.ZodOptional<z.ZodString>;
638
+ }, "strip", z.ZodTypeAny, {
639
+ storageStatePath?: string | undefined;
640
+ }, {
641
+ storageStatePath?: string | undefined;
642
+ }>>;
643
+ history: z.ZodOptional<z.ZodObject<{
644
+ maxRuns: z.ZodOptional<z.ZodNumber>;
645
+ }, "strip", z.ZodTypeAny, {
646
+ maxRuns?: number | undefined;
647
+ }, {
648
+ maxRuns?: number | undefined;
649
+ }>>;
650
+ bugLog: z.ZodOptional<z.ZodObject<{
651
+ enabled: z.ZodOptional<z.ZodBoolean>;
652
+ backlogPath: z.ZodOptional<z.ZodString>;
653
+ resolvedPath: z.ZodOptional<z.ZodString>;
654
+ }, "strict", z.ZodTypeAny, {
655
+ enabled?: boolean | undefined;
656
+ backlogPath?: string | undefined;
657
+ resolvedPath?: string | undefined;
658
+ }, {
659
+ enabled?: boolean | undefined;
660
+ backlogPath?: string | undefined;
661
+ resolvedPath?: string | undefined;
662
+ }>>;
663
+ tracing: z.ZodOptional<z.ZodObject<{
664
+ header: z.ZodOptional<z.ZodString>;
665
+ }, "strict", z.ZodTypeAny, {
666
+ header?: string | undefined;
667
+ }, {
668
+ header?: string | undefined;
669
+ }>>;
670
+ reliability: z.ZodOptional<z.ZodObject<{
671
+ flakyThreshold: z.ZodOptional<z.ZodNumber>;
672
+ }, "strict", z.ZodTypeAny, {
673
+ flakyThreshold?: number | undefined;
674
+ }, {
675
+ flakyThreshold?: number | undefined;
676
+ }>>;
677
+ }, "strict", z.ZodTypeAny, {
678
+ target: {
679
+ url: string;
680
+ };
681
+ browser?: {
682
+ headless?: boolean | undefined;
683
+ slowMo?: number | undefined;
684
+ timeout?: number | undefined;
685
+ engine?: "chromium" | "firefox" | "webkit" | undefined;
686
+ channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
687
+ viewport?: "mobile" | "tablet" | "desktop" | {
688
+ width: number;
689
+ height: number;
690
+ } | undefined;
691
+ } | undefined;
692
+ artifacts?: {
693
+ screenshots?: "on-failure" | "all" | undefined;
694
+ networkHar?: boolean | undefined;
695
+ console?: boolean | undefined;
696
+ junit?: boolean | undefined;
697
+ } | undefined;
698
+ assertions?: {
699
+ noConsoleErrors?: boolean | undefined;
700
+ noNetworkErrors?: boolean | undefined;
701
+ maxTotalTimeMs?: number | undefined;
702
+ networkIgnorePatterns?: string[] | undefined;
703
+ } | undefined;
704
+ guardrails?: {
705
+ maxSteps?: number | undefined;
706
+ allowedDomains?: string[] | undefined;
707
+ forbiddenSelectors?: string[] | undefined;
708
+ selfHealing?: boolean | undefined;
709
+ } | undefined;
710
+ auth?: {
711
+ storageStatePath?: string | undefined;
712
+ } | undefined;
713
+ history?: {
714
+ maxRuns?: number | undefined;
715
+ } | undefined;
716
+ bugLog?: {
717
+ enabled?: boolean | undefined;
718
+ backlogPath?: string | undefined;
719
+ resolvedPath?: string | undefined;
720
+ } | undefined;
721
+ tracing?: {
722
+ header?: string | undefined;
723
+ } | undefined;
724
+ reliability?: {
725
+ flakyThreshold?: number | undefined;
726
+ } | undefined;
727
+ }, {
728
+ target: {
729
+ url: string;
730
+ };
731
+ browser?: {
732
+ headless?: boolean | undefined;
733
+ slowMo?: number | undefined;
734
+ timeout?: number | undefined;
735
+ engine?: "chromium" | "firefox" | "webkit" | undefined;
736
+ channel?: "chromium" | "chrome" | "chrome-beta" | "chrome-canary" | "chrome-dev" | "msedge" | "msedge-beta" | "msedge-canary" | "msedge-dev" | undefined;
737
+ viewport?: "mobile" | "tablet" | "desktop" | {
738
+ width: number;
739
+ height: number;
740
+ } | undefined;
741
+ } | undefined;
742
+ artifacts?: {
743
+ screenshots?: "on-failure" | "all" | undefined;
744
+ networkHar?: boolean | undefined;
745
+ console?: boolean | undefined;
746
+ junit?: boolean | undefined;
747
+ } | undefined;
748
+ assertions?: {
749
+ noConsoleErrors?: boolean | undefined;
750
+ noNetworkErrors?: boolean | undefined;
751
+ maxTotalTimeMs?: number | undefined;
752
+ networkIgnorePatterns?: string[] | undefined;
753
+ } | undefined;
754
+ guardrails?: {
755
+ maxSteps?: number | undefined;
756
+ allowedDomains?: string[] | undefined;
757
+ forbiddenSelectors?: string[] | undefined;
758
+ selfHealing?: boolean | undefined;
759
+ } | undefined;
760
+ auth?: {
761
+ storageStatePath?: string | undefined;
762
+ } | undefined;
763
+ history?: {
764
+ maxRuns?: number | undefined;
765
+ } | undefined;
766
+ bugLog?: {
767
+ enabled?: boolean | undefined;
768
+ backlogPath?: string | undefined;
769
+ resolvedPath?: string | undefined;
770
+ } | undefined;
771
+ tracing?: {
772
+ header?: string | undefined;
773
+ } | undefined;
774
+ reliability?: {
775
+ flakyThreshold?: number | undefined;
776
+ } | undefined;
777
+ }>;
778
+ declare const stepSchema: z.ZodType<Step>;
779
+ declare const huntSchema: z.ZodObject<{
780
+ name: z.ZodOptional<z.ZodString>;
781
+ description: z.ZodOptional<z.ZodString>;
782
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
783
+ vars: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
784
+ steps: z.ZodArray<z.ZodType<Step, z.ZodTypeDef, Step>, "many">;
785
+ assertions: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodObject<{
786
+ selectorExists: z.ZodString;
787
+ }, "strict", z.ZodTypeAny, {
788
+ selectorExists: string;
789
+ }, {
790
+ selectorExists: string;
791
+ }>, z.ZodObject<{
792
+ selectorNotExists: z.ZodString;
793
+ }, "strict", z.ZodTypeAny, {
794
+ selectorNotExists: string;
795
+ }, {
796
+ selectorNotExists: string;
797
+ }>, z.ZodObject<{
798
+ urlIncludes: z.ZodString;
799
+ }, "strict", z.ZodTypeAny, {
800
+ urlIncludes: string;
801
+ }, {
802
+ urlIncludes: string;
803
+ }>, z.ZodObject<{
804
+ urlEquals: z.ZodString;
805
+ }, "strict", z.ZodTypeAny, {
806
+ urlEquals: string;
807
+ }, {
808
+ urlEquals: string;
809
+ }>, z.ZodObject<{
810
+ noConsoleErrors: z.ZodBoolean;
811
+ }, "strict", z.ZodTypeAny, {
812
+ noConsoleErrors: boolean;
813
+ }, {
814
+ noConsoleErrors: boolean;
815
+ }>, z.ZodObject<{
816
+ noNetworkErrors: z.ZodBoolean;
817
+ }, "strict", z.ZodTypeAny, {
818
+ noNetworkErrors: boolean;
819
+ }, {
820
+ noNetworkErrors: boolean;
821
+ }>]>, "many">>;
822
+ retry: z.ZodOptional<z.ZodObject<{
823
+ maxRetries: z.ZodNumber;
824
+ delay: z.ZodOptional<z.ZodNumber>;
825
+ }, "strict", z.ZodTypeAny, {
826
+ maxRetries: number;
827
+ delay?: number | undefined;
828
+ }, {
829
+ maxRetries: number;
830
+ delay?: number | undefined;
831
+ }>>;
832
+ }, "strict", z.ZodTypeAny, {
833
+ steps: Step[];
834
+ assertions?: ({
835
+ selectorExists: string;
836
+ } | {
837
+ selectorNotExists: string;
838
+ } | {
839
+ urlIncludes: string;
840
+ } | {
841
+ urlEquals: string;
842
+ } | {
843
+ noConsoleErrors: boolean;
844
+ } | {
845
+ noNetworkErrors: boolean;
846
+ })[] | undefined;
847
+ name?: string | undefined;
848
+ vars?: Record<string, string> | undefined;
849
+ description?: string | undefined;
850
+ tags?: string[] | undefined;
851
+ retry?: {
852
+ maxRetries: number;
853
+ delay?: number | undefined;
854
+ } | undefined;
855
+ }, {
856
+ steps: Step[];
857
+ assertions?: ({
858
+ selectorExists: string;
859
+ } | {
860
+ selectorNotExists: string;
861
+ } | {
862
+ urlIncludes: string;
863
+ } | {
864
+ urlEquals: string;
865
+ } | {
866
+ noConsoleErrors: boolean;
867
+ } | {
868
+ noNetworkErrors: boolean;
869
+ })[] | undefined;
870
+ name?: string | undefined;
871
+ vars?: Record<string, string> | undefined;
872
+ description?: string | undefined;
873
+ tags?: string[] | undefined;
874
+ retry?: {
875
+ maxRetries: number;
876
+ delay?: number | undefined;
877
+ } | undefined;
878
+ }>;
879
+
880
+ type InterpolatedHunt = {
881
+ hunt: Hunt;
882
+ redactedFillSteps: Set<string>;
883
+ randomVars: Record<string, string>;
884
+ redactionValues: string[];
885
+ };
886
+ declare function interpolateHunt(hunt: Hunt, env: NodeJS.ProcessEnv, randomVars?: Record<string, string>): InterpolatedHunt;
887
+
888
+ type PageElement = {
889
+ tag: string;
890
+ type?: string;
891
+ selectors: Record<string, string>;
892
+ role?: string;
893
+ label?: string;
894
+ placeholder?: string;
895
+ required: boolean;
896
+ formGroup?: number;
897
+ };
898
+ type PageForm = {
899
+ index: number;
900
+ action?: string;
901
+ method?: string;
902
+ fieldCount: number;
903
+ };
904
+ type PageLink = {
905
+ text: string;
906
+ href: string;
907
+ selector: string;
908
+ };
909
+ type AnalysisResult = {
910
+ url: string;
911
+ title: string;
912
+ elements: PageElement[];
913
+ forms: PageForm[];
914
+ links: PageLink[];
915
+ };
916
+ declare function analyzePage(page: Page): Promise<AnalysisResult>;
917
+
918
+ type AiProvider = "anthropic" | "openai";
919
+ type AiConfig = {
920
+ provider: AiProvider;
921
+ model: string;
922
+ apiKey: string;
923
+ };
924
+
925
+ type GenerateOptions = {
926
+ url?: string;
927
+ analysis?: AnalysisResult;
928
+ intent: string;
929
+ browser?: string;
930
+ viewport?: string;
931
+ aiConfig?: AiConfig;
932
+ };
933
+ declare function generateHunt(options: GenerateOptions): Promise<string>;
934
+
935
+ export { type AnalysisResult, type AssertScreenshotStep, type Assertion, type AssertionResult, type BrowserChannel, type BrowserEngine, type BugFailure, type BugLogSummary, type CiFailureCluster, type CiFlakyHunt, type CiHuntResult, type CiResult, type CiStatus, type Config, DEFAULT_FLAKY_THRESHOLD, type EvalScriptStep, type FailureCluster, type FlakyScore, type GenerateOptions, type HealResult, type HistoryEntry, type HistoryFile, type Hunt, type IfStep, type MockRouteStep, type PageElement, type PageForm, type PageLink, type RankFlakyOptions, type ReliabilityConfig, type RepeatStep, type RunArtifacts, type RunOptions, type RunResult, type RunScriptStep, type RunSuiteHooks, type RunSuiteOptions, type RunSuiteResult, type Step, type StepResult, type UnmockRouteStep, type UpdateBacklogOptions, type Viewport, analyzePage, buildHealCandidates, clusterFailures, computeFlakeScore, configSchema, extractFailures, extractSelectorIntent, generateHunt, healSelector, huntSchema, interpolateHunt, listHunts, loadConfig, loadHunt, loadHuntMeta, loadHuntTags, rankFlaky, readHistory, readHuntHistory, runHunt, runSuite, stepSchema, updateBacklogFromSuite };