@scenetest/scenes 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/LICENSE +21 -0
- package/dist/__tests__/devices.test.d.ts +2 -0
- package/dist/__tests__/devices.test.d.ts.map +1 -0
- package/dist/__tests__/devices.test.js +117 -0
- package/dist/__tests__/devices.test.js.map +1 -0
- package/dist/__tests__/dsl.test.d.ts +2 -0
- package/dist/__tests__/dsl.test.d.ts.map +1 -0
- package/dist/__tests__/dsl.test.js +385 -0
- package/dist/__tests__/dsl.test.js.map +1 -0
- package/dist/__tests__/markdown-scene.test.d.ts +2 -0
- package/dist/__tests__/markdown-scene.test.d.ts.map +1 -0
- package/dist/__tests__/markdown-scene.test.js +508 -0
- package/dist/__tests__/markdown-scene.test.js.map +1 -0
- package/dist/__tests__/reactive.test.d.ts +2 -0
- package/dist/__tests__/reactive.test.d.ts.map +1 -0
- package/dist/__tests__/reactive.test.js +383 -0
- package/dist/__tests__/reactive.test.js.map +1 -0
- package/dist/__tests__/swarm.test.d.ts +2 -0
- package/dist/__tests__/swarm.test.d.ts.map +1 -0
- package/dist/__tests__/swarm.test.js +214 -0
- package/dist/__tests__/swarm.test.js.map +1 -0
- package/dist/actor.d.ts +104 -0
- package/dist/actor.d.ts.map +1 -0
- package/dist/actor.js +527 -0
- package/dist/actor.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +273 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -0
- package/dist/devices.d.ts +55 -0
- package/dist/devices.d.ts.map +1 -0
- package/dist/devices.js +167 -0
- package/dist/devices.js.map +1 -0
- package/dist/dsl.d.ts +99 -0
- package/dist/dsl.d.ts.map +1 -0
- package/dist/dsl.js +247 -0
- package/dist/dsl.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +9 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +27 -0
- package/dist/init.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +10 -0
- package/dist/loader.js.map +1 -0
- package/dist/markdown-scene.d.ts +120 -0
- package/dist/markdown-scene.d.ts.map +1 -0
- package/dist/markdown-scene.js +452 -0
- package/dist/markdown-scene.js.map +1 -0
- package/dist/message-bus.d.ts +31 -0
- package/dist/message-bus.d.ts.map +1 -0
- package/dist/message-bus.js +74 -0
- package/dist/message-bus.js.map +1 -0
- package/dist/reactive.d.ts +267 -0
- package/dist/reactive.d.ts.map +1 -0
- package/dist/reactive.js +779 -0
- package/dist/reactive.js.map +1 -0
- package/dist/runner.d.ts +51 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +306 -0
- package/dist/runner.js.map +1 -0
- package/dist/scene.d.ts +40 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +110 -0
- package/dist/scene.js.map +1 -0
- package/dist/selectors.d.ts +57 -0
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.js +193 -0
- package/dist/selectors.js.map +1 -0
- package/dist/swarm.d.ts +64 -0
- package/dist/swarm.d.ts.map +1 -0
- package/dist/swarm.js +306 -0
- package/dist/swarm.js.map +1 -0
- package/dist/team-manager.d.ts +120 -0
- package/dist/team-manager.d.ts.map +1 -0
- package/dist/team-manager.js +267 -0
- package/dist/team-manager.js.map +1 -0
- package/dist/types.d.ts +653 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
package/dist/devices.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { devices as playwrightDevices } from 'playwright';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in device profiles covering a range of form factors.
|
|
4
|
+
* Uses Playwright's device descriptors where available,
|
|
5
|
+
* with custom desktop profiles added.
|
|
6
|
+
*/
|
|
7
|
+
export const builtinDevices = [
|
|
8
|
+
// Mobile phones
|
|
9
|
+
{
|
|
10
|
+
name: 'iPhone 14',
|
|
11
|
+
category: 'mobile',
|
|
12
|
+
contextOptions: playwrightDevices['iPhone 14'] ?? {
|
|
13
|
+
viewport: { width: 390, height: 844 },
|
|
14
|
+
deviceScaleFactor: 3,
|
|
15
|
+
isMobile: true,
|
|
16
|
+
hasTouch: true,
|
|
17
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'iPhone 12',
|
|
22
|
+
category: 'mobile',
|
|
23
|
+
contextOptions: playwrightDevices['iPhone 12'] ?? {
|
|
24
|
+
viewport: { width: 390, height: 844 },
|
|
25
|
+
deviceScaleFactor: 3,
|
|
26
|
+
isMobile: true,
|
|
27
|
+
hasTouch: true,
|
|
28
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Pixel 7',
|
|
33
|
+
category: 'mobile',
|
|
34
|
+
contextOptions: playwrightDevices['Pixel 7'] ?? {
|
|
35
|
+
viewport: { width: 412, height: 915 },
|
|
36
|
+
deviceScaleFactor: 2.625,
|
|
37
|
+
isMobile: true,
|
|
38
|
+
hasTouch: true,
|
|
39
|
+
userAgent: 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Galaxy S9+',
|
|
44
|
+
category: 'mobile',
|
|
45
|
+
contextOptions: playwrightDevices['Galaxy S9+'] ?? {
|
|
46
|
+
viewport: { width: 320, height: 658 },
|
|
47
|
+
deviceScaleFactor: 4.5,
|
|
48
|
+
isMobile: true,
|
|
49
|
+
hasTouch: true,
|
|
50
|
+
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
// Tablets
|
|
54
|
+
{
|
|
55
|
+
name: 'iPad Pro 11',
|
|
56
|
+
category: 'tablet',
|
|
57
|
+
contextOptions: playwrightDevices['iPad Pro 11'] ?? {
|
|
58
|
+
viewport: { width: 834, height: 1194 },
|
|
59
|
+
deviceScaleFactor: 2,
|
|
60
|
+
isMobile: true,
|
|
61
|
+
hasTouch: true,
|
|
62
|
+
userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'iPad Mini',
|
|
67
|
+
category: 'tablet',
|
|
68
|
+
contextOptions: playwrightDevices['iPad Mini'] ?? {
|
|
69
|
+
viewport: { width: 768, height: 1024 },
|
|
70
|
+
deviceScaleFactor: 2,
|
|
71
|
+
isMobile: true,
|
|
72
|
+
hasTouch: true,
|
|
73
|
+
userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
// Desktops
|
|
77
|
+
{
|
|
78
|
+
name: 'Desktop 1920x1080',
|
|
79
|
+
category: 'desktop',
|
|
80
|
+
contextOptions: {
|
|
81
|
+
viewport: { width: 1920, height: 1080 },
|
|
82
|
+
deviceScaleFactor: 1,
|
|
83
|
+
isMobile: false,
|
|
84
|
+
hasTouch: false,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'Desktop 1366x768',
|
|
89
|
+
category: 'desktop',
|
|
90
|
+
contextOptions: {
|
|
91
|
+
viewport: { width: 1366, height: 768 },
|
|
92
|
+
deviceScaleFactor: 1,
|
|
93
|
+
isMobile: false,
|
|
94
|
+
hasTouch: false,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'Desktop 1440x900',
|
|
99
|
+
category: 'desktop',
|
|
100
|
+
contextOptions: {
|
|
101
|
+
viewport: { width: 1440, height: 900 },
|
|
102
|
+
deviceScaleFactor: 2,
|
|
103
|
+
isMobile: false,
|
|
104
|
+
hasTouch: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'Desktop 2560x1440',
|
|
109
|
+
category: 'desktop',
|
|
110
|
+
contextOptions: {
|
|
111
|
+
viewport: { width: 2560, height: 1440 },
|
|
112
|
+
deviceScaleFactor: 1,
|
|
113
|
+
isMobile: false,
|
|
114
|
+
hasTouch: false,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
/**
|
|
119
|
+
* Manages device assignment via round-robin rotation.
|
|
120
|
+
*
|
|
121
|
+
* Each actor gets the next device in the pool. The rotation advances
|
|
122
|
+
* globally across all actors and scenes within a run, so no one "picks"
|
|
123
|
+
* their device — it just rotates around.
|
|
124
|
+
*
|
|
125
|
+
* The pool can be the built-in set or a custom set from config.
|
|
126
|
+
*/
|
|
127
|
+
export class DeviceRotation {
|
|
128
|
+
pool;
|
|
129
|
+
index = 0;
|
|
130
|
+
constructor(devices) {
|
|
131
|
+
this.pool = devices && devices.length > 0 ? devices : builtinDevices;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the next device in rotation.
|
|
135
|
+
* Advances the internal counter so successive calls yield different devices.
|
|
136
|
+
*/
|
|
137
|
+
next() {
|
|
138
|
+
const device = this.pool[this.index % this.pool.length];
|
|
139
|
+
this.index++;
|
|
140
|
+
return device;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Peek at the next device without advancing the counter.
|
|
144
|
+
*/
|
|
145
|
+
peek() {
|
|
146
|
+
return this.pool[this.index % this.pool.length];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Reset rotation to the beginning.
|
|
150
|
+
*/
|
|
151
|
+
reset() {
|
|
152
|
+
this.index = 0;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the current rotation index (for reporting).
|
|
156
|
+
*/
|
|
157
|
+
get currentIndex() {
|
|
158
|
+
return this.index;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the full device pool.
|
|
162
|
+
*/
|
|
163
|
+
get devices() {
|
|
164
|
+
return this.pool;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=devices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.js","sourceRoot":"","sources":["../src/devices.ts"],"names":[],"mappings":"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"}
|
package/dist/dsl.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { DslTarget } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Text DSL Grammar:
|
|
4
|
+
*
|
|
5
|
+
* <action> <selector> [<value>]
|
|
6
|
+
*
|
|
7
|
+
* Actions:
|
|
8
|
+
* openTo <url> - Navigate to URL
|
|
9
|
+
* see <selector> - Wait for element visible
|
|
10
|
+
* notSee <selector> - Wait for element hidden
|
|
11
|
+
* seeText <text> - Wait for text visible
|
|
12
|
+
* seeToast <selector> - Wait for element appear then disappear
|
|
13
|
+
* click [<selector>] - Click element (or current scope if no selector)
|
|
14
|
+
* typeInto <selector> <value> - Fill input
|
|
15
|
+
* check <selector> - Check checkbox
|
|
16
|
+
* select <selector> <value> - Select dropdown option
|
|
17
|
+
* wait <ms> - Wait milliseconds
|
|
18
|
+
* emit <message> - Emit to message bus
|
|
19
|
+
* waitFor <message> - Block until message arrives on the bus
|
|
20
|
+
* warnIf <selector> <message> - Register script warning
|
|
21
|
+
* up [<selector>] - Navigate scope to ancestor (or page root if no selector)
|
|
22
|
+
* prev - Return to previous scope
|
|
23
|
+
* scrollToBottom - Scroll current scope to bottom
|
|
24
|
+
* seeInView <selector> - Wait for element visible AND in viewport (no scroll)
|
|
25
|
+
*
|
|
26
|
+
* Selectors can be:
|
|
27
|
+
* - Simple: 'button'
|
|
28
|
+
* - Nested: 'modal form submit-button'
|
|
29
|
+
* - With key: ['playlist-row', '12345'] (as JSON in text)
|
|
30
|
+
*
|
|
31
|
+
* Examples:
|
|
32
|
+
* 'openTo /dashboard'
|
|
33
|
+
* 'see main-content'
|
|
34
|
+
* 'click modal close-button'
|
|
35
|
+
* 'typeInto username-input testuser'
|
|
36
|
+
* 'warnIf welcome-modal should not see welcome - user has dismiss flag'
|
|
37
|
+
*/
|
|
38
|
+
export type DslAction = string;
|
|
39
|
+
/**
|
|
40
|
+
* Parse a DSL action string into its components
|
|
41
|
+
*/
|
|
42
|
+
export interface ParsedAction {
|
|
43
|
+
action: string;
|
|
44
|
+
selector?: string;
|
|
45
|
+
value?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function parseAction(line: string): ParsedAction;
|
|
48
|
+
/**
|
|
49
|
+
* Parse a multiline DSL string into individual action lines.
|
|
50
|
+
* Skips empty lines and comments (lines starting with # or //).
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseDslLines(text: string): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Apply a single parsed DSL action to any target that has DSL methods.
|
|
55
|
+
*
|
|
56
|
+
* This is the synchronous core — it calls the method on the target without
|
|
57
|
+
* awaiting. For scene-model targets (ActorHandle / ActionChain) the method
|
|
58
|
+
* returns an ActionChain; for reactive targets it returns the actor. Either
|
|
59
|
+
* way the caller doesn't inspect the return value.
|
|
60
|
+
*/
|
|
61
|
+
export declare function applyDslAction(target: DslTarget, parsed: ParsedAction): void;
|
|
62
|
+
/**
|
|
63
|
+
* Define a macro as a named sequence of DSL actions
|
|
64
|
+
*/
|
|
65
|
+
export type Macro = DslAction[];
|
|
66
|
+
/**
|
|
67
|
+
* Register a named macro.
|
|
68
|
+
*
|
|
69
|
+
* Macros use `[namespace.field]` interpolation:
|
|
70
|
+
* - `[self.field]` — current actor's fields
|
|
71
|
+
* - `[alias.field]` — aliased actor from macro call (e.g., `target=alice`)
|
|
72
|
+
* - `[team.field]` — team metadata
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* defineMacro('login', [
|
|
77
|
+
* 'see login-form',
|
|
78
|
+
* 'typeInto username [self.username]',
|
|
79
|
+
* 'typeInto password [self.password]',
|
|
80
|
+
* 'click submit-button',
|
|
81
|
+
* 'see dashboard',
|
|
82
|
+
* ])
|
|
83
|
+
*
|
|
84
|
+
* defineMacro('send-friend-request', [
|
|
85
|
+
* 'typeInto search [target.username]',
|
|
86
|
+
* 'click send-request-button',
|
|
87
|
+
* ])
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function defineMacro(name: string, actions: Macro): void;
|
|
91
|
+
/**
|
|
92
|
+
* Get a registered macro by name
|
|
93
|
+
*/
|
|
94
|
+
export declare function getMacro(name: string): Macro | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Clear all registered macros
|
|
97
|
+
*/
|
|
98
|
+
export declare function clearMacros(): void;
|
|
99
|
+
//# sourceMappingURL=dsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsl.d.ts","sourceRoot":"","sources":["../src/dsl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAoD9B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAsDtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKpD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA6F5E;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,SAAS,EAAE,CAAA;AAO/B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAExD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/dist/dsl.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the last token from a string.
|
|
3
|
+
* A token is either a quoted string ('...' or "...") or a single word.
|
|
4
|
+
*
|
|
5
|
+
* @returns { before: string, token: string } where `before` is everything
|
|
6
|
+
* before the last token (trimmed), and `token` is the extracted value
|
|
7
|
+
* (with quotes removed if quoted).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* extractLastToken('modal search-input hello')
|
|
11
|
+
* // => { before: 'modal search-input', token: 'hello' }
|
|
12
|
+
*
|
|
13
|
+
* extractLastToken("search-input 'hello world'")
|
|
14
|
+
* // => { before: 'search-input', token: 'hello world' }
|
|
15
|
+
*
|
|
16
|
+
* extractLastToken('single')
|
|
17
|
+
* // => { before: '', token: 'single' }
|
|
18
|
+
*/
|
|
19
|
+
function extractLastToken(str) {
|
|
20
|
+
const trimmed = str.trim();
|
|
21
|
+
// Check if ends with a quoted string
|
|
22
|
+
const lastChar = trimmed[trimmed.length - 1];
|
|
23
|
+
if (lastChar === "'" || lastChar === '"') {
|
|
24
|
+
// Find the matching opening quote
|
|
25
|
+
const quote = lastChar;
|
|
26
|
+
let i = trimmed.length - 2;
|
|
27
|
+
while (i >= 0 && trimmed[i] !== quote) {
|
|
28
|
+
i--;
|
|
29
|
+
}
|
|
30
|
+
if (i >= 0) {
|
|
31
|
+
// Found matching quote
|
|
32
|
+
const token = trimmed.slice(i + 1, -1); // Remove quotes
|
|
33
|
+
const before = trimmed.slice(0, i).trim();
|
|
34
|
+
return { before, token };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// No quotes — last word is the token
|
|
38
|
+
const lastSpace = trimmed.lastIndexOf(' ');
|
|
39
|
+
if (lastSpace === -1) {
|
|
40
|
+
return { before: '', token: trimmed };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
before: trimmed.slice(0, lastSpace).trim(),
|
|
44
|
+
token: trimmed.slice(lastSpace + 1),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function parseAction(line) {
|
|
48
|
+
const trimmed = line.trim();
|
|
49
|
+
if (!trimmed) {
|
|
50
|
+
throw new Error('Empty action line');
|
|
51
|
+
}
|
|
52
|
+
// Split on first space to get action name
|
|
53
|
+
const firstSpace = trimmed.indexOf(' ');
|
|
54
|
+
if (firstSpace === -1) {
|
|
55
|
+
// Action with no arguments (click, prev, scrollToBottom)
|
|
56
|
+
return { action: trimmed };
|
|
57
|
+
}
|
|
58
|
+
const action = trimmed.slice(0, firstSpace);
|
|
59
|
+
const rest = trimmed.slice(firstSpace + 1).trim();
|
|
60
|
+
// Actions that take only a selector
|
|
61
|
+
const selectorOnlyActions = ['see', 'seeInView', 'notSee', 'click', 'check', 'seeToast', 'up'];
|
|
62
|
+
// Actions that take a value only (no selector)
|
|
63
|
+
const valueOnlyActions = ['openTo', 'seeText', 'wait', 'emit', 'waitFor'];
|
|
64
|
+
// Actions that take selector + value (everything after first selector word is value)
|
|
65
|
+
const selectorValueActions = ['typeInto', 'select', 'warnIf'];
|
|
66
|
+
if (valueOnlyActions.includes(action)) {
|
|
67
|
+
return { action, value: rest };
|
|
68
|
+
}
|
|
69
|
+
if (selectorOnlyActions.includes(action)) {
|
|
70
|
+
return { action, selector: rest };
|
|
71
|
+
}
|
|
72
|
+
if (selectorValueActions.includes(action)) {
|
|
73
|
+
// For these, selector can be multi-word (nested), value is the last token.
|
|
74
|
+
// A token is either a quoted string ('...' or "...") or a single word.
|
|
75
|
+
//
|
|
76
|
+
// Examples:
|
|
77
|
+
// typeInto email alice@test.com → selector=email, value=alice@test.com
|
|
78
|
+
// typeInto modal search-input hello → selector="modal search-input", value=hello
|
|
79
|
+
// typeInto search-input 'hello world' → selector=search-input, value="hello world"
|
|
80
|
+
// warnIf modal 'should not appear' → selector=modal, value="should not appear"
|
|
81
|
+
const { before, token } = extractLastToken(rest);
|
|
82
|
+
if (before) {
|
|
83
|
+
return { action, selector: before, value: token };
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Only one token — it's the selector, no value
|
|
87
|
+
return { action, selector: token };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Unknown action - treat as selector-only
|
|
91
|
+
return { action, selector: rest };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Parse a multiline DSL string into individual action lines.
|
|
95
|
+
* Skips empty lines and comments (lines starting with # or //).
|
|
96
|
+
*/
|
|
97
|
+
export function parseDslLines(text) {
|
|
98
|
+
return text
|
|
99
|
+
.split('\n')
|
|
100
|
+
.map((line) => line.trim())
|
|
101
|
+
.filter((line) => line && !line.startsWith('#') && !line.startsWith('//'));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Apply a single parsed DSL action to any target that has DSL methods.
|
|
105
|
+
*
|
|
106
|
+
* This is the synchronous core — it calls the method on the target without
|
|
107
|
+
* awaiting. For scene-model targets (ActorHandle / ActionChain) the method
|
|
108
|
+
* returns an ActionChain; for reactive targets it returns the actor. Either
|
|
109
|
+
* way the caller doesn't inspect the return value.
|
|
110
|
+
*/
|
|
111
|
+
export function applyDslAction(target, parsed) {
|
|
112
|
+
const { action, selector, value } = parsed;
|
|
113
|
+
switch (action) {
|
|
114
|
+
case 'openTo':
|
|
115
|
+
if (!value)
|
|
116
|
+
throw new Error('openTo requires a URL');
|
|
117
|
+
target.openTo(value);
|
|
118
|
+
break;
|
|
119
|
+
case 'see':
|
|
120
|
+
if (!selector)
|
|
121
|
+
throw new Error('see requires a selector');
|
|
122
|
+
target.see(selector);
|
|
123
|
+
break;
|
|
124
|
+
case 'seeInView':
|
|
125
|
+
if (!selector)
|
|
126
|
+
throw new Error('seeInView requires a selector');
|
|
127
|
+
target.seeInView(selector);
|
|
128
|
+
break;
|
|
129
|
+
case 'notSee':
|
|
130
|
+
if (!selector)
|
|
131
|
+
throw new Error('notSee requires a selector');
|
|
132
|
+
target.notSee(selector);
|
|
133
|
+
break;
|
|
134
|
+
case 'seeText':
|
|
135
|
+
if (!value)
|
|
136
|
+
throw new Error('seeText requires text');
|
|
137
|
+
target.seeText(value);
|
|
138
|
+
break;
|
|
139
|
+
case 'seeToast':
|
|
140
|
+
if (!selector)
|
|
141
|
+
throw new Error('seeToast requires a selector');
|
|
142
|
+
target.seeToast(selector);
|
|
143
|
+
break;
|
|
144
|
+
case 'click':
|
|
145
|
+
target.click(selector);
|
|
146
|
+
break;
|
|
147
|
+
case 'typeInto':
|
|
148
|
+
if (!selector)
|
|
149
|
+
throw new Error('typeInto requires a selector');
|
|
150
|
+
if (!value)
|
|
151
|
+
throw new Error('typeInto requires a value');
|
|
152
|
+
target.typeInto(selector, value);
|
|
153
|
+
break;
|
|
154
|
+
case 'check':
|
|
155
|
+
if (!selector)
|
|
156
|
+
throw new Error('check requires a selector');
|
|
157
|
+
target.check(selector);
|
|
158
|
+
break;
|
|
159
|
+
case 'select':
|
|
160
|
+
if (!selector)
|
|
161
|
+
throw new Error('select requires a selector');
|
|
162
|
+
if (!value)
|
|
163
|
+
throw new Error('select requires a value');
|
|
164
|
+
target.select(selector, value);
|
|
165
|
+
break;
|
|
166
|
+
case 'wait':
|
|
167
|
+
if (!value)
|
|
168
|
+
throw new Error('wait requires milliseconds');
|
|
169
|
+
const ms = parseInt(value, 10);
|
|
170
|
+
if (isNaN(ms))
|
|
171
|
+
throw new Error(`wait requires a number, got: ${value}`);
|
|
172
|
+
target.wait(ms);
|
|
173
|
+
break;
|
|
174
|
+
case 'emit':
|
|
175
|
+
if (!value)
|
|
176
|
+
throw new Error('emit requires a message');
|
|
177
|
+
target.emit(value);
|
|
178
|
+
break;
|
|
179
|
+
case 'warnIf':
|
|
180
|
+
if (!selector)
|
|
181
|
+
throw new Error('warnIf requires a selector');
|
|
182
|
+
if (!value)
|
|
183
|
+
throw new Error('warnIf requires a message');
|
|
184
|
+
target.warnIf(selector, value);
|
|
185
|
+
break;
|
|
186
|
+
case 'up':
|
|
187
|
+
target.up(selector);
|
|
188
|
+
break;
|
|
189
|
+
case 'prev':
|
|
190
|
+
target.prev();
|
|
191
|
+
break;
|
|
192
|
+
case 'scrollToBottom':
|
|
193
|
+
target.scrollToBottom();
|
|
194
|
+
break;
|
|
195
|
+
case 'waitFor':
|
|
196
|
+
if (!value)
|
|
197
|
+
throw new Error('waitFor requires a message');
|
|
198
|
+
target.waitFor(value);
|
|
199
|
+
break;
|
|
200
|
+
default:
|
|
201
|
+
throw new Error(`Unknown DSL action: ${action}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Macro registry for reusable action sequences
|
|
206
|
+
*/
|
|
207
|
+
const macroRegistry = new Map();
|
|
208
|
+
/**
|
|
209
|
+
* Register a named macro.
|
|
210
|
+
*
|
|
211
|
+
* Macros use `[namespace.field]` interpolation:
|
|
212
|
+
* - `[self.field]` — current actor's fields
|
|
213
|
+
* - `[alias.field]` — aliased actor from macro call (e.g., `target=alice`)
|
|
214
|
+
* - `[team.field]` — team metadata
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* defineMacro('login', [
|
|
219
|
+
* 'see login-form',
|
|
220
|
+
* 'typeInto username [self.username]',
|
|
221
|
+
* 'typeInto password [self.password]',
|
|
222
|
+
* 'click submit-button',
|
|
223
|
+
* 'see dashboard',
|
|
224
|
+
* ])
|
|
225
|
+
*
|
|
226
|
+
* defineMacro('send-friend-request', [
|
|
227
|
+
* 'typeInto search [target.username]',
|
|
228
|
+
* 'click send-request-button',
|
|
229
|
+
* ])
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export function defineMacro(name, actions) {
|
|
233
|
+
macroRegistry.set(name, actions);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get a registered macro by name
|
|
237
|
+
*/
|
|
238
|
+
export function getMacro(name) {
|
|
239
|
+
return macroRegistry.get(name);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Clear all registered macros
|
|
243
|
+
*/
|
|
244
|
+
export function clearMacros() {
|
|
245
|
+
macroRegistry.clear();
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=dsl.js.map
|
package/dist/dsl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsl.js","sourceRoot":"","sources":["../src/dsl.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { scene } from './scene.js';
|
|
2
|
+
export { defineConfig } from './config.js';
|
|
3
|
+
export { flow } from './reactive.js';
|
|
4
|
+
export { defineMacro, getMacro, clearMacros } from './dsl.js';
|
|
5
|
+
export type { DslAction, Macro } from './dsl.js';
|
|
6
|
+
export { parseMarkdownScenes, loadMarkdownScene } from './markdown-scene.js';
|
|
7
|
+
export type { MarkdownScene, ActorBlock, SceneAction } from './markdown-scene.js';
|
|
8
|
+
export { setAliases, getAliases, clearAliases, explainSelector } from './selectors.js';
|
|
9
|
+
export { DeviceRotation, builtinDevices } from './devices.js';
|
|
10
|
+
export type { DeviceProfile } from './devices.js';
|
|
11
|
+
export { SwarmTrigger } from './swarm.js';
|
|
12
|
+
export type { ScenetestConfig, TeamConfig, ActorConfig, SceneContext, SequentialActorHandle, ActionChain, SceneReport, RunReport, AssertionResult, ScriptWarning, Selector, ConcurrentActorHandle, FlowContext, FlowFn, SwarmConfig, SwarmReport, SwarmSceneResult, SwarmRunDetail, SwarmClassification, } from './types.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAGpC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7D,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAGhD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5E,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGjF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGtF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGzC,YAAY,EACV,eAAe,EACf,UAAU,EACV,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,WAAW,EACX,MAAM,EACN,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Public API for scene specs
|
|
2
|
+
export { scene } from './scene.js';
|
|
3
|
+
export { defineConfig } from './config.js';
|
|
4
|
+
// Reactive flow API
|
|
5
|
+
export { flow } from './reactive.js';
|
|
6
|
+
// Text DSL for declarative scenes
|
|
7
|
+
export { defineMacro, getMacro, clearMacros } from './dsl.js';
|
|
8
|
+
// Markdown scene parser
|
|
9
|
+
export { parseMarkdownScenes, loadMarkdownScene } from './markdown-scene.js';
|
|
10
|
+
// Selector utilities
|
|
11
|
+
export { setAliases, getAliases, clearAliases, explainSelector } from './selectors.js';
|
|
12
|
+
// Device rotation
|
|
13
|
+
export { DeviceRotation, builtinDevices } from './devices.js';
|
|
14
|
+
// Swarm mode
|
|
15
|
+
export { SwarmTrigger } from './swarm.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,oBAAoB;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,kCAAkC;AAClC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG7D,wBAAwB;AACxB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAG5E,qBAAqB;AACrB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEtF,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAG7D,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhF"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize scenetest folder structure in the given directory.
|
|
5
|
+
*/
|
|
6
|
+
export async function init(cwd, options = {}) {
|
|
7
|
+
const scenesDir = path.join(cwd, 'scenes');
|
|
8
|
+
const configPath = path.join(cwd, 'scenetest.config.ts');
|
|
9
|
+
if (!options.force && fs.existsSync(scenesDir)) {
|
|
10
|
+
console.log('scenes/ directory already exists. Use --force to overwrite.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
fs.mkdirSync(scenesDir, { recursive: true });
|
|
14
|
+
if (!fs.existsSync(configPath) || options.force) {
|
|
15
|
+
fs.writeFileSync(configPath, `import { defineConfig } from '@scenetest/scenes'
|
|
16
|
+
|
|
17
|
+
export default defineConfig({
|
|
18
|
+
baseUrl: 'http://localhost:5173',
|
|
19
|
+
scenes: './scenes',
|
|
20
|
+
})
|
|
21
|
+
`);
|
|
22
|
+
console.log('Created scenetest.config.ts');
|
|
23
|
+
}
|
|
24
|
+
console.log('Created scenes/ directory');
|
|
25
|
+
console.log('Run `pnpm scenetest` to start running scene specs.');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAMvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,UAAuB,EAAE;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAA;IAExD,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAA;QAC1E,OAAM;IACR,CAAC;IAED,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAChD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE;;;;;;CAMhC,CAAC,CAAA;QACE,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;IAC5C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;IACxC,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;AACnE,CAAC"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAK/D"}
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { pathToFileURL } from 'url';
|
|
2
|
+
import { createJiti } from 'jiti';
|
|
3
|
+
const jiti = createJiti(import.meta.url);
|
|
4
|
+
export async function importFile(filepath) {
|
|
5
|
+
if (filepath.endsWith('.ts')) {
|
|
6
|
+
return jiti.import(filepath);
|
|
7
|
+
}
|
|
8
|
+
return import(pathToFileURL(filepath).href);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAEjC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAA;AAC7C,CAAC"}
|