@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,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Viewport dimensions. */
|
|
3
|
+
export const ViewportSchema = z.object({
|
|
4
|
+
width: z.number().int().positive(),
|
|
5
|
+
height: z.number().int().positive(),
|
|
6
|
+
});
|
|
7
|
+
/** A single test case: a name and ordered list of plain-English steps. */
|
|
8
|
+
export const TestCaseSchema = z.object({
|
|
9
|
+
name: z.string().min(1),
|
|
10
|
+
description: z.string().optional(),
|
|
11
|
+
steps: z.array(z.string().min(1)).min(1),
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Top-level suite definition — matches the YAML format from the spec.
|
|
15
|
+
*
|
|
16
|
+
* reusable_steps is a map of name → step list.
|
|
17
|
+
* variables is a map of name → string value.
|
|
18
|
+
*/
|
|
19
|
+
export const SuiteSchema = z.object({
|
|
20
|
+
suite: z.string().min(1),
|
|
21
|
+
base_url: z.url().optional(),
|
|
22
|
+
viewport: ViewportSchema.optional(),
|
|
23
|
+
model: z
|
|
24
|
+
.union([
|
|
25
|
+
z.string().min(1),
|
|
26
|
+
z.object({ planner: z.string().min(1), pilot: z.string().min(1) }),
|
|
27
|
+
])
|
|
28
|
+
.optional(),
|
|
29
|
+
variables: z.record(z.string(), z.string()).optional(),
|
|
30
|
+
reusable_steps: z.record(z.string(), z.array(z.string().min(1))).optional(),
|
|
31
|
+
tests: z.array(TestCaseSchema).min(1),
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/parser/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,2BAA2B;AAC3B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAA;AAEF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACxC,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC5B,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,KAAK,EAAE,CAAC;SACN,KAAK,CAAC;QACN,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjB,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;SACD,QAAQ,EAAE;IACZ,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtD,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3E,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACrC,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step preprocessor — expands compound steps into individual atomic steps.
|
|
3
|
+
*
|
|
4
|
+
* Runs at load time before execution, so there's no runtime cost.
|
|
5
|
+
* Each output step maps to exactly one browser action.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Expand compound steps in a step list.
|
|
9
|
+
* E.g. "Select Företag - Ventilation - Kylteknik in the leads form"
|
|
10
|
+
* becomes three steps: click "Företag", click "Ventilation", click "Kylteknik".
|
|
11
|
+
*/
|
|
12
|
+
export declare function expandSteps(steps: string[]): string[];
|
|
13
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/parser/steps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAMrD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step preprocessor — expands compound steps into individual atomic steps.
|
|
3
|
+
*
|
|
4
|
+
* Runs at load time before execution, so there's no runtime cost.
|
|
5
|
+
* Each output step maps to exactly one browser action.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Expand compound steps in a step list.
|
|
9
|
+
* E.g. "Select Företag - Ventilation - Kylteknik in the leads form"
|
|
10
|
+
* becomes three steps: click "Företag", click "Ventilation", click "Kylteknik".
|
|
11
|
+
*/
|
|
12
|
+
export function expandSteps(steps) {
|
|
13
|
+
const result = [];
|
|
14
|
+
for (const step of steps) {
|
|
15
|
+
result.push(...expandStep(step));
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
function expandStep(step) {
|
|
20
|
+
// "Select X - Y - Z in <context>" → click each item in context
|
|
21
|
+
const selectChain = /^select\s+(.+?)(?:\s+(?:in|from|on)\s+(.+))?$/i.exec(step);
|
|
22
|
+
if (selectChain) {
|
|
23
|
+
const items = selectChain[1];
|
|
24
|
+
const context = selectChain[2];
|
|
25
|
+
// Only split on " - " (spaced dashes) to avoid splitting hyphenated words
|
|
26
|
+
const parts = items.split(/\s+-\s+/);
|
|
27
|
+
if (parts.length > 1) {
|
|
28
|
+
return parts.map((part) => {
|
|
29
|
+
const trimmed = part.trim();
|
|
30
|
+
return context
|
|
31
|
+
? `click "${trimmed}" in ${context}`
|
|
32
|
+
: `click "${trimmed}"`;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// "Do X, then Y, then Z" → individual steps
|
|
37
|
+
const thenParts = step.split(/,?\s+then\s+/i);
|
|
38
|
+
if (thenParts.length > 1) {
|
|
39
|
+
return thenParts.map((part) => part.trim());
|
|
40
|
+
}
|
|
41
|
+
// No expansion needed
|
|
42
|
+
return [step];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/parser/steps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe;IAC1C,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC/B,+DAA+D;IAC/D,MAAM,WAAW,GAAG,gDAAgD,CAAC,IAAI,CACxE,IAAI,CACJ,CAAA;IACD,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAE9B,0EAA0E;QAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;gBAC3B,OAAO,OAAO;oBACb,CAAC,CAAC,UAAU,OAAO,QAAQ,OAAO,EAAE;oBACpC,CAAC,CAAC,UAAU,OAAO,GAAG,CAAA;YACxB,CAAC,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED,4CAA4C;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;IAC7C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAC5C,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable interpolation for suite definitions.
|
|
3
|
+
*
|
|
4
|
+
* Resolves patterns like:
|
|
5
|
+
* {{varName}} → from suite-level variables
|
|
6
|
+
* {{env.VAR_NAME}} → from process.env
|
|
7
|
+
* {{timestamp}} → current unix timestamp
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Resolve all `{{...}}` references in a string.
|
|
11
|
+
* Throws if a variable cannot be resolved.
|
|
12
|
+
*/
|
|
13
|
+
export declare function interpolate(template: string, variables: Record<string, string>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve variables in all steps of a suite (mutates nothing — returns a new array).
|
|
16
|
+
*/
|
|
17
|
+
export declare function interpolateSteps(steps: string[], variables: Record<string, string>): string[];
|
|
18
|
+
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../src/parser/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,wBAAgB,WAAW,CAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,CA8BR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,EAAE,CAEV"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable interpolation for suite definitions.
|
|
3
|
+
*
|
|
4
|
+
* Resolves patterns like:
|
|
5
|
+
* {{varName}} → from suite-level variables
|
|
6
|
+
* {{env.VAR_NAME}} → from process.env
|
|
7
|
+
* {{timestamp}} → current unix timestamp
|
|
8
|
+
*/
|
|
9
|
+
const PATTERN = /\{\{(.+?)\}\}/g;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve all `{{...}}` references in a string.
|
|
12
|
+
* Throws if a variable cannot be resolved.
|
|
13
|
+
*/
|
|
14
|
+
export function interpolate(template, variables) {
|
|
15
|
+
return template.replace(PATTERN, (_match, key) => {
|
|
16
|
+
const trimmed = key.trim();
|
|
17
|
+
// Built-in: timestamp
|
|
18
|
+
if (trimmed === "timestamp") {
|
|
19
|
+
return String(Date.now());
|
|
20
|
+
}
|
|
21
|
+
// Environment variable: env.X
|
|
22
|
+
if (trimmed.startsWith("env.")) {
|
|
23
|
+
const envKey = trimmed.slice(4);
|
|
24
|
+
const value = process.env[envKey];
|
|
25
|
+
if (value === undefined) {
|
|
26
|
+
throw new Error(`Environment variable "${envKey}" is not set (referenced as "{{${trimmed}}}")`);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
// Suite-level variable
|
|
31
|
+
if (!(trimmed in variables)) {
|
|
32
|
+
throw new Error(`Unknown variable "{{${trimmed}}}". ` +
|
|
33
|
+
`Available: ${Object.keys(variables).join(", ") || "(none)"}`);
|
|
34
|
+
}
|
|
35
|
+
return variables[trimmed];
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve variables in all steps of a suite (mutates nothing — returns a new array).
|
|
40
|
+
*/
|
|
41
|
+
export function interpolateSteps(steps, variables) {
|
|
42
|
+
return steps.map((step) => interpolate(step, variables));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../src/parser/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,OAAO,GAAG,gBAAgB,CAAA;AAEhC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAC1B,QAAgB,EAChB,SAAiC;IAEjC,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAW,EAAE,EAAE;QACxD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;QAE1B,sBAAsB;QACtB,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC1B,CAAC;QAED,8BAA8B;QAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACd,yBAAyB,MAAM,kCAAkC,OAAO,MAAM,CAC9E,CAAA;YACF,CAAC;YACD,OAAO,KAAK,CAAA;QACb,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,CAAC,OAAO,IAAI,SAAS,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACd,uBAAuB,OAAO,OAAO;gBACpC,cAAc,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CAC9D,CAAA;QACF,CAAC;QACD,OAAO,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC/B,KAAe,EACf,SAAiC;IAEjC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAA;AACzD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility tree snapshot parser with stable ref assignment.
|
|
3
|
+
*/
|
|
4
|
+
import type { A11yNode } from "../reporter/types.js";
|
|
5
|
+
/** Reset stable ref tracking (call between test cases). */
|
|
6
|
+
export declare function resetRefCounter(): void;
|
|
7
|
+
export interface ParsedLine {
|
|
8
|
+
indent: number;
|
|
9
|
+
role: string;
|
|
10
|
+
name: string;
|
|
11
|
+
attrs: string[];
|
|
12
|
+
url?: string;
|
|
13
|
+
raw: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse Playwright's ariaSnapshot YAML-like output into A11yNode tree with refs.
|
|
17
|
+
* Refs are stable across captures: the same element (identified by its
|
|
18
|
+
* structural path: role + name + sibling index at each tree level) always
|
|
19
|
+
* gets the same ref within a test case.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseA11ySnapshot(raw: string): A11yNode[];
|
|
22
|
+
/**
|
|
23
|
+
* Format the a11y tree as a readable string with refs, for display and LLM consumption.
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatA11yTree(nodes: A11yNode[], indent?: number): string;
|
|
26
|
+
//# sourceMappingURL=a11y-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-parser.d.ts","sourceRoot":"","sources":["../../src/pilot/a11y-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAsBpD,2DAA2D;AAC3D,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AA0CD,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,CAuEzD;AAyDD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,SAAI,GAAG,MAAM,CAkBpE"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility tree snapshot parser with stable ref assignment.
|
|
3
|
+
*/
|
|
4
|
+
// ── Stable ref assignment ─────────────────────────────────────────────
|
|
5
|
+
/**
|
|
6
|
+
* Stable ref assignment.
|
|
7
|
+
*
|
|
8
|
+
* Refs are derived from a structural path: each interactive element gets a
|
|
9
|
+
* ref based on its role, name, and sibling index among same-role siblings.
|
|
10
|
+
* This makes refs stable across captures — a button "Submit" keeps its ref
|
|
11
|
+
* even when new elements appear elsewhere in the tree.
|
|
12
|
+
*
|
|
13
|
+
* A short integer ref (e1, e2, ...) is assigned to each unique structural
|
|
14
|
+
* path via a persistent map that survives across captures within a test case.
|
|
15
|
+
* New elements get the next available integer. Removed elements keep their
|
|
16
|
+
* slot so that the LLM never sees a ref reassigned to a different element.
|
|
17
|
+
*/
|
|
18
|
+
/** Map from structural path -> stable ref. Persists across captures within a test case. */
|
|
19
|
+
let stableRefMap = new Map();
|
|
20
|
+
let nextRefId = 0;
|
|
21
|
+
/** Reset stable ref tracking (call between test cases). */
|
|
22
|
+
export function resetRefCounter() {
|
|
23
|
+
stableRefMap = new Map();
|
|
24
|
+
nextRefId = 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get or assign a stable ref for a structural path.
|
|
28
|
+
* The path encodes the element's position: role, name, and sibling index
|
|
29
|
+
* at each level of the tree.
|
|
30
|
+
*/
|
|
31
|
+
function getStableRef(structuralPath) {
|
|
32
|
+
const existing = stableRefMap.get(structuralPath);
|
|
33
|
+
if (existing)
|
|
34
|
+
return existing;
|
|
35
|
+
nextRefId++;
|
|
36
|
+
const ref = `e${String(nextRefId)}`;
|
|
37
|
+
stableRefMap.set(structuralPath, ref);
|
|
38
|
+
return ref;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Roles that represent interactive elements the Pilot can act on.
|
|
42
|
+
* Non-interactive structural roles (list, listitem, paragraph, etc.)
|
|
43
|
+
* still appear in the tree but don't get refs.
|
|
44
|
+
*/
|
|
45
|
+
const INTERACTIVE_ROLES = new Set([
|
|
46
|
+
"link",
|
|
47
|
+
"button",
|
|
48
|
+
"searchbox",
|
|
49
|
+
"textbox",
|
|
50
|
+
"checkbox",
|
|
51
|
+
"radio",
|
|
52
|
+
"combobox",
|
|
53
|
+
"menuitem",
|
|
54
|
+
"menuitemcheckbox",
|
|
55
|
+
"menuitemradio",
|
|
56
|
+
"option",
|
|
57
|
+
"slider",
|
|
58
|
+
"spinbutton",
|
|
59
|
+
"switch",
|
|
60
|
+
"tab",
|
|
61
|
+
"treeitem",
|
|
62
|
+
"img",
|
|
63
|
+
"heading",
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* Parse Playwright's ariaSnapshot YAML-like output into A11yNode tree with refs.
|
|
67
|
+
* Refs are stable across captures: the same element (identified by its
|
|
68
|
+
* structural path: role + name + sibling index at each tree level) always
|
|
69
|
+
* gets the same ref within a test case.
|
|
70
|
+
*/
|
|
71
|
+
export function parseA11ySnapshot(raw) {
|
|
72
|
+
const lines = raw.split("\n");
|
|
73
|
+
const rootNodes = [];
|
|
74
|
+
// Stack tracks: indent level, node, structural path prefix, and
|
|
75
|
+
// sibling counters (role -> count) for assigning sibling indices.
|
|
76
|
+
const stack = [];
|
|
77
|
+
// Sibling counters at root level
|
|
78
|
+
const rootSiblingCounts = new Map();
|
|
79
|
+
for (const line of lines) {
|
|
80
|
+
if (!line.trim())
|
|
81
|
+
continue;
|
|
82
|
+
// Metadata lines like " - /url: ..." — attach to parent
|
|
83
|
+
const urlMatch = /^(\s*)- \/url:\s*(.+)$/.exec(line);
|
|
84
|
+
if (urlMatch) {
|
|
85
|
+
const lastNode = stack.at(-1)?.node;
|
|
86
|
+
if (lastNode) {
|
|
87
|
+
lastNode.url = urlMatch[2].trim();
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const parsed = parseLine(line);
|
|
92
|
+
if (!parsed)
|
|
93
|
+
continue;
|
|
94
|
+
// Find parent based on indent level
|
|
95
|
+
while (stack.length > 0) {
|
|
96
|
+
const top = stack.at(-1);
|
|
97
|
+
if (top && top.indent >= parsed.indent) {
|
|
98
|
+
stack.pop();
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Compute structural path for stable ref assignment
|
|
105
|
+
const parent = stack.at(-1);
|
|
106
|
+
const siblingCounts = parent ? parent.siblingCounts : rootSiblingCounts;
|
|
107
|
+
const pathPrefix = parent ? parent.pathPrefix : "";
|
|
108
|
+
// Sibling key: role + name (elements with the same role and name
|
|
109
|
+
// under the same parent get distinguished by index)
|
|
110
|
+
const siblingKey = `${parsed.role}:${parsed.name}`;
|
|
111
|
+
const siblingIndex = siblingCounts.get(siblingKey) ?? 0;
|
|
112
|
+
siblingCounts.set(siblingKey, siblingIndex + 1);
|
|
113
|
+
const structuralPath = `${pathPrefix}/${parsed.role}:${parsed.name}[${String(siblingIndex)}]`;
|
|
114
|
+
const node = buildNode(parsed, structuralPath);
|
|
115
|
+
if (!parent) {
|
|
116
|
+
rootNodes.push(node);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
parent.node.children ??= [];
|
|
120
|
+
parent.node.children.push(node);
|
|
121
|
+
}
|
|
122
|
+
stack.push({
|
|
123
|
+
indent: parsed.indent,
|
|
124
|
+
node,
|
|
125
|
+
pathPrefix: structuralPath,
|
|
126
|
+
siblingCounts: new Map(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return rootNodes;
|
|
130
|
+
}
|
|
131
|
+
function parseLine(line) {
|
|
132
|
+
// Match: " - role "name" [attrs]" or " - role: text" or " - role"
|
|
133
|
+
const match = /^(\s*)- (\w+)(?:\s+"([^"]*)")?(.*)$/.exec(line);
|
|
134
|
+
if (!match)
|
|
135
|
+
return null;
|
|
136
|
+
const [, spaces, role, quotedName, remainder] = match;
|
|
137
|
+
const indent = spaces.length;
|
|
138
|
+
let name = quotedName || "";
|
|
139
|
+
const rest = remainder.trim();
|
|
140
|
+
// Parse attributes like [level=1] [checked]
|
|
141
|
+
const attrs = [];
|
|
142
|
+
const attrMatches = rest.matchAll(/\[([^\]]+)\]/g);
|
|
143
|
+
for (const m of attrMatches) {
|
|
144
|
+
attrs.push(m[1]);
|
|
145
|
+
}
|
|
146
|
+
// If no quoted name, check for "role: text" pattern
|
|
147
|
+
if (!name && rest.startsWith(":")) {
|
|
148
|
+
name = rest.slice(1).trim();
|
|
149
|
+
}
|
|
150
|
+
// Extract level from attrs
|
|
151
|
+
const levelAttr = attrs.find((a) => a.startsWith("level="));
|
|
152
|
+
return {
|
|
153
|
+
indent,
|
|
154
|
+
role,
|
|
155
|
+
name,
|
|
156
|
+
attrs,
|
|
157
|
+
raw: line.trim(),
|
|
158
|
+
...(levelAttr ? {} : {}),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function buildNode(parsed, structuralPath) {
|
|
162
|
+
const isInteractive = INTERACTIVE_ROLES.has(parsed.role);
|
|
163
|
+
const ref = isInteractive ? getStableRef(structuralPath) : `_${parsed.role}`;
|
|
164
|
+
const node = {
|
|
165
|
+
ref,
|
|
166
|
+
role: parsed.role,
|
|
167
|
+
name: parsed.name,
|
|
168
|
+
raw: parsed.raw,
|
|
169
|
+
};
|
|
170
|
+
// Extract level for headings
|
|
171
|
+
const levelAttr = parsed.attrs.find((a) => a.startsWith("level="));
|
|
172
|
+
if (levelAttr) {
|
|
173
|
+
node.level = parseInt(levelAttr.split("=")[1], 10);
|
|
174
|
+
}
|
|
175
|
+
return node;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Format the a11y tree as a readable string with refs, for display and LLM consumption.
|
|
179
|
+
*/
|
|
180
|
+
export function formatA11yTree(nodes, indent = 0) {
|
|
181
|
+
const lines = [];
|
|
182
|
+
const prefix = " ".repeat(indent);
|
|
183
|
+
for (const node of nodes) {
|
|
184
|
+
const refLabel = node.ref.startsWith("_") ? "" : `[${node.ref}] `;
|
|
185
|
+
const nameStr = node.name ? ` "${node.name}"` : "";
|
|
186
|
+
const levelStr = node.level != null ? ` [level=${String(node.level)}]` : "";
|
|
187
|
+
const urlStr = node.url ? ` → ${node.url}` : "";
|
|
188
|
+
lines.push(`${prefix}${refLabel}${node.role}${nameStr}${levelStr}${urlStr}`);
|
|
189
|
+
if (node.children) {
|
|
190
|
+
lines.push(formatA11yTree(node.children, indent + 1));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return lines.join("\n");
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=a11y-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-parser.js","sourceRoot":"","sources":["../../src/pilot/a11y-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion execution — validates page state against expected conditions.
|
|
3
|
+
*/
|
|
4
|
+
import type { Page } from "playwright";
|
|
5
|
+
import type { Action, A11yNode } from "../reporter/types.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 declare function pollAssertion(check: () => Promise<void>, timeoutMs?: number): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute an assertion against the current page state.
|
|
14
|
+
* Positive assertions (checking something exists/appears) are polled with
|
|
15
|
+
* a timeout to handle async page updates (dropdowns, navigation, etc.).
|
|
16
|
+
* Negative assertions (checking something is absent) run once immediately.
|
|
17
|
+
*/
|
|
18
|
+
export declare function executeAssertion(page: Page, action: Action, a11yTree: A11yNode[]): Promise<void>;
|
|
19
|
+
/** Extract a numeric value from a text string. */
|
|
20
|
+
export declare function extractNumber(text: string): number | null;
|
|
21
|
+
/**
|
|
22
|
+
* Execute a compare assertion: read a current value from the page,
|
|
23
|
+
* compare it against a remembered value using the specified operator.
|
|
24
|
+
*/
|
|
25
|
+
export declare function executeCompareAssertion(page: Page, action: Action, a11yTree: A11yNode[]): Promise<void>;
|
|
26
|
+
export declare function buildAssertionCheck(page: Page, assertion: {
|
|
27
|
+
type: string;
|
|
28
|
+
expected: string;
|
|
29
|
+
}): () => Promise<void>;
|
|
30
|
+
//# sourceMappingURL=assertions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../src/pilot/assertions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAI5D;;;;GAIG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC1B,SAAS,SAAO,GACd,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKzD;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC5C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC,CAoFf;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3C,MAAM,OAAO,CAAC,IAAI,CAAC,CAqFrB"}
|