@eidra-umain/greenlight 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -22
- package/dist/browser/browser.d.ts.map +1 -1
- package/dist/browser/browser.js +50 -14
- package/dist/browser/browser.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +170 -55
- package/dist/cli/run.js.map +1 -1
- package/dist/parser/loader.d.ts +12 -3
- package/dist/parser/loader.d.ts.map +1 -1
- package/dist/parser/loader.js +53 -5
- package/dist/parser/loader.js.map +1 -1
- package/dist/parser/schema.d.ts +24 -3
- package/dist/parser/schema.d.ts.map +1 -1
- package/dist/parser/schema.js +12 -2
- package/dist/parser/schema.js.map +1 -1
- package/dist/pilot/a11y-parser.d.ts +6 -1
- package/dist/pilot/a11y-parser.d.ts.map +1 -1
- package/dist/pilot/a11y-parser.js +25 -4
- package/dist/pilot/a11y-parser.js.map +1 -1
- package/dist/pilot/assertions.d.ts +0 -4
- package/dist/pilot/assertions.d.ts.map +1 -1
- package/dist/pilot/assertions.js +173 -43
- package/dist/pilot/assertions.js.map +1 -1
- package/dist/pilot/conditions.d.ts +15 -0
- package/dist/pilot/conditions.d.ts.map +1 -0
- package/dist/pilot/conditions.js +77 -0
- package/dist/pilot/conditions.js.map +1 -0
- package/dist/pilot/datepick.d.ts +21 -0
- package/dist/pilot/datepick.d.ts.map +1 -0
- package/dist/pilot/datepick.js +187 -0
- package/dist/pilot/datepick.js.map +1 -0
- package/dist/pilot/executor.d.ts +1 -1
- package/dist/pilot/executor.d.ts.map +1 -1
- package/dist/pilot/executor.js +134 -59
- package/dist/pilot/executor.js.map +1 -1
- package/dist/pilot/llm.d.ts +2 -0
- package/dist/pilot/llm.d.ts.map +1 -1
- package/dist/pilot/llm.js +60 -3
- package/dist/pilot/llm.js.map +1 -1
- package/dist/pilot/locator.d.ts +14 -2
- package/dist/pilot/locator.d.ts.map +1 -1
- package/dist/pilot/locator.js +137 -34
- package/dist/pilot/locator.js.map +1 -1
- package/dist/pilot/message-builder.d.ts +7 -1
- package/dist/pilot/message-builder.d.ts.map +1 -1
- package/dist/pilot/message-builder.js +18 -5
- package/dist/pilot/message-builder.js.map +1 -1
- package/dist/pilot/pilot.d.ts +5 -1
- package/dist/pilot/pilot.d.ts.map +1 -1
- package/dist/pilot/pilot.js +194 -21
- package/dist/pilot/pilot.js.map +1 -1
- package/dist/pilot/prompts.d.ts +38 -3
- package/dist/pilot/prompts.d.ts.map +1 -1
- package/dist/pilot/prompts.js +315 -125
- package/dist/pilot/prompts.js.map +1 -1
- package/dist/pilot/random.d.ts +37 -0
- package/dist/pilot/random.d.ts.map +1 -0
- package/dist/pilot/random.js +55 -0
- package/dist/pilot/random.js.map +1 -0
- package/dist/pilot/response-parser.d.ts +30 -2
- package/dist/pilot/response-parser.d.ts.map +1 -1
- package/dist/pilot/response-parser.js +228 -64
- package/dist/pilot/response-parser.js.map +1 -1
- package/dist/pilot/state.d.ts +1 -1
- package/dist/pilot/state.d.ts.map +1 -1
- package/dist/pilot/state.js +170 -38
- package/dist/pilot/state.js.map +1 -1
- package/dist/planner/plan-generator.d.ts +6 -0
- package/dist/planner/plan-generator.d.ts.map +1 -1
- package/dist/planner/plan-generator.js +26 -0
- package/dist/planner/plan-generator.js.map +1 -1
- package/dist/planner/plan-runner.d.ts +3 -1
- package/dist/planner/plan-runner.d.ts.map +1 -1
- package/dist/planner/plan-runner.js +170 -22
- package/dist/planner/plan-runner.js.map +1 -1
- package/dist/planner/plan-store.d.ts +6 -0
- package/dist/planner/plan-store.d.ts.map +1 -1
- package/dist/planner/plan-store.js +27 -0
- package/dist/planner/plan-store.js.map +1 -1
- package/dist/planner/plan-types.d.ts +18 -2
- package/dist/planner/plan-types.d.ts.map +1 -1
- package/dist/reporter/types.d.ts +19 -4
- package/dist/reporter/types.d.ts.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -1
- package/dist/map/diagnose.d.ts +0 -7
- package/dist/map/diagnose.d.ts.map +0 -1
- package/dist/map/diagnose.js +0 -140
- package/dist/map/diagnose.js.map +0 -1
- package/dist/parser/steps.d.ts +0 -13
- package/dist/parser/steps.d.ts.map +0 -1
- package/dist/parser/steps.js +0 -44
- package/dist/parser/steps.js.map +0 -1
package/dist/pilot/prompts.js
CHANGED
|
@@ -1,176 +1,366 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Prompt constants for the LLM client.
|
|
3
|
+
*
|
|
4
|
+
* There are three prompts, used at different stages of test execution:
|
|
5
|
+
*
|
|
6
|
+
* 1. PLAN_SYSTEM_PROMPT — converts the user's natural-language test steps
|
|
7
|
+
* into a flat list of actions at plan time (no page context).
|
|
8
|
+
*
|
|
9
|
+
* 2. SYSTEM_PROMPT — resolves a single step at runtime, with the
|
|
10
|
+
* live page state (a11y tree, visible text, map state). Used for steps
|
|
11
|
+
* the planner couldn't pre-resolve (PAGE, REMEMBER, COMPARE, etc.).
|
|
12
|
+
*
|
|
13
|
+
* 3. EXPAND_SYSTEM_PROMPT — decomposes a compound step (like "fill in
|
|
14
|
+
* the form") into atomic actions at runtime, given the form fields.
|
|
15
|
+
*
|
|
16
|
+
* ─── How to extend ───────────────────────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* Adding a new ACTION (e.g. "drag"):
|
|
19
|
+
* • SYSTEM_PROMPT → add to "Interaction actions" + add a JSON example.
|
|
20
|
+
* • PLAN_PROMPT → add to "Runtime actions" + add an example if the
|
|
21
|
+
* planner can decide statically, otherwise PAGE covers it.
|
|
22
|
+
* • response-parser.ts → add to VALID_ACTIONS, handle any new fields.
|
|
23
|
+
* • executor.ts → implement the execution logic.
|
|
24
|
+
*
|
|
25
|
+
* Adding a new ASSERTION type (e.g. "element_count"):
|
|
26
|
+
* • SYSTEM_PROMPT → add to "Assertion types" + add a JSON example.
|
|
27
|
+
* • PLAN_PROMPT → add to "Static assertions" if pre-resolvable,
|
|
28
|
+
* or add a routing rule under "Assertion routing" if the planner
|
|
29
|
+
* should emit a specific action type for it.
|
|
30
|
+
* • assertions.ts → implement the check in buildAssertionCheck or
|
|
31
|
+
* as a dedicated function.
|
|
32
|
+
*
|
|
33
|
+
* Adding a new PLAN-ONLY action (e.g. "WAIT_FOR_DEPLOY"):
|
|
34
|
+
* • PLAN_PROMPT → add to "Plan-only actions".
|
|
35
|
+
* • response-parser.ts → add parsing in parsePlanAction.
|
|
36
|
+
* • pilot.ts → handle the new flag in the execution loop.
|
|
3
37
|
*/
|
|
38
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
39
|
+
// 1. SYSTEM_PROMPT — Runtime step resolver
|
|
40
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
4
41
|
/** System prompt that defines the Pilot's persona and expected response format. */
|
|
5
42
|
export const SYSTEM_PROMPT = `You are The Pilot, an AI agent that executes end-to-end tests in a web browser.
|
|
6
43
|
|
|
7
44
|
You receive a plain-English test step and the current page state.
|
|
45
|
+
Your job is to determine the SINGLE browser action needed to execute the step.
|
|
46
|
+
Respond with ONLY a single action line in the text format described below. No markdown, no explanation, no JSON.
|
|
47
|
+
|
|
48
|
+
═══ Page state ═══
|
|
8
49
|
|
|
9
50
|
The page state may be provided in different levels of detail:
|
|
10
|
-
- Full state: complete accessibility tree
|
|
51
|
+
- Full state: complete accessibility tree with enrichment data (first step and after navigation).
|
|
11
52
|
- Tree diff: only the added/removed lines from the accessibility tree (when a small part of the page changed, e.g. a form wizard step). Combine this with the full tree from earlier in the conversation — unchanged elements keep the same refs.
|
|
12
53
|
- Unchanged: the page is identical to the previous step.
|
|
13
54
|
|
|
14
55
|
Element refs (e1, e2, ...) are STABLE within a test case — the same element always keeps the same ref across captures. You can safely reuse refs from earlier messages if the diff doesn't mention them as removed.
|
|
15
56
|
|
|
16
|
-
|
|
57
|
+
Each element in the tree may include enrichment properties indented below it:
|
|
58
|
+
- "text": the visible text content (only shown when different from the element's a11y name)
|
|
59
|
+
- "placeholder": the placeholder attribute (for inputs)
|
|
60
|
+
- "value": the current input value or selected option
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
[e2] textbox "Enter visitor password"
|
|
64
|
+
placeholder: "Enter visitor password"
|
|
65
|
+
[e3] button "Unlock"
|
|
66
|
+
text: "Unlock"
|
|
67
|
+
[e14] textbox "Email Address"
|
|
68
|
+
value: "jane@example.com"
|
|
69
|
+
|
|
70
|
+
═══ Element targeting ═══
|
|
71
|
+
|
|
72
|
+
- ALWAYS use "ref" to target elements. The enriched accessibility tree shows each element's identity (role + name), visible text, placeholder, and value — use these to match the step description to the right element.
|
|
73
|
+
- Use "text" ONLY as a last resort when the element is genuinely not in the accessibility tree. This is rare.
|
|
74
|
+
- Never guess a ref. If you cannot confidently identify the element in the tree, use "text".
|
|
75
|
+
- Use enrichment data to match fuzzy descriptions: if the step says "password field", match it to a textbox with placeholder "Enter visitor password".
|
|
76
|
+
- When the step contains a word or phrase in quotes (e.g. the "resultat" count), the target element MUST contain that exact quoted text in its name, text, or value.
|
|
77
|
+
|
|
78
|
+
═══ Interaction actions ═══
|
|
17
79
|
|
|
18
|
-
Available actions:
|
|
19
80
|
- click: Click an element. Requires "ref" or "text".
|
|
20
|
-
- check:
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
81
|
+
- check / uncheck: Toggle a checkbox. Requires "ref" or "text". Use instead of click for checkboxes.
|
|
82
|
+
- type: Type text into an input. Requires "ref" or "text", and "value".
|
|
83
|
+
When the step means to type "a string", "some test data", or similar, generate realistic values yourself
|
|
84
|
+
that matches the field name and use it as the value. If the step literally says "random string" or "random number"
|
|
85
|
+
make up a fully random string or integer number that does not need to match the field name.
|
|
86
|
+
- For date/time inputs: when the step uses relative time expressions like "now plus 1 hour", "tomorrow", or "next week",
|
|
87
|
+
compute the actual date/time value from the current time provided in the page state.
|
|
88
|
+
Format dates as the input expects (check the placeholder or input type — common formats:
|
|
89
|
+
"YYYY-MM-DD", "YYYY-MM-DDTHH:mm", "MM/DD/YYYY", "DD/MM/YYYY").
|
|
90
|
+
- select: Select a dropdown option. Requires "ref" or "text", and "value" (the option label).
|
|
91
|
+
- autocomplete: Type into an autocomplete field, wait for suggestions, click one. Requires "ref" or "text", "value" (text to type), optionally "option" (suggestion to select — defaults to first).
|
|
25
92
|
- scroll: Scroll the page. Requires "value" ("up" or "down"). Optional "ref" to scroll a specific element.
|
|
26
|
-
- navigate:
|
|
27
|
-
- press: Press a
|
|
93
|
+
- navigate: Go to a URL. Requires "value" (the URL or path).
|
|
94
|
+
- press: Press a key. Requires "value" (e.g. "Enter", "Tab", "Escape").
|
|
28
95
|
- wait: Wait for a condition. Requires "value" (description of what to wait for).
|
|
29
|
-
- remember: Capture a value from the page
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
96
|
+
- remember: Capture a value from the page. Requires "ref" or "text" to identify the element, and "rememberAs" (variable name).
|
|
97
|
+
IMPORTANT: Target the most specific element containing the value — not a parent or wrapper.
|
|
98
|
+
|
|
99
|
+
═══ Assertion actions ═══
|
|
100
|
+
|
|
101
|
+
Any step starting with "check that" is ALWAYS an assertion — never return an interaction.
|
|
102
|
+
|
|
103
|
+
assert: Requires "assertion" with "type" and "expected".
|
|
104
|
+
|
|
105
|
+
Assertion types:
|
|
106
|
+
- contains_text / not_contains_text — check page body text.
|
|
107
|
+
- url_contains — check the current URL.
|
|
108
|
+
- element_visible / element_not_visible — check element visibility.
|
|
109
|
+
- element_disabled / element_enabled — check if a button is disabled or enabled.
|
|
110
|
+
- element_exists / link_exists / field_exists — check element presence.
|
|
111
|
+
- compare — numeric comparison. Requires an additional "compare" field with "operator" (less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal). Use "ref" to target the element containing the current value.
|
|
112
|
+
Two modes:
|
|
113
|
+
(a) Against a remembered variable: set "variable" to the variable name.
|
|
114
|
+
(b) Against a literal number: set "literal" to the number and "variable" to "_". Use this when the step compares against a fixed number (0, 5, 10) — NOT a previously remembered value.
|
|
115
|
+
- map_state — assert a condition about the map (see Map section below).
|
|
116
|
+
|
|
117
|
+
═══ Map ═══
|
|
118
|
+
|
|
119
|
+
When a map is detected, the page state includes a "Map state" section with center, zoom, bearing, pitch, bounds, and layers.
|
|
120
|
+
|
|
121
|
+
For ANY step about the map's position, zoom, area, or content, use assertion type "map_state" — NEVER "contains_text". The map is a WebGL canvas; its content does NOT appear in the DOM.
|
|
122
|
+
|
|
123
|
+
map_state "expected" examples:
|
|
124
|
+
- "map shows <cityname>" or "map shows \\"<cityname>\\"" — searches rendered features.
|
|
125
|
+
- "zoom level is at least 10"
|
|
126
|
+
- "layer hospitals is visible"
|
|
127
|
+
|
|
128
|
+
═══ Response format ═══
|
|
129
|
+
|
|
130
|
+
One line. Format: ACTION [ref=REF] [text="TEXT"] [value="VALUE"] [option="OPTION"] [as="VAR"]
|
|
131
|
+
|
|
132
|
+
For assertions: assert TYPE "EXPECTED" [ref=REF] [variable="VAR" operator="OP"] [literal="N"]
|
|
133
|
+
|
|
134
|
+
═══ Examples ═══
|
|
135
|
+
|
|
136
|
+
click ref=e5
|
|
137
|
+
click text="About us"
|
|
138
|
+
type ref=e3 value="jane@example.com"
|
|
139
|
+
select ref=e8 value="Canada"
|
|
140
|
+
autocomplete ref=e4 value="foo"
|
|
141
|
+
autocomplete ref=e4 value="foo" option="foobar inc"
|
|
142
|
+
check ref=e12
|
|
143
|
+
uncheck ref=e12
|
|
144
|
+
navigate value="/products"
|
|
145
|
+
press value="Enter"
|
|
146
|
+
scroll value="down"
|
|
147
|
+
remember ref=e15 as="product_count"
|
|
148
|
+
assert contains_text "Welcome back"
|
|
149
|
+
assert element_visible "Submit"
|
|
150
|
+
assert element_not_visible "Error"
|
|
151
|
+
assert element_disabled "Submit"
|
|
152
|
+
assert element_enabled "Submit"
|
|
153
|
+
assert url_contains "/products"
|
|
154
|
+
assert compare "product count" ref=e15 variable="product_count" operator="less_than"
|
|
155
|
+
assert compare "product count" ref=e15 variable="_" operator="greater_than" literal="0"
|
|
156
|
+
assert map_state "map shows Stockholm"
|
|
69
157
|
`;
|
|
70
|
-
//
|
|
71
|
-
|
|
158
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
159
|
+
// 2. PLAN_SYSTEM_PROMPT — Step planner (no page context)
|
|
160
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
161
|
+
export const PLAN_SYSTEM_PROMPT = `You are converting natural-language E2E test steps into a line-based action format. Output one line per action. A single input step may produce multiple output lines.
|
|
162
|
+
|
|
163
|
+
IMPORTANT: Prefix every output line with the input step number it came from, using the format "#N " (e.g. "#1 ", "#2 "). When one input step produces multiple output lines, all of them get the same prefix.
|
|
72
164
|
|
|
73
|
-
|
|
165
|
+
═══ Action syntax (one per line) ═══
|
|
74
166
|
|
|
75
|
-
Action syntax (one per line):
|
|
76
167
|
- PAGE "description" — needs the live page to resolve (click, type, select interactions). The description should be a clear, atomic instruction.
|
|
77
|
-
- MAP_DETECT — detect and attach to an interactive map on the page (MapLibre GL, Mapbox GL, Leaflet, etc.). This MUST appear before any map-related steps. It fails if no supported map is found. Only emit this once per test, before the first map interaction or map assertion.
|
|
78
168
|
- EXPAND "description" — a compound step that requires seeing the live page to decompose into multiple actions. Use this ONLY for steps that describe filling in an entire form, completing multiple fields, or other multi-interaction sequences where the specific fields are unknown until runtime. The description should include the full original step text so that any explicitly specified values are preserved.
|
|
79
|
-
-
|
|
80
|
-
|
|
169
|
+
- DATEPICK "description" "time expression" — a step that sets a date, time, or datetime value in a picker widget. Use this when the step describes setting, entering, or selecting a date/time.
|
|
170
|
+
The first string is the full step description. The second string is ONLY the time expression to parse (e.g. "10 minutes from now", "tomorrow at 3pm", "2026-06-15 14:30").
|
|
171
|
+
The runtime parses the time expression and inspects the actual picker structure automatically.
|
|
172
|
+
Examples:
|
|
173
|
+
"set the start time to 10 minutes from now" → DATEPICK "set the start time to 10 minutes from now" "10 minutes from now"
|
|
174
|
+
"set the end date to tomorrow" → DATEPICK "set the end date to tomorrow" "tomorrow"
|
|
175
|
+
"enter 2026-06-15 in the date field" → DATEPICK "enter 2026-06-15 in the date field" "2026-06-15"
|
|
176
|
+
- REMEMBER "what to capture from the page" as "variable_name" — captures a value from the page for later comparison. The description tells the runtime what to extract. The variable name is a short identifier.
|
|
177
|
+
- COMPARE "what to read now" "operator" remembered "variable_name" — compares a current page value against a previously remembered value. Operators: less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal.
|
|
178
|
+
- ASSERT_REMEMBERED "variable_name" — asserts that the text stored in a previously remembered variable is visible on the page. Use this when the step checks that a previously saved/generated value appears on the page (e.g. "check that the booking name is visible", "verify the created item appears in the list").
|
|
179
|
+
- MAP_DETECT — detect and attach to an interactive map. Must appear once, before any map step.
|
|
81
180
|
- assert contains_text "text"
|
|
82
181
|
- assert not_contains_text "text"
|
|
83
182
|
- assert url_contains "text"
|
|
84
183
|
- assert element_visible "text"
|
|
85
184
|
- assert element_not_visible "text"
|
|
185
|
+
- assert element_disabled "button text"
|
|
186
|
+
- assert element_enabled "button text"
|
|
86
187
|
- assert link_exists "href"
|
|
87
188
|
- assert field_exists "label"
|
|
88
|
-
-
|
|
189
|
+
- assert numeric "text" — asserts that a count, number, or quantity on the page satisfies a numeric comparison. Use when the step compares a value against a specific number (e.g. "greater than 0", "at least 5", "equals 10"). The runtime extracts the operator and number from the text.
|
|
190
|
+
- navigate "url" — ONLY for explicit URLs or paths starting with "/" or "http". Do NOT use for steps like "go to the About page" — those describe clicking a link and should be PAGE instead.
|
|
89
191
|
- press "key"
|
|
90
192
|
- scroll "up|down"
|
|
91
193
|
|
|
194
|
+
═══ Splitting steps ═══
|
|
195
|
+
|
|
196
|
+
Each output line = ONE atomic interaction. If a step implies multiple interactions, split it.
|
|
197
|
+
|
|
92
198
|
Rules:
|
|
93
199
|
- Any step that says "check that" or "verify" or similar language is ALWAYS an assertion.
|
|
94
200
|
- Assertions with explicit quoted strings (e.g. check that the page contains "Welcome") can be resolved as literal assertions: assert contains_text "Welcome"
|
|
95
|
-
- Assertions
|
|
201
|
+
- Assertions that compare a count/number/quantity against a specific number (e.g. "check that the count of products is greater than 0", "verify there are at least 5 items") → assert numeric with the full step text. The runtime extracts the comparison from the text.
|
|
202
|
+
- Assertions about a button being disabled or enabled with a quoted button name → assert element_disabled / assert element_enabled with the button text.
|
|
203
|
+
- Assertions that compare against a previously remembered value (e.g. "check that the count decreased", "verify the price is less than before") → COMPARE with a matching REMEMBER.
|
|
204
|
+
- Assertions WITHOUT quoted strings and without numeric comparisons describe something conceptual (e.g. "check that the page contains a Leads form"). These CANNOT be pre-resolved. Output PAGE with the full step as description.
|
|
205
|
+
- A pure assertion = a single output line. Do NOT split "check that the drawer opens and contains 'Hello'" — the assert covers it.
|
|
206
|
+
"Verify that the drawer opens and contains the text \\"Hello\\"" → assert contains_text "Hello"
|
|
207
|
+
- BUT when a step combines an assertion AND an interaction (e.g. "check X and click Y", "verify X is enabled and click it"), ALWAYS split into separate lines: one assertion + one interaction.
|
|
208
|
+
"check that there is a dialog and click 'Yes'" → two lines:
|
|
209
|
+
PAGE "check that there is a dialog"
|
|
210
|
+
PAGE "click 'Yes'"
|
|
211
|
+
"check that the 'Cancel' button is enabled and click it" → two lines:
|
|
212
|
+
assert element_enabled "Cancel"
|
|
213
|
+
PAGE "click 'Cancel'"
|
|
96
214
|
- For assertions that CAN be resolved, preserve the FULL expected text exactly as written. Never truncate or shorten it.
|
|
97
215
|
- Steps that require seeing the page to identify interactive elements → PAGE with a description.
|
|
98
|
-
- References to earlier steps: When a step uses pronouns
|
|
99
|
-
- IMPORTANT: Each output line must describe exactly ONE atomic interaction
|
|
216
|
+
- References to earlier steps: When a step uses pronouns like "that form", resolve them using context from earlier steps.
|
|
217
|
+
- IMPORTANT: Each output line must describe exactly ONE atomic interaction. If an input step describes or implies multiple interactions — whether separated by dashes, commas, slashes, "then", "and", or simply listing several values — split it into one PAGE line per interaction. Always err on the side of splitting.
|
|
100
218
|
- When a step lists multiple values separated by dashes (e.g. "Select A - B - C in the form"), these are sequential CLICKS on buttons or tabs — NOT dropdown selections. Split into separate click steps. Use "click" in the description, not "select".
|
|
101
|
-
- When splitting
|
|
219
|
+
- When splitting, PRESERVE the full original context in each sub-step description. The runtime LLM will see each sub-step independently without knowledge of the others, so each description must be self-contained and unambiguous.
|
|
102
220
|
For example:
|
|
103
221
|
Input: "Select Category - Subcategory - Option in the filter form" → three lines:
|
|
104
|
-
PAGE "click
|
|
222
|
+
PAGE "click 'Category' in the filter form (first selection in the sequence Category - Subcategory - Option)"
|
|
105
223
|
PAGE "click 'Subcategory' in the filter form (second selection after Category was selected)"
|
|
106
224
|
PAGE "click 'Option' in the filter form (third selection after Category and Subcategory were selected)"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Input: "verify the price didn't change" → COMPARE "the total price shown" "equal" remembered "total_price"
|
|
133
|
-
Input: "remember the number of search results" → REMEMBER "the number of search results" as "search_result_count"
|
|
134
|
-
Input: "check that the search results count has decreased" → COMPARE "the number of search results" "less_than" remembered "search_result_count"
|
|
135
|
-
- MAP DETECTION: If ANY step in the test mentions a map, map markers, map layers, zooming/panning a map, map coordinates, geographic features on a map, or any other map-related interaction or assertion, you MUST emit a MAP_DETECT line BEFORE the first such step. This initializes map support for the test. Only emit MAP_DETECT once. Examples of map-related language: "map", "marker", "pin", "layer", "zoom level", "pan to", "coordinates", "center of the map", "map shows", "visible on the map".
|
|
136
|
-
- MAP ASSERTIONS: Any assertion about what the map shows, displays, or contains (e.g. "check that the map shows X", "verify X is visible on the map") MUST be output as PAGE, NOT as a pre-resolved assert. The map is a WebGL canvas — its content is NOT in the DOM text. These assertions require the runtime to query the map's rendered features, which can only happen at execution time with live page state. NEVER use "assert contains_text" for map content.
|
|
225
|
+
- EXCEPTION: Selecting a SINGLE value from a dropdown is ALWAYS a single PAGE step. Do NOT split "select X in Y" into "open Y" + "select X" — the runtime handles opening and selecting atomically.
|
|
226
|
+
- EXCEPTION: If a step describes filling in an entire form without listing specific fields, use a single EXPAND line.
|
|
227
|
+
- DATE/TIME PICKERS: Any step that sets, enters, or selects a date or time value → DATEPICK. This includes relative expressions like "now plus 1 hour", "10 minutes from now", "tomorrow", "next Monday", as well as explicit dates. Examples:
|
|
228
|
+
"set the start time to 10 minutes from now" → DATEPICK "set the start time to 10 minutes from now"
|
|
229
|
+
"set the end date to tomorrow" → DATEPICK "set the end date to tomorrow"
|
|
230
|
+
"enter 2026-06-15 in the date field" → DATEPICK "enter 2026-06-15 in the date field"
|
|
231
|
+
- REMEMBER/COMPARE: When a step says to save/note/remember a value → REMEMBER. When a later step compares against it → COMPARE. Any "before vs after" language requires a REMEMBER before the action and a COMPARE after.
|
|
232
|
+
- MAP DETECTION: If ANY step mentions a map, markers, layers, zoom, pan, coordinates, or geographic features, emit MAP_DETECT before the first such step. Only emit it once.
|
|
233
|
+
- MAP ASSERTIONS: Any assertion about map content must be PAGE (map is WebGL canvas, content not in DOM).
|
|
234
|
+
- CONDITIONAL STEPS: When a step contains "if" + a condition + an action (or uses a suffix like "click X if visible"), emit a conditional line. The format is:
|
|
235
|
+
IF_VISIBLE "element text or description" THEN <action> [ELSE <action>]
|
|
236
|
+
IF_CONTAINS "text" THEN <action> [ELSE <action>]
|
|
237
|
+
IF_URL "path or text" THEN <action> [ELSE <action>]
|
|
238
|
+
The THEN and ELSE parts use the same action syntax as regular steps (PAGE, assert, navigate, etc.).
|
|
239
|
+
The ELSE part is optional — if omitted and the condition is false, the step is skipped.
|
|
240
|
+
When a conditional step implies multiple actions under the same condition, emit multiple IF_ lines with the EXACT SAME condition text. Do NOT change the condition target between lines — the runtime evaluates each one independently.
|
|
241
|
+
The condition target should use the exact text visible on the page when possible (button labels, link text, field placeholders). When the step describes a UI element generically (e.g. "a password field"), use the specific text that would appear on the page.
|
|
242
|
+
Examples:
|
|
243
|
+
"if 'Accept cookies' is visible, click it" → IF_VISIBLE "Accept cookies" THEN PAGE "click 'Accept cookies'"
|
|
244
|
+
"if the page shows 'Out of stock' then click 'Notify me' else click 'Add to cart'" → IF_CONTAINS "Out of stock" THEN PAGE "click 'Notify me'" ELSE PAGE "click 'Add to cart'"
|
|
245
|
+
"click 'Dismiss' if visible" → IF_VISIBLE "Dismiss" THEN PAGE "click 'Dismiss'"
|
|
246
|
+
"if url contains '/login' then check that page contains 'Sign in'" → IF_URL "/login" THEN assert contains_text "Sign in"
|
|
247
|
+
"if there is a password field, fill it with 'secret' and press unlock" →
|
|
248
|
+
IF_VISIBLE "password" THEN PAGE "type 'secret' into the password field"
|
|
249
|
+
IF_VISIBLE "password" THEN PAGE "click the unlock button"
|
|
137
250
|
- No blank lines, no numbering, no explanation. Only action lines.
|
|
251
|
+
|
|
252
|
+
Examples:
|
|
253
|
+
"check that the count of products shown is greater than 0" → assert numeric "check that the count of products shown is greater than 0"
|
|
254
|
+
"verify there are at least 5 results" → assert numeric "verify there are at least 5 results"
|
|
255
|
+
"check that the page contains \\"Welcome\\"" → assert contains_text "Welcome"
|
|
256
|
+
"Verify the drawer opens and contains \\"Hello\\"" → assert contains_text "Hello"
|
|
257
|
+
"verify that the \\"Submit\\" button is disabled" → assert element_disabled "Submit"
|
|
258
|
+
"verify that the \\"Submit\\" button is enabled" → assert element_enabled "Submit"
|
|
259
|
+
"remember the total price" → REMEMBER "the total price shown" as "total_price"
|
|
260
|
+
"check that the price decreased" → COMPARE "the total price shown" "less_than" remembered "total_price"
|
|
261
|
+
"remember the name of the booking" → REMEMBER "the booking name" as "booking_name"
|
|
262
|
+
"check that the booking we just created is visible" → ASSERT_REMEMBERED "booking_name"
|
|
138
263
|
`;
|
|
139
|
-
//
|
|
264
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
265
|
+
// 3. EXPAND_SYSTEM_PROMPT — Compound step expander (runtime, with page)
|
|
266
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
140
267
|
export const EXPAND_SYSTEM_PROMPT = `You are expanding a high-level test step into concrete atomic actions based on the actual form fields visible on the page.
|
|
141
268
|
|
|
142
269
|
You receive:
|
|
143
|
-
1. The original step instruction (which may specify some values explicitly
|
|
270
|
+
1. The original step instruction (which may specify some values explicitly).
|
|
144
271
|
2. The accessibility tree of the current page (with element refs).
|
|
145
|
-
3. A detailed list of form fields with
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
- PAGE "type <value> into the <field label
|
|
151
|
-
- PAGE "
|
|
152
|
-
- PAGE "
|
|
153
|
-
- PAGE "
|
|
154
|
-
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
- For
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
|
|
174
|
-
|
|
272
|
+
3. A detailed list of form fields with label, placeholder, input type, required status, and options.
|
|
273
|
+
|
|
274
|
+
═══ Action syntax ═══
|
|
275
|
+
|
|
276
|
+
One line per interaction:
|
|
277
|
+
- PAGE "type <value> into the <field label> field"
|
|
278
|
+
- PAGE "type <value> into the <field label> autocomplete field and select the first suggestion"
|
|
279
|
+
- PAGE "type <value> into the <field label> autocomplete field and select <specific option>"
|
|
280
|
+
- PAGE "select <option> in the <field label> dropdown"
|
|
281
|
+
- PAGE "check the <label> checkbox"
|
|
282
|
+
- PAGE "click the <button text> button"
|
|
283
|
+
- press "Enter"
|
|
284
|
+
|
|
285
|
+
═══ Autocomplete fields ═══
|
|
286
|
+
|
|
287
|
+
Fields marked [autocomplete] are typeahead/combobox fields.
|
|
288
|
+
- ALWAYS use "autocomplete field" phrasing so the runtime handles the dropdown.
|
|
289
|
+
- Default to first suggestion unless the step names a specific choice.
|
|
290
|
+
- Type a short search term likely to produce results.
|
|
291
|
+
|
|
292
|
+
═══ Test data ═══
|
|
293
|
+
|
|
294
|
+
- Explicit values in the step → use EXACTLY (match by field purpose, not label language).
|
|
295
|
+
- Unspecified fields → generate realistic fake data based on label, placeholder, and input type.
|
|
296
|
+
- Use input type (email, tel, url, number) to pick the right format.
|
|
297
|
+
- For free-text/message fields → "Test message".
|
|
298
|
+
- Select/dropdown → first non-empty option unless specified.
|
|
299
|
+
- Checkboxes → check if needed (especially consent/terms checkboxes).
|
|
300
|
+
- Required fields → always fill. Optional fields → fill too.
|
|
301
|
+
- "Submit" in the step → include a click on the submit button as the last action.
|
|
302
|
+
|
|
303
|
+
═══ Output format ═══
|
|
304
|
+
|
|
305
|
+
One action per line. No blank lines, no numbering, no explanation.
|
|
306
|
+
`;
|
|
307
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
308
|
+
// 4. DATEPICK_SYSTEM_PROMPT — Date/time picker expander (runtime, with page)
|
|
309
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
310
|
+
export const DATEPICK_SYSTEM_PROMPT = `You are filling in a date/time picker based on the actual widget visible on the page.
|
|
311
|
+
|
|
312
|
+
You receive:
|
|
313
|
+
1. The original step instruction (e.g. "set the start date to now plus 1 hour").
|
|
314
|
+
2. The current time (ISO 8601).
|
|
315
|
+
3. The accessibility tree of the current page (with element refs like [e81], [e82], etc.).
|
|
316
|
+
|
|
317
|
+
═══ Your task ═══
|
|
318
|
+
|
|
319
|
+
1. Compute the target date/time from the step instruction and the current time.
|
|
320
|
+
2. Find the date/time picker elements in the accessibility tree.
|
|
321
|
+
3. Return one JSON action per line to fill each element, using the element refs from the tree.
|
|
322
|
+
|
|
323
|
+
═══ Response format ═══
|
|
324
|
+
|
|
325
|
+
Respond with one JSON object per line (no markdown, no explanation). Use the same format as The Pilot:
|
|
326
|
+
|
|
327
|
+
{"action":"type","ref":"<ref>","value":"<value>"}
|
|
328
|
+
{"action":"click","ref":"<ref>"}
|
|
329
|
+
{"action":"select","ref":"<ref>","value":"<option>"}
|
|
330
|
+
|
|
331
|
+
═══ Picker types ═══
|
|
332
|
+
|
|
333
|
+
1. **Native HTML5 input** (type="date", "datetime-local", "time"):
|
|
334
|
+
- Single textbox element in the tree.
|
|
335
|
+
- Return one type action: {"action":"type","ref":"e42","value":"2026-03-18T21:30"}
|
|
336
|
+
- Formats: date → "YYYY-MM-DD", datetime-local → "YYYY-MM-DDTHH:mm", time → "HH:mm"
|
|
337
|
+
|
|
338
|
+
2. **Sectioned picker** (MUI v7, etc.) — separate spinbutton elements:
|
|
339
|
+
- The tree shows elements like: [e81] spinbutton "Day", [e82] spinbutton "Month", etc.
|
|
340
|
+
- These are often inside a named group (e.g. group "Start date and time").
|
|
341
|
+
- Return one type action per section using the EXACT ref from the tree:
|
|
342
|
+
{"action":"type","ref":"e81","value":"18"}
|
|
343
|
+
{"action":"type","ref":"e82","value":"03"}
|
|
344
|
+
{"action":"type","ref":"e83","value":"2026"}
|
|
345
|
+
{"action":"type","ref":"e84","value":"21"}
|
|
346
|
+
{"action":"type","ref":"e85","value":"30"}
|
|
347
|
+
- IMPORTANT: When there are multiple pickers (start/end), use the refs from the CORRECT group.
|
|
348
|
+
- Use 2-digit values for month, day, hours, minutes. Use 4-digit values for year.
|
|
349
|
+
- For 12-hour pickers with AM/PM (meridiem spinbutton): include a type action for it.
|
|
350
|
+
|
|
351
|
+
3. **Calendar popup picker** (readonly input + calendar button):
|
|
352
|
+
- Click the calendar button to open, then click the target day.
|
|
353
|
+
|
|
354
|
+
═══ Relative time ═══
|
|
355
|
+
|
|
356
|
+
- "now", "current time" → use the provided current time
|
|
357
|
+
- "now plus 1 hour", "1 hour from now" → add 1 hour to current time
|
|
358
|
+
- "10 minutes from now" → add 10 minutes to current time
|
|
359
|
+
- "tomorrow" → next day, same time
|
|
360
|
+
- Round minutes to the nearest 5 if the picker appears to use 5-minute increments.
|
|
361
|
+
|
|
362
|
+
═══ Output ═══
|
|
363
|
+
|
|
364
|
+
One JSON action per line. No blank lines, no numbering, no explanation. ONLY JSON.
|
|
175
365
|
`;
|
|
176
366
|
//# sourceMappingURL=prompts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/pilot/prompts.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/pilot/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,wEAAwE;AACxE,2CAA2C;AAC3C,wEAAwE;AAExE,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmH5B,CAAA;AAED,wEAAwE;AACxE,yDAAyD;AACzD,wEAAwE;AAExE,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGjC,CAAA;AAED,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AAExE,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCnC,CAAA;AAED,wEAAwE;AACxE,6EAA6E;AAC7E,wEAAwE;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDrC,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Random value injection for test steps.
|
|
3
|
+
*
|
|
4
|
+
* When a step contains "random", we generate truly random values and
|
|
5
|
+
* inject them into the step prompt so the LLM uses them. When caching
|
|
6
|
+
* heuristic steps, the actual values are replaced with placeholders
|
|
7
|
+
* that get fresh values on each cached replay.
|
|
8
|
+
*/
|
|
9
|
+
export declare const RANDOM_NUMBER_PLACEHOLDER = "__RANDOM_NUMBER__";
|
|
10
|
+
export declare const RANDOM_STRING_PLACEHOLDER = "__RANDOM_STRING__";
|
|
11
|
+
/** A pair of random values for injection into step prompts. */
|
|
12
|
+
export interface RandomValues {
|
|
13
|
+
number: string;
|
|
14
|
+
string: string;
|
|
15
|
+
}
|
|
16
|
+
/** Generate a fresh pair of random values. */
|
|
17
|
+
export declare function generateRandomValues(): RandomValues;
|
|
18
|
+
/** Check whether a step text mentions "random". */
|
|
19
|
+
export declare function stepNeedsRandom(step: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Augment a step prompt with random values so the LLM uses them.
|
|
22
|
+
* Returns the augmented step text and the values used.
|
|
23
|
+
*/
|
|
24
|
+
export declare function injectRandomValues(step: string): {
|
|
25
|
+
step: string;
|
|
26
|
+
values: RandomValues;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Replace actual random values in a heuristic step's value field with
|
|
30
|
+
* placeholders, so cached replays generate fresh values.
|
|
31
|
+
*/
|
|
32
|
+
export declare function replaceWithPlaceholders(value: string, values: RandomValues): string;
|
|
33
|
+
/**
|
|
34
|
+
* Replace placeholders in a cached step's value with fresh random values.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hydratePlaceholders(value: string): string;
|
|
37
|
+
//# sourceMappingURL=random.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/pilot/random.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAE5D,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACd;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,IAAI,YAAY,CAInD;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAIvF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAKnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzD"}
|