playwright-mimic 0.1.1 → 0.1.2
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/README.md +134 -72
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/mimic/annotations.d.ts +2 -1
- package/dist/mimic/annotations.d.ts.map +1 -1
- package/dist/mimic/annotations.js +10 -4
- package/dist/mimic/annotations.js.map +1 -1
- package/dist/mimic/cli.js +1 -1
- package/dist/mimic/cli.js.map +1 -1
- package/dist/mimic/click.d.ts +4 -4
- package/dist/mimic/click.d.ts.map +1 -1
- package/dist/mimic/click.js +233 -118
- package/dist/mimic/click.js.map +1 -1
- package/dist/mimic/forms.d.ts +11 -6
- package/dist/mimic/forms.d.ts.map +1 -1
- package/dist/mimic/forms.js +371 -124
- package/dist/mimic/forms.js.map +1 -1
- package/dist/mimic/markers.d.ts +133 -0
- package/dist/mimic/markers.d.ts.map +1 -0
- package/dist/mimic/markers.js +589 -0
- package/dist/mimic/markers.js.map +1 -0
- package/dist/mimic/navigation.d.ts.map +1 -1
- package/dist/mimic/navigation.js +29 -10
- package/dist/mimic/navigation.js.map +1 -1
- package/dist/mimic/playwrightCodeGenerator.d.ts +55 -0
- package/dist/mimic/playwrightCodeGenerator.d.ts.map +1 -0
- package/dist/mimic/playwrightCodeGenerator.js +270 -0
- package/dist/mimic/playwrightCodeGenerator.js.map +1 -0
- package/dist/mimic/replay.d.ts.map +1 -1
- package/dist/mimic/replay.js +45 -36
- package/dist/mimic/replay.js.map +1 -1
- package/dist/mimic/schema/action.d.ts +26 -26
- package/dist/mimic/schema/action.d.ts.map +1 -1
- package/dist/mimic/schema/action.js +13 -31
- package/dist/mimic/schema/action.js.map +1 -1
- package/dist/mimic/selector.d.ts +6 -2
- package/dist/mimic/selector.d.ts.map +1 -1
- package/dist/mimic/selector.js +681 -269
- package/dist/mimic/selector.js.map +1 -1
- package/dist/mimic/selectorDescriptor.d.ts +15 -3
- package/dist/mimic/selectorDescriptor.d.ts.map +1 -1
- package/dist/mimic/selectorDescriptor.js +25 -2
- package/dist/mimic/selectorDescriptor.js.map +1 -1
- package/dist/mimic/selectorSerialization.d.ts +5 -17
- package/dist/mimic/selectorSerialization.d.ts.map +1 -1
- package/dist/mimic/selectorSerialization.js +4 -142
- package/dist/mimic/selectorSerialization.js.map +1 -1
- package/dist/mimic/selectorTypes.d.ts +24 -102
- package/dist/mimic/selectorTypes.d.ts.map +1 -1
- package/dist/mimic/selectorUtils.d.ts +33 -7
- package/dist/mimic/selectorUtils.d.ts.map +1 -1
- package/dist/mimic/selectorUtils.js +159 -52
- package/dist/mimic/selectorUtils.js.map +1 -1
- package/dist/mimic/storage.d.ts +43 -8
- package/dist/mimic/storage.d.ts.map +1 -1
- package/dist/mimic/storage.js +258 -46
- package/dist/mimic/storage.js.map +1 -1
- package/dist/mimic/types.d.ts +38 -16
- package/dist/mimic/types.d.ts.map +1 -1
- package/dist/mimic.d.ts +1 -0
- package/dist/mimic.d.ts.map +1 -1
- package/dist/mimic.js +240 -84
- package/dist/mimic.js.map +1 -1
- package/package.json +27 -6
package/README.md
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
- 📝 **Gherkin-Style Syntax**: Write tests in natural language, one instruction per line
|
|
12
12
|
- 🔄 **Self-Repair Capability**: Automatically repairs broken tests when application code changes
|
|
13
13
|
- 🎭 **Playwright Integration**: Built on top of Playwright for reliable browser automation
|
|
14
|
-
- 📊 **Token Tracking**: Built-in token usage tracking for AI model calls
|
|
14
|
+
- 📊 **Token Tracking**: Built-in token usage tracking for AI model calls (early mode - working out the best way to report on usage)
|
|
15
15
|
- 💾 **Snapshot Storage**: Automatically saves and replays successful test executions
|
|
16
|
-
- 🎯 **Best Selector System**: Stores optimal selectors (role, label, testid)
|
|
16
|
+
- 🎯 **Best Selector System**: Stores optimal selectors (role, label, testid) for reliable element identification
|
|
17
17
|
|
|
18
18
|
## How It Works
|
|
19
19
|
|
|
@@ -37,11 +37,11 @@ await mimic`
|
|
|
37
37
|
|
|
38
38
|
During **Learn**, Mimic:
|
|
39
39
|
|
|
40
|
-
- **Dynamically injects marker code** into the page to assign `data-mimic-id` attributes to elements,
|
|
40
|
+
- **Dynamically injects marker code** into the page to assign `data-mimic-id` attributes to elements, helping align the LLM on which components to interact with
|
|
41
41
|
- Uses an AI model to:
|
|
42
42
|
- Interpret your intent
|
|
43
43
|
- Reason about the structure and semantics of the page
|
|
44
|
-
- Identify the most likely elements to interact with
|
|
44
|
+
- Identify the most likely elements to interact with (using marker IDs to reference elements)
|
|
45
45
|
- Generate executable Playwright steps
|
|
46
46
|
|
|
47
47
|
This is the most flexible phase — it's where Mimic figures out what you meant, not just what to click. The marker injection happens automatically and transparently — no changes to your application code are needed.
|
|
@@ -60,7 +60,7 @@ It stores a verified recording (snapshot) of the execution, including:
|
|
|
60
60
|
|
|
61
61
|
The storage system automatically saves snapshots to `<testfile-name>.mimic.json` files alongside your test files. These snapshots contain:
|
|
62
62
|
- **SelectorDescriptor objects**: The best available selector for each element (e.g., `getByRole('button', { name: 'Submit' })`)
|
|
63
|
-
- **Mimic IDs**:
|
|
63
|
+
- **Mimic IDs**: Reference identifiers from dynamically injected `data-mimic-id` attributes (used during learning to help align the LLM on components)
|
|
64
64
|
- **Action results**: Complete details of what action was performed and how
|
|
65
65
|
|
|
66
66
|
You can review the execution (for example, via Playwright's video output) to confirm it behaves exactly as expected. Once verified, this recording becomes the trusted reference for future runs.
|
|
@@ -77,14 +77,13 @@ In this phase:
|
|
|
77
77
|
- Token usage drops to near zero
|
|
78
78
|
- Tests run faster and more deterministically
|
|
79
79
|
- Behavior is repeatable because it's based on a known-good run
|
|
80
|
-
- **Selector reconstruction**: Uses stored `SelectorDescriptor` objects to rebuild locators
|
|
80
|
+
- **Selector reconstruction**: Uses stored `SelectorDescriptor` objects to rebuild locators
|
|
81
81
|
|
|
82
82
|
The replay system:
|
|
83
83
|
1. Loads the snapshot from the `.mimic.json` file
|
|
84
|
-
2. Dynamically injects marker code to assign `data-mimic-id` attributes to page elements
|
|
84
|
+
2. Dynamically injects marker code to assign `data-mimic-id` attributes to page elements (for reference during troubleshooting if needed)
|
|
85
85
|
3. Reconstructs locators from stored selector descriptors (e.g., `getByRole('button', { name: 'Submit' })`)
|
|
86
86
|
4. Executes actions directly without AI analysis
|
|
87
|
-
5. Falls back to dynamically injected `data-mimic-id` markers if selectors become stale
|
|
88
87
|
|
|
89
88
|
As long as the application hasn't changed in a way that breaks the test, Mimic stays in Repeat mode.
|
|
90
89
|
|
|
@@ -96,11 +95,18 @@ During **Troubleshoot & Fix**, Mimic:
|
|
|
96
95
|
|
|
97
96
|
- Analyzes what failed and why
|
|
98
97
|
- Re-learns the updated application structure
|
|
99
|
-
- Repairs or regenerates the broken steps
|
|
98
|
+
- Repairs or regenerates the broken steps (with selective regeneration: only regenerates steps that failed or changed)
|
|
100
99
|
- Saves a new verified recording
|
|
101
100
|
|
|
102
101
|
Once repaired and validated, the test returns to Repeat mode — stable, fast, and low-cost again.
|
|
103
102
|
|
|
103
|
+
**Troubleshoot Mode**: You can force Mimic to regenerate snapshots by running tests with the `--troubleshoot` flag:
|
|
104
|
+
```bash
|
|
105
|
+
npx playwright test --troubleshoot
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Even in troubleshoot mode, Mimic will attempt to use existing snapshots first and only regenerate if replay fails.
|
|
109
|
+
|
|
104
110
|
### The Full Loop
|
|
105
111
|
|
|
106
112
|
**Learn → Remember → Repeat → Troubleshoot & Fix → Repeat**
|
|
@@ -116,7 +122,7 @@ Built on top of Playwright with AI model integration for natural language proces
|
|
|
116
122
|
|
|
117
123
|
Mimic uses a sophisticated element identification system:
|
|
118
124
|
|
|
119
|
-
- **Dynamic Marker Injection**: Automatically injects `data-mimic-id` attributes into page elements at runtime. These
|
|
125
|
+
- **Dynamic Marker Injection**: Automatically injects `data-mimic-id` attributes into page elements at runtime. These identifiers are added dynamically to help align the LLM on which components to interact with during the learning phase, without requiring any manual changes to your application code.
|
|
120
126
|
- **Best Selector Generation**: Generates optimal selectors using Playwright's semantic locators:
|
|
121
127
|
- `getByRole()` for ARIA roles
|
|
122
128
|
- `getByLabel()` for form labels
|
|
@@ -124,9 +130,8 @@ Mimic uses a sophisticated element identification system:
|
|
|
124
130
|
- `getByText()` for visible text
|
|
125
131
|
- CSS selectors as fallback
|
|
126
132
|
- **Snapshot Storage**: Stores `SelectorDescriptor` objects (JSON-serializable) in snapshots for fast replay
|
|
127
|
-
- **Dual Fallback**: Uses best selector first, falls back to marker ID if selector becomes stale
|
|
128
133
|
|
|
129
|
-
The marker system works entirely behind the scenes — Mimic dynamically loads marker code into the page to assign
|
|
134
|
+
The marker system works entirely behind the scenes — Mimic dynamically loads marker code into the page to assign `data-mimic-id` attributes to interactive, display, and structural elements. These markers help the LLM identify and reference elements during the learning phase, making element identification more reliable without requiring any modifications to your application.
|
|
130
135
|
|
|
131
136
|
This ensures tests remain stable even when DOM structure changes, while preferring semantic selectors over brittle CSS paths.
|
|
132
137
|
|
|
@@ -182,6 +187,7 @@ import { test as base } from '@playwright/test';
|
|
|
182
187
|
import { createMimic, type Mimic } from 'playwright-mimic';
|
|
183
188
|
import { openai } from '@ai-sdk/openai';
|
|
184
189
|
// or for Ollama: import { ollama } from 'ollama-ai-provider-v2';
|
|
190
|
+
import { LanguageModel } from 'ai';
|
|
185
191
|
|
|
186
192
|
// Configure your AI model
|
|
187
193
|
const brains = openai('gpt-4o-mini');
|
|
@@ -197,7 +203,8 @@ export const test = base.extend<{
|
|
|
197
203
|
const mimic = createMimic({
|
|
198
204
|
page,
|
|
199
205
|
brains,
|
|
200
|
-
eyes
|
|
206
|
+
// eyes is optional and may be removed in future versions
|
|
207
|
+
// If provided, can use a different model for visual analysis
|
|
201
208
|
testInfo,
|
|
202
209
|
});
|
|
203
210
|
await use(mimic);
|
|
@@ -281,6 +288,16 @@ await mimic`
|
|
|
281
288
|
|
|
282
289
|
#### Form Interactions
|
|
283
290
|
|
|
291
|
+
Mimic supports the following form actions:
|
|
292
|
+
- `type`: Type text character by character (simulates real typing)
|
|
293
|
+
- `fill`: Replace all content in a field with text (faster, preferred for most cases)
|
|
294
|
+
- `select`: Select an option from a dropdown/select element
|
|
295
|
+
- `check`: Check a checkbox
|
|
296
|
+
- `uncheck`: Uncheck a checkbox
|
|
297
|
+
- `clear`: Clear field content
|
|
298
|
+
- `press`: Press a single keyboard key (e.g., "Enter", "Tab", "Escape")
|
|
299
|
+
- `setInputFiles`: Upload a file
|
|
300
|
+
|
|
284
301
|
```typescript
|
|
285
302
|
await mimic`
|
|
286
303
|
type "john@example.com" into the email field
|
|
@@ -288,6 +305,8 @@ await mimic`
|
|
|
288
305
|
select "United States" from the country dropdown
|
|
289
306
|
check the terms and conditions checkbox
|
|
290
307
|
uncheck the newsletter checkbox
|
|
308
|
+
clear the message field
|
|
309
|
+
press "Enter" in the search field
|
|
291
310
|
`;
|
|
292
311
|
```
|
|
293
312
|
|
|
@@ -343,7 +362,7 @@ test('custom usage', async ({ page, testInfo }) => {
|
|
|
343
362
|
{
|
|
344
363
|
page,
|
|
345
364
|
brains,
|
|
346
|
-
eyes
|
|
365
|
+
// eyes is optional and may be removed in future versions
|
|
347
366
|
testInfo,
|
|
348
367
|
}
|
|
349
368
|
);
|
|
@@ -359,7 +378,7 @@ Creates a mimic function that can be used as a template literal tag.
|
|
|
359
378
|
**Parameters:**
|
|
360
379
|
- `config.page` (required): Playwright `Page` object
|
|
361
380
|
- `config.brains` (required): Language model for reasoning (from `ai` SDK)
|
|
362
|
-
- `config.eyes` (
|
|
381
|
+
- `config.eyes` (optional): Language model for visual analysis (may be removed in future versions)
|
|
363
382
|
- `config.testInfo` (optional): Playwright `TestInfo` object for test tracking
|
|
364
383
|
|
|
365
384
|
**Returns:** A function that accepts template literals
|
|
@@ -372,67 +391,90 @@ Direct function call version.
|
|
|
372
391
|
- `input` (string): Newline-separated test steps
|
|
373
392
|
- `config`: Same as `createMimic`
|
|
374
393
|
|
|
375
|
-
### Exported Utilities
|
|
376
|
-
|
|
377
|
-
You can also import individual utilities for custom implementations:
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
import {
|
|
381
|
-
getBaseAction,
|
|
382
|
-
getClickAction,
|
|
383
|
-
executeClickAction,
|
|
384
|
-
getNavigationAction,
|
|
385
|
-
executeNavigationAction,
|
|
386
|
-
getFormAction,
|
|
387
|
-
executeFormAction,
|
|
388
|
-
captureTargets,
|
|
389
|
-
buildSelectorForTarget,
|
|
390
|
-
} from 'playwright-mimic';
|
|
391
|
-
```
|
|
392
|
-
|
|
393
394
|
## Snapshot Files
|
|
394
395
|
|
|
395
|
-
Mimic automatically creates snapshot files (`.mimic.json`) in `__mimic__/` directories alongside your test files.
|
|
396
|
+
Mimic automatically creates snapshot files (`.mimic.json`) in `__mimic__/` directories alongside your test files. Each file can contain multiple test snapshots, with each test identified by a unique `testHash`.
|
|
396
397
|
|
|
397
|
-
|
|
398
|
-
- **Steps**: Array of executed steps with:
|
|
399
|
-
- Step text and hash
|
|
400
|
-
- Action details (navigation, click, form)
|
|
401
|
-
- **Target element**: Contains `SelectorDescriptor` (primary) and `mimicId` (fallback)
|
|
402
|
-
- Execution timestamp
|
|
403
|
-
- **Flags**: Metadata about the snapshot (needsRetry, hasErrors, etc.)
|
|
398
|
+
### Snapshot File Structure
|
|
404
399
|
|
|
405
|
-
|
|
400
|
+
The snapshot file is a JSON object containing a `tests` array:
|
|
406
401
|
|
|
407
402
|
```json
|
|
408
403
|
{
|
|
409
|
-
"
|
|
410
|
-
"testText": "click on \"Submit\"\nfill the email field with \"test@example.com\"",
|
|
411
|
-
"steps": [
|
|
404
|
+
"tests": [
|
|
412
405
|
{
|
|
413
|
-
"
|
|
414
|
-
"
|
|
415
|
-
"
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
"
|
|
421
|
-
"
|
|
422
|
-
"
|
|
423
|
-
|
|
424
|
-
|
|
406
|
+
"testHash": "abc123...",
|
|
407
|
+
"testText": "click on \"Submit\"\nfill the email field with \"test@example.com\"",
|
|
408
|
+
"stepsByHash": {
|
|
409
|
+
"def456...": {
|
|
410
|
+
"stepHash": "def456...",
|
|
411
|
+
"stepIndex": 0,
|
|
412
|
+
"stepText": "click on \"Submit\"",
|
|
413
|
+
"actionKind": "click",
|
|
414
|
+
"actionDetails": { ... },
|
|
415
|
+
"targetElement": {
|
|
416
|
+
"selector": {
|
|
417
|
+
"type": "role",
|
|
418
|
+
"role": "button",
|
|
419
|
+
"name": "Submit"
|
|
420
|
+
},
|
|
421
|
+
"mimicId": 42
|
|
422
|
+
},
|
|
423
|
+
"executedAt": "2024-01-01T12:00:00.000Z"
|
|
424
|
+
}
|
|
425
425
|
},
|
|
426
|
-
"
|
|
426
|
+
"steps": [
|
|
427
|
+
{
|
|
428
|
+
"stepHash": "def456...",
|
|
429
|
+
"stepIndex": 0,
|
|
430
|
+
"stepText": "click on \"Submit\"",
|
|
431
|
+
"actionKind": "click",
|
|
432
|
+
"actionDetails": { ... },
|
|
433
|
+
"targetElement": {
|
|
434
|
+
"selector": {
|
|
435
|
+
"type": "role",
|
|
436
|
+
"role": "button",
|
|
437
|
+
"name": "Submit"
|
|
438
|
+
},
|
|
439
|
+
"mimicId": 42
|
|
440
|
+
},
|
|
441
|
+
"executedAt": "2024-01-01T12:00:00.000Z"
|
|
442
|
+
}
|
|
443
|
+
],
|
|
444
|
+
"flags": {
|
|
445
|
+
"needsRetry": false,
|
|
446
|
+
"hasErrors": false,
|
|
447
|
+
"troubleshootingEnabled": false,
|
|
448
|
+
"skipSnapshot": false,
|
|
449
|
+
"forceRegenerate": false,
|
|
450
|
+
"debugMode": false,
|
|
451
|
+
"createdAt": "2024-01-01T12:00:00.000Z",
|
|
452
|
+
"lastPassedAt": "2024-01-01T12:00:00.000Z",
|
|
453
|
+
"lastFailedAt": null
|
|
454
|
+
}
|
|
427
455
|
}
|
|
428
|
-
]
|
|
429
|
-
"flags": { ... }
|
|
456
|
+
]
|
|
430
457
|
}
|
|
431
458
|
```
|
|
432
459
|
|
|
433
|
-
|
|
460
|
+
### Snapshot Structure Details
|
|
461
|
+
|
|
462
|
+
Each test snapshot contains:
|
|
463
|
+
|
|
464
|
+
- **testHash**: Unique identifier for the test (hash of test text)
|
|
465
|
+
- **testText**: Original test text (mimic template string)
|
|
466
|
+
- **stepsByHash**: Object mapping step hashes to step data (for efficient lookup and selective regeneration)
|
|
467
|
+
- **steps**: Array of executed steps in order (for backward compatibility and ordered replay)
|
|
468
|
+
- **stepHash**: Unique identifier for the step (hash of step text)
|
|
469
|
+
- **stepIndex**: Index of the step in the test (0-based)
|
|
470
|
+
- **stepText**: Original step text
|
|
471
|
+
- **actionKind**: Type of action ("click", "form update", "navigation")
|
|
472
|
+
- **actionDetails**: Complete details of what action was performed
|
|
473
|
+
- **targetElement**: Contains `SelectorDescriptor` (primary selector) and `mimicId` (reference identifier used during learning)
|
|
474
|
+
- **executedAt**: Timestamp when the step was executed
|
|
475
|
+
- **flags**: Metadata about the snapshot (needsRetry, hasErrors, troubleshootingEnabled, etc.)
|
|
434
476
|
|
|
435
|
-
**Note**: The `mimicId` values in snapshots reference `data-mimic-id` attributes that are dynamically injected into the page by Mimic at runtime. These markers are
|
|
477
|
+
**Note**: The `mimicId` values in snapshots reference `data-mimic-id` attributes that are dynamically injected into the page by Mimic at runtime. These markers are used during the learning phase to help align the LLM on which components to interact with — you don't need to add them to your application code.
|
|
436
478
|
|
|
437
479
|
## Configuration
|
|
438
480
|
|
|
@@ -450,11 +492,7 @@ import { ollama } from 'ollama-ai-provider-v2';
|
|
|
450
492
|
const brains = ollama('llama3.2') as LanguageModel;
|
|
451
493
|
```
|
|
452
494
|
|
|
453
|
-
**
|
|
454
|
-
```typescript
|
|
455
|
-
const brains = openai('gpt-4o-mini'); // For reasoning
|
|
456
|
-
const eyes = openai('gpt-4-vision-preview'); // For visual analysis (if needed)
|
|
457
|
-
```
|
|
495
|
+
**Note**: The `eyes` parameter is optional and may be removed in future versions. Currently, if not provided, the `brains` model is used for all operations.
|
|
458
496
|
|
|
459
497
|
### Playwright Configuration
|
|
460
498
|
|
|
@@ -520,6 +558,8 @@ await mimic`
|
|
|
520
558
|
`;
|
|
521
559
|
```
|
|
522
560
|
|
|
561
|
+
Mimic also captures an initial screenshot with markers and attaches it to the test report, making it easy to see the page state at the start of the test.
|
|
562
|
+
|
|
523
563
|
### 4. Handle Dynamic Content
|
|
524
564
|
|
|
525
565
|
For dynamic content, combine mimic with Playwright waits:
|
|
@@ -530,9 +570,11 @@ await page.waitForSelector('text=New Content');
|
|
|
530
570
|
await mimic`click on "New Content"`;
|
|
531
571
|
```
|
|
532
572
|
|
|
573
|
+
Mimic automatically handles waiting for elements to be ready before interacting with them, but you may need additional waits for complex dynamic content.
|
|
574
|
+
|
|
533
575
|
### 5. Token Usage
|
|
534
576
|
|
|
535
|
-
Mimic tracks token usage automatically. Monitor your AI provider's usage to optimize costs:
|
|
577
|
+
Mimic tracks token usage automatically (early mode - we're working out the best way to report on usage). Monitor your AI provider's usage to optimize costs:
|
|
536
578
|
|
|
537
579
|
- Use smaller models (like `gpt-4o-mini`) for faster, cheaper tests
|
|
538
580
|
- Use larger models only when needed for complex reasoning
|
|
@@ -560,16 +602,32 @@ AI model calls take time. To speed up:
|
|
|
560
602
|
If snapshots aren't working as expected:
|
|
561
603
|
1. Check that `.mimic.json` files are being created in `__mimic__/` directories
|
|
562
604
|
2. Verify selector descriptors in snapshots are valid
|
|
563
|
-
3. If selectors become stale, Mimic will automatically
|
|
605
|
+
3. If selectors become stale, Mimic will automatically regenerate the affected steps
|
|
564
606
|
4. Delete the snapshot file to force regeneration if needed
|
|
607
|
+
5. Use `--troubleshoot` flag to force regeneration: `npx playwright test --troubleshoot`
|
|
608
|
+
|
|
609
|
+
### Troubleshoot Mode
|
|
610
|
+
|
|
611
|
+
Troubleshoot mode can be enabled by passing the `--troubleshoot` flag when running tests:
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
npx playwright test --troubleshoot
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
This mode:
|
|
618
|
+
- Still attempts to use existing snapshots first
|
|
619
|
+
- Regenerates actions only if snapshot replay fails
|
|
620
|
+
- Useful for debugging and updating snapshots after fixing issues
|
|
565
621
|
|
|
566
622
|
### Storage System
|
|
567
623
|
|
|
568
|
-
The snapshot storage system
|
|
624
|
+
The snapshot storage system provides:
|
|
569
625
|
- ✅ Automatic snapshot creation on successful test runs
|
|
570
|
-
- ✅ Selector descriptor storage
|
|
626
|
+
- ✅ Selector descriptor storage for reliable element identification
|
|
571
627
|
- ✅ Fast replay without AI calls
|
|
572
|
-
-
|
|
628
|
+
- ✅ Selective regeneration: only regenerates steps that don't exist or have changed
|
|
629
|
+
- ✅ Multiple tests per snapshot file (organized by testHash)
|
|
630
|
+
- ✅ Efficient lookup using `stepsByHash` for fast step retrieval
|
|
573
631
|
|
|
574
632
|
### API Key Issues
|
|
575
633
|
|
|
@@ -578,6 +636,10 @@ Ensure your `.env` file is loaded:
|
|
|
578
636
|
import "dotenv/config"; // At the top of your test-utils.ts
|
|
579
637
|
```
|
|
580
638
|
|
|
639
|
+
### Test Tags
|
|
640
|
+
|
|
641
|
+
Test tags like `@mimic` are used for internal reference and filtering during development. They are not part of the public API and may change.
|
|
642
|
+
|
|
581
643
|
## Examples
|
|
582
644
|
|
|
583
645
|
### E-commerce Checkout Flow
|
package/dist/index.d.ts
CHANGED
|
@@ -8,9 +8,6 @@ export { getBaseAction } from './mimic/actionType.js';
|
|
|
8
8
|
export { getClickAction, executeClickAction } from './mimic/click.js';
|
|
9
9
|
export { getNavigationAction, executeNavigationAction } from './mimic/navigation.js';
|
|
10
10
|
export { getFormAction, executeFormAction, type FormActionResult } from './mimic/forms.js';
|
|
11
|
-
export {
|
|
11
|
+
export { getMimic, type MarkerElementInfo } from './mimic/markers.js';
|
|
12
12
|
export type { NavigationAction, ClickActionResult, Point, } from './mimic/schema/action.js';
|
|
13
|
-
export { createAgenticMimic, type AgenticMimic } from './agentic-mimic.js';
|
|
14
|
-
export { Agent } from './agentic/agent.js';
|
|
15
|
-
export type { AgentState, AgentConfig, ActionRecord, ActionReflection, PlanningResult, PlanStep, ReasoningResult, DecidedAction, } from './agentic/index.js';
|
|
16
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGtE,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,GACN,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,5 @@ export { getBaseAction } from './mimic/actionType.js';
|
|
|
10
10
|
export { getClickAction, executeClickAction } from './mimic/click.js';
|
|
11
11
|
export { getNavigationAction, executeNavigationAction } from './mimic/navigation.js';
|
|
12
12
|
export { getFormAction, executeFormAction } from './mimic/forms.js';
|
|
13
|
-
export {
|
|
14
|
-
// Agentic system exports
|
|
15
|
-
export { createAgenticMimic } from './agentic-mimic.js';
|
|
16
|
-
export { Agent } from './agentic/agent.js';
|
|
13
|
+
export { getMimic } from './mimic/markers.js';
|
|
17
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2BAA2B;AAC3B,OAAO,EAAE,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAE5D,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2BAA2B;AAC3B,OAAO,EAAE,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAE5D,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAA0B,MAAM,oBAAoB,CAAC"}
|
|
@@ -14,7 +14,8 @@ import { TestInfo } from '@playwright/test';
|
|
|
14
14
|
* @param testInfo - Playwright TestInfo object (optional, for test context)
|
|
15
15
|
* @param gherkinStep - The original Gherkin step that triggered this action (used as annotation type)
|
|
16
16
|
* @param description - The description of what action is being performed (used as annotation description)
|
|
17
|
+
* @param playwrightCode - Optional Playwright code equivalent to add to the annotation
|
|
17
18
|
* @returns void
|
|
18
19
|
*/
|
|
19
|
-
export declare function addAnnotation(testInfo: TestInfo | undefined, gherkinStep: string | undefined, description: string): void;
|
|
20
|
+
export declare function addAnnotation(testInfo: TestInfo | undefined, gherkinStep: string | undefined, description: string, playwrightCode?: string): void;
|
|
20
21
|
//# sourceMappingURL=annotations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/mimic/annotations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/mimic/annotations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI,CAgBN"}
|
|
@@ -13,18 +13,24 @@
|
|
|
13
13
|
* @param testInfo - Playwright TestInfo object (optional, for test context)
|
|
14
14
|
* @param gherkinStep - The original Gherkin step that triggered this action (used as annotation type)
|
|
15
15
|
* @param description - The description of what action is being performed (used as annotation description)
|
|
16
|
+
* @param playwrightCode - Optional Playwright code equivalent to add to the annotation
|
|
16
17
|
* @returns void
|
|
17
18
|
*/
|
|
18
|
-
export function addAnnotation(testInfo, gherkinStep, description) {
|
|
19
|
+
export function addAnnotation(testInfo, gherkinStep, description, playwrightCode) {
|
|
20
|
+
// Combine description with Playwright code if provided
|
|
21
|
+
let fullDescription = description;
|
|
22
|
+
if (playwrightCode) {
|
|
23
|
+
fullDescription += `\n 📝 Playwright: ${playwrightCode}`;
|
|
24
|
+
}
|
|
19
25
|
if (testInfo && gherkinStep) {
|
|
20
26
|
testInfo.annotations.push({
|
|
21
27
|
type: gherkinStep,
|
|
22
|
-
description
|
|
28
|
+
description: fullDescription
|
|
23
29
|
});
|
|
24
30
|
}
|
|
25
31
|
else {
|
|
26
|
-
// Fallback to console.log when testInfo is not available
|
|
27
|
-
console.log(
|
|
32
|
+
// Fallback to console.log when testInfo is not available
|
|
33
|
+
console.log(fullDescription);
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
//# sourceMappingURL=annotations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/mimic/annotations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/mimic/annotations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA8B,EAC9B,WAA+B,EAC/B,WAAmB,EACnB,cAAuB;IAEvB,uDAAuD;IACvD,IAAI,eAAe,GAAG,WAAW,CAAC;IAClC,IAAI,cAAc,EAAE,CAAC;QACnB,eAAe,IAAI,sBAAsB,cAAc,EAAE,CAAC;IAC5D,CAAC;IAED,IAAI,QAAQ,IAAI,WAAW,EAAE,CAAC;QAC5B,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;YACxB,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,eAAe;SAC7B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
package/dist/mimic/cli.js
CHANGED
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
* @returns true if --troubleshoot flag is present in process.argv
|
|
13
13
|
*/
|
|
14
14
|
export function isTroubleshootMode() {
|
|
15
|
-
return
|
|
15
|
+
return process.argv.includes('--troubleshoot');
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=cli.js.map
|
package/dist/mimic/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/mimic/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/mimic/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACjD,CAAC"}
|
package/dist/mimic/click.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type LanguageModel } from 'ai';
|
|
2
2
|
import { Locator, Page, TestInfo } from '@playwright/test';
|
|
3
3
|
import { type ClickActionResult } from './schema/action.js';
|
|
4
|
-
import type { TargetInfo } from './selector.js';
|
|
5
4
|
import type { TestContext } from '../mimic.js';
|
|
5
|
+
import type { SelectorDescriptor } from './selectorTypes.js';
|
|
6
6
|
/**
|
|
7
7
|
* Get click action by matching Gherkin step against captured target elements
|
|
8
8
|
*
|
|
@@ -13,11 +13,11 @@ import type { TestContext } from '../mimic.js';
|
|
|
13
13
|
* @param page - Playwright Page object (currently unused but kept for consistency)
|
|
14
14
|
* @param brain - LanguageModel instance for AI analysis
|
|
15
15
|
* @param gherkinStep - The Gherkin step to match (e.g., "I click on the Submit button")
|
|
16
|
-
* @param targetElements - Array of captured
|
|
16
|
+
* @param targetElements - Array of captured elements with marker IDs from the page
|
|
17
17
|
* @param testContext - Optional test context with previous steps and current state
|
|
18
18
|
* @returns Promise resolving to ClickActionResult with top candidates and click type
|
|
19
19
|
*/
|
|
20
|
-
export declare const getClickAction: (
|
|
20
|
+
export declare const getClickAction: (page: Page, brain: LanguageModel, gherkinStep: string, testContext?: TestContext) => Promise<ClickActionResult>;
|
|
21
21
|
/**
|
|
22
22
|
* Execute a click action on a page element with plain English annotation
|
|
23
23
|
*
|
|
@@ -34,6 +34,6 @@ export declare const getClickAction: (_page: Page, brain: LanguageModel, gherkin
|
|
|
34
34
|
*/
|
|
35
35
|
export declare const executeClickAction: (element: Locator | null, clickActionResult: ClickActionResult, selectedCandidate: ClickActionResult["candidates"][0], testInfo: TestInfo | undefined, gherkinStep: string) => Promise<{
|
|
36
36
|
actionResult: ClickActionResult;
|
|
37
|
-
selector:
|
|
37
|
+
selector: SelectorDescriptor | null;
|
|
38
38
|
}>;
|
|
39
39
|
//# sourceMappingURL=click.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../src/mimic/click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,IAAI,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE1D,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../src/mimic/click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,IAAI,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE1D,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,IAAI,EACV,OAAO,aAAa,EACpB,aAAa,MAAM,EACnB,cAAc,WAAW,KACxB,OAAO,CAAC,iBAAiB,CA6P3B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,OAAO,GAAG,IAAI,EACvB,mBAAmB,iBAAiB,EACpC,mBAAmB,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EACrD,UAAU,QAAQ,GAAG,SAAS,EAC9B,aAAa,MAAM,KAClB,OAAO,CAAC;IAAE,YAAY,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAA;CAAE,CAiGlF,CAAC"}
|