@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,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message bus for inter-actor coordination.
|
|
3
|
+
*
|
|
4
|
+
* Key behavior: Messages are "sticky" - they persist on the bus.
|
|
5
|
+
* If you listen AFTER a message was emitted, you still receive it (once).
|
|
6
|
+
* This prevents race conditions when declaring causality early in scenes.
|
|
7
|
+
*/
|
|
8
|
+
export class MessageBus {
|
|
9
|
+
emittedMessages = new Set();
|
|
10
|
+
listeners = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Emit a message to the bus.
|
|
13
|
+
* All current and future listeners for this message will be triggered.
|
|
14
|
+
*/
|
|
15
|
+
emit(message) {
|
|
16
|
+
this.emittedMessages.add(message);
|
|
17
|
+
// Trigger any waiting listeners
|
|
18
|
+
const callbacks = this.listeners.get(message);
|
|
19
|
+
if (callbacks) {
|
|
20
|
+
for (const cb of callbacks) {
|
|
21
|
+
cb();
|
|
22
|
+
}
|
|
23
|
+
this.listeners.delete(message);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Wait for a message to be emitted.
|
|
28
|
+
* If the message was already emitted, resolves immediately.
|
|
29
|
+
*/
|
|
30
|
+
waitFor(message, timeout = 30000) {
|
|
31
|
+
// If already emitted, resolve immediately (sticky behavior)
|
|
32
|
+
if (this.emittedMessages.has(message)) {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const timer = setTimeout(() => {
|
|
37
|
+
// Remove this listener on timeout
|
|
38
|
+
const callbacks = this.listeners.get(message);
|
|
39
|
+
if (callbacks) {
|
|
40
|
+
const index = callbacks.indexOf(callback);
|
|
41
|
+
if (index !== -1) {
|
|
42
|
+
callbacks.splice(index, 1);
|
|
43
|
+
}
|
|
44
|
+
if (callbacks.length === 0) {
|
|
45
|
+
this.listeners.delete(message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
reject(new Error(`Timeout waiting for message: "${message}"`));
|
|
49
|
+
}, timeout);
|
|
50
|
+
const callback = () => {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
resolve();
|
|
53
|
+
};
|
|
54
|
+
const callbacks = this.listeners.get(message) || [];
|
|
55
|
+
callbacks.push(callback);
|
|
56
|
+
this.listeners.set(message, callbacks);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if a message has been emitted.
|
|
61
|
+
*/
|
|
62
|
+
hasEmitted(message) {
|
|
63
|
+
return this.emittedMessages.has(message);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Clear all messages and listeners.
|
|
67
|
+
* Call this between scene runs.
|
|
68
|
+
*/
|
|
69
|
+
clear() {
|
|
70
|
+
this.emittedMessages.clear();
|
|
71
|
+
this.listeners.clear();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=message-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-bus.js","sourceRoot":"","sources":["../src/message-bus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,UAAU;IACb,eAAe,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAA;IAExD;;;OAGG;IACH,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEjC,gCAAgC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC3B,EAAE,EAAE,CAAA;YACN,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,OAAe,EAAE,OAAO,GAAG,KAAK;QACtC,4DAA4D;QAC5D,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,kCAAkC;gBAClC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBAC7C,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;oBACzC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACjB,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;oBAC5B,CAAC;oBACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBAChC,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,OAAO,GAAG,CAAC,CAAC,CAAA;YAChE,CAAC,EAAE,OAAO,CAAC,CAAA;YAEX,MAAM,QAAQ,GAAG,GAAG,EAAE;gBACpB,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,OAAO,EAAE,CAAA;YACX,CAAC,CAAA;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;YACnD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QACxC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,OAAe;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1C,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;QAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reactive flow execution model.
|
|
3
|
+
*
|
|
4
|
+
* In the standard `scene()` model, `await` is the trigger — actions queue
|
|
5
|
+
* on a chain and execute only when awaited. The test writer carries a
|
|
6
|
+
* mental timeline: "has this happened yet? do I need to wait?"
|
|
7
|
+
*
|
|
8
|
+
* In the reactive `flow()` model:
|
|
9
|
+
*
|
|
10
|
+
* 1. Actor DSL calls are **declarations** — they push to a persistent
|
|
11
|
+
* per-actor queue and return immediately.
|
|
12
|
+
* 2. After the flow function returns, all actors **drain their queues
|
|
13
|
+
* concurrently** — each actor advances through its own queue as fast
|
|
14
|
+
* as the DOM allows.
|
|
15
|
+
* 3. `see()`, `seeText()`, and friends already poll/wait for DOM state,
|
|
16
|
+
* so cross-actor synchronization happens *through the application
|
|
17
|
+
* under test* rather than through `await` ordering in the script.
|
|
18
|
+
*
|
|
19
|
+
* This eliminates the "test-writer conceptualisation race condition" —
|
|
20
|
+
* you can declare `bob.seeText('Hello')` at any point relative to
|
|
21
|
+
* `alice.click('send')` and it will work, because bob's queue reaches
|
|
22
|
+
* that instruction whenever it reaches it. If the text is already
|
|
23
|
+
* there, it resolves instantly. If not, it polls. No `waitUntil`
|
|
24
|
+
* API is needed.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { flow } from '@scenetest/scenes'
|
|
29
|
+
*
|
|
30
|
+
* flow('two users chat', ({ actor }) => {
|
|
31
|
+
* const alice = actor('alice')
|
|
32
|
+
* const bob = actor('bob')
|
|
33
|
+
*
|
|
34
|
+
* // Declaration phase — nothing executes yet
|
|
35
|
+
* alice.openTo('/chat')
|
|
36
|
+
* alice.see('message-input').typeInto('message-input', 'Hello!').click('send')
|
|
37
|
+
*
|
|
38
|
+
* bob.openTo('/chat')
|
|
39
|
+
* bob.seeText('Hello!')
|
|
40
|
+
* // ↑ no race: bob will poll for "Hello!" whenever he gets to that
|
|
41
|
+
* // instruction in his queue. alice may or may not have sent it yet.
|
|
42
|
+
*
|
|
43
|
+
* // When this function returns, browsers launch in parallel,
|
|
44
|
+
* // then both actors drain concurrently.
|
|
45
|
+
* })
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
import type { Page } from 'playwright';
|
|
49
|
+
import type { ActorConfig, Selector, TimelineEntry, ScriptWarning, FlowFn, ConcurrentActorHandle } from './types.js';
|
|
50
|
+
import { MessageBus } from './message-bus.js';
|
|
51
|
+
/**
|
|
52
|
+
* Concurrent actor handle implementation (declarative / flow model).
|
|
53
|
+
*
|
|
54
|
+
* Unlike `SequentialActorHandleImpl`, every DSL method pushes to a single
|
|
55
|
+
* persistent queue on the actor itself and returns `this`. Scope lives on
|
|
56
|
+
* the actor so it flows naturally through the sequential drain.
|
|
57
|
+
*/
|
|
58
|
+
export declare class ConcurrentActorHandleImpl implements ConcurrentActorHandle {
|
|
59
|
+
private bus;
|
|
60
|
+
private timeline;
|
|
61
|
+
private warnings;
|
|
62
|
+
private actionTimeout;
|
|
63
|
+
private warnAfter;
|
|
64
|
+
readonly role: string;
|
|
65
|
+
readonly id: string;
|
|
66
|
+
readonly username?: string;
|
|
67
|
+
readonly email?: string;
|
|
68
|
+
readonly password?: string;
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
private _page;
|
|
71
|
+
private queue;
|
|
72
|
+
private currentScope;
|
|
73
|
+
private scopeStack;
|
|
74
|
+
private warningTriggers;
|
|
75
|
+
private conditionalMonitors;
|
|
76
|
+
private _draining;
|
|
77
|
+
private _aborted;
|
|
78
|
+
private _abortReason?;
|
|
79
|
+
/** Registry of all actors in this scene, for [actor.field] interpolation */
|
|
80
|
+
private _actorRegistry;
|
|
81
|
+
/** Team metadata for [team.field] interpolation */
|
|
82
|
+
private _teamMetadata;
|
|
83
|
+
constructor(role: string, config: ActorConfig, page: Page | null, bus: MessageBus, timeline: TimelineEntry[], warnings: ScriptWarning[], actionTimeout: number, warnAfter: number);
|
|
84
|
+
/**
|
|
85
|
+
* Playwright page for this actor.
|
|
86
|
+
* Available after page initialization (before drain).
|
|
87
|
+
*/
|
|
88
|
+
get page(): Page;
|
|
89
|
+
/**
|
|
90
|
+
* Set the Playwright page for this actor.
|
|
91
|
+
* Called by the flow runner after declaration, before drain.
|
|
92
|
+
*/
|
|
93
|
+
_setPage(page: Page): void;
|
|
94
|
+
/**
|
|
95
|
+
* Set the actor registry for [actor.field] interpolation.
|
|
96
|
+
* Called by the flow runner after all actors are created.
|
|
97
|
+
*/
|
|
98
|
+
_setActorRegistry(registry: Map<string, ConcurrentActorHandle>): void;
|
|
99
|
+
/**
|
|
100
|
+
* Set team metadata for [team.field] interpolation.
|
|
101
|
+
*/
|
|
102
|
+
_setTeamMetadata(metadata: Record<string, string>): void;
|
|
103
|
+
private push;
|
|
104
|
+
/** Number of queued actions */
|
|
105
|
+
get pending(): number;
|
|
106
|
+
/** Whether this actor has been aborted by a peer failure */
|
|
107
|
+
get aborted(): boolean;
|
|
108
|
+
private get scope();
|
|
109
|
+
openTo(url: string): this;
|
|
110
|
+
scrollToBottom(): this;
|
|
111
|
+
see(selector: Selector): this;
|
|
112
|
+
seeInView(selector: Selector): this;
|
|
113
|
+
notSee(selector: Selector): this;
|
|
114
|
+
seeText(text: string): this;
|
|
115
|
+
seeToast(selector: Selector): this;
|
|
116
|
+
click(selector?: Selector): this;
|
|
117
|
+
typeInto(selector: Selector, value: string): this;
|
|
118
|
+
check(selector: Selector): this;
|
|
119
|
+
select(selector: Selector, value: string): this;
|
|
120
|
+
up(selector?: Selector): this;
|
|
121
|
+
prev(): this;
|
|
122
|
+
wait(ms: number): this;
|
|
123
|
+
emit(message: string): this;
|
|
124
|
+
/**
|
|
125
|
+
* Block this actor's queue until a message arrives on the bus.
|
|
126
|
+
*
|
|
127
|
+
* Because the bus is sticky, if the message was already emitted this
|
|
128
|
+
* resolves immediately — no race.
|
|
129
|
+
*/
|
|
130
|
+
waitFor(message: string): this;
|
|
131
|
+
do(fn: (page: Page) => Promise<void>): this;
|
|
132
|
+
/**
|
|
133
|
+
* Queue actions from a text DSL string.
|
|
134
|
+
*
|
|
135
|
+
* Parses the multiline string into individual action lines and pushes
|
|
136
|
+
* each onto the actor's queue. Returns `this` for chaining.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* user.dsl(`
|
|
141
|
+
* openTo /login
|
|
142
|
+
* see login-form
|
|
143
|
+
* typeInto email alice@test.com
|
|
144
|
+
* click submit
|
|
145
|
+
* `)
|
|
146
|
+
* user.see('dashboard')
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
dsl(text: string): this;
|
|
150
|
+
/**
|
|
151
|
+
* Interpolate [namespace.field] references in a string.
|
|
152
|
+
*
|
|
153
|
+
* Supported namespaces:
|
|
154
|
+
* - [self.field] — this actor's own fields
|
|
155
|
+
* - [role.field] — another actor's fields (requires actor registry)
|
|
156
|
+
* - [team.field] — team metadata
|
|
157
|
+
*/
|
|
158
|
+
private _interpolate;
|
|
159
|
+
/**
|
|
160
|
+
* Register a persistent warning trigger.
|
|
161
|
+
* If the selector becomes visible during any action, a warning is recorded.
|
|
162
|
+
* Unlike the `scene()` model, there are no watchers that clear after
|
|
163
|
+
* each await — warnings are the right primitive for reactive flows.
|
|
164
|
+
*/
|
|
165
|
+
warnIf(selector: Selector, message: string): void;
|
|
166
|
+
/**
|
|
167
|
+
* Conditional monitor — "if this appears at any point, do these things."
|
|
168
|
+
*
|
|
169
|
+
* Registers a persistent monitor that polls during every subsequent
|
|
170
|
+
* action in the actor's queue. When `selector` becomes visible, the
|
|
171
|
+
* sub-actions declared inside `callback` execute inline (the current
|
|
172
|
+
* action is paused, the sub-actions run, then the action resumes).
|
|
173
|
+
* One-shot: the monitor stops polling after it fires once.
|
|
174
|
+
*
|
|
175
|
+
* The callback receives `this` (the actor), but while it runs the
|
|
176
|
+
* actor's internal queue is temporarily swapped so that DSL calls
|
|
177
|
+
* push to the monitor's sub-action list instead of the main queue.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* alice.openTo('/app')
|
|
182
|
+
* alice.if('welcome-modal', a => a.click('dismiss'))
|
|
183
|
+
* alice.see('dashboard')
|
|
184
|
+
* // If the welcome modal pops up during any action after the if(),
|
|
185
|
+
* // click('dismiss') fires inline, then the action resumes.
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
if(selector: Selector, callback: (actor: this) => void): void;
|
|
189
|
+
/**
|
|
190
|
+
* Abort this actor's queue. Called by `drainAll` when a peer actor fails.
|
|
191
|
+
* The actor will throw at its next action boundary.
|
|
192
|
+
*/
|
|
193
|
+
abort(reason: string): void;
|
|
194
|
+
/**
|
|
195
|
+
* Drain the action queue.
|
|
196
|
+
*
|
|
197
|
+
* Executes all queued actions sequentially. Called automatically by the
|
|
198
|
+
* flow runner after the declaration phase completes.
|
|
199
|
+
*
|
|
200
|
+
* Each action is executed with concurrent warning-trigger polling (same
|
|
201
|
+
* approach as `ActionChainImpl.executeWithWatchers`).
|
|
202
|
+
*/
|
|
203
|
+
drain(): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Execute a single action while polling monitors concurrently.
|
|
206
|
+
*
|
|
207
|
+
* Handles both warning triggers (record a warning) and conditional
|
|
208
|
+
* monitors (execute sub-actions inline).
|
|
209
|
+
*/
|
|
210
|
+
private executeWithMonitors;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Drain all actors concurrently.
|
|
214
|
+
*
|
|
215
|
+
* When any actor fails, all others are aborted so they don't hang waiting
|
|
216
|
+
* for DOM state that will never arrive. We use `Promise.allSettled` to
|
|
217
|
+
* collect all results and throw the first *original* (non-abort) error.
|
|
218
|
+
*/
|
|
219
|
+
export declare function drainAll(actors: ConcurrentActorHandleImpl[]): Promise<void>;
|
|
220
|
+
/**
|
|
221
|
+
* Define a reactive flow.
|
|
222
|
+
*
|
|
223
|
+
* Inside the flow function, actor DSL calls just queue actions — nothing
|
|
224
|
+
* executes. After the function returns, all actors drain their queues
|
|
225
|
+
* concurrently through the application.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* import { flow } from '@scenetest/scenes'
|
|
230
|
+
*
|
|
231
|
+
* flow('user updates profile', ({ actor }) => {
|
|
232
|
+
* const user = actor('user')
|
|
233
|
+
*
|
|
234
|
+
* user.openTo('/login')
|
|
235
|
+
* user
|
|
236
|
+
* .see('login-form')
|
|
237
|
+
* .typeInto('email', user.email!)
|
|
238
|
+
* .typeInto('password', user.password!)
|
|
239
|
+
* .click('submit')
|
|
240
|
+
*
|
|
241
|
+
* user.see('dashboard')
|
|
242
|
+
* user.openTo('/profile')
|
|
243
|
+
* user
|
|
244
|
+
* .see('profile-form')
|
|
245
|
+
* .typeInto('name-input', 'New Name')
|
|
246
|
+
* .click('save-button')
|
|
247
|
+
*
|
|
248
|
+
* user.seeText('New Name')
|
|
249
|
+
* })
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @example Multi-actor
|
|
253
|
+
* ```ts
|
|
254
|
+
* flow('two users chat', ({ actor }) => {
|
|
255
|
+
* const alice = actor('alice')
|
|
256
|
+
* const bob = actor('bob')
|
|
257
|
+
*
|
|
258
|
+
* alice.openTo('/chat')
|
|
259
|
+
* alice.see('message-input').typeInto('message-input', 'Hello!').click('send')
|
|
260
|
+
*
|
|
261
|
+
* bob.openTo('/chat')
|
|
262
|
+
* bob.seeText('Hello!')
|
|
263
|
+
* })
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
export declare function flow(name: string, fn: FlowFn): void;
|
|
267
|
+
//# sourceMappingURL=reactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"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"}
|