@eidra-umain/greenlight 0.1.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 +391 -0
- package/dist/browser/browser.d.ts +24 -0
- package/dist/browser/browser.d.ts.map +1 -0
- package/dist/browser/browser.js +44 -0
- package/dist/browser/browser.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +140 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/run.d.ts +9 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +277 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +107 -0
- package/dist/config.js.map +1 -0
- package/dist/globals.d.ts +21 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +24 -0
- package/dist/globals.js.map +1 -0
- package/dist/parser/loader.d.ts +7 -0
- package/dist/parser/loader.d.ts.map +1 -0
- package/dist/parser/loader.js +43 -0
- package/dist/parser/loader.js.map +1 -0
- package/dist/parser/schema.d.ts +42 -0
- package/dist/parser/schema.d.ts.map +1 -0
- package/dist/parser/schema.js +33 -0
- package/dist/parser/schema.js.map +1 -0
- package/dist/parser/steps.d.ts +13 -0
- package/dist/parser/steps.d.ts.map +1 -0
- package/dist/parser/steps.js +44 -0
- package/dist/parser/steps.js.map +1 -0
- package/dist/parser/variables.d.ts +18 -0
- package/dist/parser/variables.d.ts.map +1 -0
- package/dist/parser/variables.js +44 -0
- package/dist/parser/variables.js.map +1 -0
- package/dist/pilot/a11y-parser.d.ts +26 -0
- package/dist/pilot/a11y-parser.d.ts.map +1 -0
- package/dist/pilot/a11y-parser.js +195 -0
- package/dist/pilot/a11y-parser.js.map +1 -0
- package/dist/pilot/assertions.d.ts +30 -0
- package/dist/pilot/assertions.d.ts.map +1 -0
- package/dist/pilot/assertions.js +219 -0
- package/dist/pilot/assertions.js.map +1 -0
- package/dist/pilot/checkbox.d.ts +12 -0
- package/dist/pilot/checkbox.d.ts.map +1 -0
- package/dist/pilot/checkbox.js +104 -0
- package/dist/pilot/checkbox.js.map +1 -0
- package/dist/pilot/executor.d.ts +17 -0
- package/dist/pilot/executor.d.ts.map +1 -0
- package/dist/pilot/executor.js +462 -0
- package/dist/pilot/executor.js.map +1 -0
- package/dist/pilot/form-fields.d.ts +34 -0
- package/dist/pilot/form-fields.d.ts.map +1 -0
- package/dist/pilot/form-fields.js +139 -0
- package/dist/pilot/form-fields.js.map +1 -0
- package/dist/pilot/llm.d.ts +49 -0
- package/dist/pilot/llm.d.ts.map +1 -0
- package/dist/pilot/llm.js +188 -0
- package/dist/pilot/llm.js.map +1 -0
- package/dist/pilot/locator.d.ts +58 -0
- package/dist/pilot/locator.d.ts.map +1 -0
- package/dist/pilot/locator.js +248 -0
- package/dist/pilot/locator.js.map +1 -0
- package/dist/pilot/message-builder.d.ts +31 -0
- package/dist/pilot/message-builder.d.ts.map +1 -0
- package/dist/pilot/message-builder.js +112 -0
- package/dist/pilot/message-builder.js.map +1 -0
- package/dist/pilot/network.d.ts +23 -0
- package/dist/pilot/network.d.ts.map +1 -0
- package/dist/pilot/network.js +92 -0
- package/dist/pilot/network.js.map +1 -0
- package/dist/pilot/pilot.d.ts +27 -0
- package/dist/pilot/pilot.d.ts.map +1 -0
- package/dist/pilot/pilot.js +249 -0
- package/dist/pilot/pilot.js.map +1 -0
- package/dist/pilot/prompts.d.ts +8 -0
- package/dist/pilot/prompts.d.ts.map +1 -0
- package/dist/pilot/prompts.js +163 -0
- package/dist/pilot/prompts.js.map +1 -0
- package/dist/pilot/providers/anthropic.d.ts +6 -0
- package/dist/pilot/providers/anthropic.d.ts.map +1 -0
- package/dist/pilot/providers/anthropic.js +45 -0
- package/dist/pilot/providers/anthropic.js.map +1 -0
- package/dist/pilot/providers/gemini.d.ts +6 -0
- package/dist/pilot/providers/gemini.d.ts.map +1 -0
- package/dist/pilot/providers/gemini.js +55 -0
- package/dist/pilot/providers/gemini.js.map +1 -0
- package/dist/pilot/providers/index.d.ts +10 -0
- package/dist/pilot/providers/index.d.ts.map +1 -0
- package/dist/pilot/providers/index.js +25 -0
- package/dist/pilot/providers/index.js.map +1 -0
- package/dist/pilot/providers/openai-compatible.d.ts +7 -0
- package/dist/pilot/providers/openai-compatible.d.ts.map +1 -0
- package/dist/pilot/providers/openai-compatible.js +34 -0
- package/dist/pilot/providers/openai-compatible.js.map +1 -0
- package/dist/pilot/providers/types.d.ts +12 -0
- package/dist/pilot/providers/types.d.ts.map +1 -0
- package/dist/pilot/providers/types.js +2 -0
- package/dist/pilot/providers/types.js.map +1 -0
- package/dist/pilot/response-parser.d.ts +31 -0
- package/dist/pilot/response-parser.d.ts.map +1 -0
- package/dist/pilot/response-parser.js +188 -0
- package/dist/pilot/response-parser.js.map +1 -0
- package/dist/pilot/state.d.ts +19 -0
- package/dist/pilot/state.d.ts.map +1 -0
- package/dist/pilot/state.js +67 -0
- package/dist/pilot/state.js.map +1 -0
- package/dist/pilot/trace.d.ts +16 -0
- package/dist/pilot/trace.d.ts.map +1 -0
- package/dist/pilot/trace.js +117 -0
- package/dist/pilot/trace.js.map +1 -0
- package/dist/planner/hasher.d.ts +14 -0
- package/dist/planner/hasher.d.ts.map +1 -0
- package/dist/planner/hasher.js +21 -0
- package/dist/planner/hasher.js.map +1 -0
- package/dist/planner/plan-generator.d.ts +23 -0
- package/dist/planner/plan-generator.d.ts.map +1 -0
- package/dist/planner/plan-generator.js +56 -0
- package/dist/planner/plan-generator.js.map +1 -0
- package/dist/planner/plan-runner.d.ts +16 -0
- package/dist/planner/plan-runner.d.ts.map +1 -0
- package/dist/planner/plan-runner.js +375 -0
- package/dist/planner/plan-runner.js.map +1 -0
- package/dist/planner/plan-store.d.ts +22 -0
- package/dist/planner/plan-store.d.ts.map +1 -0
- package/dist/planner/plan-store.js +71 -0
- package/dist/planner/plan-store.js.map +1 -0
- package/dist/planner/plan-types.d.ts +64 -0
- package/dist/planner/plan-types.d.ts.map +1 -0
- package/dist/planner/plan-types.js +7 -0
- package/dist/planner/plan-types.js.map +1 -0
- package/dist/reporter/types.d.ts +130 -0
- package/dist/reporter/types.d.ts.map +1 -0
- package/dist/reporter/types.js +5 -0
- package/dist/reporter/types.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion execution — validates page state against expected conditions.
|
|
3
|
+
*/
|
|
4
|
+
import { globals } from "../globals.js";
|
|
5
|
+
import { resolveActionTarget } from "./locator.js";
|
|
6
|
+
/**
|
|
7
|
+
* Poll an assertion until it passes or the timeout expires.
|
|
8
|
+
* This handles cases where the page is still updating (e.g. dropdown
|
|
9
|
+
* appearing after typing, navigation completing, etc.).
|
|
10
|
+
*/
|
|
11
|
+
export async function pollAssertion(check, timeoutMs = 5000) {
|
|
12
|
+
const deadline = performance.now() + timeoutMs;
|
|
13
|
+
let lastError = new Error("Assertion timed out");
|
|
14
|
+
while (performance.now() < deadline) {
|
|
15
|
+
try {
|
|
16
|
+
await check();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
21
|
+
}
|
|
22
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
23
|
+
}
|
|
24
|
+
throw lastError;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Execute an assertion against the current page state.
|
|
28
|
+
* Positive assertions (checking something exists/appears) are polled with
|
|
29
|
+
* a timeout to handle async page updates (dropdowns, navigation, etc.).
|
|
30
|
+
* Negative assertions (checking something is absent) run once immediately.
|
|
31
|
+
*/
|
|
32
|
+
export async function executeAssertion(page, action, a11yTree) {
|
|
33
|
+
const assertion = action.assertion;
|
|
34
|
+
if (!assertion) {
|
|
35
|
+
throw new Error("executeAssertion called without an assertion");
|
|
36
|
+
}
|
|
37
|
+
// Handle compare assertions separately — they need the value store
|
|
38
|
+
if (assertion.type === "compare" && action.compare) {
|
|
39
|
+
await executeCompareAssertion(page, action, a11yTree);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const check = buildAssertionCheck(page, assertion);
|
|
43
|
+
// Positive assertions benefit from polling (content may still be loading).
|
|
44
|
+
// Negative assertions and URL checks should fail immediately.
|
|
45
|
+
const shouldPoll = assertion.type === "contains_text" ||
|
|
46
|
+
assertion.type === "element_visible" ||
|
|
47
|
+
assertion.type === "element_exists" ||
|
|
48
|
+
assertion.type === "link_exists" ||
|
|
49
|
+
assertion.type === "field_exists";
|
|
50
|
+
if (shouldPoll) {
|
|
51
|
+
await pollAssertion(check);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
await check();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Extract a numeric value from a text string. */
|
|
58
|
+
export function extractNumber(text) {
|
|
59
|
+
// Remove thousand separators and normalize decimal separators
|
|
60
|
+
const cleaned = text.replace(/\s/g, "").replace(/,/g, ".");
|
|
61
|
+
const match = /(-?\d+\.?\d*)/.exec(cleaned);
|
|
62
|
+
return match ? parseFloat(match[1]) : null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Execute a compare assertion: read a current value from the page,
|
|
66
|
+
* compare it against a remembered value using the specified operator.
|
|
67
|
+
*/
|
|
68
|
+
export async function executeCompareAssertion(page, action, a11yTree) {
|
|
69
|
+
if (!action.compare) {
|
|
70
|
+
throw new Error("executeCompareAssertion called without compare metadata");
|
|
71
|
+
}
|
|
72
|
+
const { variable, operator } = action.compare;
|
|
73
|
+
// Get the remembered value from the global value store
|
|
74
|
+
if (!globals.valueStore.has(variable)) {
|
|
75
|
+
throw new Error(`No remembered value found for "${variable}"`);
|
|
76
|
+
}
|
|
77
|
+
const rememberedText = globals.valueStore.get(variable);
|
|
78
|
+
if (rememberedText === undefined) {
|
|
79
|
+
throw new Error(`No remembered value found for "${variable}"`);
|
|
80
|
+
}
|
|
81
|
+
// Get the current value from the page
|
|
82
|
+
let currentText;
|
|
83
|
+
if (action.ref || action.text) {
|
|
84
|
+
const locator = await resolveActionTarget(page, action, a11yTree);
|
|
85
|
+
currentText = (await locator.textContent() ?? "").trim();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// No element target — use keyword search on the page (same approach
|
|
89
|
+
// as the remember fallback). Extract keywords from the variable name
|
|
90
|
+
// and find a matching text segment containing a number.
|
|
91
|
+
const keywords = variable
|
|
92
|
+
.replace(/_/g, " ")
|
|
93
|
+
.split(" ")
|
|
94
|
+
.filter((w) => w.length > 2);
|
|
95
|
+
const innerText = await page.locator("body").innerText();
|
|
96
|
+
const segments = innerText
|
|
97
|
+
.split(/[\n\t]+/)
|
|
98
|
+
.map((s) => s.trim())
|
|
99
|
+
.filter(Boolean);
|
|
100
|
+
let best = "";
|
|
101
|
+
for (const seg of segments) {
|
|
102
|
+
if (!/\d/.test(seg))
|
|
103
|
+
continue;
|
|
104
|
+
const lower = seg.toLowerCase();
|
|
105
|
+
if (keywords.some((kw) => lower.includes(kw.toLowerCase()))) {
|
|
106
|
+
if (!best || seg.length < best.length) {
|
|
107
|
+
best = seg;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!best) {
|
|
112
|
+
throw new Error(`compare assertion: could not find a value on the page matching "${variable}"`);
|
|
113
|
+
}
|
|
114
|
+
currentText = best;
|
|
115
|
+
if (globals.debug) {
|
|
116
|
+
console.log(` [compare] Found current value by keyword search: "${currentText}"`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const rememberedNum = extractNumber(rememberedText);
|
|
120
|
+
const currentNum = extractNumber(currentText);
|
|
121
|
+
if (rememberedNum === null) {
|
|
122
|
+
throw new Error(`Cannot extract number from remembered value "${rememberedText}"`);
|
|
123
|
+
}
|
|
124
|
+
if (currentNum === null) {
|
|
125
|
+
throw new Error(`Cannot extract number from current value "${currentText}"`);
|
|
126
|
+
}
|
|
127
|
+
if (globals.debug) {
|
|
128
|
+
console.log(` [compare] "${variable}" = ${String(rememberedNum)}, current = ${String(currentNum)}, operator = ${operator}`);
|
|
129
|
+
}
|
|
130
|
+
let passed;
|
|
131
|
+
switch (operator) {
|
|
132
|
+
case "less_than":
|
|
133
|
+
passed = currentNum < rememberedNum;
|
|
134
|
+
break;
|
|
135
|
+
case "greater_than":
|
|
136
|
+
passed = currentNum > rememberedNum;
|
|
137
|
+
break;
|
|
138
|
+
case "equal":
|
|
139
|
+
passed = currentNum === rememberedNum;
|
|
140
|
+
break;
|
|
141
|
+
case "not_equal":
|
|
142
|
+
passed = currentNum !== rememberedNum;
|
|
143
|
+
break;
|
|
144
|
+
case "less_or_equal":
|
|
145
|
+
passed = currentNum <= rememberedNum;
|
|
146
|
+
break;
|
|
147
|
+
case "greater_or_equal":
|
|
148
|
+
passed = currentNum >= rememberedNum;
|
|
149
|
+
break;
|
|
150
|
+
default: throw new Error(`Unknown comparison operator: ${String(operator)}`);
|
|
151
|
+
}
|
|
152
|
+
if (!passed) {
|
|
153
|
+
throw new Error(`Comparison failed: current value ${String(currentNum)} is not ${operator.replace(/_/g, " ")} remembered "${variable}" (${String(rememberedNum)})`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export function buildAssertionCheck(page, assertion) {
|
|
157
|
+
return async () => {
|
|
158
|
+
switch (assertion.type) {
|
|
159
|
+
case "contains_text": {
|
|
160
|
+
const body = await page.locator("body").textContent();
|
|
161
|
+
if (!body?.toLowerCase().includes(assertion.expected.toLowerCase())) {
|
|
162
|
+
throw new Error(`Page does not contain text: "${assertion.expected}"`);
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case "not_contains_text": {
|
|
167
|
+
const bodyText = await page.locator("body").textContent();
|
|
168
|
+
if (bodyText?.toLowerCase().includes(assertion.expected.toLowerCase())) {
|
|
169
|
+
throw new Error(`Page contains text it should not: "${assertion.expected}"`);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "url_contains": {
|
|
174
|
+
const url = page.url();
|
|
175
|
+
if (!url.includes(assertion.expected)) {
|
|
176
|
+
throw new Error(`URL "${url}" does not contain "${assertion.expected}"`);
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "element_visible":
|
|
181
|
+
case "element_exists": {
|
|
182
|
+
const visible = await page.getByText(assertion.expected).isVisible();
|
|
183
|
+
if (!visible) {
|
|
184
|
+
throw new Error(`Element with text "${assertion.expected}" is not visible`);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "element_not_visible": {
|
|
189
|
+
const visible = await page.getByText(assertion.expected).isVisible();
|
|
190
|
+
if (visible) {
|
|
191
|
+
throw new Error(`Element with text "${assertion.expected}" is still visible`);
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case "link_exists": {
|
|
196
|
+
const link = page.locator(`a[href="${assertion.expected}"], a[href$="${assertion.expected}"]`);
|
|
197
|
+
const count = await link.count();
|
|
198
|
+
if (count === 0) {
|
|
199
|
+
throw new Error(`No link found with href matching "${assertion.expected}"`);
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case "field_exists": {
|
|
204
|
+
// Check for a form field by label, placeholder, or aria-label
|
|
205
|
+
const byLabel = page.getByLabel(assertion.expected);
|
|
206
|
+
const byPlaceholder = page.getByPlaceholder(assertion.expected);
|
|
207
|
+
const labelCount = await byLabel.count();
|
|
208
|
+
const placeholderCount = await byPlaceholder.count();
|
|
209
|
+
if (labelCount === 0 && placeholderCount === 0) {
|
|
210
|
+
throw new Error(`No form field found matching "${assertion.expected}"`);
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
default:
|
|
215
|
+
throw new Error(`Unknown assertion type: ${assertion.type}`);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=assertions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../src/pilot/assertions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkbox interaction — handles check/uncheck across different UI frameworks.
|
|
3
|
+
*/
|
|
4
|
+
import type { Page, Locator } from "playwright";
|
|
5
|
+
/**
|
|
6
|
+
* Check or uncheck a checkbox using multiple strategies.
|
|
7
|
+
* Modern frameworks (React, Vue, etc.) use synthetic event systems that
|
|
8
|
+
* don't respond to native DOM property changes. We try multiple approaches
|
|
9
|
+
* in order until the checkbox state actually changes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkCheckbox(page: Page, locator: Locator, checked: boolean): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../src/pilot/checkbox.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAG/C;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC,CA6Ff"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkbox interaction — handles check/uncheck across different UI frameworks.
|
|
3
|
+
*/
|
|
4
|
+
import { globals } from "../globals.js";
|
|
5
|
+
/**
|
|
6
|
+
* Check or uncheck a checkbox using multiple strategies.
|
|
7
|
+
* Modern frameworks (React, Vue, etc.) use synthetic event systems that
|
|
8
|
+
* don't respond to native DOM property changes. We try multiple approaches
|
|
9
|
+
* in order until the checkbox state actually changes.
|
|
10
|
+
*/
|
|
11
|
+
export async function checkCheckbox(page, locator, checked) {
|
|
12
|
+
const method = checked ? "check" : "uncheck";
|
|
13
|
+
// Strategy 1: Playwright's native check/uncheck (works for standard checkboxes)
|
|
14
|
+
try {
|
|
15
|
+
if (checked) {
|
|
16
|
+
await locator.check({ timeout: 3000 });
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
await locator.uncheck({ timeout: 3000 });
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
if (globals.debug) {
|
|
25
|
+
console.log(` [${method}] Playwright ${method}() timed out, trying label click`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Strategy 2: Find and click the associated <label> element.
|
|
29
|
+
// This is the most reliable approach for custom-styled checkboxes
|
|
30
|
+
// because it mimics what a real user does.
|
|
31
|
+
try {
|
|
32
|
+
const labelClicked = await locator.evaluate((el) => {
|
|
33
|
+
// If this IS the input, find its label
|
|
34
|
+
const input = el.tagName === "INPUT"
|
|
35
|
+
? el
|
|
36
|
+
: el.querySelector("input[type='checkbox']");
|
|
37
|
+
if (!input)
|
|
38
|
+
return false;
|
|
39
|
+
// Try label[for="id"]
|
|
40
|
+
if (input.id) {
|
|
41
|
+
const label = document.querySelector(`label[for="${input.id}"]`);
|
|
42
|
+
if (label) {
|
|
43
|
+
label.click();
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Try wrapping <label>
|
|
48
|
+
const label = input.closest("label");
|
|
49
|
+
if (label) {
|
|
50
|
+
label.click();
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
});
|
|
55
|
+
if (labelClicked) {
|
|
56
|
+
if (globals.debug) {
|
|
57
|
+
console.log(` [${method}] Label click succeeded`);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Continue to next strategy
|
|
64
|
+
}
|
|
65
|
+
// Strategy 3: Force click the element itself
|
|
66
|
+
try {
|
|
67
|
+
await locator.click({ force: true, timeout: 2000 });
|
|
68
|
+
if (globals.debug) {
|
|
69
|
+
console.log(` [${method}] Force click succeeded`);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
if (globals.debug) {
|
|
75
|
+
console.log(` [${method}] Force click failed, using JS property set + React workaround`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Strategy 4: Set the property and fire React-compatible events.
|
|
79
|
+
// React uses an internal event system that tracks the input's value
|
|
80
|
+
// via a property descriptor override. We need to use the native
|
|
81
|
+
// setter and then dispatch events to trigger React's onChange.
|
|
82
|
+
await locator.evaluate((el, targetChecked) => {
|
|
83
|
+
const input = el.tagName === "INPUT"
|
|
84
|
+
? el
|
|
85
|
+
: el.querySelector("input[type='checkbox']");
|
|
86
|
+
if (!input) {
|
|
87
|
+
el.click();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// Use the native property setter to bypass React's override
|
|
91
|
+
const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "checked");
|
|
92
|
+
if (descriptor?.set) {
|
|
93
|
+
descriptor.set.call(input, targetChecked);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
input.checked = targetChecked;
|
|
97
|
+
}
|
|
98
|
+
// Fire events that React's synthetic event system listens for
|
|
99
|
+
input.dispatchEvent(new Event("click", { bubbles: true }));
|
|
100
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
101
|
+
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
102
|
+
}, checked);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=checkbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkbox.js","sourceRoot":"","sources":["../../src/pilot/checkbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action executor — translates LLM Action objects into Playwright browser calls.
|
|
3
|
+
*/
|
|
4
|
+
import type { Page } from "playwright";
|
|
5
|
+
import type { Action, A11yNode, ExecutionResult } from "../reporter/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Run an action that might trigger navigation.
|
|
8
|
+
* Listens for a 'framenavigated' event during the action — if one fires,
|
|
9
|
+
* waits for the new page to reach domcontentloaded. If no navigation
|
|
10
|
+
* happens, returns immediately with no delay.
|
|
11
|
+
*/
|
|
12
|
+
export declare function runWithNavigationHandling(page: Page, action: () => Promise<void>): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Execute a single Action against the browser page.
|
|
15
|
+
*/
|
|
16
|
+
export declare function executeAction(page: Page, action: Action, a11yTree: A11yNode[], _valueStore?: Map<string, string>): Promise<ExecutionResult>;
|
|
17
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/pilot/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EACX,MAAM,EACN,QAAQ,EACR,eAAe,EAEf,MAAM,sBAAsB,CAAA;AAY7B;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC9C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACzB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAiCD;;GAEG;AACH,wBAAsB,aAAa,CAClC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAAE,EACpB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,eAAe,CAAC,CAid1B"}
|