@serenity-js/core 3.42.2 → 3.43.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/CHANGELOG.md +12 -0
- package/esm/Serenity.d.ts +3 -1
- package/esm/Serenity.d.ts.map +1 -1
- package/esm/Serenity.js +4 -3
- package/esm/Serenity.js.map +1 -1
- package/esm/screenplay/Actor.d.ts +1 -1
- package/esm/screenplay/Actor.d.ts.map +1 -1
- package/esm/screenplay/Actor.js +5 -6
- package/esm/screenplay/Actor.js.map +1 -1
- package/esm/screenplay/abilities/Discardable.d.ts +3 -2
- package/esm/screenplay/abilities/Discardable.d.ts.map +1 -1
- package/esm/screenplay/abilities/Discardable.js +25 -1
- package/esm/screenplay/abilities/Discardable.js.map +1 -1
- package/esm/screenplay/abilities/Initialisable.d.ts +4 -3
- package/esm/screenplay/abilities/Initialisable.d.ts.map +1 -1
- package/esm/screenplay/abilities/Initialisable.js +22 -1
- package/esm/screenplay/abilities/Initialisable.js.map +1 -1
- package/esm/stage/ActorLifecycleManager.d.ts +191 -0
- package/esm/stage/ActorLifecycleManager.d.ts.map +1 -0
- package/esm/stage/ActorLifecycleManager.js +255 -0
- package/esm/stage/ActorLifecycleManager.js.map +1 -0
- package/esm/stage/Stage.d.ts +22 -38
- package/esm/stage/Stage.d.ts.map +1 -1
- package/esm/stage/Stage.js +61 -117
- package/esm/stage/Stage.js.map +1 -1
- package/esm/stage/StageManager.d.ts +2 -4
- package/esm/stage/StageManager.d.ts.map +1 -1
- package/esm/stage/StageManager.js +0 -5
- package/esm/stage/StageManager.js.map +1 -1
- package/esm/stage/index.d.ts +1 -0
- package/esm/stage/index.d.ts.map +1 -1
- package/esm/stage/index.js +1 -0
- package/esm/stage/index.js.map +1 -1
- package/lib/Serenity.d.ts +3 -1
- package/lib/Serenity.d.ts.map +1 -1
- package/lib/Serenity.js +4 -3
- package/lib/Serenity.js.map +1 -1
- package/lib/screenplay/Actor.d.ts +1 -1
- package/lib/screenplay/Actor.d.ts.map +1 -1
- package/lib/screenplay/Actor.js +4 -5
- package/lib/screenplay/Actor.js.map +1 -1
- package/lib/screenplay/abilities/Discardable.d.ts +3 -2
- package/lib/screenplay/abilities/Discardable.d.ts.map +1 -1
- package/lib/screenplay/abilities/Discardable.js +27 -0
- package/lib/screenplay/abilities/Discardable.js.map +1 -1
- package/lib/screenplay/abilities/Initialisable.d.ts +4 -3
- package/lib/screenplay/abilities/Initialisable.d.ts.map +1 -1
- package/lib/screenplay/abilities/Initialisable.js +24 -0
- package/lib/screenplay/abilities/Initialisable.js.map +1 -1
- package/lib/stage/ActorLifecycleManager.d.ts +191 -0
- package/lib/stage/ActorLifecycleManager.d.ts.map +1 -0
- package/lib/stage/ActorLifecycleManager.js +259 -0
- package/lib/stage/ActorLifecycleManager.js.map +1 -0
- package/lib/stage/Stage.d.ts +22 -38
- package/lib/stage/Stage.d.ts.map +1 -1
- package/lib/stage/Stage.js +57 -113
- package/lib/stage/Stage.js.map +1 -1
- package/lib/stage/StageManager.d.ts +2 -4
- package/lib/stage/StageManager.d.ts.map +1 -1
- package/lib/stage/StageManager.js +0 -5
- package/lib/stage/StageManager.js.map +1 -1
- package/lib/stage/index.d.ts +1 -0
- package/lib/stage/index.d.ts.map +1 -1
- package/lib/stage/index.js +1 -0
- package/lib/stage/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Serenity.ts +5 -2
- package/src/screenplay/Actor.ts +6 -9
- package/src/screenplay/abilities/Discardable.ts +7 -2
- package/src/screenplay/abilities/Initialisable.ts +10 -3
- package/src/stage/ActorLifecycleManager.ts +314 -0
- package/src/stage/Stage.ts +87 -165
- package/src/stage/StageManager.ts +3 -7
- package/src/stage/index.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActorLifecycleManager.d.ts","sourceRoot":"","sources":["../../src/stage/ActorLifecycleManager.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAgB,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,YAAY,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,qBAAqB;IAuB1B,SAAS,CAAC,IAAI,EAAE,IAAI;IACpB,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAC/B,SAAS,CAAC,kBAAkB,EAAE,QAAQ;IAvB1C;;OAEG;IACH,OAAO,CAAC,YAAY,CAAC,CAAQ;IAE7B;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAA+C;IAExE,OAAO,CAAC,iBAAiB,CAA4B;IAErD,OAAO,CAAC,MAAM,CAGb;IAED,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;gBAGT,IAAI,EAAE,IAAI,EACD,KAAK,EAAE,KAAK,EACrB,kBAAkB,EAAE,QAAQ;IAI1C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,kBAAkB,EAAE,EAAE;QAAE,kBAAkB,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI;IAIzE;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;IAI1B;;;;OAIG;IACH,WAAW,IAAI,IAAI;IAInB;;;;;;;;;;;;;OAaG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAwCjC,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,mBAAmB;IAM3B;;;;OAIG;IACI,sBAAsB,IAAI,OAAO;IAIxC;;;;;;;;OAQG;IACI,mBAAmB,IAAI,KAAK;IAQnC;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIpC;;;;OAIG;IACH,YAAY,IAAI,UAAU;IAI1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,EAAE;IAIpC;;;;;;;OAOG;IACH,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAS3C;;;;;;;OAOG;IACH,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAGzC"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ActorLifecycleManager = void 0;
|
|
4
|
+
const tiny_types_1 = require("tiny-types");
|
|
5
|
+
const index_js_1 = require("../errors/index.js");
|
|
6
|
+
const index_js_2 = require("../events/index.js");
|
|
7
|
+
const index_js_3 = require("../model/index.js");
|
|
8
|
+
const index_js_4 = require("../screenplay/index.js");
|
|
9
|
+
/**
|
|
10
|
+
* Manages the lifecycle of [actors](https://serenity-js.org/api/core/class/Actor/) on the [stage](https://serenity-js.org/api/core/class/Stage/),
|
|
11
|
+
* including their creation, retrieval, and tracking of which actors are in the foreground (scene-scoped)
|
|
12
|
+
* versus background (test run-scoped).
|
|
13
|
+
*
|
|
14
|
+
* The `ActorLifecycleManager` is responsible for:
|
|
15
|
+
* - Instantiating and caching actors via the configured [cast](https://serenity-js.org/api/core/class/Cast/)
|
|
16
|
+
* - Tracking which actor is currently in the spotlight (active)
|
|
17
|
+
* - Managing the focus area (foreground vs background) where new actors are created
|
|
18
|
+
* - Providing access to actors for dismissal when scenes or test runs finish
|
|
19
|
+
*
|
|
20
|
+
* ## Default behaviour
|
|
21
|
+
*
|
|
22
|
+
* By default, actors created before the actual test scenario starts, e.g. in beforeAll hooks, are placed in the `'background'` focus area.
|
|
23
|
+
* When a [`SceneStarts`](https://serenity-js.org/api/core-events/class/SceneStarts/) event is announced,
|
|
24
|
+
* the focus switches to `'foreground'`. When a [`SceneFinishes`](https://serenity-js.org/api/core-events/class/SceneFinishes/)
|
|
25
|
+
* event is announced, foreground actors are dismissed, their abilities [discarded](https://serenity-js.org/api/core/interface/Discardable/)
|
|
26
|
+
* and focus returns to `'background'`.
|
|
27
|
+
*
|
|
28
|
+
* ## Custom lifecycle management
|
|
29
|
+
*
|
|
30
|
+
* Test runner adapters like [`@serenity-js/playwright-test`](https://serenity-js.org/api/playwright-test/),
|
|
31
|
+
* where test execution and reporting happen in separate processes, can inject a custom `ActorLifecycleManager` instance
|
|
32
|
+
* to control actor lifecycle programmatically.
|
|
33
|
+
*
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const actorLifecycleManager = new ActorLifecycleManager(cast, clock, interactionTimeout);
|
|
36
|
+
* const serenity = new Serenity(clock, cueTimeout, actorLifecycleManager);
|
|
37
|
+
*
|
|
38
|
+
* // At the start of each test:
|
|
39
|
+
* actorLifecycleManager.switchFocus('foreground');
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* ## Learn more
|
|
43
|
+
* - [`Stage`](https://serenity-js.org/api/core/class/Stage/)
|
|
44
|
+
* - [`Cast`](https://serenity-js.org/api/core/class/Cast/)
|
|
45
|
+
* - [`Actor`](https://serenity-js.org/api/core/class/Actor/)
|
|
46
|
+
*
|
|
47
|
+
* @group Stage
|
|
48
|
+
*/
|
|
49
|
+
class ActorLifecycleManager {
|
|
50
|
+
cast;
|
|
51
|
+
clock;
|
|
52
|
+
interactionTimeout;
|
|
53
|
+
/**
|
|
54
|
+
* The most recent actor referenced via the {@apilink actor} method
|
|
55
|
+
*/
|
|
56
|
+
currentActor;
|
|
57
|
+
/**
|
|
58
|
+
* The scene in which the spotlight was last set.
|
|
59
|
+
* Used to detect when the spotlight shifts to a different scene context.
|
|
60
|
+
*/
|
|
61
|
+
currentActorScene = new index_js_3.CorrelationId('unknown');
|
|
62
|
+
currentFocusValue = 'background';
|
|
63
|
+
actors = {
|
|
64
|
+
'foreground': new Map(),
|
|
65
|
+
'background': new Map(),
|
|
66
|
+
};
|
|
67
|
+
stage;
|
|
68
|
+
constructor(cast, clock, interactionTimeout) {
|
|
69
|
+
this.cast = cast;
|
|
70
|
+
this.clock = clock;
|
|
71
|
+
this.interactionTimeout = interactionTimeout;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Configures the manager with new settings.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Configuration options
|
|
77
|
+
* @param options.interactionTimeout - The maximum time to wait for an interaction to complete
|
|
78
|
+
*/
|
|
79
|
+
configure({ interactionTimeout }) {
|
|
80
|
+
this.interactionTimeout = interactionTimeout;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Associates this manager with a [`Stage`](https://serenity-js.org/api/core/class/Stage/) instance.
|
|
84
|
+
*
|
|
85
|
+
* This method is called automatically by the `Stage` during construction.
|
|
86
|
+
* It establishes the bidirectional relationship between the manager and the stage,
|
|
87
|
+
* allowing the manager to emit [domain events](https://serenity-js.org/api/core-events/class/DomainEvent/)
|
|
88
|
+
* when actors enter the stage or are spotlighted.
|
|
89
|
+
*
|
|
90
|
+
* @param stage - The Stage instance to associate with this manager
|
|
91
|
+
*/
|
|
92
|
+
assignTo(stage) {
|
|
93
|
+
this.stage = stage;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Configures the manager to use the provided [cast](https://serenity-js.org/api/core/class/Cast/) for preparing actors.
|
|
97
|
+
*
|
|
98
|
+
* @param actors - The cast to use for preparing new actors
|
|
99
|
+
*
|
|
100
|
+
* @throws [`ConfigurationError`](https://serenity-js.org/api/core/class/ConfigurationError/)
|
|
101
|
+
* If the provided cast is not defined or doesn't have a `prepare` method
|
|
102
|
+
*/
|
|
103
|
+
engage(actors) {
|
|
104
|
+
this.cast = (0, tiny_types_1.ensure)('actors', actors, (0, tiny_types_1.isDefined)(), (0, tiny_types_1.property)('prepare', (0, tiny_types_1.isDefined)()));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns the current [cast](https://serenity-js.org/api/core/class/Cast/) used for preparing actors.
|
|
108
|
+
*
|
|
109
|
+
* @returns The currently configured cast
|
|
110
|
+
*/
|
|
111
|
+
currentCast() {
|
|
112
|
+
return this.cast;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Instantiates a new [`Actor`](https://serenity-js.org/api/core/class/Actor/) or fetches an existing one
|
|
116
|
+
* identified by their name if they've already been instantiated.
|
|
117
|
+
*
|
|
118
|
+
* When a new actor is instantiated, an [`ActorEntersStage`](https://serenity-js.org/api/core-events/class/ActorEntersStage/)
|
|
119
|
+
* event is announced. When the spotlight shifts to a different actor (or the same actor in a different scene),
|
|
120
|
+
* an [`ActorSpotlighted`](https://serenity-js.org/api/core-events/class/ActorSpotlighted/) event is announced.
|
|
121
|
+
*
|
|
122
|
+
* Actors are first looked up in the `'background'` focus area, then in `'foreground'`.
|
|
123
|
+
* New actors are always created in the current focus area.
|
|
124
|
+
*
|
|
125
|
+
* @param name - Case-sensitive name of the Actor, e.g. `Alice`
|
|
126
|
+
* @returns The actor with the given name
|
|
127
|
+
*/
|
|
128
|
+
actor(name) {
|
|
129
|
+
if (!this.existingActorCalled(name)) {
|
|
130
|
+
const actor = this.prepareActor(new index_js_4.Actor(name, this.stage, [
|
|
131
|
+
new index_js_1.RaiseErrors(this.stage),
|
|
132
|
+
new index_js_4.ScheduleWork(this.clock, this.interactionTimeout)
|
|
133
|
+
]));
|
|
134
|
+
this.actors[this.currentFocusValue].set(actor.name, actor);
|
|
135
|
+
this.stage.announce(new index_js_2.ActorEntersStage(this.stage.currentSceneId(), actor.toJSON(), this.stage.currentTime()));
|
|
136
|
+
}
|
|
137
|
+
const previousActorInSpotlight = this.currentActor;
|
|
138
|
+
const previousSceneOfSpotlightedActor = this.currentActorScene;
|
|
139
|
+
this.currentActor = this.existingActorCalled(name);
|
|
140
|
+
this.currentActorScene = this.stage.currentSceneId();
|
|
141
|
+
const spotlightShifted = this.currentActor !== previousActorInSpotlight
|
|
142
|
+
|| !this.stage.currentSceneId().equals(previousSceneOfSpotlightedActor);
|
|
143
|
+
if (spotlightShifted) {
|
|
144
|
+
this.stage.announce(new index_js_2.ActorSpotlighted(this.stage.currentSceneId(), this.currentActor.toJSON(), this.stage.currentTime()));
|
|
145
|
+
}
|
|
146
|
+
return this.currentActor;
|
|
147
|
+
}
|
|
148
|
+
prepareActor(actor) {
|
|
149
|
+
let preparedActor;
|
|
150
|
+
try {
|
|
151
|
+
preparedActor = this.cast.prepare(actor);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
throw new index_js_1.ConfigurationError(`${this.typeOf(this.cast)} encountered a problem when preparing actor "${actor.name}" for stage`, error);
|
|
155
|
+
}
|
|
156
|
+
if (!(preparedActor instanceof index_js_4.Actor)) {
|
|
157
|
+
throw new index_js_1.ConfigurationError(`Instead of a new instance of actor "${actor.name}", ${this.typeOf(this.cast)} returned ${preparedActor}`);
|
|
158
|
+
}
|
|
159
|
+
return preparedActor;
|
|
160
|
+
}
|
|
161
|
+
typeOf(cast) {
|
|
162
|
+
return cast.constructor === Object
|
|
163
|
+
? 'Cast'
|
|
164
|
+
: cast.constructor.name;
|
|
165
|
+
}
|
|
166
|
+
existingActorCalled(name) {
|
|
167
|
+
return this.actors['background'].has(name)
|
|
168
|
+
? this.actors['background'].get(name)
|
|
169
|
+
: this.actors['foreground'].get(name);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Returns `true` if there is an [`Actor`](https://serenity-js.org/api/core/class/Actor/) in the spotlight, `false` otherwise.
|
|
173
|
+
*
|
|
174
|
+
* @returns `true` if an actor is currently spotlighted
|
|
175
|
+
*/
|
|
176
|
+
hasActorInTheSpotlight() {
|
|
177
|
+
return Boolean(this.currentActor);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns the last [`Actor`](https://serenity-js.org/api/core/class/Actor/) instantiated
|
|
181
|
+
* via [`actor`](https://serenity-js.org/api/core/class/ActorLifecycleManager/#actor).
|
|
182
|
+
*
|
|
183
|
+
* @returns The currently spotlighted actor
|
|
184
|
+
*
|
|
185
|
+
* @throws [`LogicError`](https://serenity-js.org/api/core/class/LogicError/)
|
|
186
|
+
* If no [`Actor`](https://serenity-js.org/api/core/class/Actor/) has been activated yet
|
|
187
|
+
*/
|
|
188
|
+
actorInTheSpotlight() {
|
|
189
|
+
if (!this.currentActor) {
|
|
190
|
+
throw new index_js_1.LogicError(`There is no actor in the spotlight yet. Make sure you instantiate one with stage.actor(actorName) before calling this method.`);
|
|
191
|
+
}
|
|
192
|
+
return this.currentActor;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Switches the focus to the specified stage area.
|
|
196
|
+
*
|
|
197
|
+
* Actors created after this call will be added to the specified area.
|
|
198
|
+
* This method is typically called automatically by the [`Stage`](https://serenity-js.org/api/core/class/Stage/)
|
|
199
|
+
* in response to [`SceneStarts`](https://serenity-js.org/api/core-events/class/SceneStarts/) and
|
|
200
|
+
* [`SceneFinishes`](https://serenity-js.org/api/core-events/class/SceneFinishes/) events.
|
|
201
|
+
*
|
|
202
|
+
* Test runner adapters can also call this method directly to control actor lifecycle
|
|
203
|
+
* when scene events are not available (e.g., in Playwright Test where the reporter
|
|
204
|
+
* runs in a separate process).
|
|
205
|
+
*
|
|
206
|
+
* @param focus - The focus area to switch to: `'foreground'` for scene-scoped actors,
|
|
207
|
+
* `'background'` for test run-scoped actors
|
|
208
|
+
*/
|
|
209
|
+
switchFocus(focus) {
|
|
210
|
+
this.currentFocusValue = focus;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Returns the current focus area.
|
|
214
|
+
*
|
|
215
|
+
* @returns The current focus: `'foreground'` or `'background'`
|
|
216
|
+
*/
|
|
217
|
+
currentFocus() {
|
|
218
|
+
return this.currentFocusValue;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Returns all actors in the specified focus area.
|
|
222
|
+
*
|
|
223
|
+
* This method is used by the [`Stage`](https://serenity-js.org/api/core/class/Stage/) to retrieve
|
|
224
|
+
* actors for dismissal when scenes or test runs finish.
|
|
225
|
+
*
|
|
226
|
+
* @param focus - The focus area to retrieve actors from
|
|
227
|
+
* @returns An array of actors in the specified focus area
|
|
228
|
+
*/
|
|
229
|
+
actorsIn(focus) {
|
|
230
|
+
return Array.from(this.actors[focus].values());
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Clears the spotlight if the current actor is in the specified focus area.
|
|
234
|
+
*
|
|
235
|
+
* This ensures that after actors in a focus area are dismissed, the spotlight
|
|
236
|
+
* doesn't reference a dismissed actor.
|
|
237
|
+
*
|
|
238
|
+
* @param focus - The focus area to check
|
|
239
|
+
*/
|
|
240
|
+
clearSpotlightIfIn(focus) {
|
|
241
|
+
const actors = this.actorsIn(focus);
|
|
242
|
+
if (actors.includes(this.currentActor)) {
|
|
243
|
+
this.currentActor = undefined;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Clears all actors from the specified focus area.
|
|
248
|
+
*
|
|
249
|
+
* This method is called by the [`Stage`](https://serenity-js.org/api/core/class/Stage/) after
|
|
250
|
+
* actors have been dismissed to remove them from the internal tracking maps.
|
|
251
|
+
*
|
|
252
|
+
* @param focus - The focus area to clear
|
|
253
|
+
*/
|
|
254
|
+
clearActorsIn(focus) {
|
|
255
|
+
this.actors[focus].clear();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
exports.ActorLifecycleManager = ActorLifecycleManager;
|
|
259
|
+
//# sourceMappingURL=ActorLifecycleManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActorLifecycleManager.js","sourceRoot":"","sources":["../../src/stage/ActorLifecycleManager.ts"],"names":[],"mappings":";;;AAAA,2CAAyD;AAEzD,iDAAiF;AACjF,iDAAyE;AACzE,gDAAkD;AAElD,qDAA6D;AAc7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAa,qBAAqB;IAuBhB;IACS;IACT;IAvBd;;OAEG;IACK,YAAY,CAAS;IAE7B;;;OAGG;IACK,iBAAiB,GAAkB,IAAI,wBAAa,CAAC,SAAS,CAAC,CAAC;IAEhE,iBAAiB,GAAe,YAAY,CAAC;IAE7C,MAAM,GAA2C;QACrD,YAAY,EAAE,IAAI,GAAG,EAAiB;QACtC,YAAY,EAAE,IAAI,GAAG,EAAiB;KACzC,CAAA;IAES,KAAK,CAAQ;IAEvB,YACc,IAAU,EACD,KAAY,EACrB,kBAA4B;QAF5B,SAAI,GAAJ,IAAI,CAAM;QACD,UAAK,GAAL,KAAK,CAAO;QACrB,uBAAkB,GAAlB,kBAAkB,CAAU;IAE1C,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,EAAE,kBAAkB,EAAoC;QAC9D,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IACjD,CAAC;IAED;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAY;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAY;QACf,IAAI,CAAC,IAAI,GAAG,IAAA,mBAAM,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,EAAC,SAAS,EAAE,IAAA,sBAAS,GAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED;;;;OAIG;IACH,WAAW;QACP,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,KAAK,CAAC,IAAY;QACrB,IAAI,CAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,gBAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE;gBACxD,IAAI,sBAAW,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC3B,IAAI,uBAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,CAAC;aACxD,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAE3D,IAAI,CAAC,KAAK,CAAC,QAAQ,CACf,IAAI,2BAAgB,CAChB,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,EAC3B,KAAK,CAAC,MAAM,EAAE,EACd,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAC3B,CACJ,CAAC;QACN,CAAC;QAED,MAAM,wBAAwB,GAAG,IAAI,CAAC,YAAY,CAAC;QACnD,MAAM,+BAA+B,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAE/D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QAErD,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,KAAK,wBAAwB;eAChE,CAAE,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAE7E,IAAI,gBAAgB,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,CAAC,QAAQ,CACf,IAAI,2BAAgB,CAChB,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,EAC3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAC1B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAC3B,CACJ,CAAC;QACN,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAEO,YAAY,CAAC,KAAY;QAE7B,IAAI,aAAoB,CAAC;QAEzB,IAAI,CAAC;YACD,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,6BAAkB,CAAC,GAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAE,gDAAiD,KAAK,CAAC,IAAK,aAAa,EAAE,KAAK,CAAC,CAAC;QAC9I,CAAC;QAED,IAAI,CAAE,CAAC,aAAa,YAAY,gBAAK,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,6BAAkB,CAAC,uCAAwC,KAAK,CAAC,IAAK,MAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAE,aAAc,aAAc,EAAE,CAAC,CAAC;QAClJ,CAAC;QAED,OAAO,aAAa,CAAC;IACzB,CAAC;IAEO,MAAM,CAAC,IAAU;QACrB,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM;YAC9B,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAChC,CAAC;IAEO,mBAAmB,CAAC,IAAY;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YACtC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACI,sBAAsB;QACzB,OAAO,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;;;OAQG;IACI,mBAAmB;QACtB,IAAI,CAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,qBAAU,CAAC,+HAA+H,CAAC,CAAC;QAC1J,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,KAAiB;QACzB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,YAAY;QACR,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAClC,CAAC;IAED;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAiB;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,KAAiB;QAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAClC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAiB;QAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACJ;AA7PD,sDA6PC"}
|
package/lib/stage/Stage.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import type { SerenityConfig } from '../config/index.js';
|
|
|
2
2
|
import { ErrorFactory, type ErrorOptions, type RuntimeError } from '../errors/index.js';
|
|
3
3
|
import { type DomainEvent, type EmitsDomainEvents } from '../events/index.js';
|
|
4
4
|
import { type ActivityDetails, CorrelationId, type CorrelationIdFactory } from '../model/index.js';
|
|
5
|
-
import { Actor
|
|
6
|
-
import type {
|
|
5
|
+
import type { Actor } from '../screenplay/index.js';
|
|
6
|
+
import type { Clock, Duration, Timestamp } from '../screenplay/index.js';
|
|
7
|
+
import { ActorLifecycleManager } from './ActorLifecycleManager.js';
|
|
7
8
|
import type { Cast } from './Cast.js';
|
|
9
|
+
import type { ListensToDomainEvents } from './ListensToDomainEvents.js';
|
|
8
10
|
import type { StageManager } from './StageManager.js';
|
|
9
11
|
/**
|
|
10
12
|
* Stage is the place where [actors](https://serenity-js.org/api/core/class/Actor/) perform.
|
|
@@ -23,44 +25,28 @@ import type { StageManager } from './StageManager.js';
|
|
|
23
25
|
* @group Stage
|
|
24
26
|
*/
|
|
25
27
|
export declare class Stage implements EmitsDomainEvents {
|
|
26
|
-
private
|
|
27
|
-
private manager;
|
|
28
|
+
private readonly manager;
|
|
28
29
|
private errors;
|
|
29
30
|
private readonly clock;
|
|
30
|
-
private interactionTimeout;
|
|
31
31
|
private readonly sceneIdFactory;
|
|
32
32
|
static readonly unknownSceneId: CorrelationId;
|
|
33
|
-
/**
|
|
34
|
-
* Actors instantiated after the scene has started,
|
|
35
|
-
* who will be dismissed when the scene finishes.
|
|
36
|
-
*/
|
|
37
|
-
private actorsOnFrontStage;
|
|
38
|
-
/**
|
|
39
|
-
* Actors instantiated before the scene has started,
|
|
40
|
-
* who will be dismissed when the test run finishes.
|
|
41
|
-
*/
|
|
42
|
-
private actorsOnBackstage;
|
|
43
|
-
private actorsOnStage;
|
|
44
|
-
/**
|
|
45
|
-
* The most recent actor referenced via the [`Actor`](https://serenity-js.org/api/core/class/Actor/) method
|
|
46
|
-
*/
|
|
47
|
-
private actorInTheSpotlight;
|
|
48
|
-
/**
|
|
49
|
-
* The scene in which the spotlight was last set.
|
|
50
|
-
* Used to detect when the spotlight shifts to a different scene context.
|
|
51
|
-
*/
|
|
52
|
-
private sceneOfSpotlightedActor;
|
|
53
33
|
private currentActivity;
|
|
54
34
|
private currentScene;
|
|
35
|
+
private readonly actorLifecycleManager;
|
|
55
36
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
* @param
|
|
61
|
-
* @param
|
|
62
|
-
|
|
63
|
-
|
|
37
|
+
* Creates a new Stage instance.
|
|
38
|
+
*
|
|
39
|
+
* @param cast - The default cast to use for preparing actors
|
|
40
|
+
* @param manager - The stage manager responsible for notifying listeners of domain events
|
|
41
|
+
* @param errors - Factory for creating runtime errors with proper context
|
|
42
|
+
* @param clock - Clock used for timestamping domain events
|
|
43
|
+
* @param interactionTimeout - Default timeout for actor interactions
|
|
44
|
+
* @param sceneIdFactory - Factory for creating scene correlation IDs
|
|
45
|
+
* @param actorLifecycleManager - Optional custom ActorLifecycleManager instance.
|
|
46
|
+
* When provided, allows test runner adapters to control actor lifecycle programmatically.
|
|
47
|
+
* If not provided, a default manager is created.
|
|
48
|
+
*/
|
|
49
|
+
constructor(cast: Cast, manager: StageManager, errors: ErrorFactory, clock: Clock, interactionTimeout: Duration, sceneIdFactory?: CorrelationIdFactory, actorLifecycleManager?: ActorLifecycleManager);
|
|
64
50
|
configure(options: Pick<SerenityConfig, 'actors' | 'cueTimeout' | 'interactionTimeout' | 'diffFormatter'>): void;
|
|
65
51
|
/**
|
|
66
52
|
* An alias for [`Stage.actor`](https://serenity-js.org/api/core/class/Stage/#actor)
|
|
@@ -97,7 +83,7 @@ export declare class Stage implements EmitsDomainEvents {
|
|
|
97
83
|
engage(actors: Cast): void;
|
|
98
84
|
/**
|
|
99
85
|
* Assigns listeners to be notified of [Serenity/JS domain events](https://serenity-js.org/api/core-events/class/DomainEvent/)
|
|
100
|
-
* emitted via [`Stage.announce`](https://serenity-js.org/api/core/class/Stage/#announce).
|
|
86
|
+
* emitted via [`Stage.announce`](https://serenity-js.org/api/core/class/Stage/#announce).
|
|
101
87
|
*
|
|
102
88
|
* @param listeners
|
|
103
89
|
*/
|
|
@@ -110,6 +96,8 @@ export declare class Stage implements EmitsDomainEvents {
|
|
|
110
96
|
*/
|
|
111
97
|
announce(...events: Array<DomainEvent>): void;
|
|
112
98
|
private announceSingle;
|
|
99
|
+
private notifyOfStageExit;
|
|
100
|
+
private dismissActorsIn;
|
|
113
101
|
/**
|
|
114
102
|
* Returns current time. This method should be used whenever
|
|
115
103
|
* [`DomainEvent`](https://serenity-js.org/api/core-events/class/DomainEvent/) objects are instantiated by you programmatically.
|
|
@@ -161,9 +149,5 @@ export declare class Stage implements EmitsDomainEvents {
|
|
|
161
149
|
*/
|
|
162
150
|
waitForNextCue(): Promise<void>;
|
|
163
151
|
createError<RE extends RuntimeError>(errorType: new (...args: any[]) => RE, options: ErrorOptions): RE;
|
|
164
|
-
private instantiatedActorCalled;
|
|
165
|
-
private notifyOfStageExit;
|
|
166
|
-
private dismiss;
|
|
167
|
-
private typeOf;
|
|
168
152
|
}
|
|
169
153
|
//# sourceMappingURL=Stage.d.ts.map
|
package/lib/stage/Stage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stage.d.ts","sourceRoot":"","sources":["../../src/stage/Stage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"Stage.d.ts","sourceRoot":"","sources":["../../src/stage/Stage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACH,YAAY,EACZ,KAAK,YAAY,EAEjB,KAAK,YAAY,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAKH,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAIzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAQ,MAAM,mBAAmB,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAC,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAmB,MAAM,4BAA4B,CAAC;AACpF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,KAAM,YAAW,iBAAiB;IAyBvC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IA3BnC,gBAAuB,cAAc,gBAA+B;IAEpE,OAAO,CAAC,eAAe,CAA8D;IAErF,OAAO,CAAC,YAAY,CAAuC;IAE3D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuB;IAE7D;;;;;;;;;;;;OAYG;gBAEC,IAAI,EAAE,IAAI,EACO,OAAO,EAAE,YAAY,EAC9B,MAAM,EAAE,YAAY,EACX,KAAK,EAAE,KAAK,EAC7B,kBAAkB,EAAE,QAAQ,EACX,cAAc,GAAE,oBAAoC,EACrE,qBAAqB,CAAC,EAAE,qBAAqB;IAajD,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,YAAY,GAAG,oBAAoB,GAAG,eAAe,CAAC,GAAG,IAAI;IAkBhH;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAInC;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAI1B;;;;;;OAMG;IACH,sBAAsB,IAAI,KAAK;IAI/B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;IAI1B;;;;;OAKG;IACH,MAAM,CAAC,GAAG,SAAS,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAInD;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI;IAM7C,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,iBAAiB;YAUX,eAAe;IAqC7B;;;OAGG;IACH,WAAW,IAAI,SAAS;IAIxB;;;;;;;;;OASG;IACH,gBAAgB,IAAI,aAAa;IAMjC;;;;;OAKG;IACH,cAAc,IAAI,aAAa;IAI/B;;;;;;;;;OASG;IACH,mBAAmB,CAAC,eAAe,EAAE,eAAe,GAAG,aAAa;IASpE;;;;;OAKG;IACH,iBAAiB,IAAI,aAAa;IAQlC;;;;;;;OAOG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,SAAS,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,YAAY,GAAG,EAAE;CAMzG"}
|
package/lib/stage/Stage.js
CHANGED
|
@@ -5,7 +5,7 @@ const tiny_types_1 = require("tiny-types");
|
|
|
5
5
|
const index_js_1 = require("../errors/index.js");
|
|
6
6
|
const index_js_2 = require("../events/index.js");
|
|
7
7
|
const index_js_3 = require("../model/index.js");
|
|
8
|
-
const
|
|
8
|
+
const ActorLifecycleManager_js_1 = require("./ActorLifecycleManager.js");
|
|
9
9
|
/**
|
|
10
10
|
* Stage is the place where [actors](https://serenity-js.org/api/core/class/Actor/) perform.
|
|
11
11
|
*
|
|
@@ -23,49 +23,31 @@ const index_js_4 = require("../screenplay/index.js");
|
|
|
23
23
|
* @group Stage
|
|
24
24
|
*/
|
|
25
25
|
class Stage {
|
|
26
|
-
cast;
|
|
27
26
|
manager;
|
|
28
27
|
errors;
|
|
29
28
|
clock;
|
|
30
|
-
interactionTimeout;
|
|
31
29
|
sceneIdFactory;
|
|
32
30
|
static unknownSceneId = new index_js_3.CorrelationId('unknown');
|
|
33
|
-
/**
|
|
34
|
-
* Actors instantiated after the scene has started,
|
|
35
|
-
* who will be dismissed when the scene finishes.
|
|
36
|
-
*/
|
|
37
|
-
actorsOnFrontStage = new Map();
|
|
38
|
-
/**
|
|
39
|
-
* Actors instantiated before the scene has started,
|
|
40
|
-
* who will be dismissed when the test run finishes.
|
|
41
|
-
*/
|
|
42
|
-
actorsOnBackstage = new Map();
|
|
43
|
-
actorsOnStage = this.actorsOnBackstage;
|
|
44
|
-
/**
|
|
45
|
-
* The most recent actor referenced via the [`Actor`](https://serenity-js.org/api/core/class/Actor/) method
|
|
46
|
-
*/
|
|
47
|
-
actorInTheSpotlight = undefined;
|
|
48
|
-
/**
|
|
49
|
-
* The scene in which the spotlight was last set.
|
|
50
|
-
* Used to detect when the spotlight shifts to a different scene context.
|
|
51
|
-
*/
|
|
52
|
-
sceneOfSpotlightedActor = undefined;
|
|
53
31
|
currentActivity = undefined;
|
|
54
32
|
currentScene = Stage.unknownSceneId;
|
|
33
|
+
actorLifecycleManager;
|
|
55
34
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
* @param
|
|
61
|
-
* @param
|
|
35
|
+
* Creates a new Stage instance.
|
|
36
|
+
*
|
|
37
|
+
* @param cast - The default cast to use for preparing actors
|
|
38
|
+
* @param manager - The stage manager responsible for notifying listeners of domain events
|
|
39
|
+
* @param errors - Factory for creating runtime errors with proper context
|
|
40
|
+
* @param clock - Clock used for timestamping domain events
|
|
41
|
+
* @param interactionTimeout - Default timeout for actor interactions
|
|
42
|
+
* @param sceneIdFactory - Factory for creating scene correlation IDs
|
|
43
|
+
* @param actorLifecycleManager - Optional custom ActorLifecycleManager instance.
|
|
44
|
+
* When provided, allows test runner adapters to control actor lifecycle programmatically.
|
|
45
|
+
* If not provided, a default manager is created.
|
|
62
46
|
*/
|
|
63
|
-
constructor(cast, manager, errors, clock, interactionTimeout, sceneIdFactory = index_js_3.CorrelationId) {
|
|
64
|
-
this.cast = cast;
|
|
47
|
+
constructor(cast, manager, errors, clock, interactionTimeout, sceneIdFactory = index_js_3.CorrelationId, actorLifecycleManager) {
|
|
65
48
|
this.manager = manager;
|
|
66
49
|
this.errors = errors;
|
|
67
50
|
this.clock = clock;
|
|
68
|
-
this.interactionTimeout = interactionTimeout;
|
|
69
51
|
this.sceneIdFactory = sceneIdFactory;
|
|
70
52
|
(0, tiny_types_1.ensure)('Cast', cast, (0, tiny_types_1.isDefined)());
|
|
71
53
|
(0, tiny_types_1.ensure)('StageManager', manager, (0, tiny_types_1.isDefined)());
|
|
@@ -73,11 +55,15 @@ class Stage {
|
|
|
73
55
|
(0, tiny_types_1.ensure)('Clock', clock, (0, tiny_types_1.isDefined)());
|
|
74
56
|
(0, tiny_types_1.ensure)('interactionTimeout', interactionTimeout, (0, tiny_types_1.isDefined)());
|
|
75
57
|
(0, tiny_types_1.ensure)('sceneIdFactory', sceneIdFactory, (0, tiny_types_1.isDefined)());
|
|
58
|
+
this.actorLifecycleManager = actorLifecycleManager ?? new ActorLifecycleManager_js_1.ActorLifecycleManager(cast, this.clock, interactionTimeout);
|
|
59
|
+
this.actorLifecycleManager.assignTo(this);
|
|
76
60
|
}
|
|
77
61
|
configure(options) {
|
|
78
|
-
|
|
62
|
+
if (options.interactionTimeout) {
|
|
63
|
+
this.actorLifecycleManager.configure({ interactionTimeout: options.interactionTimeout });
|
|
64
|
+
}
|
|
79
65
|
if (options.actors) {
|
|
80
|
-
this.engage(options.actors);
|
|
66
|
+
this.actorLifecycleManager.engage(options.actors);
|
|
81
67
|
}
|
|
82
68
|
if (options.cueTimeout) {
|
|
83
69
|
this.manager.configure({ cueTimeout: options.cueTimeout });
|
|
@@ -102,34 +88,7 @@ class Stage {
|
|
|
102
88
|
* Case-sensitive name of the Actor, e.g. `Alice`
|
|
103
89
|
*/
|
|
104
90
|
actor(name) {
|
|
105
|
-
|
|
106
|
-
let actor;
|
|
107
|
-
try {
|
|
108
|
-
const newActor = new index_js_4.Actor(name, this, [
|
|
109
|
-
new index_js_1.RaiseErrors(this),
|
|
110
|
-
new index_js_4.ScheduleWork(this.clock, this.interactionTimeout)
|
|
111
|
-
]);
|
|
112
|
-
actor = this.cast.prepare(newActor);
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
throw new index_js_1.ConfigurationError(`${this.typeOf(this.cast)} encountered a problem when preparing actor "${name}" for stage`, error);
|
|
116
|
-
}
|
|
117
|
-
if (!(actor instanceof index_js_4.Actor)) {
|
|
118
|
-
throw new index_js_1.ConfigurationError(`Instead of a new instance of actor "${name}", ${this.typeOf(this.cast)} returned ${actor}`);
|
|
119
|
-
}
|
|
120
|
-
this.actorsOnStage.set(name, actor);
|
|
121
|
-
this.announce(new index_js_2.ActorEntersStage(this.currentScene, actor.toJSON()));
|
|
122
|
-
}
|
|
123
|
-
const previousActorInSpotlight = this.actorInTheSpotlight;
|
|
124
|
-
const previousSceneOfSpotlightedActor = this.sceneOfSpotlightedActor;
|
|
125
|
-
this.actorInTheSpotlight = this.instantiatedActorCalled(name);
|
|
126
|
-
this.sceneOfSpotlightedActor = this.currentScene;
|
|
127
|
-
const spotlightShifted = this.actorInTheSpotlight !== previousActorInSpotlight
|
|
128
|
-
|| !this.currentScene.equals(previousSceneOfSpotlightedActor);
|
|
129
|
-
if (spotlightShifted) {
|
|
130
|
-
this.announce(new index_js_2.ActorSpotlighted(this.currentScene, this.actorInTheSpotlight.toJSON()));
|
|
131
|
-
}
|
|
132
|
-
return this.actorInTheSpotlight;
|
|
91
|
+
return this.actorLifecycleManager.actor(name);
|
|
133
92
|
}
|
|
134
93
|
/**
|
|
135
94
|
* Returns the last [`Actor`](https://serenity-js.org/api/core/class/Actor/) instantiated via [`Stage.actor`](https://serenity-js.org/api/core/class/Stage/#actor).
|
|
@@ -139,16 +98,13 @@ class Stage {
|
|
|
139
98
|
* If no [`Actor`](https://serenity-js.org/api/core/class/Actor/) has been activated yet
|
|
140
99
|
*/
|
|
141
100
|
theActorInTheSpotlight() {
|
|
142
|
-
|
|
143
|
-
throw new index_js_1.LogicError(`There is no actor in the spotlight yet. Make sure you instantiate one with stage.actor(actorName) before calling this method.`);
|
|
144
|
-
}
|
|
145
|
-
return this.actorInTheSpotlight;
|
|
101
|
+
return this.actorLifecycleManager.actorInTheSpotlight();
|
|
146
102
|
}
|
|
147
103
|
/**
|
|
148
104
|
* Returns `true` if there is an [`Actor`](https://serenity-js.org/api/core/class/Actor/) in the spotlight, `false` otherwise.
|
|
149
105
|
*/
|
|
150
106
|
theShowHasStarted() {
|
|
151
|
-
return
|
|
107
|
+
return this.actorLifecycleManager.hasActorInTheSpotlight();
|
|
152
108
|
}
|
|
153
109
|
/**
|
|
154
110
|
* Configures the Stage to prepare [actors](https://serenity-js.org/api/core/class/Actor/)
|
|
@@ -157,11 +113,11 @@ class Stage {
|
|
|
157
113
|
* @param actors
|
|
158
114
|
*/
|
|
159
115
|
engage(actors) {
|
|
160
|
-
this.
|
|
116
|
+
this.actorLifecycleManager.engage(actors);
|
|
161
117
|
}
|
|
162
118
|
/**
|
|
163
119
|
* Assigns listeners to be notified of [Serenity/JS domain events](https://serenity-js.org/api/core-events/class/DomainEvent/)
|
|
164
|
-
* emitted via [`Stage.announce`](https://serenity-js.org/api/core/class/Stage/#announce).
|
|
120
|
+
* emitted via [`Stage.announce`](https://serenity-js.org/api/core/class/Stage/#announce).
|
|
165
121
|
*
|
|
166
122
|
* @param listeners
|
|
167
123
|
*/
|
|
@@ -181,26 +137,52 @@ class Stage {
|
|
|
181
137
|
}
|
|
182
138
|
announceSingle(event) {
|
|
183
139
|
if (event instanceof index_js_2.SceneStarts) {
|
|
184
|
-
this.
|
|
140
|
+
this.actorLifecycleManager.switchFocus('foreground');
|
|
185
141
|
}
|
|
186
142
|
if (event instanceof index_js_2.SceneFinishes || event instanceof index_js_2.TestRunFinishes) {
|
|
187
|
-
this.notifyOfStageExit(this.
|
|
143
|
+
this.notifyOfStageExit(this.actorLifecycleManager.currentFocus());
|
|
188
144
|
}
|
|
189
145
|
this.manager.notifyOf(event);
|
|
190
146
|
if (event instanceof index_js_2.SceneFinishes) {
|
|
191
|
-
this.
|
|
192
|
-
this.
|
|
147
|
+
this.dismissActorsIn('foreground');
|
|
148
|
+
this.actorLifecycleManager.switchFocus('background');
|
|
193
149
|
}
|
|
194
150
|
if (event instanceof index_js_2.TestRunFinishes) {
|
|
195
|
-
this.
|
|
151
|
+
this.dismissActorsIn('background');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
notifyOfStageExit(focus) {
|
|
155
|
+
for (const actor of this.actorLifecycleManager.actorsIn(focus)) {
|
|
156
|
+
this.announce(new index_js_2.ActorStageExitStarts(this.currentSceneId(), actor.toJSON(), this.currentTime()));
|
|
196
157
|
}
|
|
197
158
|
}
|
|
159
|
+
async dismissActorsIn(focus) {
|
|
160
|
+
const actors = this.actorLifecycleManager.actorsIn(focus);
|
|
161
|
+
this.actorLifecycleManager.clearSpotlightIfIn(focus);
|
|
162
|
+
// Wait for the Photographer to finish taking any screenshots
|
|
163
|
+
await this.manager.waitForAsyncOperationsToComplete();
|
|
164
|
+
const actorsToDismiss = new Map(actors.map(actor => [actor, index_js_3.CorrelationId.create()]));
|
|
165
|
+
for (const [actor, correlationId] of actorsToDismiss) {
|
|
166
|
+
this.announce(new index_js_2.ActorStageExitAttempted(correlationId, new index_js_3.Name(actor.name), this.currentTime()));
|
|
167
|
+
}
|
|
168
|
+
// Try to dismiss each actor
|
|
169
|
+
for (const [actor, correlationId] of actorsToDismiss) {
|
|
170
|
+
try {
|
|
171
|
+
await actor.dismiss();
|
|
172
|
+
this.announce(new index_js_2.ActorStageExitCompleted(correlationId, new index_js_3.Name(actor.name), this.currentTime()));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
this.announce(new index_js_2.ActorStageExitFailed(error, correlationId, this.currentTime()));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
this.actorLifecycleManager.clearActorsIn(focus);
|
|
179
|
+
}
|
|
198
180
|
/**
|
|
199
181
|
* Returns current time. This method should be used whenever
|
|
200
182
|
* [`DomainEvent`](https://serenity-js.org/api/core-events/class/DomainEvent/) objects are instantiated by you programmatically.
|
|
201
183
|
*/
|
|
202
184
|
currentTime() {
|
|
203
|
-
return this.
|
|
185
|
+
return this.clock.now();
|
|
204
186
|
}
|
|
205
187
|
/**
|
|
206
188
|
* Generates and remembers a `CorrelationId`
|
|
@@ -271,44 +253,6 @@ class Stage {
|
|
|
271
253
|
...options,
|
|
272
254
|
});
|
|
273
255
|
}
|
|
274
|
-
instantiatedActorCalled(name) {
|
|
275
|
-
return this.actorsOnBackstage.has(name)
|
|
276
|
-
? this.actorsOnBackstage.get(name)
|
|
277
|
-
: this.actorsOnFrontStage.get(name);
|
|
278
|
-
}
|
|
279
|
-
notifyOfStageExit(sceneId) {
|
|
280
|
-
for (const actor of this.actorsOnStage.values()) {
|
|
281
|
-
this.announce(new index_js_2.ActorStageExitStarts(sceneId, actor.toJSON(), this.currentTime()));
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
async dismiss(activeActors) {
|
|
285
|
-
const actors = Array.from(activeActors.values());
|
|
286
|
-
if (actors.includes(this.actorInTheSpotlight)) {
|
|
287
|
-
this.actorInTheSpotlight = undefined;
|
|
288
|
-
}
|
|
289
|
-
// Wait for the Photographer to finish taking any screenshots
|
|
290
|
-
await this.manager.waitForAsyncOperationsToComplete();
|
|
291
|
-
const actorsToDismiss = new Map(actors.map(actor => [actor, index_js_3.CorrelationId.create()]));
|
|
292
|
-
for (const [actor, correlationId] of actorsToDismiss) {
|
|
293
|
-
this.announce(new index_js_2.ActorStageExitAttempted(correlationId, new index_js_3.Name(actor.name), this.currentTime()));
|
|
294
|
-
}
|
|
295
|
-
// Try to dismiss each actor
|
|
296
|
-
for (const [actor, correlationId] of actorsToDismiss) {
|
|
297
|
-
try {
|
|
298
|
-
await actor.dismiss();
|
|
299
|
-
this.announce(new index_js_2.ActorStageExitCompleted(correlationId, new index_js_3.Name(actor.name), this.currentTime()));
|
|
300
|
-
}
|
|
301
|
-
catch (error) {
|
|
302
|
-
this.announce(new index_js_2.ActorStageExitFailed(error, correlationId, this.currentTime()));
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
activeActors.clear();
|
|
306
|
-
}
|
|
307
|
-
typeOf(cast) {
|
|
308
|
-
return cast.constructor === Object
|
|
309
|
-
? 'Cast'
|
|
310
|
-
: cast.constructor.name;
|
|
311
|
-
}
|
|
312
256
|
}
|
|
313
257
|
exports.Stage = Stage;
|
|
314
258
|
//# sourceMappingURL=Stage.js.map
|