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.
Files changed (66) hide show
  1. package/README.md +134 -72
  2. package/dist/index.d.ts +1 -4
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/mimic/annotations.d.ts +2 -1
  7. package/dist/mimic/annotations.d.ts.map +1 -1
  8. package/dist/mimic/annotations.js +10 -4
  9. package/dist/mimic/annotations.js.map +1 -1
  10. package/dist/mimic/cli.js +1 -1
  11. package/dist/mimic/cli.js.map +1 -1
  12. package/dist/mimic/click.d.ts +4 -4
  13. package/dist/mimic/click.d.ts.map +1 -1
  14. package/dist/mimic/click.js +233 -118
  15. package/dist/mimic/click.js.map +1 -1
  16. package/dist/mimic/forms.d.ts +11 -6
  17. package/dist/mimic/forms.d.ts.map +1 -1
  18. package/dist/mimic/forms.js +371 -124
  19. package/dist/mimic/forms.js.map +1 -1
  20. package/dist/mimic/markers.d.ts +133 -0
  21. package/dist/mimic/markers.d.ts.map +1 -0
  22. package/dist/mimic/markers.js +589 -0
  23. package/dist/mimic/markers.js.map +1 -0
  24. package/dist/mimic/navigation.d.ts.map +1 -1
  25. package/dist/mimic/navigation.js +29 -10
  26. package/dist/mimic/navigation.js.map +1 -1
  27. package/dist/mimic/playwrightCodeGenerator.d.ts +55 -0
  28. package/dist/mimic/playwrightCodeGenerator.d.ts.map +1 -0
  29. package/dist/mimic/playwrightCodeGenerator.js +270 -0
  30. package/dist/mimic/playwrightCodeGenerator.js.map +1 -0
  31. package/dist/mimic/replay.d.ts.map +1 -1
  32. package/dist/mimic/replay.js +45 -36
  33. package/dist/mimic/replay.js.map +1 -1
  34. package/dist/mimic/schema/action.d.ts +26 -26
  35. package/dist/mimic/schema/action.d.ts.map +1 -1
  36. package/dist/mimic/schema/action.js +13 -31
  37. package/dist/mimic/schema/action.js.map +1 -1
  38. package/dist/mimic/selector.d.ts +6 -2
  39. package/dist/mimic/selector.d.ts.map +1 -1
  40. package/dist/mimic/selector.js +681 -269
  41. package/dist/mimic/selector.js.map +1 -1
  42. package/dist/mimic/selectorDescriptor.d.ts +15 -3
  43. package/dist/mimic/selectorDescriptor.d.ts.map +1 -1
  44. package/dist/mimic/selectorDescriptor.js +25 -2
  45. package/dist/mimic/selectorDescriptor.js.map +1 -1
  46. package/dist/mimic/selectorSerialization.d.ts +5 -17
  47. package/dist/mimic/selectorSerialization.d.ts.map +1 -1
  48. package/dist/mimic/selectorSerialization.js +4 -142
  49. package/dist/mimic/selectorSerialization.js.map +1 -1
  50. package/dist/mimic/selectorTypes.d.ts +24 -102
  51. package/dist/mimic/selectorTypes.d.ts.map +1 -1
  52. package/dist/mimic/selectorUtils.d.ts +33 -7
  53. package/dist/mimic/selectorUtils.d.ts.map +1 -1
  54. package/dist/mimic/selectorUtils.js +159 -52
  55. package/dist/mimic/selectorUtils.js.map +1 -1
  56. package/dist/mimic/storage.d.ts +43 -8
  57. package/dist/mimic/storage.d.ts.map +1 -1
  58. package/dist/mimic/storage.js +258 -46
  59. package/dist/mimic/storage.js.map +1 -1
  60. package/dist/mimic/types.d.ts +38 -16
  61. package/dist/mimic/types.d.ts.map +1 -1
  62. package/dist/mimic.d.ts +1 -0
  63. package/dist/mimic.d.ts.map +1 -1
  64. package/dist/mimic.js +240 -84
  65. package/dist/mimic.js.map +1 -1
  66. package/package.json +27 -6
@@ -2,6 +2,9 @@ import { generateText, Output } from 'ai';
2
2
  import { zClickActionResult } from './schema/action.js';
3
3
  import { countTokens } from '../utils/token-counter.js';
4
4
  import { addAnnotation } from './annotations.js';
5
+ import { generateBestSelectorForElement } from './selector.js';
6
+ import { selectorToPlaywrightCode, generateClickCode } from './playwrightCodeGenerator.js';
7
+ import { captureScreenshot, generateAriaSnapshot } from './markers.js';
5
8
  /**
6
9
  * Get click action by matching Gherkin step against captured target elements
7
10
  *
@@ -12,140 +15,230 @@ import { addAnnotation } from './annotations.js';
12
15
  * @param page - Playwright Page object (currently unused but kept for consistency)
13
16
  * @param brain - LanguageModel instance for AI analysis
14
17
  * @param gherkinStep - The Gherkin step to match (e.g., "I click on the Submit button")
15
- * @param targetElements - Array of captured target elements from the page
18
+ * @param targetElements - Array of captured elements with marker IDs from the page
16
19
  * @param testContext - Optional test context with previous steps and current state
17
20
  * @returns Promise resolving to ClickActionResult with top candidates and click type
18
21
  */
19
- export const getClickAction = async (_page, brain, gherkinStep, targetElements, testContext) => {
20
- // Format target elements with their indices for the prompt
21
- // Include all relevant identifying information
22
- const elementsWithIndices = targetElements.map((element, index) => ({
23
- index,
24
- tag: element.tag,
25
- text: element.text,
26
- id: element.id,
27
- role: element.role,
28
- label: element.label,
29
- ariaLabel: element.ariaLabel,
30
- typeAttr: element.typeAttr,
31
- nameAttr: element.nameAttr,
32
- href: element.href,
33
- dataset: element.dataset,
34
- nthOfType: element.nthOfType,
35
- }));
36
- // Group elements by tag type
37
- const elementsByTag = new Map();
38
- for (const el of elementsWithIndices) {
39
- const tagKey = el.tag === 'a' ? 'links' : el.tag === 'button' ? 'buttons' : el.tag === 'input' ? 'inputs' : el.tag;
40
- if (!elementsByTag.has(tagKey)) {
41
- elementsByTag.set(tagKey, []);
42
- }
43
- elementsByTag.get(tagKey).push(el);
44
- }
45
- // Format element fields in selector priority order, skipping null/empty values
46
- const formatElement = (roleSection) => (el) => {
47
- const parts = [];
48
- // Priority order: testId text → role → ariaLabel → label → name → type → href → dataAttributes → tag → id → nthOfType
49
- if (el.dataset.testid) {
50
- parts.push(` testId: "${el.dataset.testid}"`);
51
- }
52
- if (el.text && el.text.trim()) {
53
- parts.push(` text: "${el.text.trim()}"`);
54
- }
55
- if (el.role && roleSection !== el.role) {
56
- parts.push(` role: ${el.role}`);
57
- }
58
- if (el.ariaLabel) {
59
- parts.push(` ariaLabel: "${el.ariaLabel}"`);
60
- }
61
- if (el.label) {
62
- parts.push(` label: "${el.label}"`);
63
- }
64
- if (el.nameAttr) {
65
- parts.push(` name: "${el.nameAttr}"`);
66
- }
67
- if (el.typeAttr) {
68
- parts.push(` type: ${el.typeAttr}`);
69
- }
70
- if (el.href) {
71
- parts.push(` href: "${el.href}"`);
72
- }
73
- if (Object.keys(el.dataset).length > 0) {
74
- const dataKeys = Object.keys(el.dataset).filter(k => k !== 'testid');
75
- if (dataKeys.length > 0) {
76
- parts.push(` dataAttributes: ${JSON.stringify(dataKeys)}`);
77
- }
78
- }
79
- parts.push(` tag: ${el.tag}`);
80
- // if (el.id) {
81
- // parts.push(` id: "${el.id}"`);
82
- // }
83
- parts.push(` index: ${el.index}`);
84
- if (el.nthOfType > 1) {
85
- parts.push(` nthOfType: ${el.nthOfType}`);
86
- }
87
- return ` - ${parts.join('\n ')}`;
88
- };
89
- // Create formatted description grouped by tag
90
- const elementsDescription = Array.from(elementsByTag.entries())
91
- .map(([tagKey, elements]) => {
92
- const formattedElements = elements.map(formatElement(tagKey)).join('\n');
93
- return `${tagKey}:\n${formattedElements}`;
94
- })
95
- .join('\n\n');
22
+ export const getClickAction = async (page, brain, gherkinStep, testContext) => {
23
+ const startTime = Date.now();
24
+ // Capture screenshot with markers and positioning data
25
+ console.log('📸 [getClickAction] Starting screenshot capture with markers...');
26
+ const screenshotStart = Date.now();
27
+ const { image: screenshot, markers: markerData } = await captureScreenshot(page);
28
+ const screenshotTime = Date.now() - screenshotStart;
29
+ console.log(`📸 [getClickAction] Screenshot captured in ${screenshotTime}ms (${(screenshotTime / 1000).toFixed(2)}s)`);
30
+ const base64Start = Date.now();
31
+ const screenshotBase64 = screenshot.toString('base64');
32
+ const base64Time = Date.now() - base64Start;
33
+ console.log(`📸 [getClickAction] Screenshot converted to base64 in ${base64Time}ms (${(base64Time / 1000).toFixed(2)}s), size: ${(screenshotBase64.length / 1024).toFixed(2)}KB`);
34
+ // Generate accessibility snapshot to explain the screenshot structure
35
+ console.log('🔍 [getClickAction] Generating accessibility snapshot...');
36
+ const ariaSnapshotStart = Date.now();
37
+ const ariaSnapshot = await generateAriaSnapshot(page);
38
+ const ariaSnapshotTime = Date.now() - ariaSnapshotStart;
39
+ console.log(`🔍 [getClickAction] Accessibility snapshot generated in ${ariaSnapshotTime}ms (${(ariaSnapshotTime / 1000).toFixed(2)}s), length: ${ariaSnapshot.length} chars`);
40
+ // Convert marker data to format expected by prompt
41
+ const markerStart = Date.now();
42
+ const markerInfo = markerData?.map(m => {
43
+ return {
44
+ id: m.mimicId,
45
+ tag: m.tag,
46
+ text: m.text,
47
+ role: m.role,
48
+ ariaLabel: m.ariaLabel,
49
+ };
50
+ });
51
+ const markerTime = Date.now() - markerStart;
52
+ console.log(`🔍 [getClickAction] Processed ${markerInfo.length} markers in ${markerTime}ms (${(markerTime / 1000).toFixed(2)}s)`);
53
+ // Build marker summary for the prompt
54
+ const summaryStart = Date.now();
55
+ const markerSummary = markerInfo
56
+ .slice(0, 50) // Limit to first 50 markers to avoid prompt size issues
57
+ .map(m => ` Marker ${m.id}: ${m.tag}${m.role ? ` (role: ${m.role})` : ''}${m.text ? ` - "${m.text.substring(0, 50)}"` : ''}${m.ariaLabel ? ` [aria-label: "${m.ariaLabel}"]` : ''}`)
58
+ .join('\n');
59
+ const summaryTime = Date.now() - summaryStart;
60
+ console.log(`📝 [getClickAction] Built marker summary in ${summaryTime}ms`);
96
61
  // Build context description for the prompt
62
+ const promptStart = Date.now();
63
+ // Build context description with defensive checks for optional testContext
64
+ // Ensure previousSteps exists and is an array before calling .map()
97
65
  const contextDescription = testContext ? `
98
66
  **Test Context:**
99
67
  - Current URL: ${testContext.currentState.url}
100
68
  - Current Page Title: ${testContext.currentState.pageTitle}
101
69
  - Step ${testContext.currentStepIndex + 1} of ${testContext.totalSteps}
102
- ${testContext.previousSteps.length > 0 ? `
70
+ ${testContext.previousSteps && Array.isArray(testContext.previousSteps) && testContext.previousSteps.length > 0 ? `
103
71
  **Previous Steps Executed:**
104
72
  ${testContext.previousSteps.map((prevStep, idx) => `${idx + 1}. Step ${prevStep.stepIndex + 1}: "${prevStep.stepText}" (${prevStep.actionKind}${prevStep.url ? ` → ${prevStep.url}` : ''})`).join('\n')}
105
73
  ` : ''}
106
74
  ` : '';
107
- const prompt = `You are an expert Playwright test engineer specializing in mapping Gherkin steps to concrete DOM interactions.
75
+ const prompt = `You are an expert Playwright test engineer specializing in mapping Gherkin steps to concrete DOM interactions using visual analysis.
108
76
 
109
77
  Your task is to analyze:
110
- 1. A single Gherkin step that implies a click action.
111
- 2. A list of candidate DOM elements extracted from the page.
78
+ 1. A screenshot of the page with numbered marker badges on elements
79
+ 2. An accessibility snapshot (provided below) that describes the page structure with roles, names, data-testid, and data-mimic-* attributes
80
+ 3. A single Gherkin step that implies a click action
81
+
82
+ **CRITICAL: Click Type Determination**
83
+ You must determine the correct click type from the Gherkin step. Use these rules:
84
+
85
+ **Click Type Equivalencies (these are the SAME):**
86
+ - "click", "left click", and "primary click" → use "primary"
87
+ - "right click" and "secondary click" → use "secondary"
88
+ - "middle click" and "tertiary click" → use "tertiary"
89
+ - "double click" or "double-click" → use "double"
90
+
91
+ **Default Behavior:**
92
+ - If the step just says "click" (without specifying left/right/middle/double), ALWAYS use "primary"
93
+ - "click" by itself means a standard left/primary click, NOT a hover
94
+
95
+ **Hover Rules (STRICT):**
96
+ - ONLY use "hover" when the Gherkin step EXPLICITLY mentions "hover", "hover over", or "move mouse over"
97
+ - NEVER use "hover" for a step that says "click" - these are DIFFERENT actions
98
+ - Hover is ONLY for revealing tooltips, dropdowns, or additional UI elements that appear on mouseover
99
+ - If the step says "click", it means click, NOT hover
112
100
 
113
- You must return the **top 5 most likely elements** that the Gherkin step is referring to.
101
+ **Modifier Keys:**
102
+ - Detect if modifier keys are mentioned: shift, control (ctrl), alt, meta (command)
103
+ - These are optional and should be included in the modifiers field if present
104
+
105
+ **IMPORTANT**: Look at the screenshot to identify elements by their marker numbers. Each element has a numbered badge:
106
+ - **RED badges** = Interactive elements (buttons, links, inputs, etc.)
107
+ - **BLUE badges** = Display-only content elements
108
+ - **GREEN badges** = Structure/test anchor elements
109
+
110
+ You must return the **top 5 most likely elements** that the Gherkin step is referring to, identified by their **marker ID numbers** (the numbers shown on the badges in the screenshot).
114
111
 
115
112
  ---
116
113
 
117
114
  ### IMPORTANT RULES
118
115
 
119
- - Rank elements from **most likely (rank 1)** to **least likely (rank 5)**.
116
+ - **ALWAYS use the marker ID (mimicId)** from the screenshot - this is the number shown on the element's badge
117
+ - Rank elements from **most likely (rank 1)** to **least likely (rank 5)**
120
118
  - Prefer **semantic matches** first:
121
- - Visible text
119
+ - Visible text (what you can read in the screenshot)
120
+ - Element position and visual appearance
122
121
  - Accessible name (label, aria-label, role)
123
122
  - Button / link intent
124
- - Use "index" **only as a secondary disambiguation signal**, never as the primary reason.
125
- - Do NOT invent elements or field values.
126
- - Do NOT include more than 5 results.
127
- - If fewer than 5 reasonable matches exist, return fewer.
128
- - Do NOT assume navigation or side effects — this task is only about **what element is clicked**.
129
- - For each candidate, provide a **clear, human-readable description** that identifies the element (e.g., "Submit button", "Login link with text 'Sign in'", "Email input field labeled 'Email address'"). This description will be used in test annotations.
130
- - Consider the test context - what steps came before may help identify the correct element.
123
+ - Do NOT invent elements or marker IDs - only use marker IDs that are visible in the screenshot
124
+ - Do NOT include more than 5 results
125
+ - If fewer than 5 reasonable matches exist, return fewer
126
+ - Do NOT assume navigation or side effects this task is only about **what element is clicked**
127
+ - For each candidate, provide:
128
+ - The **mimicId** (marker number from the screenshot badge)
129
+ - A **clear, human-readable description** that identifies the element (e.g., "Submit button", "Login link with text 'Sign in'")
130
+ - Element metadata (tag, text, role, etc.) based on what you can see in the screenshot and the marker information provided
131
+ - Consider the test context - what steps came before may help identify the correct element
131
132
 
132
133
  ${contextDescription}
133
134
  **Gherkin Step:**
134
135
  ${gherkinStep}
135
136
 
136
- **Available Target Elements (${targetElements.length} total):**
137
- ${elementsDescription}
137
+ **Available Markers (${markerInfo.length} total):**
138
+ ${markerSummary}
139
+ ${markerInfo.length > 50 ? `\n... and ${markerInfo.length - 50} more markers` : ''}
140
+
141
+ **Accessibility Snapshot (explains the screenshot structure):**
142
+ The following accessibility snapshot describes the page structure with roles, accessible names, data-testid attributes, and data-mimic-* attributes. Use this to understand the page structure alongside the screenshot:
143
+ \`\`\`
144
+ ${ariaSnapshot}
145
+ \`\`\`
138
146
 
147
+ ## Analyze the screenshot and accessibility snapshot, then return up to the top 5 most likely elements that the Gherkin step is referring to.
148
+ Use the marker ID numbers (mimicId) shown on the badges in the screenshot and referenced in the accessibility snapshot to identify elements.
139
149
 
140
- ## Reason and return up to the top 5 most likely elements that the Gherkin step is referring to.
150
+ **Remember:**
151
+ - "click" = primary click (left click) - the default for any click action
152
+ - "hover" is ONLY for explicit hover instructions, NEVER for click steps
153
+ - When in doubt about click type, default to "primary"
141
154
  `;
142
- const res = await generateText({
143
- model: brain,
144
- prompt,
145
- maxRetries: 3,
146
- output: Output.object({ schema: zClickActionResult, name: 'clickActionResult' }),
147
- });
155
+ const promptTime = Date.now() - promptStart;
156
+ console.log(`📝 [getClickAction] Built prompt in ${promptTime}ms, prompt length: ${prompt.length} chars`);
157
+ // Build message content - try without image first, then retry with image if needed
158
+ const messageStart = Date.now();
159
+ // First attempt: text-only (no image) - faster and cheaper
160
+ const messageContentTextOnly = [
161
+ { type: 'text', text: prompt }
162
+ ];
163
+ // Second attempt: with image (if first attempt fails)
164
+ const messageContentWithImage = [
165
+ { type: 'text', text: prompt },
166
+ { type: 'image', image: screenshotBase64 }
167
+ ];
168
+ const messageTime = Date.now() - messageStart;
169
+ console.log(`📨 [getClickAction] Built message content in ${messageTime}ms`);
170
+ // Set explicit timeout for AI calls to prevent indefinite hangs
171
+ // 2 minutes should be sufficient for most AI responses, even with retries
172
+ const aiTimeout = 120_000; // 2 minutes
173
+ let res;
174
+ let aiTime;
175
+ let usedImage = false;
176
+ // First attempt: try without image (text-only with accessibility snapshot)
177
+ console.log('🤖 [getClickAction] Calling AI model (text-only, no image)...');
178
+ const aiStart = Date.now();
179
+ try {
180
+ res = await Promise.race([
181
+ generateText({
182
+ model: brain,
183
+ messages: [
184
+ {
185
+ role: 'user',
186
+ content: messageContentTextOnly
187
+ }
188
+ ],
189
+ maxRetries: 2, // Fewer retries for first attempt
190
+ output: Output.object({ schema: zClickActionResult, name: 'clickActionResult' }),
191
+ }),
192
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`AI model call timed out after ${aiTimeout}ms`)), aiTimeout))
193
+ ]);
194
+ // Validate the response
195
+ if (!res.output || !res.output.candidates || !Array.isArray(res.output.candidates) || res.output.candidates.length === 0) {
196
+ throw new Error('First attempt returned invalid result, retrying with image...');
197
+ }
198
+ aiTime = Date.now() - aiStart;
199
+ console.log(`✅ [getClickAction] AI model responded successfully (text-only) in ${aiTime}ms (${(aiTime / 1000).toFixed(2)}s)`);
200
+ }
201
+ catch (error) {
202
+ // First attempt failed - retry with image
203
+ console.log(`⚠️ [getClickAction] First attempt failed, retrying with image: ${error instanceof Error ? error.message : String(error)}`);
204
+ const retryStart = Date.now();
205
+ usedImage = true;
206
+ try {
207
+ res = await Promise.race([
208
+ generateText({
209
+ model: brain,
210
+ messages: [
211
+ {
212
+ role: 'user',
213
+ content: messageContentWithImage
214
+ }
215
+ ],
216
+ maxRetries: 3,
217
+ output: Output.object({ schema: zClickActionResult, name: 'clickActionResult' }),
218
+ }),
219
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`AI model call timed out after ${aiTimeout}ms`)), aiTimeout))
220
+ ]);
221
+ aiTime = Date.now() - retryStart;
222
+ console.log(`✅ [getClickAction] AI model responded successfully (with image) in ${aiTime}ms (${(aiTime / 1000).toFixed(2)}s)`);
223
+ }
224
+ catch (retryError) {
225
+ const elapsed = Date.now() - aiStart;
226
+ throw new Error(`AI model call failed after ${elapsed}ms (tried both text-only and with image): ${retryError instanceof Error ? retryError.message : String(retryError)}`);
227
+ }
228
+ }
148
229
  await countTokens(res);
230
+ const totalTime = Date.now() - startTime;
231
+ console.log(`⏱️ [getClickAction] Total time: ${totalTime}ms (${(totalTime / 1000).toFixed(2)}s)${usedImage ? ' (used image on retry)' : ' (text-only, no image needed)'}`);
232
+ console.log(` Breakdown: screenshot=${screenshotTime}ms, base64=${base64Time}ms, markers=${markerTime}ms, summary=${summaryTime}ms, prompt=${promptTime}ms, message=${messageTime}ms, AI=${aiTime}ms`);
233
+ // Validate that the AI model returned a valid structured output
234
+ // The output should always be defined when using structured outputs, but add defensive check
235
+ if (!res.output) {
236
+ throw new Error('AI model failed to generate valid click action result. The output is undefined.');
237
+ }
238
+ // Validate that candidates array exists and is not empty
239
+ if (!res.output.candidates || !Array.isArray(res.output.candidates) || res.output.candidates.length === 0) {
240
+ throw new Error(`AI model returned invalid click action result: candidates array is missing, not an array, or empty. Received: ${JSON.stringify(res.output)}`);
241
+ }
149
242
  return res.output;
150
243
  };
151
244
  /**
@@ -173,16 +266,16 @@ export const executeClickAction = async (element, clickActionResult, selectedCan
173
266
  // Build annotation description based on click type
174
267
  let annotationDescription = '';
175
268
  switch (clickActionResult.clickType) {
176
- case 'left':
269
+ case 'primary':
177
270
  annotationDescription = `→ Clicking on ${elementDescription} with left mouse button`;
178
271
  break;
179
- case 'right':
272
+ case 'secondary':
180
273
  annotationDescription = `→ Right-clicking on ${elementDescription} to open context menu`;
181
274
  break;
182
275
  case 'double':
183
276
  annotationDescription = `→ Double-clicking on ${elementDescription} to activate`;
184
277
  break;
185
- case 'middle':
278
+ case 'tertiary':
186
279
  annotationDescription = `→ Clicking on ${elementDescription} with middle mouse button`;
187
280
  break;
188
281
  case 'hover':
@@ -191,34 +284,56 @@ export const executeClickAction = async (element, clickActionResult, selectedCan
191
284
  default:
192
285
  throw new Error(`Unknown click type: ${clickActionResult.clickType}`);
193
286
  }
194
- // Add annotation using centralized utility
195
- addAnnotation(testInfo, gherkinStep, annotationDescription);
196
- // Get selector string for snapshot storage
197
- // Try to get a CSS selector representation if possible
287
+ // Generate Playwright code equivalent BEFORE performing the action
288
+ // This ensures the element is still available (before navigation/closure)
289
+ let playwrightCode;
198
290
  let selector = null;
199
291
  try {
200
- // Attempt to get a selector string from the locator
201
- // This is best-effort and may not always work
202
- const locatorString = element.toString();
203
- if (locatorString && locatorString !== '[object Object]') {
204
- selector = locatorString;
205
- }
292
+ // Generate the best selector descriptor from the element
293
+ // This gives us a descriptive, stable selector for snapshot storage
294
+ // Use 30-second timeout for selector generation
295
+ const selectorDescriptor = await generateBestSelectorForElement(element, { timeout: 30000 });
296
+ const selectorCode = selectorToPlaywrightCode(selectorDescriptor);
297
+ playwrightCode = generateClickCode(selectorCode, clickActionResult.clickType);
298
+ // Store the selector descriptor for snapshot storage
299
+ selector = selectorDescriptor;
206
300
  }
207
301
  catch (error) {
208
- // If we can't get selector, that's okay - we'll rebuild from TargetInfo
302
+ // If generating from element fails, fall back to mimicId if available
303
+ // This can happen if the element is not available or page is closing
304
+ const errorMessage = error?.message || String(error);
305
+ // Check if page closed - this can happen with navigation after clicks
306
+ if (errorMessage.includes('closed') || errorMessage.includes('Target page')) {
307
+ console.warn('Page closed during selector generation, using mimicId fallback');
308
+ }
309
+ if (selectedCandidate.mimicId) {
310
+ const selectorCode = `page.locator('[data-mimic-id="${selectedCandidate.mimicId}"]')`;
311
+ playwrightCode = generateClickCode(selectorCode, clickActionResult.clickType);
312
+ // Create a CSS selector descriptor as fallback
313
+ selector = {
314
+ type: 'css',
315
+ selector: `[data-mimic-id="${selectedCandidate.mimicId}"]`
316
+ };
317
+ }
318
+ else {
319
+ // If we can't generate the code, that's okay - just skip it
320
+ console.warn('Could not generate Playwright code for click action:', errorMessage);
321
+ }
209
322
  }
323
+ // Add annotation using centralized utility (includes Playwright code if available)
324
+ addAnnotation(testInfo, gherkinStep, annotationDescription, playwrightCode);
210
325
  // Perform the click action
211
326
  switch (clickActionResult.clickType) {
212
- case 'left':
327
+ case 'primary':
213
328
  await element.click();
214
329
  break;
215
- case 'right':
330
+ case 'secondary':
216
331
  await element.click({ button: 'right' });
217
332
  break;
218
333
  case 'double':
219
334
  await element.dblclick();
220
335
  break;
221
- case 'middle':
336
+ case 'tertiary':
222
337
  await element.click({ button: 'middle' });
223
338
  break;
224
339
  case 'hover':
@@ -1 +1 @@
1
- {"version":3,"file":"click.js","sourceRoot":"","sources":["../../src/mimic/click.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"click.js","sourceRoot":"","sources":["../../src/mimic/click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAG7D,OAAO,EACL,kBAAkB,EAEnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGvE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,IAAU,EACV,KAAoB,EACpB,WAAmB,EACnB,WAAyB,EACG,EAAE;IAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,uDAAuD;IACvD,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,8CAA8C,cAAc,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEvH,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,yDAAyD,UAAU,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAElL,sEAAsE;IACtE,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IACxE,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACrC,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,2DAA2D,gBAAgB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,YAAY,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE9K,mDAAmD;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,UAAU,GAMX,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;QAEvB,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,OAAO;YACb,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,iCAAiC,UAAU,CAAC,MAAM,eAAe,UAAU,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAElI,sCAAsC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,aAAa,GAAG,UAAU;SAC7B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,wDAAwD;SACrE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACpL,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,+CAA+C,WAAW,IAAI,CAAC,CAAC;IAE5E,2CAA2C;IAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,CAAC;;iBAE1B,WAAW,CAAC,YAAY,CAAC,GAAG;wBACrB,WAAW,CAAC,YAAY,CAAC,SAAS;SACjD,WAAW,CAAC,gBAAgB,GAAG,CAAC,OAAO,WAAW,CAAC,UAAU;EACpE,WAAW,CAAC,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;;EAEhH,WAAW,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAChD,GAAG,GAAG,GAAG,CAAC,UAAU,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,QAAQ,MAAM,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CACzI,CAAC,IAAI,CAAC,IAAI,CAAC;CACX,CAAC,CAAC,CAAC,EAAE;CACL,CAAC,CAAC,CAAC,EAAE,CAAC;IAEL,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0Df,kBAAkB;;EAElB,WAAW;;uBAEU,UAAU,CAAC,MAAM;EACtC,aAAa;EACb,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,UAAU,CAAC,MAAM,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE;;;;;EAKhF,YAAY;;;;;;;;;;CAUb,CAAC;IACA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,uCAAuC,UAAU,sBAAsB,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE1G,mFAAmF;IACnF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,2DAA2D;IAC3D,MAAM,sBAAsB,GAA0C;QACpE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;KAC/B,CAAC;IAEF,sDAAsD;IACtD,MAAM,uBAAuB,GAA6E;QACxG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;QAC9B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE;KAC3C,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,gDAAgD,WAAW,IAAI,CAAC,CAAC;IAE7E,gEAAgE;IAChE,0EAA0E;IAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,YAAY;IACvC,IAAI,GAAG,CAAC;IACR,IAAI,MAAc,CAAC;IACnB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,2EAA2E;IAC3E,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACvB,YAAY,CAAC;gBACX,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,sBAAsB;qBAChC;iBACF;gBACD,UAAU,EAAE,CAAC,EAAE,kCAAkC;gBACjD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;aACjF,CAAC;YACF,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,SAAS,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAC/F;SACF,CAAC,CAAC;QAEH,wBAAwB;QACxB,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzH,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,qEAAqE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChI,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0CAA0C;QAC1C,OAAO,CAAC,GAAG,CAAC,mEAAmE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzI,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,SAAS,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBACvB,YAAY,CAAC;oBACX,KAAK,EAAE,KAAK;oBACZ,QAAQ,EAAE;wBACR;4BACE,IAAI,EAAE,MAAM;4BACZ,OAAO,EAAE,uBAAuB;yBACjC;qBACF;oBACD,UAAU,EAAE,CAAC;oBACb,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;iBACjF,CAAC;gBACF,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,SAAS,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAC/F;aACF,CAAC,CAAC;YAEH,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,sEAAsE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjI,CAAC;QAAC,OAAO,UAAU,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,6CAA6C,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC7K,CAAC;IACH,CAAC;IAED,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAEvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,oCAAoC,SAAS,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,+BAA+B,EAAE,CAAC,CAAC;IAC5K,OAAO,CAAC,GAAG,CAAC,4BAA4B,cAAc,cAAc,UAAU,eAAe,UAAU,eAAe,WAAW,cAAc,UAAU,eAAe,WAAW,UAAU,MAAM,IAAI,CAAC,CAAC;IAEzM,gEAAgE;IAChE,6FAA6F;IAC7F,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1G,MAAM,IAAI,KAAK,CAAC,iHAAiH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjK,CAAC;IAED,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,OAAuB,EACvB,iBAAoC,EACpC,iBAAqD,EACrD,QAA8B,EAC9B,WAAmB,EACgE,EAAE;IACrF,uDAAuD;IACvD,mEAAmE;IACnE,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,WAAW,IAAI,SAAS,CAAC;IAEtE,oDAAoD;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,mDAAmD;IACnD,IAAI,qBAAqB,GAAG,EAAE,CAAC;IAC/B,QAAQ,iBAAiB,CAAC,SAAS,EAAE,CAAC;QACpC,KAAK,SAAS;YACZ,qBAAqB,GAAG,iBAAiB,kBAAkB,yBAAyB,CAAC;YACrF,MAAM;QACR,KAAK,WAAW;YACd,qBAAqB,GAAG,uBAAuB,kBAAkB,uBAAuB,CAAC;YACzF,MAAM;QACR,KAAK,QAAQ;YACX,qBAAqB,GAAG,wBAAwB,kBAAkB,cAAc,CAAC;YACjF,MAAM;QACR,KAAK,UAAU;YACb,qBAAqB,GAAG,iBAAiB,kBAAkB,2BAA2B,CAAC;YACvF,MAAM;QACR,KAAK,OAAO;YACV,qBAAqB,GAAG,mBAAmB,kBAAkB,+BAA+B,CAAC;YAC7F,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,iBAAiB,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,mEAAmE;IACnE,0EAA0E;IAC1E,IAAI,cAAkC,CAAC;IACvC,IAAI,QAAQ,GAA8B,IAAI,CAAC;IAE/C,IAAI,CAAC;QACH,yDAAyD;QACzD,oEAAoE;QACpE,gDAAgD;QAChD,MAAM,kBAAkB,GAAG,MAAM,8BAA8B,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7F,MAAM,YAAY,GAAG,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;QAClE,cAAc,GAAG,iBAAiB,CAAC,YAAY,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE9E,qDAAqD;QACrD,QAAQ,GAAG,kBAAkB,CAAC;IAChC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,sEAAsE;QACtE,qEAAqE;QACrE,MAAM,YAAY,GAAG,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;QAErD,sEAAsE;QACtE,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,iCAAiC,iBAAiB,CAAC,OAAO,MAAM,CAAC;YACtF,cAAc,GAAG,iBAAiB,CAAC,YAAY,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC9E,+CAA+C;YAC/C,QAAQ,GAAG;gBACT,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,mBAAmB,iBAAiB,CAAC,OAAO,IAAI;aAC3D,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,4DAA4D;YAC5D,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,YAAY,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,mFAAmF;IACnF,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE,cAAc,CAAC,CAAC;IAE5E,2BAA2B;IAC3B,QAAQ,iBAAiB,CAAC,SAAS,EAAE,CAAC;QACpC,KAAK,SAAS;YACZ,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM;QACR,KAAK,WAAW;YACd,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YACzC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM;QACR,KAAK,UAAU;YACb,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1C,MAAM;QACR,KAAK,OAAO;YACV,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,iBAAiB,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,yDAAyD;IACzD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;AACvD,CAAC,CAAC"}
@@ -1,15 +1,17 @@
1
1
  import { Locator, Page, TestInfo } from '@playwright/test';
2
2
  import { type LanguageModel } from 'ai';
3
3
  import z from 'zod';
4
- import { TargetInfo } from './selector';
5
4
  import type { TestContext } from '../mimic.js';
5
+ import type { SelectorDescriptor } from './selectorTypes.js';
6
6
  declare const zFormActionResult: z.ZodObject<{
7
+ mimicId: z.ZodNumber;
7
8
  type: z.ZodEnum<{
9
+ click: "click";
8
10
  type: "type";
9
- select: "select";
10
11
  fill: "fill";
11
- check: "check";
12
+ select: "select";
12
13
  uncheck: "uncheck";
14
+ check: "check";
13
15
  setInputFiles: "setInputFiles";
14
16
  clear: "clear";
15
17
  keypress: "keypress";
@@ -17,17 +19,17 @@ declare const zFormActionResult: z.ZodObject<{
17
19
  params: z.ZodObject<{
18
20
  value: z.ZodString;
19
21
  modifiers: z.ZodArray<z.ZodEnum<{
20
- none: "none";
21
22
  Alt: "Alt";
22
23
  Control: "Control";
23
24
  Meta: "Meta";
24
25
  Shift: "Shift";
26
+ none: "none";
25
27
  }>>;
26
28
  }, z.core.$strip>;
27
29
  elementDescription: z.ZodString;
28
30
  }, z.core.$strip>;
29
31
  export type FormActionResult = z.infer<typeof zFormActionResult>;
30
- export declare const getFormAction: (_page: Page, brain: LanguageModel, gherkinStep: string, targetElements: TargetInfo[], testContext?: TestContext) => Promise<FormActionResult>;
32
+ export declare const getFormAction: (page: Page, brain: LanguageModel, gherkinStep: string, testContext?: TestContext) => Promise<FormActionResult>;
31
33
  /**
32
34
  * Execute a form action on a page element with plain English annotation
33
35
  *
@@ -42,6 +44,9 @@ export declare const getFormAction: (_page: Page, brain: LanguageModel, gherkinS
42
44
  * @param gherkinStep - The original Gherkin step for annotation type (optional)
43
45
  * @returns Promise that resolves when the form action is complete
44
46
  */
45
- export declare const executeFormAction: (page: Page, formActionResult: FormActionResult, targetElement: Locator | null, testInfo?: TestInfo, gherkinStep?: string) => Promise<void | string[]>;
47
+ export declare const executeFormAction: (page: Page, formActionResult: FormActionResult, targetElement: Locator | null, testInfo?: TestInfo, gherkinStep?: string) => Promise<{
48
+ actionResult: FormActionResult;
49
+ selector: SelectorDescriptor | null;
50
+ }>;
46
51
  export {};
47
52
  //# sourceMappingURL=forms.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/mimic/forms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,IAAI,CAAA;AAC7D,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;iBAWrB,CAAA;AAGF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,eAAO,MAAM,aAAa,GACxB,OAAO,IAAI,EACX,OAAO,aAAa,EACpB,aAAa,MAAM,EACnB,gBAAgB,UAAU,EAAE,EAC5B,cAAc,WAAW,KACxB,OAAO,CAAC,gBAAgB,CAmJ1B,CAAA;AAGD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,IAAI,EACV,kBAAkB,gBAAgB,EAClC,eAAe,OAAO,GAAG,IAAI,EAC7B,WAAW,QAAQ,EACnB,cAAc,MAAM,KACnB,OAAO,CAAC,IAAI,GAAG,MAAM,EAAE,CA+FzB,CAAA"}
1
+ {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/mimic/forms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,IAAI,CAAA;AAC7D,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;iBAgBrB,CAAA;AAGF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,eAAO,MAAM,aAAa,GACxB,MAAM,IAAI,EACV,OAAO,aAAa,EACpB,aAAa,MAAM,EACnB,cAAc,WAAW,KACxB,OAAO,CAAC,gBAAgB,CAsP1B,CAAA;AAGD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,IAAI,EACV,kBAAkB,gBAAgB,EAClC,eAAe,OAAO,GAAG,IAAI,EAC7B,WAAW,QAAQ,EACnB,cAAc,MAAM,KACnB,OAAO,CAAC;IAAE,YAAY,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAA;CAAE,CAmQjF,CAAA"}