testchimp-runner-core 0.0.21 → 0.0.23
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/VISION_DIAGNOSTICS_IMPROVEMENTS.md +336 -0
- package/dist/credit-usage-service.d.ts +9 -0
- package/dist/credit-usage-service.d.ts.map +1 -1
- package/dist/credit-usage-service.js +20 -5
- package/dist/credit-usage-service.js.map +1 -1
- package/dist/execution-service.d.ts +7 -2
- package/dist/execution-service.d.ts.map +1 -1
- package/dist/execution-service.js +91 -36
- package/dist/execution-service.js.map +1 -1
- package/dist/index.d.ts +30 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -26
- package/dist/index.js.map +1 -1
- package/dist/llm-facade.d.ts +64 -8
- package/dist/llm-facade.d.ts.map +1 -1
- package/dist/llm-facade.js +361 -109
- package/dist/llm-facade.js.map +1 -1
- package/dist/llm-provider.d.ts +39 -0
- package/dist/llm-provider.d.ts.map +1 -0
- package/dist/llm-provider.js +7 -0
- package/dist/llm-provider.js.map +1 -0
- package/dist/model-constants.d.ts +21 -0
- package/dist/model-constants.d.ts.map +1 -0
- package/dist/model-constants.js +24 -0
- package/dist/model-constants.js.map +1 -0
- package/dist/orchestrator/index.d.ts +8 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +23 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestrator-agent.d.ts +66 -0
- package/dist/orchestrator/orchestrator-agent.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator-agent.js +855 -0
- package/dist/orchestrator/orchestrator-agent.js.map +1 -0
- package/dist/orchestrator/tool-registry.d.ts +74 -0
- package/dist/orchestrator/tool-registry.d.ts.map +1 -0
- package/dist/orchestrator/tool-registry.js +131 -0
- package/dist/orchestrator/tool-registry.js.map +1 -0
- package/dist/orchestrator/tools/check-page-ready.d.ts +13 -0
- package/dist/orchestrator/tools/check-page-ready.d.ts.map +1 -0
- package/dist/orchestrator/tools/check-page-ready.js +72 -0
- package/dist/orchestrator/tools/check-page-ready.js.map +1 -0
- package/dist/orchestrator/tools/extract-data.d.ts +13 -0
- package/dist/orchestrator/tools/extract-data.d.ts.map +1 -0
- package/dist/orchestrator/tools/extract-data.js +84 -0
- package/dist/orchestrator/tools/extract-data.js.map +1 -0
- package/dist/orchestrator/tools/index.d.ts +10 -0
- package/dist/orchestrator/tools/index.d.ts.map +1 -0
- package/dist/orchestrator/tools/index.js +18 -0
- package/dist/orchestrator/tools/index.js.map +1 -0
- package/dist/orchestrator/tools/inspect-page.d.ts +13 -0
- package/dist/orchestrator/tools/inspect-page.d.ts.map +1 -0
- package/dist/orchestrator/tools/inspect-page.js +39 -0
- package/dist/orchestrator/tools/inspect-page.js.map +1 -0
- package/dist/orchestrator/tools/recall-history.d.ts +13 -0
- package/dist/orchestrator/tools/recall-history.d.ts.map +1 -0
- package/dist/orchestrator/tools/recall-history.js +64 -0
- package/dist/orchestrator/tools/recall-history.js.map +1 -0
- package/dist/orchestrator/tools/take-screenshot.d.ts +15 -0
- package/dist/orchestrator/tools/take-screenshot.d.ts.map +1 -0
- package/dist/orchestrator/tools/take-screenshot.js +112 -0
- package/dist/orchestrator/tools/take-screenshot.js.map +1 -0
- package/dist/orchestrator/types.d.ts +133 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +28 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/playwright-mcp-service.d.ts +9 -0
- package/dist/playwright-mcp-service.d.ts.map +1 -1
- package/dist/playwright-mcp-service.js +20 -5
- package/dist/playwright-mcp-service.js.map +1 -1
- package/dist/progress-reporter.d.ts +97 -0
- package/dist/progress-reporter.d.ts.map +1 -0
- package/dist/progress-reporter.js +18 -0
- package/dist/progress-reporter.js.map +1 -0
- package/dist/prompts.d.ts +24 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +593 -68
- package/dist/prompts.js.map +1 -1
- package/dist/providers/backend-proxy-llm-provider.d.ts +25 -0
- package/dist/providers/backend-proxy-llm-provider.d.ts.map +1 -0
- package/dist/providers/backend-proxy-llm-provider.js +76 -0
- package/dist/providers/backend-proxy-llm-provider.js.map +1 -0
- package/dist/providers/local-llm-provider.d.ts +21 -0
- package/dist/providers/local-llm-provider.d.ts.map +1 -0
- package/dist/providers/local-llm-provider.js +35 -0
- package/dist/providers/local-llm-provider.js.map +1 -0
- package/dist/scenario-service.d.ts +27 -1
- package/dist/scenario-service.d.ts.map +1 -1
- package/dist/scenario-service.js +48 -12
- package/dist/scenario-service.js.map +1 -1
- package/dist/scenario-worker-class.d.ts +39 -2
- package/dist/scenario-worker-class.d.ts.map +1 -1
- package/dist/scenario-worker-class.js +614 -86
- package/dist/scenario-worker-class.js.map +1 -1
- package/dist/script-utils.d.ts +2 -0
- package/dist/script-utils.d.ts.map +1 -1
- package/dist/script-utils.js +44 -4
- package/dist/script-utils.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/browser-utils.d.ts +20 -1
- package/dist/utils/browser-utils.d.ts.map +1 -1
- package/dist/utils/browser-utils.js +102 -51
- package/dist/utils/browser-utils.js.map +1 -1
- package/dist/utils/page-info-utils.d.ts +23 -4
- package/dist/utils/page-info-utils.d.ts.map +1 -1
- package/dist/utils/page-info-utils.js +174 -43
- package/dist/utils/page-info-utils.js.map +1 -1
- package/package.json +1 -2
- package/plandocs/HUMAN_LIKE_IMPROVEMENTS.md +642 -0
- package/plandocs/MULTI_AGENT_ARCHITECTURE_REVIEW.md +844 -0
- package/plandocs/ORCHESTRATOR_MVP_SUMMARY.md +539 -0
- package/plandocs/PHASE1_ABSTRACTION_COMPLETE.md +241 -0
- package/plandocs/PHASE1_FINAL_STATUS.md +210 -0
- package/plandocs/PLANNING_SESSION_SUMMARY.md +372 -0
- package/plandocs/SCRIPT_CLEANUP_FEATURE.md +201 -0
- package/plandocs/SCRIPT_GENERATION_ARCHITECTURE.md +364 -0
- package/plandocs/SELECTOR_IMPROVEMENTS.md +139 -0
- package/src/credit-usage-service.ts +23 -5
- package/src/execution-service.ts +152 -42
- package/src/index.ts +169 -26
- package/src/llm-facade.ts +500 -126
- package/src/llm-provider.ts +43 -0
- package/src/model-constants.ts +23 -0
- package/src/orchestrator/index.ts +33 -0
- package/src/orchestrator/orchestrator-agent.ts +1037 -0
- package/src/orchestrator/tool-registry.ts +182 -0
- package/src/orchestrator/tools/check-page-ready.ts +75 -0
- package/src/orchestrator/tools/extract-data.ts +92 -0
- package/src/orchestrator/tools/index.ts +11 -0
- package/src/orchestrator/tools/inspect-page.ts +42 -0
- package/src/orchestrator/tools/recall-history.ts +72 -0
- package/src/orchestrator/tools/take-screenshot.ts +128 -0
- package/src/orchestrator/types.ts +200 -0
- package/src/playwright-mcp-service.ts +23 -5
- package/src/progress-reporter.ts +109 -0
- package/src/prompts.ts +606 -69
- package/src/providers/backend-proxy-llm-provider.ts +91 -0
- package/src/providers/local-llm-provider.ts +38 -0
- package/src/scenario-service.ts +83 -13
- package/src/scenario-worker-class.ts +740 -72
- package/src/script-utils.ts +50 -5
- package/src/types.ts +13 -1
- package/src/utils/browser-utils.ts +123 -51
- package/src/utils/page-info-utils.ts +210 -53
- package/testchimp-runner-core-0.0.22.tgz +0 -0
package/dist/prompts.js
CHANGED
|
@@ -17,53 +17,417 @@ exports.PROMPTS = {
|
|
|
17
17
|
},
|
|
18
18
|
// Scenario breakdown
|
|
19
19
|
SCENARIO_BREAKDOWN: {
|
|
20
|
-
SYSTEM: `
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
SYSTEM: `Split user scenarios into individual steps. Copy each step exactly as provided. Do not add, expand, or modify.`,
|
|
21
|
+
USER: (scenario) => `Split this into steps. Keep each step exactly as written.
|
|
22
|
+
|
|
23
|
+
${scenario}
|
|
24
|
+
|
|
25
|
+
Return JSON: {"steps": ["step 1", "step 2", ...]}`
|
|
26
|
+
},
|
|
27
|
+
// Goal completion assessment
|
|
28
|
+
GOAL_COMPLETION_CHECK: {
|
|
29
|
+
SYSTEM: 'You are an expert test automation analyst. Evaluate whether a goal has been fully achieved. Be EXTREMELY CONSERVATIVE - mark goals complete when the PRIMARY action succeeds. DO NOT invent verification steps that were not explicitly requested. However, if the scenario explicitly specifies verification requirements, those MUST be completed and not skipped.',
|
|
30
|
+
USER: (goalDescription, completedActions, pageInfo) => `Analyze whether the following goal has been fully completed:
|
|
31
|
+
|
|
32
|
+
GOAL: "${goalDescription}"
|
|
33
|
+
|
|
34
|
+
COMPLETED ACTIONS IN THIS STEP:
|
|
35
|
+
${completedActions.map((action, idx) => `${idx + 1}. ${action}`).join('\n')}
|
|
36
|
+
|
|
37
|
+
CURRENT PAGE STATE:
|
|
38
|
+
- URL: ${pageInfo.url}
|
|
39
|
+
- Title: ${pageInfo.title}
|
|
40
|
+
- Interactive Elements:
|
|
41
|
+
${pageInfo.formattedElements}
|
|
42
|
+
|
|
43
|
+
CRITICAL GUIDELINES - MARK COMPLETE AGGRESSIVELY:
|
|
44
|
+
|
|
45
|
+
1. **Action Goals vs Verification Goals**:
|
|
46
|
+
- If goal is an ACTION (click, type, select, send, submit), mark COMPLETE after successful action
|
|
47
|
+
- If goal is VERIFICATION (verify, check, ensure, assert), mark COMPLETE after assertion passes
|
|
48
|
+
- NEVER add verification to action goals - if the goal doesn't mention verification, don't require it
|
|
49
|
+
- HOWEVER: If verification is EXPLICITLY mentioned in the goal, it MUST be completed - do not skip it
|
|
50
|
+
|
|
51
|
+
2. **Understand Action Semantics** (what does the action verb really mean):
|
|
52
|
+
|
|
53
|
+
Some actions are ATOMIC (one operation):
|
|
54
|
+
- "Click X" → Just click
|
|
55
|
+
- "Type X into field" → Just type
|
|
56
|
+
- "Navigate to URL" → Just navigate
|
|
57
|
+
- "Select option" → Just select
|
|
58
|
+
|
|
59
|
+
Other actions imply a WORKFLOW with implicit final trigger:
|
|
60
|
+
- ANY action verb that implies submission/sending/triggering
|
|
61
|
+
- If the action includes data to provide, it usually implies using that data
|
|
62
|
+
- If the action name is a business process (login, register, send, post, etc.), think about what the user expects to happen
|
|
63
|
+
|
|
64
|
+
**General Pattern Recognition:**
|
|
65
|
+
|
|
66
|
+
Ask yourself: "In normal usage, does [ACTION VERB] require a final trigger/button?"
|
|
67
|
+
- "Login" → Yes, requires clicking a login/submit button after entering credentials
|
|
68
|
+
- "Send" → Yes, requires clicking a send button after typing content
|
|
69
|
+
- "Post" → Yes, requires clicking a post/publish button after entering content
|
|
70
|
+
- "Search for X" → Yes, requires triggering search after entering search term
|
|
71
|
+
- "Filter by X" → Maybe, depends on if filter auto-applies or needs button
|
|
72
|
+
- "Fill in X" → No, just data entry unless goal says "fill AND submit"
|
|
73
|
+
|
|
74
|
+
Mark COMPLETE when the BUSINESS ACTION is done from user perspective:
|
|
75
|
+
- Not complete if you only prepared data (filled fields) but didn't trigger the action
|
|
76
|
+
- Complete when the system would have processed/submitted/executed the action
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
- "Login with credentials: X" → Incomplete until credentials submitted (button clicked)
|
|
80
|
+
- "Send message: Y" → Incomplete until message sent (send button clicked)
|
|
81
|
+
- "Fill in name field" → Complete after fill (no submission implied)
|
|
82
|
+
- "Search for products" → Incomplete until search triggered
|
|
83
|
+
|
|
84
|
+
Think: "From a user's perspective, is the action done?" not "Did I type the data?"
|
|
85
|
+
|
|
86
|
+
3. **Multi-part Goals** (explicit multiple requirements):
|
|
87
|
+
- "Fill in ALL fields" → Need multiple fills for each field
|
|
88
|
+
- "Click submit AND verify success message appears" → Need both click + explicit verification
|
|
89
|
+
- Goals with explicit "and" requiring multiple distinct actions
|
|
90
|
+
|
|
91
|
+
4. **NEVER Create Hallucinated Verification Sub-goals, BUT Honor Explicit Verification Requirements**:
|
|
92
|
+
- Don't invent verification steps that weren't in the original goal
|
|
93
|
+
- Don't look for confirmation messages unless goal explicitly asks for them
|
|
94
|
+
- Don't check for success indicators unless goal explicitly requires verification
|
|
95
|
+
- Trust Playwright's execution - if action succeeded without error, it worked
|
|
96
|
+
- Action success IS the completion criteria for action goals
|
|
97
|
+
- CRITICAL: If the goal explicitly says "verify", "check", "ensure", "confirm" something, that verification MUST be completed
|
|
98
|
+
|
|
99
|
+
5. **State Changes After Actions Are SUCCESS, Not Failure**:
|
|
100
|
+
- Button becomes disabled after click → SUCCESS (expected behavior)
|
|
101
|
+
- Form clears after submit → SUCCESS (expected behavior)
|
|
102
|
+
- Page navigates after action → SUCCESS (expected behavior)
|
|
103
|
+
- Element disappears after interaction → SUCCESS (expected behavior)
|
|
104
|
+
|
|
105
|
+
6. **What "nextSubGoal" Should Look Like**:
|
|
106
|
+
- For "Fill in all fields" with 5 fields, if 2 filled: "Fill in the remaining 3 fields" ✅
|
|
107
|
+
- For "Click submit AND verify", if clicked but not verified: "Verify the success message appears" ✅
|
|
108
|
+
- For "Click send button" after click succeeds: NO nextSubGoal - COMPLETE ✅
|
|
109
|
+
- DON'T create nextSubGoal for verification unless goal explicitly asks for it ❌
|
|
110
|
+
|
|
111
|
+
CRITICAL - Preserve specific values in nextSubGoal:
|
|
112
|
+
- Original: "Login with credentials: admin, pass123" (username filled, password not)
|
|
113
|
+
✅ nextSubGoal: "Enter password: pass123"
|
|
114
|
+
❌ NOT: "Complete the login" (loses the password value!)
|
|
115
|
+
|
|
116
|
+
- Original: "Enter user details: Name: John, Email: john@test.com" (name done, email not)
|
|
117
|
+
✅ nextSubGoal: "Enter email: john@test.com"
|
|
118
|
+
❌ NOT: "Enter email address" (loses specific email!)
|
|
119
|
+
|
|
120
|
+
Examples:
|
|
121
|
+
|
|
122
|
+
✅ PURE ACTION GOALS (no verification in description - complete after action):
|
|
123
|
+
- Goal: "Click the send button" + Action: click() succeeded → COMPLETE ✅ (no verification needed)
|
|
124
|
+
- Goal: "Enter email address" + Action: fill() succeeded → COMPLETE ✅ (no verification needed)
|
|
125
|
+
- Goal: "Navigate to dashboard" + Action: goto() succeeded → COMPLETE ✅ (no verification needed)
|
|
126
|
+
- Goal: "Submit the form" + Action: click() succeeded → COMPLETE ✅ (no verification needed)
|
|
127
|
+
|
|
128
|
+
⏳ GOALS WITH EXPLICIT VERIFICATION (must complete BOTH action AND verification):
|
|
129
|
+
- Goal: "Click send and verify message sent" + Action: click() succeeded → INCOMPLETE ⏳ nextSubGoal: "Verify message sent confirmation"
|
|
130
|
+
- Goal: "Submit form and check for success message" + Action: submit clicked → INCOMPLETE ⏳ nextSubGoal: "Check for success message"
|
|
131
|
+
- Goal: "Login and verify dashboard appears" + Action: login completed → INCOMPLETE ⏳ nextSubGoal: "Verify dashboard appears"
|
|
132
|
+
|
|
133
|
+
✅ PURE VERIFICATION GOALS (complete after verification):
|
|
134
|
+
- Goal: "Verify page title is correct" + Action: assertion passed → COMPLETE ✅
|
|
135
|
+
- Goal: "Check that the error message is displayed" + Action: assertion passed → COMPLETE ✅
|
|
136
|
+
- Goal: "Ensure user is logged in" + Action: assertion passed → COMPLETE ✅
|
|
137
|
+
|
|
138
|
+
⏳ MULTI-STEP ACTION GOALS (complete all parts):
|
|
139
|
+
- Goal: "Fill in all required fields" + Action: filled 2 of 5 → INCOMPLETE ⏳ nextSubGoal: "Fill in remaining 3 fields"
|
|
140
|
+
|
|
141
|
+
GOLDEN RULE:
|
|
142
|
+
- If the goal is a SIMPLE ACTION and that action SUCCEEDED, mark COMPLETE immediately
|
|
143
|
+
- Don't hallucinate verification requirements that weren't explicitly requested
|
|
144
|
+
- BUT if verification IS explicitly mentioned in the goal, it MUST be completed before marking COMPLETE
|
|
145
|
+
- Only verify what is instructed to be verified, nothing more, nothing less
|
|
146
|
+
|
|
147
|
+
Respond with JSON:
|
|
148
|
+
{
|
|
149
|
+
"isComplete": true/false,
|
|
150
|
+
"reason": "brief explanation - if action succeeded and goal was just the action, mark complete",
|
|
151
|
+
"nextSubGoal": "ONLY if goal has multiple parts and not all parts done yet - must be based on ACTUAL goal requirements, not invented verification"
|
|
152
|
+
}`
|
|
153
|
+
},
|
|
154
|
+
// Screenshot need assessment
|
|
155
|
+
SCREENSHOT_NEED_ASSESSMENT: {
|
|
156
|
+
SYSTEM: 'You are an expert test automation analyst. Determine if visual screenshot analysis is ABSOLUTELY NECESSARY to solve this failure. Vision mode is expensive (GPT-4o), so only recommend when there is CLEAR diagnostic value that DOM cannot provide.',
|
|
157
|
+
USER: (stepDescription, errorMessage, attemptCount, pageInfo) => `After 2 failures, determine if VISION MODE is absolutely necessary. This is the ONLY chance to use vision.
|
|
158
|
+
|
|
159
|
+
STEP: "${stepDescription}"
|
|
160
|
+
ERROR: "${errorMessage}"
|
|
161
|
+
ATTEMPT: ${attemptCount} (after ${attemptCount - 1} failures - vision can diagnose the issue)
|
|
162
|
+
|
|
163
|
+
CURRENT DOM INFO AVAILABLE:
|
|
164
|
+
- URL: ${pageInfo.url}
|
|
165
|
+
- Interactive Elements:
|
|
166
|
+
${pageInfo.formattedElements}
|
|
167
|
+
|
|
168
|
+
🎯 VISION MODE - USE SPARINGLY (Expensive GPT-4o):
|
|
169
|
+
|
|
170
|
+
Vision provides diagnostic value ONLY when DOM information is truly insufficient.
|
|
171
|
+
|
|
172
|
+
✅ **RECOMMEND SCREENSHOT only for these HIGH-VALUE cases:**
|
|
173
|
+
|
|
174
|
+
1. **Suspected Element Hallucination** (HIGH priority):
|
|
175
|
+
- Previous attempts tried getByText/toBeVisible for elements that might not exist
|
|
176
|
+
- Error: "not found" or "timeout" on verification attempts
|
|
177
|
+
- Visual will definitively show if elements exist or if we need alternative verification
|
|
178
|
+
|
|
179
|
+
2. **Visual-Only Elements**:
|
|
180
|
+
- Icons, images, or visual indicators without text/roles
|
|
181
|
+
- Elements identified by position ("button on the right")
|
|
182
|
+
- Shadow DOM or complex component structures
|
|
183
|
+
|
|
184
|
+
3. **Visual Blockers**:
|
|
185
|
+
- Overlays, modals, or popups blocking interactions
|
|
186
|
+
- Z-index issues preventing clicks
|
|
187
|
+
- Scrolling problems that DOM doesn't reveal
|
|
188
|
+
|
|
189
|
+
❌ **DO NOT RECOMMEND SCREENSHOT when:**
|
|
190
|
+
- **Strict mode violations / multiple matches** - Accessibility tree shows duplicates, use DOM info to scope selector
|
|
191
|
+
- Simple selector errors (try different selector strategies first)
|
|
192
|
+
- Navigation issues (URL problems are not visual)
|
|
193
|
+
- Invalid Playwright API (syntax errors)
|
|
194
|
+
- Timing issues that can be solved with better waits
|
|
195
|
+
- DOM clearly shows the solution (IDs, data-testid available)
|
|
196
|
+
- Error has obvious DOM-based fix
|
|
197
|
+
|
|
198
|
+
**Conservative Assessment Required:**
|
|
199
|
+
- Vision mode is EXPENSIVE (uses GPT-4o)
|
|
200
|
+
- This is the ONLY chance (attempt 3 of 4)
|
|
201
|
+
- Only recommend if DOM truly cannot solve it
|
|
202
|
+
- If in doubt, suggest DOM-based alternative instead
|
|
203
|
+
|
|
204
|
+
Respond with JSON:
|
|
205
|
+
{
|
|
206
|
+
"needsScreenshot": true/false,
|
|
207
|
+
"reason": "If true: [specific diagnostic value vision provides]. If false: [why DOM-based approach is sufficient]",
|
|
208
|
+
"alternativeApproach": "REQUIRED if needsScreenshot=false: [specific DOM-based solution to try next]"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
Remember: Default to NO unless there's compelling evidence that visual analysis is the ONLY way to solve this.`
|
|
38
212
|
},
|
|
39
213
|
// Playwright command generation
|
|
40
214
|
PLAYWRIGHT_COMMAND: {
|
|
41
|
-
SYSTEM: 'You are an expert Playwright automation engineer
|
|
42
|
-
USER: (stepDescription, pageInfo, previousCommands, attemptHistory, errorContext) => `You are
|
|
215
|
+
SYSTEM: 'You are an expert Playwright automation engineer with strong self-awareness and problem-solving skills. You understand cause-and-effect, learn from your own actions, and can reason about application state changes.',
|
|
216
|
+
USER: (stepDescription, pageInfo, previousCommands, attemptHistory, errorContext) => `You are working to achieve a specific goal. Generate ONE precise Playwright command that makes progress.
|
|
43
217
|
|
|
218
|
+
🎯 CURRENT GOAL: "${stepDescription}"
|
|
219
|
+
|
|
220
|
+
📋 WHAT YOU'VE ALREADY DONE IN THIS STEP:
|
|
221
|
+
${previousCommands || 'Nothing yet - this is the first action for this goal'}
|
|
222
|
+
|
|
223
|
+
${errorContext ? `⚠️ PREVIOUS ATTEMPT FAILED:\n${errorContext}\n` : ''}
|
|
224
|
+
${attemptHistory ? `📊 ALL ATTEMPTS SO FAR:\n${attemptHistory}\n` : ''}
|
|
225
|
+
|
|
226
|
+
🧠 SELF-AWARENESS & REASONING:
|
|
227
|
+
|
|
228
|
+
1. **Analyze Your Own Actions**:
|
|
229
|
+
- Review what you've ALREADY done in this step above
|
|
230
|
+
- Did your previous actions CAUSE the current state?
|
|
231
|
+
- Ask: "What is the LOGICAL consequence of what I just did?"
|
|
232
|
+
- Understand that your actions change the application state
|
|
233
|
+
|
|
234
|
+
2. **Understand Cause & Effect**:
|
|
235
|
+
- Element state changed? → Did YOUR previous action cause it?
|
|
236
|
+
- Element not found? → Did YOUR action remove it or navigate away?
|
|
237
|
+
- Validation error? → Did YOUR action trigger it (empty field, wrong format)?
|
|
238
|
+
- Before retrying, ask: "Is this the EXPECTED result of my actions?"
|
|
239
|
+
|
|
240
|
+
3. **Self-Correction Logic**:
|
|
241
|
+
- If you caused the problem → Fix it (don't just retry)
|
|
242
|
+
- If you achieved the goal (even with side effects) → Move on!
|
|
243
|
+
- If you're stuck in a loop → You're fighting expected behavior, change approach
|
|
244
|
+
- Don't undo successful work or fight against normal state transitions
|
|
245
|
+
|
|
246
|
+
4. **Smart Recovery**:
|
|
247
|
+
- Element not ready/unavailable → Identify what prerequisite is missing, complete it first
|
|
248
|
+
- Element not found → Distinguish between: your action removed it (success) vs genuine error
|
|
249
|
+
- Multiple failures on same approach → Fundamentally rethink strategy, don't iterate blindly
|
|
250
|
+
- Stuck in retry loop → Step back, analyze root cause, try completely different approach
|
|
251
|
+
|
|
252
|
+
5. **NEVER Hallucinate Verification Elements**:
|
|
253
|
+
- ONLY verify elements that ACTUALLY EXIST in the current DOM state
|
|
254
|
+
- Check the "CURRENT PAGE STATE" section for what elements are available
|
|
255
|
+
- Don't look for "success message", "confirmation text", or "sent message" unless you see them in the DOM
|
|
256
|
+
- Don't invent text patterns or regex for elements that don't exist
|
|
257
|
+
- If verification is needed but element doesn't exist, use alternative methods:
|
|
258
|
+
* Check for state changes (button disabled, form cleared, URL changed)
|
|
259
|
+
* Wait for page load state changes
|
|
260
|
+
* Check for element detachment/attachment
|
|
261
|
+
* Use waitForResponse for network verification
|
|
262
|
+
- When previous attempts failed looking for non-existent elements, STOP trying to find them
|
|
263
|
+
|
|
264
|
+
6. **Navigation and Redirects** (CRITICAL):
|
|
265
|
+
|
|
266
|
+
Handle redirects properly - DON'T keep retrying original URL if navigation succeeded:
|
|
267
|
+
|
|
268
|
+
- For navigation, use explicit 10-second timeout (default is 5s, too short for redirects):
|
|
269
|
+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 10000 })
|
|
270
|
+
|
|
271
|
+
- Why longer timeout for navigation:
|
|
272
|
+
* Redirects take extra time
|
|
273
|
+
* Initial page loads are slower
|
|
274
|
+
* Default 5s timeout is for fast element operations only
|
|
275
|
+
|
|
276
|
+
- If navigation times out or throws "execution context destroyed":
|
|
277
|
+
* CHECK CURRENT URL FIRST: const currentUrl = page.url()
|
|
278
|
+
* If URL changed from about:blank → Navigation SUCCEEDED (even if redirected)
|
|
279
|
+
* DON'T retry goto() if already on a page
|
|
280
|
+
* Proceed with next step
|
|
281
|
+
|
|
282
|
+
- Navigation succeeded if:
|
|
283
|
+
* page.url() is NOT 'about:blank'
|
|
284
|
+
* page.url() changed from previous URL
|
|
285
|
+
* Even if different from target URL (redirects are normal)
|
|
286
|
+
|
|
287
|
+
- Only retry navigation if:
|
|
288
|
+
* page.url() is still 'about:blank' or previous URL
|
|
289
|
+
* AND no redirect happened
|
|
290
|
+
|
|
291
|
+
7. **Real-World Web App Resilience**:
|
|
292
|
+
|
|
293
|
+
Common Interruptions (handle gracefully):
|
|
294
|
+
- Cookie consent banners → Dismiss if blocking main UI (look for "Accept", "OK", "Close")
|
|
295
|
+
- Modal popups → Close if not relevant to current goal (look for X button, "Dismiss")
|
|
296
|
+
- Page refreshes → Re-find elements, don't assume page state persists
|
|
297
|
+
- Loading states → Wait for content, check for spinners/loading indicators
|
|
298
|
+
- Overlays → Dismiss or wait for them to disappear before proceeding
|
|
299
|
+
|
|
300
|
+
Detection Patterns:
|
|
301
|
+
- If element suddenly not found → Check if overlay/modal appeared
|
|
302
|
+
- If click fails → Check if cookie banner is blocking element
|
|
303
|
+
- If page URL changed unexpectedly → Handle redirect/refresh gracefully
|
|
304
|
+
- If timeout occurs → Check for loading indicators, wait for them to disappear
|
|
305
|
+
|
|
306
|
+
Resilience Strategies:
|
|
307
|
+
- Before critical interactions, check for and dismiss blocking overlays
|
|
308
|
+
- After page loads, wait for dynamic content (networkidle, specific elements)
|
|
309
|
+
- If element covered/blocked, look for overlay and close it
|
|
310
|
+
- Use flexible selectors that work across page refreshes
|
|
311
|
+
- Add waits for elements that load dynamically
|
|
312
|
+
|
|
313
|
+
Examples:
|
|
314
|
+
- If cookie banner present: await page.getByRole('button', {name: /accept|ok|agree/i}).click();
|
|
315
|
+
- If modal blocking: await page.getByRole('button', {name: /close|dismiss|x/i}).click();
|
|
316
|
+
- After action that might refresh: await page.waitForLoadState('domcontentloaded');
|
|
317
|
+
- For dynamic content: await page.getByText('expected content').waitFor();
|
|
318
|
+
|
|
319
|
+
8. **Use Specific Values from Goal Description**:
|
|
320
|
+
|
|
321
|
+
CRITICAL: Extract and use exact values mentioned in the goal.
|
|
322
|
+
|
|
323
|
+
Examples:
|
|
324
|
+
- Goal: "Login with credentials: Willy, Willy@1234"
|
|
325
|
+
✅ Use: await page.fill('username', 'Willy'); await page.fill('password', 'Willy@1234');
|
|
326
|
+
❌ NOT: await page.fill('username', process.env.USERNAME);
|
|
327
|
+
|
|
328
|
+
- Goal: "Enter name: John Doe"
|
|
329
|
+
✅ Use: await page.fill('[name="name"]', 'John Doe');
|
|
330
|
+
❌ NOT: await page.fill('[name="name"]', 'Test User');
|
|
331
|
+
|
|
332
|
+
Apply this to ANY specific value in the goal (amounts, dates, selections, text, etc.).
|
|
333
|
+
|
|
334
|
+
NEVER:
|
|
335
|
+
- Replace specific values with environment variables
|
|
336
|
+
- Replace specific values with generic test data
|
|
337
|
+
- Hallucinate different values than what's in the goal
|
|
338
|
+
- Use process.env, config, or placeholder values
|
|
339
|
+
|
|
340
|
+
Be creative ONLY when goal doesn't specify values:
|
|
341
|
+
- "Login with valid credentials" → Infer reasonable values
|
|
342
|
+
- "Login with credentials: admin, pass123" → Use EXACTLY those values
|
|
343
|
+
|
|
344
|
+
GOAL-ORIENTED APPROACH:
|
|
345
|
+
- What needs to be done to achieve this goal?
|
|
346
|
+
- Have I ALREADY done parts of this? (check "WHAT YOU'VE ALREADY DONE")
|
|
347
|
+
- If yes, what's the NEXT logical action?
|
|
348
|
+
- If retrying after failure, WHY did it fail? Did I cause it?
|
|
349
|
+
- Is something blocking the UI? (cookie banner, modal, overlay)
|
|
350
|
+
- Extract any specific values from the goal and use them EXACTLY
|
|
351
|
+
|
|
352
|
+
9. **Strict Mode Violations & Multiple Matches** (CRITICAL):
|
|
353
|
+
|
|
354
|
+
Playwright throws "strict mode violation" when a selector matches MULTIPLE elements.
|
|
355
|
+
|
|
356
|
+
**PROACTIVE DETECTION** - Check BEFORE generating command:
|
|
357
|
+
- Review the "CURRENT PAGE STATE" section below (accessibility tree / aria snapshot)
|
|
358
|
+
- Look for duplicate elements with same role/text (e.g., multiple links with "Employee Information")
|
|
359
|
+
- If duplicates exist, generate a MORE SPECIFIC selector from the start
|
|
360
|
+
- Don't wait for strict mode error - prevent it by analyzing the DOM structure
|
|
361
|
+
|
|
362
|
+
🚨 ERROR PATTERNS:
|
|
363
|
+
- "strict mode violation" → Your selector matched multiple elements
|
|
364
|
+
- "Multiple elements found" → Same issue
|
|
365
|
+
- Command chain with multiple strategies → Sign of selector problems
|
|
366
|
+
|
|
367
|
+
✅ SOLUTIONS (in order of preference):
|
|
368
|
+
|
|
369
|
+
**Option 1: Be More Specific** (BEST):
|
|
370
|
+
- BAD: page.locator('a', { hasText: 'Employee Information' }).click() → Matches multiple links
|
|
371
|
+
- GOOD: page.locator('nav a', { hasText: 'Employee Information' }).click() → Scoped to nav
|
|
372
|
+
- GOOD: page.getByRole('navigation').getByRole('link', { name: 'Employee Information' }).click() → Role-based scoping
|
|
373
|
+
- GOOD: page.locator('a[href*="/employee"]', { hasText: 'Employee Information' }).click() → Combined attributes
|
|
374
|
+
|
|
375
|
+
**Option 2: Use Position-Based Selection**:
|
|
376
|
+
- If multiple matches are expected: page.locator('a', { hasText: 'Employee Information' }).first().click()
|
|
377
|
+
- Or use: .nth(0) for first, .last() for last
|
|
378
|
+
|
|
379
|
+
**Option 3: Filter by Visibility/State**:
|
|
380
|
+
- page.locator('button', { hasText: 'Submit' }).filter({ hasNotText: 'Draft' }).click()
|
|
381
|
+
|
|
382
|
+
🚫 **ANTI-PATTERNS (DON'T DO THIS)**:
|
|
383
|
+
- BAD: Chaining multiple selector strategies in one command with semicolons
|
|
384
|
+
- BAD: Using page.evaluate() to find/click elements (defeats Playwright's auto-waiting)
|
|
385
|
+
- GOOD: ONE clear, specific selector like page.locator('nav a', { hasText: 'Employee Information' }).click()
|
|
386
|
+
|
|
387
|
+
**When You See Strict Mode Errors:**
|
|
388
|
+
1. Analyze - Why did my selector match multiple elements?
|
|
389
|
+
2. Narrow Down - Add parent context (nav, sidebar, header)
|
|
390
|
+
3. Combine - Use multiple attributes (role + text, class + href)
|
|
391
|
+
4. Position - If truly ambiguous, use .first() or .nth()
|
|
392
|
+
5. NEVER - Chain multiple selector attempts or use page.evaluate()
|
|
393
|
+
|
|
394
|
+
**Key Principle:**
|
|
395
|
+
- ONE command = ONE clear selector strategy
|
|
396
|
+
- Don't hedge your bets with multiple approaches
|
|
397
|
+
- Trust Playwright's auto-waiting and built-in selectors
|
|
398
|
+
|
|
44
399
|
CRITICAL RULES:
|
|
45
|
-
- Generate ONLY ONE command
|
|
400
|
+
- Generate ONLY ONE command that moves toward the goal
|
|
401
|
+
- NEVER undo your own successful work (don't clear fields you just filled!)
|
|
402
|
+
- If previous attempts failed, analyze WHY before trying different approach
|
|
403
|
+
- Learn from failures and your own action history
|
|
46
404
|
- Use the most reliable selectors (prefer getByRole, getByText, getByLabel)
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
- Learn from failures and adapt your strategy
|
|
405
|
+
- Trust Playwright's auto-waiting - if click succeeded, it worked!
|
|
406
|
+
- If strict mode violation: Make selector MORE SPECIFIC or use .first()
|
|
407
|
+
- Generate ONE clear command, not multiple chained selector attempts
|
|
51
408
|
|
|
52
409
|
ELEMENT SELECTION PRIORITY:
|
|
53
|
-
1.
|
|
54
|
-
2.
|
|
55
|
-
3.
|
|
56
|
-
4.
|
|
57
|
-
5.
|
|
58
|
-
6.
|
|
59
|
-
|
|
60
|
-
|
|
410
|
+
1. getByTestId() - BEST if data-testid is available (most stable, designed for tests)
|
|
411
|
+
2. locator('#id') - EXCELLENT if element has unique ID (stable, direct targeting)
|
|
412
|
+
3. getByRole() - Very reliable for interactive elements (semantic)
|
|
413
|
+
4. getByText() - For text content (good for unique text)
|
|
414
|
+
5. getByLabel() - For form inputs (semantic)
|
|
415
|
+
6. getByPlaceholder() - For input placeholders
|
|
416
|
+
7. locator() with CSS classes - Last resort (brittle, changes frequently)
|
|
417
|
+
|
|
418
|
+
COMMON PATTERNS (prefer IDs/data-testid when available):
|
|
61
419
|
- Navigation: await page.goto('url')
|
|
62
|
-
- Click: await page.
|
|
63
|
-
-
|
|
420
|
+
- Click with testid: await page.getByTestId('submit-btn').click()
|
|
421
|
+
- Click with ID: await page.locator('#login-button').click()
|
|
422
|
+
- Click with role: await page.getByRole('button', { name: 'text' }).click()
|
|
423
|
+
- Type with testid: await page.getByTestId('username-input').fill('text')
|
|
424
|
+
- Type with ID: await page.locator('#email').fill('text')
|
|
425
|
+
- Type with role: await page.getByRole('textbox', { name: 'label' }).fill('text')
|
|
64
426
|
- Wait: await page.waitForLoadState('networkidle')
|
|
65
427
|
- Verify: await expect(page).toHaveTitle(/expected/)
|
|
66
428
|
|
|
429
|
+
IMPORTANT: Use IDs/data attributes in COMMANDS, but keep goal descriptions semantic!
|
|
430
|
+
|
|
67
431
|
CODE STYLE GUIDELINES:
|
|
68
432
|
- Keep commands concise and clean
|
|
69
433
|
- Avoid explicit timeouts unless necessary
|
|
@@ -71,11 +435,30 @@ exports.PROMPTS = {
|
|
|
71
435
|
- Only add timeouts for specific slow operations
|
|
72
436
|
- Prefer single-line commands when possible
|
|
73
437
|
|
|
438
|
+
VALID PLAYWRIGHT API REFERENCE:
|
|
439
|
+
- locator.waitFor({ state: 'visible'|'hidden'|'attached'|'detached' }) - ONLY these states
|
|
440
|
+
- NEVER use waitFor({ state: 'enabled' }) - THIS IS INVALID
|
|
441
|
+
- For disabled elements: Use page.waitForFunction() with DOM check
|
|
442
|
+
- CSS selectors: Standard CSS only (no :has-text(), :enabled pseudo-classes)
|
|
443
|
+
- Playwright pseudo-selectors only work in locator(), NOT in querySelector()
|
|
444
|
+
|
|
74
445
|
RETRY STRATEGIES:
|
|
75
|
-
- Timeout errors: Add waitFor() or increase timeout
|
|
76
|
-
- Not found errors: Try different selectors
|
|
77
|
-
- Not visible errors: Scroll into view or wait for visibility
|
|
78
|
-
- Not enabled errors:
|
|
446
|
+
- Timeout errors: Add waitFor() or increase timeout, check for loading states
|
|
447
|
+
- Not found errors: Try different selectors, wait for element, or check if DOM changed
|
|
448
|
+
- Not visible errors: Scroll into view, dismiss overlays, or wait for visibility
|
|
449
|
+
- Not enabled/Disabled errors: Identify and complete prerequisites that enable the element
|
|
450
|
+
- Detached errors: Element removed from DOM, refetch or use different selector
|
|
451
|
+
- Covered/Blocked errors: Close overlays, modals, or popups blocking the element
|
|
452
|
+
|
|
453
|
+
ELEMENT STATE AWARENESS:
|
|
454
|
+
- Element disabled/inactive? → Identify and complete the prerequisite (fill required fields, check boxes, select options)
|
|
455
|
+
- Interacting with unavailable elements ALWAYS fails → Enable/prepare element state first
|
|
456
|
+
- Review your action history → Did you reverse a prerequisite? Complete it again before proceeding
|
|
457
|
+
- Different element states need different handling:
|
|
458
|
+
* Disabled → Complete prerequisites (validation, required fields, agreements)
|
|
459
|
+
* Hidden/Not visible → Scroll, dismiss overlays, or wait for visibility
|
|
460
|
+
* Detached → Element removed from DOM, may need navigation or different selector
|
|
461
|
+
* Loading → Wait for completion before interaction
|
|
79
462
|
|
|
80
463
|
TIMEOUT GUIDELINES:
|
|
81
464
|
- Only add explicit timeouts for slow operations (file uploads, large data loads)
|
|
@@ -93,10 +476,8 @@ exports.PROMPTS = {
|
|
|
93
476
|
Current State:
|
|
94
477
|
- URL: ${pageInfo.url}
|
|
95
478
|
- Title: ${pageInfo.title}
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
- Form Fields: ${pageInfo.formFields}
|
|
99
|
-
- All Elements: ${pageInfo.elements}
|
|
479
|
+
- Interactive Elements:
|
|
480
|
+
${pageInfo.formattedElements}
|
|
100
481
|
|
|
101
482
|
Previous Commands:
|
|
102
483
|
\`\`\`javascript
|
|
@@ -108,33 +489,136 @@ exports.PROMPTS = {
|
|
|
108
489
|
${errorContext}
|
|
109
490
|
|
|
110
491
|
Step to execute: "${stepDescription}"`
|
|
492
|
+
},
|
|
493
|
+
// Vision diagnostic analysis (supervisor reviewing screenshot)
|
|
494
|
+
VISION_DIAGNOSTIC_ANALYSIS: {
|
|
495
|
+
SYSTEM: 'You are a senior QA supervisor with vision capabilities. Analyze the screenshot AND DOM snapshot together to identify what went wrong and provide specific instructions with accurate selectors.',
|
|
496
|
+
USER: (stepDescription, pageInfo, previousCommands, attemptHistory, errorContext) => `Analyze screenshot + DOM snapshot to diagnose failures and provide specific instructions.
|
|
497
|
+
|
|
498
|
+
🎯 GOAL: "${stepDescription}"
|
|
499
|
+
|
|
500
|
+
📸 SCREENSHOT + 🌳 DOM SNAPSHOT:
|
|
501
|
+
Correlate visual elements in screenshot with DOM structure below.
|
|
502
|
+
|
|
503
|
+
**DOM Snapshot:**
|
|
504
|
+
- URL: ${pageInfo.url}
|
|
505
|
+
- Title: ${pageInfo.title}
|
|
506
|
+
- Interactive Elements:
|
|
507
|
+
${pageInfo.formattedElements}
|
|
508
|
+
|
|
509
|
+
**Previous Failed Attempts:**
|
|
510
|
+
${previousCommands || 'None'}
|
|
511
|
+
|
|
512
|
+
**Errors:**
|
|
513
|
+
${errorContext || 'None'}
|
|
514
|
+
|
|
515
|
+
**Your Task:**
|
|
516
|
+
1. Look at screenshot - identify target element visually
|
|
517
|
+
2. Look at DOM - find matching element in ARIA tree
|
|
518
|
+
3. Check if element has ID or data-testid (best selectors)
|
|
519
|
+
4. Provide EXACT selector from DOM
|
|
520
|
+
|
|
521
|
+
Respond with JSON:
|
|
522
|
+
{
|
|
523
|
+
"visualAnalysis": "I see...",
|
|
524
|
+
"rootCause": "Failed because...",
|
|
525
|
+
"specificInstructions": "Click element with [exact selector from DOM]...",
|
|
526
|
+
"recommendedApproach": "Use page.locator('[exact-attribute]')...",
|
|
527
|
+
"elementsFound": ["element with id='x'", "button[name='y']"],
|
|
528
|
+
"elementsNotFound": ["element worker looked for but doesn't exist"]
|
|
529
|
+
}`
|
|
530
|
+
},
|
|
531
|
+
// Playwright command generation with supervisor instructions
|
|
532
|
+
PLAYWRIGHT_COMMAND_WITH_SUPERVISOR: {
|
|
533
|
+
SYSTEM: 'You are a Playwright automation engineer. Your supervisor has analyzed a screenshot and provided specific instructions. Follow their instructions EXACTLY to generate the correct command.',
|
|
534
|
+
USER: (stepDescription, supervisorInstructions, supervisorAnalysis, elementsFound, elementsNotFound, pageInfo) => `Your supervisor has reviewed the screenshot and provided specific instructions. Follow them EXACTLY.
|
|
535
|
+
|
|
536
|
+
🎯 ORIGINAL GOAL: "${stepDescription}"
|
|
537
|
+
|
|
538
|
+
👔 SUPERVISOR'S VISUAL ANALYSIS:
|
|
539
|
+
${supervisorAnalysis}
|
|
540
|
+
|
|
541
|
+
📋 SUPERVISOR'S SPECIFIC INSTRUCTIONS:
|
|
542
|
+
${supervisorInstructions}
|
|
543
|
+
|
|
544
|
+
✅ ELEMENTS THAT EXIST (confirmed by supervisor from screenshot):
|
|
545
|
+
${elementsFound.length > 0 ? elementsFound.map((el, i) => `${i + 1}. ${el}`).join('\n') : 'None specified'}
|
|
546
|
+
|
|
547
|
+
❌ ELEMENTS THAT DON'T EXIST (confirmed absent from screenshot):
|
|
548
|
+
${elementsNotFound.length > 0 ? elementsNotFound.map((el, i) => `${i + 1}. ${el}`).join('\n') : 'None specified'}
|
|
549
|
+
|
|
550
|
+
**YOUR TASK:**
|
|
551
|
+
Generate ONE Playwright command that implements the supervisor's instructions EXACTLY.
|
|
552
|
+
|
|
553
|
+
**CRITICAL RULES:**
|
|
554
|
+
1. Follow supervisor's instructions to the letter
|
|
555
|
+
2. ONLY use elements from "ELEMENTS THAT EXIST" list
|
|
556
|
+
3. NEVER try to find elements from "ELEMENTS THAT DON'T EXIST" list
|
|
557
|
+
4. Use the exact selectors/strategies supervisor recommended
|
|
558
|
+
5. If supervisor said "don't verify X, check Y instead" - do exactly that
|
|
559
|
+
|
|
560
|
+
**Current DOM Context:**
|
|
561
|
+
- URL: ${pageInfo.url}
|
|
562
|
+
- Interactive Elements:
|
|
563
|
+
${pageInfo.formattedElements}
|
|
564
|
+
|
|
565
|
+
Respond with JSON:
|
|
566
|
+
{
|
|
567
|
+
"command": "await page.locator('#exact-selector').click();",
|
|
568
|
+
"reasoning": "Following supervisor's instruction to [what you're doing]"
|
|
569
|
+
}`
|
|
570
|
+
},
|
|
571
|
+
// Legacy vision command generation (kept for compatibility)
|
|
572
|
+
PLAYWRIGHT_COMMAND_WITH_VISION: {
|
|
573
|
+
SYSTEM: 'Analyze screenshot + DOM together. Correlate visual elements with DOM to generate accurate Playwright commands with precise selectors.',
|
|
574
|
+
USER: (stepDescription, pageInfo, previousCommands, attemptHistory, errorContext) => `Vision mode: Correlate screenshot with DOM to generate command.
|
|
575
|
+
|
|
576
|
+
🎯 GOAL: "${stepDescription}"
|
|
577
|
+
|
|
578
|
+
📸 SCREENSHOT + 🌳 DOM SNAPSHOT:
|
|
579
|
+
Correlate visual elements in screenshot with DOM structure below.
|
|
580
|
+
|
|
581
|
+
**DOM Snapshot:**
|
|
582
|
+
- URL: ${pageInfo.url}
|
|
583
|
+
- Title: ${pageInfo.title}
|
|
584
|
+
- Interactive Elements:
|
|
585
|
+
${pageInfo.formattedElements}
|
|
586
|
+
|
|
587
|
+
**Previous Failed Attempts:**
|
|
588
|
+
${previousCommands || 'None'}
|
|
589
|
+
|
|
590
|
+
**Errors:**
|
|
591
|
+
${errorContext || 'None'}
|
|
592
|
+
|
|
593
|
+
**Your Task:**
|
|
594
|
+
1. Look at screenshot - identify target element visually
|
|
595
|
+
2. Look at DOM - find matching element in ARIA tree
|
|
596
|
+
3. Check if element has ID or data-testid (best selectors)
|
|
597
|
+
4. Generate command with EXACT selector from DOM
|
|
598
|
+
|
|
599
|
+
Respond with JSON:
|
|
600
|
+
{
|
|
601
|
+
"command": "await page.locator('[exact-selector-from-dom]').click();",
|
|
602
|
+
"reasoning": "Visual element matches DOM element with [attribute]",
|
|
603
|
+
"visualInsights": "I see [element] in screenshot",
|
|
604
|
+
"failureRootCause": "Previous failed because [reason]",
|
|
605
|
+
"recommendedAlternative": "Use [strategy]"
|
|
606
|
+
}`
|
|
111
607
|
},
|
|
112
608
|
// Script parsing for AI repair
|
|
113
609
|
SCRIPT_PARSING: {
|
|
114
|
-
SYSTEM: '
|
|
115
|
-
USER: (script) => `
|
|
610
|
+
SYSTEM: 'Parse Playwright scripts into steps. Use existing // comments as step boundaries.',
|
|
611
|
+
USER: (script) => `Extract steps from this script.
|
|
116
612
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Script:
|
|
127
|
-
${script}
|
|
128
|
-
|
|
129
|
-
Return JSON object with steps array:
|
|
130
|
-
{
|
|
131
|
-
"steps": [
|
|
132
|
-
{
|
|
133
|
-
"description": "use existing comment if available, otherwise create meaningful description",
|
|
134
|
-
"code": "exact code from script - preserve all formatting and content"
|
|
135
|
-
}
|
|
136
|
-
]
|
|
137
|
-
}`
|
|
613
|
+
Find code INSIDE: test('...', async ({ page, browser, context }) => { ... })
|
|
614
|
+
|
|
615
|
+
Each // comment starts a new step. Use comment text (without //) as description.
|
|
616
|
+
Preserve code exactly.
|
|
617
|
+
|
|
618
|
+
Script:
|
|
619
|
+
${script}
|
|
620
|
+
|
|
621
|
+
Return JSON: {"steps": [{"description": "...", "code": "..."}, ...]}`
|
|
138
622
|
},
|
|
139
623
|
// Repair suggestion
|
|
140
624
|
REPAIR_SUGGESTION: {
|
|
@@ -149,8 +633,8 @@ exports.PROMPTS = {
|
|
|
149
633
|
Current Page State:
|
|
150
634
|
- URL: ${pageInfo.url}
|
|
151
635
|
- Title: ${pageInfo.title}
|
|
152
|
-
- Interactive Elements:
|
|
153
|
-
|
|
636
|
+
- Interactive Elements:
|
|
637
|
+
${pageInfo.formattedElements}
|
|
154
638
|
|
|
155
639
|
${failureHistory}
|
|
156
640
|
|
|
@@ -237,6 +721,47 @@ exports.PROMPTS = {
|
|
|
237
721
|
{
|
|
238
722
|
"script": "complete final script that can be pasted into the original file"
|
|
239
723
|
}`
|
|
724
|
+
},
|
|
725
|
+
// Script cleanup (minor adjustments only)
|
|
726
|
+
SCRIPT_CLEANUP: {
|
|
727
|
+
SYSTEM: 'You are a Playwright test script reviewer. Your job is to do MINOR cleanup only - remove obvious redundancies, but preserve the core structure and logic.',
|
|
728
|
+
USER: (script) => `Review this generated Playwright test script and make MINOR adjustments only.
|
|
729
|
+
|
|
730
|
+
SCRIPT:
|
|
731
|
+
${script}
|
|
732
|
+
|
|
733
|
+
YOUR TASK (MINOR ADJUSTMENTS ONLY):
|
|
734
|
+
1. Remove duplicate/redundant expect() assertions (e.g., same assertion repeated twice)
|
|
735
|
+
2. Remove duplicate step comments without code
|
|
736
|
+
3. Fix obvious formatting issues (inconsistent spacing, etc.)
|
|
737
|
+
4. Consolidate multiple identical assertions into one
|
|
738
|
+
5. Remove any obviously redundant waits or checks
|
|
739
|
+
|
|
740
|
+
DO NOT:
|
|
741
|
+
- Change the test logic or flow
|
|
742
|
+
- Remove legitimate assertions
|
|
743
|
+
- Restructure the code
|
|
744
|
+
- Change selectors
|
|
745
|
+
- Add new functionality
|
|
746
|
+
- Remove important waits
|
|
747
|
+
|
|
748
|
+
EXAMPLES:
|
|
749
|
+
|
|
750
|
+
❌ REMOVE redundancy:
|
|
751
|
+
await expect(page.getByText('Hello')).toBeVisible();
|
|
752
|
+
await expect(page.getByText('Hello')).toBeVisible(); // duplicate
|
|
753
|
+
|
|
754
|
+
✅ KEEP legitimate checks:
|
|
755
|
+
await expect(page.getByPlaceholder('Message...')).toBeEmpty();
|
|
756
|
+
await page.getByPlaceholder('Message...').fill('Hello');
|
|
757
|
+
await expect(page.getByPlaceholder('Message...')).toHaveValue('Hello'); // different checks
|
|
758
|
+
|
|
759
|
+
Return JSON:
|
|
760
|
+
{
|
|
761
|
+
"script": "cleaned script (or original if no changes needed)",
|
|
762
|
+
"changes": ["list of minor changes made, or empty array if none"],
|
|
763
|
+
"skipped": "reason if you chose not to make changes"
|
|
764
|
+
}`
|
|
240
765
|
}
|
|
241
766
|
};
|
|
242
767
|
//# sourceMappingURL=prompts.js.map
|