-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathactions.ts
More file actions
84 lines (79 loc) · 3.49 KB
/
Copy pathactions.ts
File metadata and controls
84 lines (79 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
* The recorded-action IR — the source of truth the session→test compiler
* compiles from (Proofkeeper Initiative 2, the moat).
*
* A drive session is captured as an ordered, typed {@link Action} list with
* Playwright-codegen-style {@link Locator} strategies. This IR is deliberately
* small, explicit, and serializable: the compiler reduces it to a `.spec.ts`
* deterministically, and the recorder only appends an action *after* it
* succeeded against a real page — so a recorded trace is, by construction, a
* sequence that held at least once.
*/
/** How to find an element, preferring resilient codegen-style strategies. */
export type Locator =
| { kind: "role"; role: string; name?: string }
| { kind: "testId"; testId: string }
| { kind: "text"; text: string }
| { kind: "label"; label: string }
| { kind: "css"; selector: string };
/**
* One recorded interaction or assertion. Browser actions drive a page; terminal
* actions (`run`, `expectOutput`, `expectExit`) drive a shell — the second of
* the "browser and a terminal" tools (ADR-083). A session may interleave both.
*/
export type Action =
// Browser actions.
| { type: "goto"; url: string }
| { type: "click"; locator: Locator }
| { type: "fill"; locator: Locator; value: string }
| { type: "check"; locator: Locator }
| { type: "press"; locator: Locator; key: string }
| { type: "expectText"; locator: Locator; text: string }
| { type: "expectVisible"; locator: Locator }
// Terminal actions. Assertions target the most recently run command's result.
| { type: "run"; command: string; cwd?: string }
| { type: "expectOutput"; match: "exact" | "contains" | "regex"; stream: "stdout" | "stderr"; value: string }
| { type: "expectExit"; code: number }
// HTTP actions. Assertions target the most recently issued request's response.
| { type: "request"; method: string; url: string; headers?: Record<string, string>; body?: string }
| { type: "expectStatus"; status: number }
| { type: "expectJson"; path: string; equals: string | number | boolean };
/** The action types that assert an observable outcome. */
const ASSERTION_TYPES: readonly Action["type"][] = [
"expectText",
"expectVisible",
"expectOutput",
"expectExit",
"expectStatus",
"expectJson",
];
/**
* Whether a session asserted at least one observable outcome. A session of
* bare navigation/clicks compiles to a trivially-green spec that verifies
* nothing — callers use this to refuse to call such a session "verified".
*/
export function sessionAssertsOutcome(session: RecordedSession): boolean {
return session.actions.some((a) => ASSERTION_TYPES.includes(a.type));
}
/** A captured drive session: its entry point and the actions recorded from it. */
export interface RecordedSession {
/** The capability this session exercises (threads to the write-back). */
capabilityId?: string;
/** Human title for the emitted test. */
title: string;
/** Product entry point the session started from. */
startUrl: string;
/**
* Unpacked browser-extension directory loaded for the drive, when verifying an
* extension. Set ⇒ the emitter produces a persistent-context spec that re-loads
* the extension and rediscovers its (non-deterministic) ID at run time.
*/
extensionPath?: string;
/** The recorded actions, in order. */
actions: Action[];
/**
* Optional human-readable Markdown test plan the model emitted before driving
* (metadata, not compiled into the spec; surfaced in the write-back).
*/
plan?: string;
}