@itmetsam/samurai-framework 0.6.0 → 0.7.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 +2 -2
- package/bin/samurai.mjs +25 -0
- package/dist/browser/evidence.d.ts +19 -0
- package/dist/browser/evidence.js +35 -0
- package/dist/browser/page.d.ts +6 -0
- package/dist/browser/page.js +20 -3
- package/dist/browser/screenshot.d.ts +2 -0
- package/dist/browser/screenshot.js +5 -2
- package/dist/cli/browsers.d.ts +1 -1
- package/dist/cli/browsers.js +2 -4
- package/dist/cli/main.js +15 -1
- package/dist/project/config-edit.d.ts +16 -0
- package/dist/project/config-edit.js +218 -0
- package/dist/project/index.d.ts +3 -0
- package/dist/project/index.js +3 -0
- package/dist/project/secrets-file.d.ts +8 -0
- package/dist/project/secrets-file.js +69 -0
- package/dist/project/variables.d.ts +6 -0
- package/dist/project/variables.js +17 -0
- package/dist/recorder/candidates.d.ts +7 -0
- package/dist/recorder/candidates.js +118 -0
- package/dist/recorder/capture.d.ts +8 -1
- package/dist/recorder/capture.js +25 -116
- package/dist/recorder/index.d.ts +1 -1
- package/dist/recorder/normalise.d.ts +28 -1
- package/dist/recorder/normalise.js +40 -1
- package/dist/recorder/recorder.d.ts +54 -0
- package/dist/recorder/recorder.js +195 -10
- package/dist/recorder/session.d.ts +15 -0
- package/dist/recorder/session.js +57 -7
- package/dist/recorder/toolbar/controller.d.ts +136 -0
- package/dist/recorder/toolbar/controller.js +471 -0
- package/dist/recorder/toolbar/inspect.d.ts +12 -0
- package/dist/recorder/toolbar/inspect.js +94 -0
- package/dist/recorder/toolbar/protocol.d.ts +135 -0
- package/dist/recorder/toolbar/protocol.js +4 -0
- package/dist/recorder/toolbar/source.d.ts +32 -0
- package/dist/recorder/toolbar/source.js +856 -0
- package/dist/recorder/toolbar/styles.d.ts +6 -0
- package/dist/recorder/toolbar/styles.js +95 -0
- package/dist/runner/reporter.d.ts +5 -1
- package/dist/runner/reporter.js +4 -3
- package/dist/runner/test-runner.d.ts +9 -0
- package/dist/runner/test-runner.js +39 -4
- package/dist/steps/emit.js +4 -0
- package/dist/steps/model.d.ts +11 -0
- package/dist/steps/parse.js +22 -3
- package/dist/transport/bidi-connection.js +32 -1
- package/dist/types/bidi-modules/script.d.ts +20 -3
- package/dist/types/test.d.ts +4 -0
- package/package.json +5 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { LocatorCall } from "../../steps/model.js";
|
|
2
|
+
/** The BiDi sandbox realm the toolbar script runs in */
|
|
3
|
+
export declare const TOOLBAR_SANDBOX = "samurai-toolbar";
|
|
4
|
+
/** `Symbol.for(TOOLBAR_KEY)` on the sandbox global holds the toolbar's hook: `update`, `reply`, `press`, `root` */
|
|
5
|
+
export declare const TOOLBAR_KEY = "samurai.toolbar";
|
|
6
|
+
export type MatcherChoice = "toBeVisible" | "toHaveText" | "toContainText" | "toHaveValue" | "toHaveAttribute" | "toHaveCount";
|
|
7
|
+
/** What the toolbar draws; secrets are names only */
|
|
8
|
+
export interface ToolbarState {
|
|
9
|
+
status: "recording" | "paused";
|
|
10
|
+
collapsed: boolean;
|
|
11
|
+
/** Top-left corner in CSS pixels; null = the default spot (top right, 12 px in) */
|
|
12
|
+
position: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
} | null;
|
|
16
|
+
steps: number;
|
|
17
|
+
environment: string;
|
|
18
|
+
/** False when the config has no `environments` */
|
|
19
|
+
canAddVariables: boolean;
|
|
20
|
+
variables: {
|
|
21
|
+
name: string;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
24
|
+
secrets: {
|
|
25
|
+
name: string;
|
|
26
|
+
set: boolean;
|
|
27
|
+
}[];
|
|
28
|
+
/** Whether `.env.<environment>` is git-ignored */
|
|
29
|
+
secretsIgnored: boolean;
|
|
30
|
+
/** Ask "Add a step that opens this page?" */
|
|
31
|
+
resumeQuestion: boolean;
|
|
32
|
+
/** Prefill for the Screenshot panel: `screenshot-<n>` */
|
|
33
|
+
nextScreenshot: string;
|
|
34
|
+
/** Shown once per id */
|
|
35
|
+
toast?: {
|
|
36
|
+
id: number;
|
|
37
|
+
text: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Element-carrying messages send the element itself (it arrives as a handle) and its candidates */
|
|
41
|
+
export type ToolbarMessage = {
|
|
42
|
+
type: "toolbar";
|
|
43
|
+
} &
|
|
44
|
+
/** `url` is the document's `location.href`; Firefox also runs the toolbar in a transient about:blank */
|
|
45
|
+
({
|
|
46
|
+
action: "ready";
|
|
47
|
+
url?: string;
|
|
48
|
+
} | {
|
|
49
|
+
action: "pause";
|
|
50
|
+
} | {
|
|
51
|
+
action: "resume";
|
|
52
|
+
} | {
|
|
53
|
+
action: "resume-goto";
|
|
54
|
+
add: boolean;
|
|
55
|
+
} | {
|
|
56
|
+
action: "stop";
|
|
57
|
+
} | {
|
|
58
|
+
action: "move";
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
} | {
|
|
62
|
+
action: "collapse";
|
|
63
|
+
collapsed: boolean;
|
|
64
|
+
} | {
|
|
65
|
+
action: "pick";
|
|
66
|
+
id: number;
|
|
67
|
+
target: unknown;
|
|
68
|
+
candidates: LocatorCall[];
|
|
69
|
+
} | {
|
|
70
|
+
action: "assert";
|
|
71
|
+
id: number;
|
|
72
|
+
target: unknown;
|
|
73
|
+
candidates: LocatorCall[];
|
|
74
|
+
matcher: MatcherChoice;
|
|
75
|
+
expected?: string;
|
|
76
|
+
attribute?: string;
|
|
77
|
+
countIndex?: number;
|
|
78
|
+
not: boolean;
|
|
79
|
+
} | {
|
|
80
|
+
action: "insert";
|
|
81
|
+
id: number;
|
|
82
|
+
target: unknown;
|
|
83
|
+
candidates: LocatorCall[];
|
|
84
|
+
kind: "env" | "secret";
|
|
85
|
+
name: string;
|
|
86
|
+
} | {
|
|
87
|
+
action: "add-insertable";
|
|
88
|
+
id: number;
|
|
89
|
+
target: unknown;
|
|
90
|
+
candidates: LocatorCall[];
|
|
91
|
+
kind: "env" | "secret";
|
|
92
|
+
name: string;
|
|
93
|
+
value: string;
|
|
94
|
+
} | {
|
|
95
|
+
action: "wait";
|
|
96
|
+
kind: "idle";
|
|
97
|
+
} | {
|
|
98
|
+
action: "wait";
|
|
99
|
+
kind: "time";
|
|
100
|
+
ms: number;
|
|
101
|
+
} | {
|
|
102
|
+
action: "screenshot";
|
|
103
|
+
name: string;
|
|
104
|
+
fullPage: boolean;
|
|
105
|
+
});
|
|
106
|
+
/** The answer to `pick` */
|
|
107
|
+
export type PickInfo = {
|
|
108
|
+
ok: true;
|
|
109
|
+
label: string;
|
|
110
|
+
text: string;
|
|
111
|
+
value?: string;
|
|
112
|
+
attributes: {
|
|
113
|
+
name: string;
|
|
114
|
+
value: string;
|
|
115
|
+
}[];
|
|
116
|
+
first: {
|
|
117
|
+
matcher: MatcherChoice;
|
|
118
|
+
expected?: string;
|
|
119
|
+
};
|
|
120
|
+
counts: {
|
|
121
|
+
label: string;
|
|
122
|
+
count: number;
|
|
123
|
+
}[];
|
|
124
|
+
} | {
|
|
125
|
+
ok: false;
|
|
126
|
+
error: string;
|
|
127
|
+
};
|
|
128
|
+
/** The answer to `insert`, `add-insertable` and `assert` */
|
|
129
|
+
export type ActionReply = {
|
|
130
|
+
ok: true;
|
|
131
|
+
} | {
|
|
132
|
+
ok: false;
|
|
133
|
+
error: string;
|
|
134
|
+
field?: "name";
|
|
135
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The BiDi sandbox realm the toolbar script runs in */
|
|
2
|
+
export const TOOLBAR_SANDBOX = "samurai-toolbar";
|
|
3
|
+
/** `Symbol.for(TOOLBAR_KEY)` on the sandbox global holds the toolbar's hook: `update`, `reply`, `press`, `root` */
|
|
4
|
+
export const TOOLBAR_KEY = "samurai.toolbar";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The recorder toolbar: a function declaration `(send) => { … }` installed as a preload script in the
|
|
3
|
+
* `samurai-toolbar` sandbox realm (the caller names the sandbox), top-level documents only. `send` is the
|
|
4
|
+
* toolbar's own channel (not the capture script's); it stays in this closure, which page script cannot
|
|
5
|
+
* reach, and the recorder takes toolbar messages only from this sandbox's realm. It draws a
|
|
6
|
+
* closed shadow root on a `<samurai-recorder-toolbar>` element and is a thin view: it renders the
|
|
7
|
+
* `ToolbarState` the recorder pushes and sends `ToolbarMessage`s; every step is decided by the recorder.
|
|
8
|
+
*
|
|
9
|
+
* `globalThis[Symbol.for("samurai.toolbar")]` in the sandbox holds the hook:
|
|
10
|
+
* - `update(state)`: the recorder's state, after every change and every page load.
|
|
11
|
+
* - `reply(id, result)`: the answer to `pick` (a `PickInfo`) or to `assert`, `insert` and `add-insertable`
|
|
12
|
+
* (an `ActionReply`).
|
|
13
|
+
* - `root`: the shadow root, for tests.
|
|
14
|
+
* - `press(action, detail?)`: runs the handler a click on that control runs (for tests). Actions:
|
|
15
|
+
* `pause`, `resume`, `stop`, `collapse`, `expand`, `resume-yes`, `resume-no` (rail);
|
|
16
|
+
* `assert`, `insert`, `wait`, `screenshot` (open or close the tool);
|
|
17
|
+
* `pick { target }` (the element a picking click hit);
|
|
18
|
+
* `matcher { matcher }`, `not`, `assert-add` (Assert panel);
|
|
19
|
+
* `insert-item { kind, name }`, `insert-first`, `insert-new { kind }` (Insert list);
|
|
20
|
+
* `new-kind { kind }`, `new-save`, `new-cancel` (New variable or secret);
|
|
21
|
+
* `wait-add`, `screenshot-add`; `escape` (the Esc key).
|
|
22
|
+
* Form inputs carry `data-field` (`expected`, `attribute`, `countIndex`, `filter`, `name`, `value`,
|
|
23
|
+
* `waitKind`, `seconds`, `shotName`, `fullPage`) and update on `input`/`change`.
|
|
24
|
+
* - `rebind(send)`: used by a second run in the same document (a new recording), which keeps the host and
|
|
25
|
+
* swaps in that recording's toolbar channel.
|
|
26
|
+
* - `state()`, `picking()`: the last state from `update` and whether the Assert picker is on (for tests).
|
|
27
|
+
* - `dispose()`: removes the host and every listener the toolbar put on the window and document (the
|
|
28
|
+
* recording ended while the document stays open).
|
|
29
|
+
*
|
|
30
|
+
* A string, so no transpiler helper can end up in it.
|
|
31
|
+
*/
|
|
32
|
+
export declare const TOOLBAR_SOURCE: string;
|