playwright-mimic 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +633 -446
  2. package/dist/agentic/agent.d.ts +106 -0
  3. package/dist/agentic/agent.d.ts.map +1 -0
  4. package/dist/agentic/agent.js +528 -0
  5. package/dist/agentic/agent.js.map +1 -0
  6. package/dist/agentic/index.d.ts +13 -0
  7. package/dist/agentic/index.d.ts.map +1 -0
  8. package/dist/agentic/index.js +12 -0
  9. package/dist/agentic/index.js.map +1 -0
  10. package/dist/agentic/planner.d.ts +41 -0
  11. package/dist/agentic/planner.d.ts.map +1 -0
  12. package/dist/agentic/planner.js +136 -0
  13. package/dist/agentic/planner.js.map +1 -0
  14. package/dist/agentic/react.d.ts +35 -0
  15. package/dist/agentic/react.d.ts.map +1 -0
  16. package/dist/agentic/react.js +170 -0
  17. package/dist/agentic/react.js.map +1 -0
  18. package/dist/agentic/recovery.d.ts +55 -0
  19. package/dist/agentic/recovery.d.ts.map +1 -0
  20. package/dist/agentic/recovery.js +200 -0
  21. package/dist/agentic/recovery.js.map +1 -0
  22. package/dist/agentic/reflection.d.ts +40 -0
  23. package/dist/agentic/reflection.d.ts.map +1 -0
  24. package/dist/agentic/reflection.js +142 -0
  25. package/dist/agentic/reflection.js.map +1 -0
  26. package/dist/agentic/types.d.ts +177 -0
  27. package/dist/agentic/types.d.ts.map +1 -0
  28. package/dist/agentic/types.js +8 -0
  29. package/dist/agentic/types.js.map +1 -0
  30. package/dist/agentic/wait.d.ts +50 -0
  31. package/dist/agentic/wait.d.ts.map +1 -0
  32. package/dist/agentic/wait.js +140 -0
  33. package/dist/agentic/wait.js.map +1 -0
  34. package/dist/agentic-mimic.d.ts +56 -0
  35. package/dist/agentic-mimic.d.ts.map +1 -0
  36. package/dist/agentic-mimic.js +98 -0
  37. package/dist/agentic-mimic.js.map +1 -0
  38. package/dist/index.d.ts +11 -8
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +12 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/mimic/actionType.d.ts +7 -0
  43. package/dist/mimic/actionType.d.ts.map +1 -0
  44. package/dist/mimic/actionType.js +44 -0
  45. package/dist/mimic/actionType.js.map +1 -0
  46. package/dist/mimic/annotations.d.ts +20 -0
  47. package/dist/mimic/annotations.d.ts.map +1 -0
  48. package/dist/mimic/annotations.js +30 -0
  49. package/dist/mimic/annotations.js.map +1 -0
  50. package/dist/mimic/cli.d.ts +15 -0
  51. package/dist/mimic/cli.d.ts.map +1 -0
  52. package/dist/mimic/cli.js +17 -0
  53. package/dist/mimic/cli.js.map +1 -0
  54. package/dist/mimic/click.d.ts +39 -0
  55. package/dist/mimic/click.d.ts.map +1 -0
  56. package/dist/mimic/click.js +233 -0
  57. package/dist/mimic/click.js.map +1 -0
  58. package/dist/mimic/forms.d.ts +47 -0
  59. package/dist/mimic/forms.d.ts.map +1 -0
  60. package/dist/mimic/forms.js +264 -0
  61. package/dist/mimic/forms.js.map +1 -0
  62. package/dist/mimic/navigation.d.ts +19 -0
  63. package/dist/mimic/navigation.d.ts.map +1 -0
  64. package/dist/mimic/navigation.js +117 -0
  65. package/dist/mimic/navigation.js.map +1 -0
  66. package/dist/mimic/replay.d.ts +21 -0
  67. package/dist/mimic/replay.d.ts.map +1 -0
  68. package/dist/mimic/replay.js +133 -0
  69. package/dist/mimic/replay.js.map +1 -0
  70. package/dist/mimic/schema/action.d.ts +315 -0
  71. package/dist/mimic/schema/action.d.ts.map +1 -0
  72. package/dist/mimic/schema/action.js +204 -0
  73. package/dist/mimic/schema/action.js.map +1 -0
  74. package/dist/mimic/selector.d.ts +139 -0
  75. package/dist/mimic/selector.d.ts.map +1 -0
  76. package/dist/mimic/selector.js +1103 -0
  77. package/dist/mimic/selector.js.map +1 -0
  78. package/dist/mimic/selectorDescriptor.d.ts +13 -0
  79. package/dist/mimic/selectorDescriptor.d.ts.map +1 -0
  80. package/dist/mimic/selectorDescriptor.js +9 -0
  81. package/dist/mimic/selectorDescriptor.js.map +1 -0
  82. package/dist/mimic/selectorSerialization.d.ts +30 -0
  83. package/dist/mimic/selectorSerialization.d.ts.map +1 -0
  84. package/dist/mimic/selectorSerialization.js +170 -0
  85. package/dist/mimic/selectorSerialization.js.map +1 -0
  86. package/dist/mimic/selectorTypes.d.ts +200 -0
  87. package/dist/mimic/selectorTypes.d.ts.map +1 -0
  88. package/dist/mimic/selectorTypes.js +2 -0
  89. package/dist/mimic/selectorTypes.js.map +1 -0
  90. package/dist/mimic/selectorUtils.d.ts +26 -0
  91. package/dist/mimic/selectorUtils.d.ts.map +1 -0
  92. package/dist/mimic/selectorUtils.js +144 -0
  93. package/dist/mimic/selectorUtils.js.map +1 -0
  94. package/dist/mimic/storage.d.ts +75 -0
  95. package/dist/mimic/storage.d.ts.map +1 -0
  96. package/dist/mimic/storage.js +197 -0
  97. package/dist/mimic/storage.js.map +1 -0
  98. package/dist/mimic/types.d.ts +63 -0
  99. package/dist/mimic/types.d.ts.map +1 -0
  100. package/dist/mimic/types.js +7 -0
  101. package/dist/mimic/types.js.map +1 -0
  102. package/dist/mimic.d.ts +28 -4
  103. package/dist/mimic.d.ts.map +1 -1
  104. package/dist/mimic.js +374 -32
  105. package/dist/mimic.js.map +1 -1
  106. package/dist/mimicry.d.ts +4 -4
  107. package/dist/mimicry.d.ts.map +1 -1
  108. package/dist/mimicry.js +22 -13
  109. package/dist/mimicry.js.map +1 -1
  110. package/package.json +5 -2
package/dist/mimic.js CHANGED
@@ -2,52 +2,382 @@
2
2
  * Minimal flow example function
3
3
  */
4
4
  import { test } from '@playwright/test';
5
- import { getBaseAction } from './mimicry/actionType.js';
6
- import { getNavigationAction, executeNavigationAction } from './mimicry/navigation.js';
7
- import { buildSelectorForTarget, captureTargets } from './mimicry/selector.js';
8
- import { executeClickAction, getClickAction } from './mimicry/click.js';
9
- import { startTestCase } from './utils/token-counter.js';
5
+ import { dirname } from 'path';
6
+ import { generateText, Output } from 'ai';
7
+ import { z } from 'zod';
8
+ import { getBaseAction } from './mimic/actionType.js';
9
+ import { getNavigationAction, executeNavigationAction } from './mimic/navigation.js';
10
+ import { buildSelectorForTarget, captureTargets } from './mimic/selector.js';
11
+ import { executeClickAction, getClickAction } from './mimic/click.js';
12
+ import { getFormAction, executeFormAction } from './mimic/forms.js';
13
+ import { startTestCase, countTokens } from './utils/token-counter.js';
14
+ import { hashTestText, getSnapshot, saveSnapshot, recordFailure, shouldUseSnapshot } from './mimic/storage.js';
15
+ import { replayFromSnapshot } from './mimic/replay.js';
16
+ import { isTroubleshootMode } from './mimic/cli.js';
17
+ import { addAnnotation } from './mimic/annotations.js';
18
+ /**
19
+ * Schema for intent accomplishment check result
20
+ *
21
+ * Note: All fields must be required (no .optional()) for AI SDK structured output compatibility.
22
+ * Use empty string for remainingActions when accomplished is true.
23
+ */
24
+ const zIntentAccomplished = z.object({
25
+ accomplished: z.boolean().describe('Whether the step intent has been fully accomplished'),
26
+ reasoning: z.string().describe('Brief explanation of why the intent is or is not accomplished'),
27
+ remainingActions: z.string().describe('What actions might still be needed if not accomplished (provide empty string "" if accomplished is true)'),
28
+ });
29
+ /**
30
+ * Check if a step's intent has been accomplished
31
+ *
32
+ * Uses the LLM to analyze the current page state and determine if the step's
33
+ * intent has been fully fulfilled. This allows the system to continue
34
+ * executing actions for a single step until the intent is complete.
35
+ *
36
+ * @param page - Playwright Page object
37
+ * @param brain - Language model for intent analysis
38
+ * @param stepText - The original step text to check intent for
39
+ * @param actionsTaken - Array of actions already taken for this step
40
+ * @returns Promise resolving to whether the intent is accomplished
41
+ */
42
+ /**
43
+ * Check if a step's intent has been accomplished
44
+ *
45
+ * Uses the LLM to analyze the current page state and determine if the step's
46
+ * intent has been fully fulfilled. This allows the system to continue
47
+ * executing actions for a single step until the intent is complete.
48
+ *
49
+ * @param page - Playwright Page object
50
+ * @param brain - Language model for intent analysis
51
+ * @param stepText - The original step text to check intent for
52
+ * @param actionsTaken - Array of actions already taken for this step
53
+ * @returns Promise resolving to whether the intent is accomplished
54
+ */
55
+ async function checkIntentAccomplished(page, brain, stepText, actionsTaken) {
56
+ try {
57
+ // Capture current page state
58
+ const currentUrl = page.url();
59
+ const pageTitle = await page.title();
60
+ const pageContent = await page.textContent('body') || '';
61
+ const pageContentPreview = pageContent.substring(0, 2000); // Limit content size
62
+ // Build description of actions taken
63
+ const actionsDescription = actionsTaken.length > 0
64
+ ? actionsTaken.map((action, idx) => `${idx + 1}. ${action.actionKind}: ${action.stepText}`).join('\n')
65
+ : 'No actions taken yet';
66
+ const prompt = `You are analyzing whether a test step's intent has been fully accomplished.
67
+
68
+ **Step Intent:**
69
+ ${stepText}
70
+
71
+ **Actions Taken So Far:**
72
+ ${actionsDescription}
73
+
74
+ **Current Page State:**
75
+ - URL: ${currentUrl}
76
+ - Page Title: ${pageTitle}
77
+ - Page Content Preview: ${pageContentPreview.substring(0, 500)}...
78
+
79
+ **Instructions:**
80
+ Analyze whether the step's intent has been FULLY accomplished based on:
81
+ 1. The literal meaning of the step text
82
+ 2. The actions that have been taken
83
+ 3. The current state of the page
84
+
85
+ Consider:
86
+ - Has the step's primary goal been achieved?
87
+ - Are there any remaining sub-tasks implied by the step?
88
+ - Would a reasonable person reading the step consider it complete?
89
+
90
+ Be strict: only mark as accomplished if the intent is FULLY satisfied. If the step requires multiple actions (e.g., "fill in the form and submit it"), it's not accomplished until ALL parts are done.
91
+
92
+ **Important:** Always provide all fields:
93
+ - If accomplished is true, set remainingActions to an empty string ""
94
+ - If accomplished is false, describe what actions are still needed in remainingActions`;
95
+ const result = await generateText({
96
+ model: brain,
97
+ prompt,
98
+ output: Output.object({ schema: zIntentAccomplished, name: 'intentAccomplished' }),
99
+ });
100
+ await countTokens(result);
101
+ const output = result.output;
102
+ if (!output.accomplished && output.remainingActions && output.remainingActions.trim()) {
103
+ console.log(`→ Step intent not yet accomplished. ${output.reasoning}`);
104
+ console.log(`→ Remaining: ${output.remainingActions}`);
105
+ }
106
+ else if (output.accomplished) {
107
+ console.log(`✓ Step intent accomplished: ${output.reasoning}`);
108
+ }
109
+ return output.accomplished;
110
+ }
111
+ catch (error) {
112
+ // If intent check fails, default to false (continue trying)
113
+ console.warn(`Failed to check intent accomplishment: ${error instanceof Error ? error.message : String(error)}`);
114
+ return false;
115
+ }
116
+ }
10
117
  /**
11
118
  * Minimal flow function that takes a Playwright page and input string
12
119
  *
13
120
  * @param page - Playwright Page object
14
121
  * @param input - Input string to process
122
+ * @param testFilePath - Directory path of the test file (for snapshot storage)
123
+ * @param troubleshootMode - Whether troubleshoot mode is enabled
15
124
  * @returns Flow execution result with validated context
16
125
  */
17
- export async function mimic(input, { page, brains, testInfo }) {
126
+ export async function mimic(input, { page, brains, testInfo, testFilePath, troubleshootMode }) {
18
127
  if (testInfo?.title)
19
128
  await startTestCase(testInfo.title);
129
+ // Generate test hash for snapshot identification
130
+ const testHash = hashTestText(input);
131
+ const isTroubleshoot = troubleshootMode ?? isTroubleshootMode();
132
+ // Normal execution with LLM - track steps for snapshot creation
20
133
  const steps = input.split('\n')
21
134
  // lets clean up things
22
135
  .map(step => step.trim())
23
136
  // and remove empty steps
24
- .filter(step => step.length > 0);
137
+ .filter((step) => step.length > 0);
138
+ const expectedStepCount = steps.length;
139
+ // Check if we should use an existing snapshot
140
+ // Even in troubleshoot mode, try to use snapshot first - only regenerate on failure
141
+ const useSnapshot = testFilePath && await shouldUseSnapshot(testFilePath, testHash, isTroubleshoot, expectedStepCount);
142
+ if (useSnapshot) {
143
+ const snapshot = await getSnapshot(testFilePath, testHash);
144
+ if (snapshot) {
145
+ // Add annotation indicating we're loading from snapshot
146
+ addAnnotation(testInfo, 'snapshot-load', `📦 Loading test from mimic snapshot file (${snapshot.steps.length} step${snapshot.steps.length !== 1 ? 's' : ''} cached)`);
147
+ try {
148
+ // Replay from snapshot (skip LLM calls for faster execution)
149
+ await replayFromSnapshot(page, snapshot, testInfo);
150
+ // If replay succeeds, we're done
151
+ return;
152
+ }
153
+ catch (error) {
154
+ // Replay failed - regenerate actions
155
+ // Add annotation at the top indicating test is being updated
156
+ addAnnotation(testInfo, 'test-update', `🔄 Test snapshot replay failed, regenerating actions: ${error instanceof Error ? error.message : String(error)}`);
157
+ // Record the failure before regenerating
158
+ if (testFilePath) {
159
+ await recordFailure(testFilePath, testHash, undefined, undefined, error instanceof Error ? error.message : String(error));
160
+ }
161
+ // Fall through to regenerate actions below
162
+ }
163
+ }
164
+ }
165
+ else if (testFilePath) {
166
+ // No snapshot exists or snapshot shouldn't be used - check if we're updating
167
+ const existingSnapshot = await getSnapshot(testFilePath, testHash);
168
+ if (existingSnapshot && existingSnapshot.lastFailedAt) {
169
+ // We have a failed snapshot - add annotation that we're regenerating
170
+ addAnnotation(testInfo, 'test-update', '🔄 Regenerating test actions due to previous failure');
171
+ }
172
+ }
173
+ // executedSteps will be populated during step execution below
174
+ const executedSteps = [];
25
175
  // now lets process each step
26
- for (const step of steps) {
27
- await test.step(step, async () => {
28
- const baseAction = await getBaseAction(page, brains, step);
29
- switch (baseAction.kind) {
30
- case 'navigation':
31
- console.log(`Navigating to ${step}`);
32
- const navigationAction = await getNavigationAction(page, brains, step);
33
- await executeNavigationAction(page, navigationAction);
34
- break;
35
- case 'click':
36
- console.log(`Clicking on ${step}`);
37
- const targetElements = await captureTargets(page, { interactableOnly: true });
38
- const clickActionResult = await getClickAction(page, brains, step, targetElements);
39
- // TODO: better way to work out if the top priority candidate is a clickable element
40
- const clickable = await buildSelectorForTarget(page, clickActionResult.candidates.find(Boolean));
41
- await executeClickAction(clickable, clickActionResult);
42
- break;
43
- case 'form update':
44
- const formElements = await captureTargets(page, { interactableOnly: true });
45
- console.log(`Form element count: ${formElements.length}`);
46
- break;
47
- default:
48
- throw new Error(`Unknown base action type: ${baseAction.kind}`);
176
+ for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
177
+ const step = steps[stepIndex];
178
+ // Type guard: ensure step is defined (should always be true after filter)
179
+ if (!step) {
180
+ continue;
181
+ }
182
+ try {
183
+ await test.step(step, async () => {
184
+ // Build test context from previous steps and current state
185
+ const currentUrl = page.url();
186
+ const currentPageTitle = await page.title().catch(() => 'Unknown');
187
+ const testContext = {
188
+ previousSteps: executedSteps.map((executedStep) => ({
189
+ stepIndex: executedStep.stepIndex,
190
+ stepText: executedStep.stepText,
191
+ actionKind: executedStep.actionKind,
192
+ // Extract URL from navigation actions if available
193
+ url: executedStep.actionKind === 'navigation'
194
+ ? executedStep.actionDetails.params?.url || undefined
195
+ : undefined,
196
+ })),
197
+ currentState: {
198
+ url: currentUrl,
199
+ pageTitle: currentPageTitle,
200
+ },
201
+ totalSteps: steps.length,
202
+ currentStepIndex: stepIndex,
203
+ };
204
+ // Track all actions taken for this step
205
+ const stepActions = [];
206
+ const maxActionsPerStep = 10; // Prevent infinite loops
207
+ let actionCount = 0;
208
+ let intentAccomplished = false;
209
+ // Loop until intent is accomplished or max actions reached
210
+ while (!intentAccomplished && actionCount < maxActionsPerStep) {
211
+ actionCount++;
212
+ // Check if intent is already accomplished (skip check on first action)
213
+ if (actionCount > 1) {
214
+ intentAccomplished = await checkIntentAccomplished(page, brains, step, stepActions);
215
+ if (intentAccomplished) {
216
+ console.log(`✓ Step intent accomplished after ${actionCount - 1} action(s)`);
217
+ break;
218
+ }
219
+ console.log(`→ Continuing to add actions for step (attempt ${actionCount})...`);
220
+ }
221
+ // Get the next action to execute for this step
222
+ const baseAction = await getBaseAction(page, brains, step, testContext);
223
+ let stepResult;
224
+ switch (baseAction.kind) {
225
+ case 'navigation':
226
+ // Navigation actions will log their own plain English annotations
227
+ const navigationAction = await getNavigationAction(page, brains, step, testContext);
228
+ const executedNavAction = await executeNavigationAction(page, navigationAction, testInfo, step);
229
+ stepResult = {
230
+ stepIndex,
231
+ stepText: step,
232
+ actionKind: 'navigation',
233
+ actionDetails: executedNavAction,
234
+ };
235
+ break;
236
+ case 'click':
237
+ // Click actions will log their own plain English annotations
238
+ const targetElements = await captureTargets(page, { interactableOnly: true });
239
+ const clickActionResult = await getClickAction(page, brains, step, targetElements, testContext);
240
+ // TODO: better way to work out if the top priority candidate is a clickable element
241
+ const selectedCandidate = clickActionResult.candidates.find(Boolean);
242
+ if (!selectedCandidate) {
243
+ throw new Error(`No candidate element found for click action: ${step}`);
244
+ }
245
+ const targetElement = targetElements[selectedCandidate.index];
246
+ if (!targetElement) {
247
+ throw new Error(`Target element not found at index ${selectedCandidate.index}`);
248
+ }
249
+ const clickable = await buildSelectorForTarget(page, targetElement);
250
+ const clickResult = await executeClickAction(clickable, clickActionResult, selectedCandidate, testInfo, step);
251
+ // Build targetElement with optional selector
252
+ // Use Object.assign to preserve all required TargetInfo properties
253
+ const targetElementWithSelector = clickResult.selector
254
+ ? Object.assign({}, targetElement, { selector: clickResult.selector })
255
+ : targetElement;
256
+ stepResult = {
257
+ stepIndex,
258
+ stepText: step,
259
+ actionKind: 'click',
260
+ actionDetails: clickResult.actionResult,
261
+ targetElement: targetElementWithSelector,
262
+ };
263
+ break;
264
+ case 'form update':
265
+ // Form actions will log their own plain English annotations
266
+ const formElements = await captureTargets(page, { interactableOnly: true });
267
+ const formActionResult = await getFormAction(page, brains, step, formElements, testContext);
268
+ // Find the target form element by matching step description
269
+ // Try to find element that matches keywords from the step (name, email, etc.)
270
+ const stepLower = step.toLowerCase();
271
+ let formElement = formElements.find(el => {
272
+ // Match by label, name, id, or placeholder
273
+ const labelMatch = el.label && stepLower.includes(el.label.toLowerCase());
274
+ const nameMatch = el.nameAttr && stepLower.includes(el.nameAttr.toLowerCase());
275
+ const idMatch = el.id && stepLower.includes(el.id.toLowerCase());
276
+ const ariaLabelMatch = el.ariaLabel && stepLower.includes(el.ariaLabel.toLowerCase());
277
+ // Also check if step mentions the element type (e.g., "name field", "email field")
278
+ const fieldTypeMatch = (stepLower.includes('name') && (el.nameAttr?.includes('name') || el.id?.includes('name') || el.label?.toLowerCase().includes('name'))) ||
279
+ (stepLower.includes('email') && (el.nameAttr?.includes('email') || el.id?.includes('email') || el.label?.toLowerCase().includes('email'))) ||
280
+ (stepLower.includes('phone') && (el.nameAttr?.includes('phone') || el.id?.includes('phone') || el.label?.toLowerCase().includes('phone'))) ||
281
+ (stepLower.includes('message') && (el.nameAttr?.includes('message') || el.id?.includes('message') || el.label?.toLowerCase().includes('message')));
282
+ return (labelMatch || nameMatch || idMatch || ariaLabelMatch || fieldTypeMatch) &&
283
+ (el.tag === 'input' || el.tag === 'textarea' || el.tag === 'select');
284
+ });
285
+ // Fallback to first form element if no match found
286
+ if (!formElement) {
287
+ formElement = formElements.find(el => el.tag === 'input' || el.tag === 'textarea' || el.tag === 'select') || formElements[0];
288
+ }
289
+ if (formElement) {
290
+ const targetFormElement = await buildSelectorForTarget(page, formElement);
291
+ const formResult = await executeFormAction(page, formActionResult, targetFormElement, testInfo, step);
292
+ // Handle the return type - executeFormAction may return void | string[] or { actionResult, selector }
293
+ let selector = undefined;
294
+ let actionDetails = formActionResult;
295
+ if (formResult && typeof formResult === 'object' && 'actionResult' in formResult) {
296
+ actionDetails = formResult.actionResult;
297
+ const resultSelector = formResult.selector;
298
+ if (resultSelector) {
299
+ selector = resultSelector;
300
+ }
301
+ }
302
+ stepResult = {
303
+ stepIndex,
304
+ stepText: step,
305
+ actionKind: 'form update',
306
+ actionDetails,
307
+ targetElement: selector
308
+ ? { ...formElement, selector }
309
+ : formElement,
310
+ };
311
+ }
312
+ else {
313
+ console.warn(`→ No form element found for step: ${step}`);
314
+ // Create a step result without target element
315
+ stepResult = {
316
+ stepIndex,
317
+ stepText: step,
318
+ actionKind: 'form update',
319
+ actionDetails: formActionResult,
320
+ };
321
+ }
322
+ break;
323
+ default:
324
+ throw new Error(`Unknown base action type: ${baseAction.kind}`);
325
+ }
326
+ // Add this action to the step's actions
327
+ stepActions.push(stepResult);
328
+ // After executing an action, check if intent is accomplished
329
+ // (but skip if we just checked before this action)
330
+ if (actionCount === 1 || actionCount >= maxActionsPerStep) {
331
+ intentAccomplished = await checkIntentAccomplished(page, brains, step, stepActions);
332
+ }
333
+ }
334
+ // Add all actions for this step to executedSteps
335
+ // Each action represents a sub-action taken to accomplish the step
336
+ executedSteps.push(...stepActions);
337
+ if (actionCount >= maxActionsPerStep && !intentAccomplished) {
338
+ console.warn(`⚠️ Reached maximum actions (${maxActionsPerStep}) for step: ${step}. Intent may not be fully accomplished.`);
339
+ }
340
+ });
341
+ }
342
+ catch (error) {
343
+ // Record failure and rethrow with step information
344
+ if (testFilePath) {
345
+ await recordFailure(testFilePath, testHash, stepIndex, step, error instanceof Error ? error.message : String(error));
49
346
  }
50
- });
347
+ throw new Error(`Step ${stepIndex + 1} failed: ${step}\n${error instanceof Error ? error.message : String(error)}`);
348
+ }
349
+ }
350
+ // Save snapshot on successful completion
351
+ // Only save if we executed at least as many steps as input lines
352
+ if (testFilePath && executedSteps.length > 0) {
353
+ // Count unique steps executed (by stepIndex)
354
+ const uniqueStepIndices = new Set(executedSteps.map(step => step.stepIndex));
355
+ const executedStepCount = uniqueStepIndices.size;
356
+ // Only save if we have at least as many steps as input lines
357
+ if (executedStepCount >= expectedStepCount) {
358
+ // Check if this was a regeneration (snapshot existed but we regenerated)
359
+ const existingSnapshot = await getSnapshot(testFilePath, testHash);
360
+ const wasRegeneration = existingSnapshot !== null;
361
+ await saveSnapshot(testFilePath, {
362
+ testHash,
363
+ testText: input,
364
+ createdAt: existingSnapshot?.createdAt || new Date().toISOString(),
365
+ lastPassedAt: new Date().toISOString(),
366
+ lastFailedAt: null,
367
+ steps: executedSteps.map(step => ({
368
+ ...step,
369
+ executedAt: new Date().toISOString(),
370
+ })),
371
+ });
372
+ // Add annotation if this was a regeneration
373
+ if (wasRegeneration) {
374
+ addAnnotation(testInfo, 'test-update', '✅ Test actions successfully regenerated and saved');
375
+ }
376
+ }
377
+ else {
378
+ // Not all steps were executed - don't save incomplete snapshot
379
+ console.warn(`⚠️ Not saving snapshot: only ${executedStepCount} of ${expectedStepCount} steps executed`);
380
+ }
51
381
  }
52
382
  }
53
383
  function trimTemplate(strings, ...values) {
@@ -63,9 +393,21 @@ function trimTemplate(strings, ...values) {
63
393
  .join('\n');
64
394
  }
65
395
  export const createMimic = (config) => {
396
+ // Extract test file path from TestInfo if available
397
+ const testFilePath = config.testInfo?.file
398
+ ? dirname(config.testInfo.file)
399
+ : undefined;
400
+ // Check troubleshoot mode
401
+ const troubleshootMode = isTroubleshootMode();
66
402
  return async (prompt, ...args) => {
67
403
  const lines = trimTemplate(prompt, ...args);
68
- return await mimic(lines, config);
404
+ return await mimic(lines, {
405
+ page: config.page,
406
+ brains: config.brains,
407
+ testInfo: config.testInfo,
408
+ ...(testFilePath ? { testFilePath } : {}),
409
+ troubleshootMode,
410
+ });
69
411
  };
70
412
  };
71
413
  //# sourceMappingURL=mimic.js.map
package/dist/mimic.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mimic.js","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mimic.js","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAG,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAmB,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA6BvD;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IACzF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;IAC/F,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0GAA0G,CAAC;CAClJ,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,uBAAuB,CACpC,IAAU,EACV,KAAoB,EACpB,QAAgB,EAChB,YAAmC;IAEnC,IAAI,CAAC;QACH,6BAA6B;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,kBAAkB,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,qBAAqB;QAEhF,qCAAqC;QACrC,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;YAChD,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAC/B,GAAG,GAAG,GAAG,CAAC,KAAK,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,QAAQ,EAAE,CACvD,CAAC,IAAI,CAAC,IAAI,CAAC;YACd,CAAC,CAAC,sBAAsB,CAAC;QAE3B,MAAM,MAAM,GAAG;;;EAGjB,QAAQ;;;EAGR,kBAAkB;;;SAGX,UAAU;gBACH,SAAS;0BACC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;uFAiByB,CAAC;QAEpF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,KAAK,EAAE,KAAK;YACZ,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;SACnF,CAAC,CAAC;QAEH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;YACtF,OAAO,CAAC,GAAG,CAAC,uCAAuC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4DAA4D;QAC5D,OAAO,CAAC,IAAI,CAAC,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjH,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAGD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,KAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAMlG;IAEC,IAAI,QAAQ,EAAE,KAAK;QAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEzD,iDAAiD;IACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,gBAAgB,IAAI,kBAAkB,EAAE,CAAC;IAEhE,gEAAgE;IAChE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,uBAAuB;SACtB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,yBAAyB;SACxB,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAErD,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC;IAEvC,8CAA8C;IAC9C,oFAAoF;IACpF,MAAM,WAAW,GAAG,YAAY,IAAI,MAAM,iBAAiB,CAAC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAEvH,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,YAAa,EAAE,QAAQ,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,wDAAwD;YACxD,aAAa,CACX,QAAQ,EACR,eAAe,EACf,6CAA6C,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAC3H,CAAC;YAEF,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACnD,iCAAiC;gBACjC,OAAO;YACT,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qCAAqC;gBACrC,6DAA6D;gBAC7D,aAAa,CACX,QAAQ,EACR,aAAa,EACb,yDAAyD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClH,CAAC;gBAEF,yCAAyC;gBACzC,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,aAAa,CACjB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;gBACJ,CAAC;gBAED,2CAA2C;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,6EAA6E;QAC7E,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACnE,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,YAAY,EAAE,CAAC;YACtD,qEAAqE;YACrE,aAAa,CACX,QAAQ,EACR,aAAa,EACb,sDAAsD,CACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,aAAa,GAA0B,EAAE,CAAC;IAEhD,6BAA6B;IAC7B,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9B,0EAA0E;QAC1E,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC/B,2DAA2D;gBAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9B,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAEnE,MAAM,WAAW,GAAgB;oBAC/B,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;wBAClD,SAAS,EAAE,YAAY,CAAC,SAAS;wBACjC,QAAQ,EAAE,YAAY,CAAC,QAAQ;wBAC/B,UAAU,EAAE,YAAY,CAAC,UAAU;wBACnC,mDAAmD;wBACnD,GAAG,EAAE,YAAY,CAAC,UAAU,KAAK,YAAY;4BAC3C,CAAC,CAAE,YAAY,CAAC,aAAqB,CAAC,MAAM,EAAE,GAAG,IAAI,SAAS;4BAC9D,CAAC,CAAC,SAAS;qBACd,CAAC,CAAC;oBACH,YAAY,EAAE;wBACZ,GAAG,EAAE,UAAU;wBACf,SAAS,EAAE,gBAAgB;qBAC5B;oBACD,UAAU,EAAE,KAAK,CAAC,MAAM;oBACxB,gBAAgB,EAAE,SAAS;iBAC5B,CAAC;gBAEF,wCAAwC;gBACxC,MAAM,WAAW,GAA0B,EAAE,CAAC;gBAC9C,MAAM,iBAAiB,GAAG,EAAE,CAAC,CAAC,yBAAyB;gBACvD,IAAI,WAAW,GAAG,CAAC,CAAC;gBACpB,IAAI,kBAAkB,GAAG,KAAK,CAAC;gBAE/B,2DAA2D;gBAC3D,OAAO,CAAC,kBAAkB,IAAI,WAAW,GAAG,iBAAiB,EAAE,CAAC;oBAC9D,WAAW,EAAE,CAAC;oBAEd,uEAAuE;oBACvE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;wBACpB,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;wBACpF,IAAI,kBAAkB,EAAE,CAAC;4BACvB,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,GAAG,CAAC,YAAY,CAAC,CAAC;4BAC7E,MAAM;wBACR,CAAC;wBACD,OAAO,CAAC,GAAG,CAAC,iDAAiD,WAAW,MAAM,CAAC,CAAC;oBAClF,CAAC;oBAED,+CAA+C;oBAC/C,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;oBAExE,IAAI,UAA+B,CAAC;oBAEpC,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;wBACxB,KAAK,YAAY;4BACf,kEAAkE;4BAClE,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;4BACpF,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAEhG,UAAU,GAAG;gCACX,SAAS;gCACT,QAAQ,EAAE,IAAI;gCACd,UAAU,EAAE,YAAY;gCACxB,aAAa,EAAE,iBAAiB;6BACjC,CAAC;4BACF,MAAM;wBAER,KAAK,OAAO;4BACV,6DAA6D;4BAC7D,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC9E,MAAM,iBAAiB,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;4BAChG,oFAAoF;4BACpF,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrE,IAAI,CAAC,iBAAiB,EAAE,CAAC;gCACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAC;4BAC1E,CAAC;4BACD,MAAM,aAAa,GAAG,cAAc,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;4BAC9D,IAAI,CAAC,aAAa,EAAE,CAAC;gCACnB,MAAM,IAAI,KAAK,CAAC,qCAAqC,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC;4BAClF,CAAC;4BACD,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;4BACpE,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAE9G,6CAA6C;4BAC7C,mEAAmE;4BACnE,MAAM,yBAAyB,GAAuC,WAAW,CAAC,QAAQ;gCACxF,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC;gCACtE,CAAC,CAAE,aAA4B,CAAC;4BAElC,UAAU,GAAG;gCACX,SAAS;gCACT,QAAQ,EAAE,IAAI;gCACd,UAAU,EAAE,OAAO;gCACnB,aAAa,EAAE,WAAW,CAAC,YAAY;gCACvC,aAAa,EAAE,yBAAyB;6BACzC,CAAC;4BACF,MAAM;wBAER,KAAK,aAAa;4BAChB,4DAA4D;4BAC5D,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC5E,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;4BAE5F,4DAA4D;4BAC5D,8EAA8E;4BAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;4BACrC,IAAI,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gCACvC,2CAA2C;gCAC3C,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gCAC1E,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;gCAC/E,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;gCACjE,MAAM,cAAc,GAAG,EAAE,CAAC,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;gCAEtF,mFAAmF;gCACnF,MAAM,cAAc,GAClB,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;oCACtI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;oCAC1I,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;oCAC1I,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gCAErJ,OAAO,CAAC,UAAU,IAAI,SAAS,IAAI,OAAO,IAAI,cAAc,IAAI,cAAc,CAAC;oCACxE,CAAC,EAAE,CAAC,GAAG,KAAK,OAAO,IAAI,EAAE,CAAC,GAAG,KAAK,UAAU,IAAI,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC;4BAC9E,CAAC,CAAC,CAAC;4BAEH,mDAAmD;4BACnD,IAAI,CAAC,WAAW,EAAE,CAAC;gCACjB,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CACnC,EAAE,CAAC,GAAG,KAAK,OAAO,IAAI,EAAE,CAAC,GAAG,KAAK,UAAU,IAAI,EAAE,CAAC,GAAG,KAAK,QAAQ,CACnE,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;4BACvB,CAAC;4BAED,IAAI,WAAW,EAAE,CAAC;gCAChB,MAAM,iBAAiB,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;gCAC1E,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gCAEtG,sGAAsG;gCACtG,IAAI,QAAQ,GAAuB,SAAS,CAAC;gCAC7C,IAAI,aAAa,GAAqB,gBAAgB,CAAC;gCAEvD,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,cAAc,IAAI,UAAU,EAAE,CAAC;oCACjF,aAAa,GAAI,UAAkB,CAAC,YAAY,CAAC;oCACjD,MAAM,cAAc,GAAI,UAAkB,CAAC,QAAQ,CAAC;oCACpD,IAAI,cAAc,EAAE,CAAC;wCACnB,QAAQ,GAAG,cAAc,CAAC;oCAC5B,CAAC;gCACH,CAAC;gCAED,UAAU,GAAG;oCACX,SAAS;oCACT,QAAQ,EAAE,IAAI;oCACd,UAAU,EAAE,aAAa;oCACzB,aAAa;oCACb,aAAa,EAAE,QAAQ;wCACrB,CAAC,CAAC,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE;wCAC9B,CAAC,CAAC,WAAW;iCAChB,CAAC;4BACJ,CAAC;iCAAM,CAAC;gCACN,OAAO,CAAC,IAAI,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;gCAC1D,8CAA8C;gCAC9C,UAAU,GAAG;oCACX,SAAS;oCACT,QAAQ,EAAE,IAAI;oCACd,UAAU,EAAE,aAAa;oCACzB,aAAa,EAAE,gBAAgB;iCAChC,CAAC;4BACJ,CAAC;4BACD,MAAM;wBAER;4BACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;oBACpE,CAAC;oBAED,wCAAwC;oBACxC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAE7B,6DAA6D;oBAC7D,mDAAmD;oBACnD,IAAI,WAAW,KAAK,CAAC,IAAI,WAAW,IAAI,iBAAiB,EAAE,CAAC;wBAC1D,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;oBACtF,CAAC;gBACH,CAAC;gBAED,iDAAiD;gBACjD,mEAAmE;gBACnE,aAAa,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;gBAEnC,IAAI,WAAW,IAAI,iBAAiB,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC5D,OAAO,CAAC,IAAI,CAAC,gCAAgC,iBAAiB,eAAe,IAAI,yCAAyC,CAAC,CAAC;gBAC9H,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,mDAAmD;YACnD,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,aAAa,CACjB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CACb,QAAQ,SAAS,GAAG,CAAC,YAAY,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,iEAAiE;IACjE,IAAI,YAAY,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,6CAA6C;QAC7C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7E,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC;QAEjD,6DAA6D;QAC7D,IAAI,iBAAiB,IAAI,iBAAiB,EAAE,CAAC;YAC3C,yEAAyE;YACzE,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YACnE,MAAM,eAAe,GAAG,gBAAgB,KAAK,IAAI,CAAC;YAElD,MAAM,YAAY,CAAC,YAAY,EAAE;gBAC/B,QAAQ;gBACR,QAAQ,EAAE,KAAK;gBACf,SAAS,EAAE,gBAAgB,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBAClE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACtC,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAChC,GAAG,IAAI;oBACP,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACrC,CAAC,CAAC;aACJ,CAAC,CAAC;YAEH,4CAA4C;YAC5C,IAAI,eAAe,EAAE,CAAC;gBACpB,aAAa,CACX,QAAQ,EACR,aAAa,EACb,mDAAmD,CACpD,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,+DAA+D;YAC/D,OAAO,CAAC,IAAI,CAAC,iCAAiC,iBAAiB,OAAO,iBAAiB,iBAAiB,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;AACH,CAAC;AACD,SAAS,YAAY,CAAC,OAA6B,EAAE,GAAG,MAAa;IACnE,uDAAuD;IACvD,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;QAC1C,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,qEAAqE;IACrE,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAI3B,EAAE,EAAE;IACH,oDAAoD;IACpD,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI;QACxC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC/B,CAAC,CAAC,SAAS,CAAC;IAEd,0BAA0B;IAC1B,MAAM,gBAAgB,GAAG,kBAAkB,EAAE,CAAC;IAE9C,OAAO,KAAK,EAAE,MAA4B,EAAE,GAAG,IAAe,EAAE,EAAE;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,gBAAgB;SACjB,CAAC,CAAC;IACL,CAAC,CAAA;AACH,CAAC,CAAA"}
package/dist/mimicry.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { Page, TestInfo } from '@playwright/test';
5
5
  import type { LanguageModel } from 'ai';
6
- export type Mimicry = (steps: TemplateStringsArray, ...args: unknown[]) => Promise<void>;
6
+ export type Mimic = (steps: TemplateStringsArray, ...args: unknown[]) => Promise<void>;
7
7
  /**
8
8
  * Minimal flow function that takes a Playwright page and input string
9
9
  *
@@ -11,12 +11,12 @@ export type Mimicry = (steps: TemplateStringsArray, ...args: unknown[]) => Promi
11
11
  * @param input - Input string to process
12
12
  * @returns Flow execution result with validated context
13
13
  */
14
- export declare function mimicry(input: string, { page, brains, testInfo }: {
14
+ export declare function mimic(input: string, { page, brains, testInfo }: {
15
15
  page: Page;
16
16
  brains: LanguageModel;
17
- testInfo?: TestInfo;
17
+ testInfo: TestInfo | undefined;
18
18
  }): Promise<void>;
19
- export declare const createMimicry: (config: {
19
+ export declare const createMimic: (config: {
20
20
  page: Page;
21
21
  brains: LanguageModel;
22
22
  testInfo?: TestInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"mimicry.d.ts","sourceRoot":"","sources":["../src/mimicry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAQ,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAQxC,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAGzF;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IACvE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,iBAwCA;AAeD,eAAO,MAAM,aAAa,GAAI,QAAQ;IACpC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,MACe,QAAQ,oBAAoB,EAAE,GAAG,MAAM,OAAO,EAAE,kBAI/D,CAAA"}
1
+ {"version":3,"file":"mimicry.d.ts","sourceRoot":"","sources":["../src/mimicry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAQ,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAQxC,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAGvF;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IACrE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;CAChC,iBA6CA;AAeD,eAAO,MAAM,WAAW,GAAI,QAAQ;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,MACe,QAAQ,oBAAoB,EAAE,GAAG,MAAM,OAAO,EAAE,kBAQ/D,CAAA"}
package/dist/mimicry.js CHANGED
@@ -2,10 +2,10 @@
2
2
  * Minimal flow example function
3
3
  */
4
4
  import { test } from '@playwright/test';
5
- import { getBaseAction } from './mimicry/actionType.js';
6
- import { getNavigationAction, executeNavigationAction } from './mimicry/navigation.js';
7
- import { buildSelectorForTarget, captureTargets } from './mimicry/selector.js';
8
- import { executeClickAction, getClickAction } from './mimicry/click.js';
5
+ import { getBaseAction } from './mimic/actionType.js';
6
+ import { getNavigationAction, executeNavigationAction } from './mimic/navigation.js';
7
+ import { buildSelectorForTarget, captureTargets } from './mimic/selector.js';
8
+ import { executeClickAction, getClickAction } from './mimic/click.js';
9
9
  import { startTestCase } from './utils/token-counter.js';
10
10
  /**
11
11
  * Minimal flow function that takes a Playwright page and input string
@@ -14,7 +14,7 @@ import { startTestCase } from './utils/token-counter.js';
14
14
  * @param input - Input string to process
15
15
  * @returns Flow execution result with validated context
16
16
  */
17
- export async function mimicry(input, { page, brains, testInfo }) {
17
+ export async function mimic(input, { page, brains, testInfo }) {
18
18
  if (testInfo?.title)
19
19
  await startTestCase(testInfo.title);
20
20
  const steps = input.split('\n')
@@ -28,21 +28,26 @@ export async function mimicry(input, { page, brains, testInfo }) {
28
28
  const baseAction = await getBaseAction(page, brains, step);
29
29
  switch (baseAction.kind) {
30
30
  case 'navigation':
31
- console.log(`Navigating to ${step}`);
31
+ // Navigation actions will log their own plain English annotations
32
32
  const navigationAction = await getNavigationAction(page, brains, step);
33
- await executeNavigationAction(page, navigationAction);
33
+ await executeNavigationAction(page, navigationAction, testInfo || undefined, step);
34
34
  break;
35
35
  case 'click':
36
- console.log(`Clicking on ${step}`);
36
+ // Click actions will log their own plain English annotations
37
37
  const targetElements = await captureTargets(page, { interactableOnly: true });
38
38
  const clickActionResult = await getClickAction(page, brains, step, targetElements);
39
39
  // TODO: better way to work out if the top priority candidate is a clickable element
40
- const clickable = await buildSelectorForTarget(page, clickActionResult.candidates.find(Boolean));
41
- await executeClickAction(clickable, clickActionResult);
40
+ const selectedCandidate = clickActionResult.candidates.find(Boolean);
41
+ if (!selectedCandidate) {
42
+ throw new Error(`No candidate element found for click action: ${step}`);
43
+ }
44
+ const clickable = await buildSelectorForTarget(page, targetElements[selectedCandidate.index]);
45
+ await executeClickAction(clickable, clickActionResult, selectedCandidate, testInfo || undefined, step);
42
46
  break;
43
47
  case 'form update':
48
+ // Form actions will log their own plain English annotations
44
49
  const formElements = await captureTargets(page, { interactableOnly: true });
45
- console.log(`Form element count: ${formElements.length}`);
50
+ console.log(`→ Processing form update: Found ${formElements.length} interactable form elements on the page`);
46
51
  break;
47
52
  default:
48
53
  throw new Error(`Unknown base action type: ${baseAction.kind}`);
@@ -62,10 +67,14 @@ function trimTemplate(strings, ...values) {
62
67
  .filter(line => line.length > 0)
63
68
  .join('\n');
64
69
  }
65
- export const createMimicry = (config) => {
70
+ export const createMimic = (config) => {
66
71
  return async (prompt, ...args) => {
67
72
  const lines = trimTemplate(prompt, ...args);
68
- return await mimicry(lines, config);
73
+ return await mimic(lines, {
74
+ page: config.page,
75
+ brains: config.brains,
76
+ testInfo: config.testInfo,
77
+ });
69
78
  };
70
79
  };
71
80
  //# sourceMappingURL=mimicry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mimicry.js","sourceRoot":"","sources":["../src/mimicry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mimicry.js","sourceRoot":"","sources":["../src/mimicry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright-mimic",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Playwright Mimic allows AI to connect LLM to help in maintaining test code based off of logical steps in the test file in English",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -19,7 +19,8 @@
19
19
  "build": "tsc",
20
20
  "test": "playwright test",
21
21
  "test:ui": "playwright test --ui",
22
- "test:debug": "playwright test --debug"
22
+ "test:debug": "playwright test --debug",
23
+ "serve": "http-server test-site -p 3000 -c-1"
23
24
  },
24
25
  "keywords": [],
25
26
  "author": "",
@@ -31,6 +32,8 @@
31
32
  "dependencies": {
32
33
  "ai": "^6.0.3",
33
34
  "dotenv": "^17.2.3",
35
+ "http-server": "^14.1.1",
36
+ "sharp": "^0.33.5",
34
37
  "typescript": "^5.9.3",
35
38
  "zod": "^4.2.1"
36
39
  },