@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swarm.test.js","sourceRoot":"","sources":["../../src/__tests__/swarm.test.ts"],"names":[],"mappings":"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"}
|
package/dist/actor.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Page, BrowserContext } from 'playwright';
|
|
2
|
+
import type { ActorConfig, SequentialActorHandle, ActionChain, AssertionResult, TimelineEntry, ScriptWarning, Selector } from './types.js';
|
|
3
|
+
import { MessageBus } from './message-bus.js';
|
|
4
|
+
/**
|
|
5
|
+
* Registered watcher for conditional handling
|
|
6
|
+
*/
|
|
7
|
+
interface Watcher {
|
|
8
|
+
selector: Selector;
|
|
9
|
+
callback: () => Promise<void>;
|
|
10
|
+
triggered: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Registered warning trigger - fires when selector becomes visible
|
|
14
|
+
*/
|
|
15
|
+
interface WarningTrigger {
|
|
16
|
+
selector: Selector;
|
|
17
|
+
message: string;
|
|
18
|
+
triggered: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Sequential actor handle implementation (classic driver model).
|
|
22
|
+
* Each DSL method creates a new ActionChain, executed on await.
|
|
23
|
+
*/
|
|
24
|
+
export declare class SequentialActorHandleImpl implements SequentialActorHandle {
|
|
25
|
+
readonly config: ActorConfig;
|
|
26
|
+
private bus;
|
|
27
|
+
private timeline;
|
|
28
|
+
private warnings;
|
|
29
|
+
private actionTimeout;
|
|
30
|
+
private warnAfter;
|
|
31
|
+
readonly role: string;
|
|
32
|
+
readonly page: Page;
|
|
33
|
+
readonly context: BrowserContext;
|
|
34
|
+
readonly assertions: AssertionResult[];
|
|
35
|
+
private watchers;
|
|
36
|
+
private warningTriggers;
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly username?: string;
|
|
39
|
+
readonly email?: string;
|
|
40
|
+
readonly password?: string;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
constructor(role: string, config: ActorConfig, page: Page, context: BrowserContext, bus: MessageBus, timeline: TimelineEntry[], warnings: ScriptWarning[], actionTimeout: number, warnAfter: number);
|
|
43
|
+
/**
|
|
44
|
+
* Get registered watchers (used by ActionChainImpl)
|
|
45
|
+
*/
|
|
46
|
+
getWatchers(): Watcher[];
|
|
47
|
+
/**
|
|
48
|
+
* Get registered warning triggers (used by ActionChainImpl)
|
|
49
|
+
*/
|
|
50
|
+
getWarningTriggers(): WarningTrigger[];
|
|
51
|
+
/**
|
|
52
|
+
* Clear all registered watchers (called after each await)
|
|
53
|
+
* Note: Warning triggers persist across the entire scene
|
|
54
|
+
*/
|
|
55
|
+
clearWatchers(): void;
|
|
56
|
+
private createChain;
|
|
57
|
+
openTo(url: string): ActionChain;
|
|
58
|
+
see(selector: Selector): ActionChain;
|
|
59
|
+
seeInView(selector: Selector): ActionChain;
|
|
60
|
+
notSee(selector: Selector): ActionChain;
|
|
61
|
+
seeText(text: string): ActionChain;
|
|
62
|
+
seeToast(selector: Selector): ActionChain;
|
|
63
|
+
click(selector?: Selector): ActionChain;
|
|
64
|
+
typeInto(selector: Selector, value: string): ActionChain;
|
|
65
|
+
check(selector: Selector): ActionChain;
|
|
66
|
+
select(selector: Selector, value: string): ActionChain;
|
|
67
|
+
wait(ms: number): ActionChain;
|
|
68
|
+
emit(message: string): ActionChain;
|
|
69
|
+
waitFor(message: string): ActionChain;
|
|
70
|
+
do(fn: (page: Page) => Promise<void>): ActionChain;
|
|
71
|
+
scrollToBottom(): ActionChain;
|
|
72
|
+
up(selector?: Selector): ActionChain;
|
|
73
|
+
prev(): ActionChain;
|
|
74
|
+
dsl(text: string): ActionChain;
|
|
75
|
+
/**
|
|
76
|
+
* Register a conditional watcher. If the selector becomes visible during
|
|
77
|
+
* the next awaited action, the callback will be executed.
|
|
78
|
+
* Watchers are cleared after each await.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* // Handle optional welcome page
|
|
83
|
+
* user.if('welcome-page', () => user.click('dismiss-button'))
|
|
84
|
+
* await user.see('dashboard') // if welcome-page appears, clicks dismiss first
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
if(selector: Selector, callback: () => Promise<void>): void;
|
|
88
|
+
/**
|
|
89
|
+
* Register a script warning. If the selector becomes visible during
|
|
90
|
+
* subsequent actions, a warning is recorded (but test continues).
|
|
91
|
+
* Unlike watchers, warning triggers persist for the entire scene.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* // We shouldn't see the welcome modal - user has dismiss flag
|
|
96
|
+
* user.warnIf('welcome-modal', 'should not see welcome - user has dismiss flag')
|
|
97
|
+
* await user.openTo('/dashboard')
|
|
98
|
+
* await user.see('main-content')
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
warnIf(selector: Selector, message: string): void;
|
|
102
|
+
}
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=actor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../src/actor.ts"],"names":[],"mappings":"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"}
|
package/dist/actor.js
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { resolveSelector } from './selectors.js';
|
|
2
|
+
import { parseDslLines, parseAction, applyDslAction } from './dsl.js';
|
|
3
|
+
/**
|
|
4
|
+
* Format a Selector for display in logs/errors
|
|
5
|
+
*/
|
|
6
|
+
function formatSelector(selector) {
|
|
7
|
+
return selector;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Chainable action builder implementation.
|
|
11
|
+
* Queues actions and executes them in sequence when awaited.
|
|
12
|
+
* Tracks current scope for scoped operations.
|
|
13
|
+
*/
|
|
14
|
+
class ActionChainImpl {
|
|
15
|
+
actor;
|
|
16
|
+
page;
|
|
17
|
+
bus;
|
|
18
|
+
timeline;
|
|
19
|
+
warnings;
|
|
20
|
+
actionTimeout;
|
|
21
|
+
warnAfter;
|
|
22
|
+
actions = [];
|
|
23
|
+
// Current scope - starts as page, changes with see()
|
|
24
|
+
currentScope;
|
|
25
|
+
// Previous scope stack for prev()
|
|
26
|
+
scopeStack = [];
|
|
27
|
+
constructor(actor, page, bus, timeline, warnings, actionTimeout, warnAfter) {
|
|
28
|
+
this.actor = actor;
|
|
29
|
+
this.page = page;
|
|
30
|
+
this.bus = bus;
|
|
31
|
+
this.timeline = timeline;
|
|
32
|
+
this.warnings = warnings;
|
|
33
|
+
this.actionTimeout = actionTimeout;
|
|
34
|
+
this.warnAfter = warnAfter;
|
|
35
|
+
this.currentScope = page;
|
|
36
|
+
}
|
|
37
|
+
addAction(name, target, execute) {
|
|
38
|
+
this.actions.push({ name, target, execute });
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Push current scope to stack and set new scope
|
|
43
|
+
*/
|
|
44
|
+
pushScope(newScope) {
|
|
45
|
+
this.scopeStack.push(this.currentScope);
|
|
46
|
+
this.currentScope = newScope;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the current scope for resolving selectors
|
|
50
|
+
*/
|
|
51
|
+
getScope() {
|
|
52
|
+
return this.currentScope;
|
|
53
|
+
}
|
|
54
|
+
openTo(url) {
|
|
55
|
+
return this.addAction('openTo', url, async () => {
|
|
56
|
+
await this.page.goto(url, { timeout: this.actionTimeout });
|
|
57
|
+
// Reset scope to page after navigation
|
|
58
|
+
this.currentScope = this.page;
|
|
59
|
+
this.scopeStack = [];
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
see(selector) {
|
|
63
|
+
const target = formatSelector(selector);
|
|
64
|
+
return this.addAction('see', target, async () => {
|
|
65
|
+
const locator = resolveSelector(this.getScope(), selector);
|
|
66
|
+
await locator.waitFor({ state: 'visible', timeout: this.actionTimeout });
|
|
67
|
+
// Update scope to the found element
|
|
68
|
+
this.pushScope(locator);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
seeInView(selector) {
|
|
72
|
+
const target = formatSelector(selector);
|
|
73
|
+
return this.addAction('seeInView', target, async () => {
|
|
74
|
+
const locator = resolveSelector(this.getScope(), selector);
|
|
75
|
+
await locator.waitFor({ state: 'visible', timeout: this.actionTimeout });
|
|
76
|
+
// Verify element is within the viewport without scrolling
|
|
77
|
+
const inViewport = await locator.evaluate((el) => {
|
|
78
|
+
const rect = el.getBoundingClientRect();
|
|
79
|
+
const vh = window.innerHeight || document.documentElement.clientHeight;
|
|
80
|
+
const vw = window.innerWidth || document.documentElement.clientWidth;
|
|
81
|
+
return rect.top >= 0 && rect.left >= 0 && rect.bottom <= vh && rect.right <= vw;
|
|
82
|
+
});
|
|
83
|
+
if (!inViewport) {
|
|
84
|
+
throw new Error(`Element "${selector}" is visible but not in the viewport (requires scrolling)`);
|
|
85
|
+
}
|
|
86
|
+
this.pushScope(locator);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
notSee(selector) {
|
|
90
|
+
const target = formatSelector(selector);
|
|
91
|
+
return this.addAction('notSee', target, async () => {
|
|
92
|
+
await resolveSelector(this.getScope(), selector).waitFor({ state: 'hidden', timeout: this.actionTimeout });
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
seeText(text) {
|
|
96
|
+
return this.addAction('seeText', text, async () => {
|
|
97
|
+
const locator = this.page.getByText(text).first();
|
|
98
|
+
await locator.waitFor({ state: 'visible', timeout: this.actionTimeout });
|
|
99
|
+
// Update scope to the found element
|
|
100
|
+
this.pushScope(locator);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
seeToast(selector) {
|
|
104
|
+
const target = formatSelector(selector);
|
|
105
|
+
return this.addAction('seeToast', target, async () => {
|
|
106
|
+
const locator = resolveSelector(this.getScope(), selector);
|
|
107
|
+
await locator.waitFor({ state: 'visible', timeout: this.actionTimeout });
|
|
108
|
+
await locator.waitFor({ state: 'hidden', timeout: this.actionTimeout });
|
|
109
|
+
// Don't update scope for toasts since they disappear
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
click(selector) {
|
|
113
|
+
if (!selector) {
|
|
114
|
+
return this.addAction('click', '(scope)', async () => {
|
|
115
|
+
const scope = this.getScope();
|
|
116
|
+
if (scope === this.page) {
|
|
117
|
+
throw new Error('click with no selector requires a scope (use see() first)');
|
|
118
|
+
}
|
|
119
|
+
await scope.click({ timeout: this.actionTimeout });
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const target = formatSelector(selector);
|
|
123
|
+
return this.addAction('click', target, async () => {
|
|
124
|
+
await resolveSelector(this.getScope(), selector).click({ timeout: this.actionTimeout });
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
typeInto(selector, value) {
|
|
128
|
+
const target = `${formatSelector(selector)}=${value}`;
|
|
129
|
+
return this.addAction('typeInto', target, async () => {
|
|
130
|
+
await resolveSelector(this.getScope(), selector).fill(value, { timeout: this.actionTimeout });
|
|
131
|
+
// typeInto stays in current scope
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
check(selector) {
|
|
135
|
+
const target = formatSelector(selector);
|
|
136
|
+
return this.addAction('check', target, async () => {
|
|
137
|
+
await resolveSelector(this.getScope(), selector).check({ timeout: this.actionTimeout });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
select(selector, value) {
|
|
141
|
+
const target = `${formatSelector(selector)}=${value}`;
|
|
142
|
+
return this.addAction('select', target, async () => {
|
|
143
|
+
await resolveSelector(this.getScope(), selector).selectOption(value, { timeout: this.actionTimeout });
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
wait(ms) {
|
|
147
|
+
return this.addAction('wait', `${ms}ms`, async () => {
|
|
148
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
emit(message) {
|
|
152
|
+
return this.addAction('emit', message, async () => {
|
|
153
|
+
this.bus.emit(message);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
waitFor(message) {
|
|
157
|
+
return this.addAction('waitFor', message, async () => {
|
|
158
|
+
await this.bus.waitFor(message);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
do(fn) {
|
|
162
|
+
return this.addAction('do', 'custom', async () => {
|
|
163
|
+
await fn(this.page);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
scrollToBottom() {
|
|
167
|
+
return this.addAction('scrollToBottom', undefined, async () => {
|
|
168
|
+
const scope = this.getScope();
|
|
169
|
+
if (scope === this.page) {
|
|
170
|
+
await this.page.evaluate(() => {
|
|
171
|
+
window.scrollTo(0, document.body.scrollHeight);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
await scope.evaluate((el) => {
|
|
176
|
+
let current = el;
|
|
177
|
+
while (current) {
|
|
178
|
+
const style = window.getComputedStyle(current);
|
|
179
|
+
if ((style.overflowY === 'auto' || style.overflowY === 'scroll') &&
|
|
180
|
+
current.scrollHeight > current.clientHeight) {
|
|
181
|
+
current.scrollTop = current.scrollHeight;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
current = current.parentElement;
|
|
185
|
+
}
|
|
186
|
+
window.scrollTo(0, document.body.scrollHeight);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
up(selector) {
|
|
192
|
+
if (!selector) {
|
|
193
|
+
return this.addAction('up', '(root)', async () => {
|
|
194
|
+
this.currentScope = this.page;
|
|
195
|
+
this.scopeStack = [];
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const target = formatSelector(selector);
|
|
199
|
+
return this.addAction('up', target, async () => {
|
|
200
|
+
const ancestorLocator = resolveSelector(this.page, selector);
|
|
201
|
+
await ancestorLocator.waitFor({ state: 'visible', timeout: this.actionTimeout });
|
|
202
|
+
this.pushScope(ancestorLocator);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
prev() {
|
|
206
|
+
return this.addAction('prev', undefined, async () => {
|
|
207
|
+
if (this.scopeStack.length === 0) {
|
|
208
|
+
// No previous scope, reset to page
|
|
209
|
+
this.currentScope = this.page;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
this.currentScope = this.scopeStack.pop();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
dsl(text) {
|
|
217
|
+
const lines = parseDslLines(text);
|
|
218
|
+
for (const line of lines) {
|
|
219
|
+
const parsed = parseAction(line);
|
|
220
|
+
applyDslAction(this, parsed);
|
|
221
|
+
}
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Delegate warnIf to the owning actor.
|
|
226
|
+
* Not part of the ActionChain public interface, but needed so the chain
|
|
227
|
+
* satisfies DslTarget when dsl() text includes a `warnIf` line.
|
|
228
|
+
*/
|
|
229
|
+
warnIf(selector, message) {
|
|
230
|
+
this.actor.warnIf(selector, message);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Execute a single action while also polling for registered watchers and warnings.
|
|
234
|
+
* If a watcher's selector becomes visible, its callback is executed.
|
|
235
|
+
* If a warning trigger's selector becomes visible, a warning is recorded.
|
|
236
|
+
*/
|
|
237
|
+
async executeWithWatchers(action) {
|
|
238
|
+
const watchers = this.actor.getWatchers();
|
|
239
|
+
const warningTriggers = this.actor.getWarningTriggers();
|
|
240
|
+
if (watchers.length === 0 && warningTriggers.length === 0) {
|
|
241
|
+
await action.execute();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
let actionComplete = false;
|
|
245
|
+
let actionError = null;
|
|
246
|
+
// Run action
|
|
247
|
+
const actionPromise = action.execute()
|
|
248
|
+
.then(() => {
|
|
249
|
+
actionComplete = true;
|
|
250
|
+
})
|
|
251
|
+
.catch((err) => {
|
|
252
|
+
actionError = err;
|
|
253
|
+
actionComplete = true;
|
|
254
|
+
});
|
|
255
|
+
// Poll for watchers and warnings concurrently
|
|
256
|
+
const pollWatchers = async () => {
|
|
257
|
+
const pollInterval = 50;
|
|
258
|
+
while (!actionComplete) {
|
|
259
|
+
// Check watchers
|
|
260
|
+
for (const watcher of watchers) {
|
|
261
|
+
if (watcher.triggered)
|
|
262
|
+
continue;
|
|
263
|
+
try {
|
|
264
|
+
const locator = resolveSelector(this.page, watcher.selector);
|
|
265
|
+
const isVisible = await locator.isVisible();
|
|
266
|
+
if (isVisible) {
|
|
267
|
+
watcher.triggered = true;
|
|
268
|
+
// Execute callback - this happens "inline" during the wait
|
|
269
|
+
await watcher.callback();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Ignore errors from isVisible check
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Check warning triggers
|
|
277
|
+
for (const trigger of warningTriggers) {
|
|
278
|
+
if (trigger.triggered)
|
|
279
|
+
continue;
|
|
280
|
+
try {
|
|
281
|
+
const locator = resolveSelector(this.page, trigger.selector);
|
|
282
|
+
const isVisible = await locator.isVisible();
|
|
283
|
+
if (isVisible) {
|
|
284
|
+
trigger.triggered = true;
|
|
285
|
+
// Record the warning
|
|
286
|
+
this.warnings.push({
|
|
287
|
+
selector: formatSelector(trigger.selector),
|
|
288
|
+
message: trigger.message,
|
|
289
|
+
timestamp: Date.now(),
|
|
290
|
+
actor: this.actor.role,
|
|
291
|
+
duringAction: `${action.name}(${action.target ?? ''})`,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// Ignore errors from isVisible check
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (!actionComplete) {
|
|
300
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
// Run both concurrently
|
|
305
|
+
await Promise.all([actionPromise, pollWatchers()]);
|
|
306
|
+
if (actionError) {
|
|
307
|
+
throw actionError;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Execute all queued actions in sequence.
|
|
312
|
+
* This is called when the chain is awaited.
|
|
313
|
+
* Emits console warnings if actions take longer than warnAfter threshold.
|
|
314
|
+
*/
|
|
315
|
+
async execute() {
|
|
316
|
+
for (const action of this.actions) {
|
|
317
|
+
const start = Date.now();
|
|
318
|
+
const entry = {
|
|
319
|
+
action: action.name,
|
|
320
|
+
target: action.target,
|
|
321
|
+
actor: this.actor.role,
|
|
322
|
+
timestamp: start,
|
|
323
|
+
};
|
|
324
|
+
// Set up warning timer
|
|
325
|
+
let warned = false;
|
|
326
|
+
const warnTimer = setInterval(() => {
|
|
327
|
+
const elapsed = Date.now() - start;
|
|
328
|
+
if (!warned) {
|
|
329
|
+
warned = true;
|
|
330
|
+
console.warn(`⏱ ${elapsed}ms - ${action.name}(${action.target ?? ''}) - still waiting...`);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
console.warn(`⏱ ${elapsed}ms - ${action.name}(${action.target ?? ''}) - still waiting...`);
|
|
334
|
+
}
|
|
335
|
+
}, this.warnAfter);
|
|
336
|
+
try {
|
|
337
|
+
await this.executeWithWatchers(action);
|
|
338
|
+
entry.duration = Date.now() - start;
|
|
339
|
+
// Log completion if we warned
|
|
340
|
+
if (warned) {
|
|
341
|
+
console.warn(`✓ ${entry.duration}ms - ${action.name}(${action.target ?? ''}) - completed`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
entry.duration = Date.now() - start;
|
|
346
|
+
entry.error = err instanceof Error ? err.message : String(err);
|
|
347
|
+
this.timeline.push(entry);
|
|
348
|
+
throw err;
|
|
349
|
+
}
|
|
350
|
+
finally {
|
|
351
|
+
clearInterval(warnTimer);
|
|
352
|
+
}
|
|
353
|
+
this.timeline.push(entry);
|
|
354
|
+
}
|
|
355
|
+
this.actions = [];
|
|
356
|
+
// Clear watchers after chain completes
|
|
357
|
+
this.actor.clearWatchers();
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Make the chain thenable so it can be awaited
|
|
361
|
+
*/
|
|
362
|
+
then(onfulfilled, onrejected) {
|
|
363
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Sequential actor handle implementation (classic driver model).
|
|
368
|
+
* Each DSL method creates a new ActionChain, executed on await.
|
|
369
|
+
*/
|
|
370
|
+
export class SequentialActorHandleImpl {
|
|
371
|
+
config;
|
|
372
|
+
bus;
|
|
373
|
+
timeline;
|
|
374
|
+
warnings;
|
|
375
|
+
actionTimeout;
|
|
376
|
+
warnAfter;
|
|
377
|
+
role;
|
|
378
|
+
page;
|
|
379
|
+
context;
|
|
380
|
+
assertions = [];
|
|
381
|
+
// Registered watchers for conditional handling
|
|
382
|
+
watchers = [];
|
|
383
|
+
// Registered warning triggers
|
|
384
|
+
warningTriggers = [];
|
|
385
|
+
// Forward config properties
|
|
386
|
+
id;
|
|
387
|
+
username;
|
|
388
|
+
email;
|
|
389
|
+
password;
|
|
390
|
+
constructor(role, config, page, context, bus, timeline, warnings, actionTimeout, warnAfter) {
|
|
391
|
+
this.config = config;
|
|
392
|
+
this.bus = bus;
|
|
393
|
+
this.timeline = timeline;
|
|
394
|
+
this.warnings = warnings;
|
|
395
|
+
this.actionTimeout = actionTimeout;
|
|
396
|
+
this.warnAfter = warnAfter;
|
|
397
|
+
this.role = role;
|
|
398
|
+
this.page = page;
|
|
399
|
+
this.context = context;
|
|
400
|
+
this.id = config.id;
|
|
401
|
+
// Copy all config properties to this instance
|
|
402
|
+
for (const [key, value] of Object.entries(config)) {
|
|
403
|
+
if (!(key in this)) {
|
|
404
|
+
this[key] = value;
|
|
405
|
+
}
|
|
406
|
+
else if (key !== 'id') {
|
|
407
|
+
this[key] = value;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get registered watchers (used by ActionChainImpl)
|
|
413
|
+
*/
|
|
414
|
+
getWatchers() {
|
|
415
|
+
return this.watchers;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Get registered warning triggers (used by ActionChainImpl)
|
|
419
|
+
*/
|
|
420
|
+
getWarningTriggers() {
|
|
421
|
+
return this.warningTriggers;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Clear all registered watchers (called after each await)
|
|
425
|
+
* Note: Warning triggers persist across the entire scene
|
|
426
|
+
*/
|
|
427
|
+
clearWatchers() {
|
|
428
|
+
this.watchers = [];
|
|
429
|
+
}
|
|
430
|
+
createChain() {
|
|
431
|
+
return new ActionChainImpl(this, this.page, this.bus, this.timeline, this.warnings, this.actionTimeout, this.warnAfter);
|
|
432
|
+
}
|
|
433
|
+
openTo(url) {
|
|
434
|
+
return this.createChain().openTo(url);
|
|
435
|
+
}
|
|
436
|
+
see(selector) {
|
|
437
|
+
return this.createChain().see(selector);
|
|
438
|
+
}
|
|
439
|
+
seeInView(selector) {
|
|
440
|
+
return this.createChain().seeInView(selector);
|
|
441
|
+
}
|
|
442
|
+
notSee(selector) {
|
|
443
|
+
return this.createChain().notSee(selector);
|
|
444
|
+
}
|
|
445
|
+
seeText(text) {
|
|
446
|
+
return this.createChain().seeText(text);
|
|
447
|
+
}
|
|
448
|
+
seeToast(selector) {
|
|
449
|
+
return this.createChain().seeToast(selector);
|
|
450
|
+
}
|
|
451
|
+
click(selector) {
|
|
452
|
+
return this.createChain().click(selector);
|
|
453
|
+
}
|
|
454
|
+
typeInto(selector, value) {
|
|
455
|
+
return this.createChain().typeInto(selector, value);
|
|
456
|
+
}
|
|
457
|
+
check(selector) {
|
|
458
|
+
return this.createChain().check(selector);
|
|
459
|
+
}
|
|
460
|
+
select(selector, value) {
|
|
461
|
+
return this.createChain().select(selector, value);
|
|
462
|
+
}
|
|
463
|
+
wait(ms) {
|
|
464
|
+
return this.createChain().wait(ms);
|
|
465
|
+
}
|
|
466
|
+
emit(message) {
|
|
467
|
+
return this.createChain().emit(message);
|
|
468
|
+
}
|
|
469
|
+
waitFor(message) {
|
|
470
|
+
return this.createChain().waitFor(message);
|
|
471
|
+
}
|
|
472
|
+
do(fn) {
|
|
473
|
+
return this.createChain().do(fn);
|
|
474
|
+
}
|
|
475
|
+
scrollToBottom() {
|
|
476
|
+
return this.createChain().scrollToBottom();
|
|
477
|
+
}
|
|
478
|
+
up(selector) {
|
|
479
|
+
return this.createChain().up(selector);
|
|
480
|
+
}
|
|
481
|
+
prev() {
|
|
482
|
+
return this.createChain().prev();
|
|
483
|
+
}
|
|
484
|
+
dsl(text) {
|
|
485
|
+
return this.createChain().dsl(text);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Register a conditional watcher. If the selector becomes visible during
|
|
489
|
+
* the next awaited action, the callback will be executed.
|
|
490
|
+
* Watchers are cleared after each await.
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```ts
|
|
494
|
+
* // Handle optional welcome page
|
|
495
|
+
* user.if('welcome-page', () => user.click('dismiss-button'))
|
|
496
|
+
* await user.see('dashboard') // if welcome-page appears, clicks dismiss first
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
if(selector, callback) {
|
|
500
|
+
this.watchers.push({
|
|
501
|
+
selector,
|
|
502
|
+
callback,
|
|
503
|
+
triggered: false,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Register a script warning. If the selector becomes visible during
|
|
508
|
+
* subsequent actions, a warning is recorded (but test continues).
|
|
509
|
+
* Unlike watchers, warning triggers persist for the entire scene.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```ts
|
|
513
|
+
* // We shouldn't see the welcome modal - user has dismiss flag
|
|
514
|
+
* user.warnIf('welcome-modal', 'should not see welcome - user has dismiss flag')
|
|
515
|
+
* await user.openTo('/dashboard')
|
|
516
|
+
* await user.see('main-content')
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
warnIf(selector, message) {
|
|
520
|
+
this.warningTriggers.push({
|
|
521
|
+
selector,
|
|
522
|
+
message,
|
|
523
|
+
triggered: false,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=actor.js.map
|