@serenity-js/core 3.42.1 → 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 +20 -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 +4 -4
- 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
package/lib/stage/Stage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stage.js","sourceRoot":"","sources":["../../src/stage/Stage.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"Stage.js","sourceRoot":"","sources":["../../src/stage/Stage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { DomainEvent } from '../events/index.js';
|
|
2
|
-
import type { Clock, Duration
|
|
2
|
+
import type { Clock, Duration } from '../screenplay/index.js';
|
|
3
3
|
import type { ListensToDomainEvents } from '../stage/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* @group Stage
|
|
6
6
|
*/
|
|
7
|
-
export declare class StageManager
|
|
7
|
+
export declare class StageManager {
|
|
8
8
|
private cueTimeout;
|
|
9
|
-
private readonly clock;
|
|
10
9
|
private readonly subscribers;
|
|
11
10
|
private readonly wip;
|
|
12
11
|
constructor(cueTimeout: Duration, clock: Clock);
|
|
@@ -18,6 +17,5 @@ export declare class StageManager implements TellsTime {
|
|
|
18
17
|
notifyOf(event: DomainEvent): void;
|
|
19
18
|
waitForAsyncOperationsToComplete(): Promise<void>;
|
|
20
19
|
waitForNextCue(): Promise<void>;
|
|
21
|
-
currentTime(): Timestamp;
|
|
22
20
|
}
|
|
23
21
|
//# sourceMappingURL=StageManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StageManager.d.ts","sourceRoot":"","sources":["../../src/stage/StageManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"StageManager.d.ts","sourceRoot":"","sources":["../../src/stage/StageManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAa,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;GAEG;AACH,qBAAa,YAAY;IAIT,OAAO,CAAC,UAAU;IAH9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;gBAEN,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK;IAItD,SAAS,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,QAAQ,CAAA;KAAE,GAAG,IAAI;IAKlD,QAAQ,CAAC,GAAG,WAAW,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAIvD,UAAU,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI;IAInD,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC,gCAAgC,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3C,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAgBxC"}
|
|
@@ -7,12 +7,10 @@ const index_js_1 = require("../events/index.js");
|
|
|
7
7
|
*/
|
|
8
8
|
class StageManager {
|
|
9
9
|
cueTimeout;
|
|
10
|
-
clock;
|
|
11
10
|
subscribers = [];
|
|
12
11
|
wip;
|
|
13
12
|
constructor(cueTimeout, clock) {
|
|
14
13
|
this.cueTimeout = cueTimeout;
|
|
15
|
-
this.clock = clock;
|
|
16
14
|
this.wip = new WIP(cueTimeout, clock);
|
|
17
15
|
}
|
|
18
16
|
configure(options) {
|
|
@@ -55,9 +53,6 @@ class StageManager {
|
|
|
55
53
|
throw new Error(this.wip.descriptionOfTimedOutOperations());
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
|
-
currentTime() {
|
|
59
|
-
return this.clock.now();
|
|
60
|
-
}
|
|
61
56
|
}
|
|
62
57
|
exports.StageManager = StageManager;
|
|
63
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StageManager.js","sourceRoot":"","sources":["../../src/stage/StageManager.ts"],"names":[],"mappings":";;;AACA,iDAA4G;AAK5G;;GAEG;AACH,MAAa,YAAY;IAID;
|
|
1
|
+
{"version":3,"file":"StageManager.js","sourceRoot":"","sources":["../../src/stage/StageManager.ts"],"names":[],"mappings":";;;AACA,iDAA4G;AAK5G;;GAEG;AACH,MAAa,YAAY;IAID;IAHH,WAAW,GAA4B,EAAE,CAAC;IAC1C,GAAG,CAAM;IAE1B,YAAoB,UAAoB,EAAE,KAAY;QAAlC,eAAU,GAAV,UAAU,CAAU;QACpC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,SAAS,CAAC,OAAiC;QACvC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,QAAQ,CAAC,GAAG,WAAoC;QAC5C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAC1C,CAAC;IAED,UAAU,CAAC,UAAiC;QACxC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,QAAQ,CAAC,KAAkB;QACvB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE9B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,gCAAgC;QAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAEnC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAExB,OAAO,OAAO,EAAE,CAAC;YACrB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;YAErC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,EAAE,CAAC;oBACvC,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,aAAa,CAAC,QAAQ,CAAC,CAAC;oBAExB,OAAO,OAAO,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,cAAc;QAEhB,MAAM,IAAI,CAAC,gCAAgC,EAAE,CAAC;QAE9C,IAAI,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC,CAAC;YAElE,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;YAEjC,MAAM,KAAK,CAAC;QAChB,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,+BAA+B,EAAE,CAAC,CAAC;QAChE,CAAC;IACL,CAAC;CACJ;AA/DD,oCA+DC;AAED;;GAEG;AACH,MAAM,GAAG;IAKO;IACS;IALJ,GAAG,GAAG,IAAI,GAAG,EAAwC,CAAC;IACtD,gBAAgB,GAAkC,EAAE,CAAC;IAEtE,YACY,UAAoB,EACX,KAAY;QADrB,eAAU,GAAV,UAAU,CAAU;QACX,UAAK,GAAL,KAAK,CAAO;IAEjC,CAAC;IAED,SAAS,CAAC,OAAiC;QACvC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACzC,CAAC;IAED,aAAa,CAAC,KAAkB;QAC5B,IAAI,KAAK,YAAY,kCAAuB,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE;gBAC1B,IAAI,EAAY,KAAK,CAAC,IAAI;gBAC1B,WAAW,EAAK,KAAK,CAAC,WAAW;gBACjC,SAAS,EAAO,KAAK,CAAC,SAAS;aAClC,CAAC,CAAC;QACP,CAAC;QAED,IAAI,KAAK,YAAY,kCAAuB,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,KAAK,YAAY,+BAAoB,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAE/C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBACvB,IAAI,EAAY,QAAQ,CAAC,IAAI;gBAC7B,WAAW,EAAK,QAAQ,CAAC,WAAW;gBACpC,SAAS,EAAO,QAAQ,CAAC,SAAS;gBAClC,QAAQ,EAAQ,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACxD,KAAK,EAAW,KAAK,CAAC,KAAK;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QACpC,CAAC;IACL,CAAC;IAED,yBAAyB;QACrB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,mBAAmB;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,mBAAmB;QACf,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,+BAA+B;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAE7B,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC,MAAM,CACjC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAE,OAAQ,EAAE,CAAC,IAAI,CAAC,KAAM,KAAM,EAAE,CAAC,WAAW,CAAC,KAAM,EAAE,CAAC,EACvG,CAAC,GAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAE,aAAc,IAAI,CAAC,UAAW,eAAe,CAAC,CACjF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,6BAA6B;QACzB,IAAI,OAAO,GAAG,GAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAE,KAAK,CAAC;QAElE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAA+B,EAAE,EAAE;YAC9D,OAAO,IAAI,IAAK,EAAE,CAAC,IAAI,CAAC,KAAM,KAAM,EAAE,CAAC,WAAW,CAAC,KAAM,MAAO,EAAE,CAAC,KAAK,CAAC,KAAM,SAAS,CAAC;QAC7F,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,qBAAqB;QACjB,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,CAAC;IAEO,gBAAgB;QACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAEO,MAAM,CAAC,gBAAwB;QACnC,OAAO,gBAAgB,KAAK,CAAC;YACzB,CAAC,CAAC,0CAA0C;YAC5C,CAAC,CAAC,GAAI,gBAAiB,2CAA2C,CAAC;IAC3E,CAAC;IAEO,GAAG,CAAC,aAA4B,EAAE,OAA8B;QACpE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAEO,GAAG,CAAC,aAA4B;QACpC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,CAAC;IAEO,MAAM,CAAC,aAA4B;QACvC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;IACpD,CAAC;IAEO,WAAW,CAAC,GAAkB;QAClC,KAAK,MAAM,CAAE,CAAC,EAAE,EAAE,CAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChB,OAAO,CAAC,CAAC;YACb,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ"}
|
package/lib/stage/index.d.ts
CHANGED
package/lib/stage/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yCAAyC,CAAC;AACxD,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yCAAyC,CAAC;AACxD,cAAc,mBAAmB,CAAC"}
|
package/lib/stage/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ActorLifecycleManager.js"), exports);
|
|
17
18
|
__exportStar(require("./Cast.js"), exports);
|
|
18
19
|
__exportStar(require("./crew/index.js"), exports);
|
|
19
20
|
__exportStar(require("./Extras.js"), exports);
|
package/lib/stage/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,kDAAgC;AAChC,8CAA4B;AAC5B,6DAA2C;AAC3C,oDAAkC;AAClC,6CAA2B;AAC3B,uDAAqC;AACrC,8DAA4C;AAC5C,0EAAwD;AACxD,oDAAkC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA2C;AAC3C,4CAA0B;AAC1B,kDAAgC;AAChC,8CAA4B;AAC5B,6DAA2C;AAC3C,oDAAkC;AAClC,6CAA2B;AAC3B,uDAAqC;AACrC,8DAA4C;AAC5C,0EAAwD;AACxD,oDAAkC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serenity-js/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.43.0",
|
|
4
4
|
"description": "The core Serenity/JS framework, providing the Screenplay Pattern interfaces, as well as the test reporting and integration infrastructure",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jan Molak",
|
|
@@ -315,7 +315,7 @@
|
|
|
315
315
|
"fast-glob": "3.3.3",
|
|
316
316
|
"filenamify": "4.3.0",
|
|
317
317
|
"graceful-fs": "4.2.11",
|
|
318
|
-
"semver": "7.
|
|
318
|
+
"semver": "7.8.0",
|
|
319
319
|
"tiny-types": "2.0.5",
|
|
320
320
|
"upath": "2.0.1",
|
|
321
321
|
"validate-npm-package-name": "7.0.2"
|
|
@@ -328,7 +328,7 @@
|
|
|
328
328
|
"@types/validate-npm-package-name": "4.0.2",
|
|
329
329
|
"assertion-error-formatter": "3.0.0",
|
|
330
330
|
"c8": "11.0.0",
|
|
331
|
-
"memfs": "4.57.
|
|
331
|
+
"memfs": "4.57.2",
|
|
332
332
|
"mocha": "11.7.5",
|
|
333
333
|
"mocha-multi": "1.1.7",
|
|
334
334
|
"ts-node": "10.9.2",
|
|
@@ -345,5 +345,5 @@
|
|
|
345
345
|
"engines": {
|
|
346
346
|
"node": "^20 || ^22 || ^24"
|
|
347
347
|
},
|
|
348
|
-
"gitHead": "
|
|
348
|
+
"gitHead": "96ffb7ecba111082c92d7b107fef007d9f56bb83"
|
|
349
349
|
}
|
package/src/Serenity.ts
CHANGED
|
@@ -11,9 +11,9 @@ import type { Actor, Timestamp } from './screenplay/index.js';
|
|
|
11
11
|
import { Clock, Duration } from './screenplay/index.js';
|
|
12
12
|
import type { Cast } from './stage/Cast.js';
|
|
13
13
|
import { Extras } from './stage/Extras.js';
|
|
14
|
-
import type { StageCrewMember, StageCrewMemberBuilder } from './stage/index.js';
|
|
14
|
+
import type { ActorLifecycleManager, StageCrewMember, StageCrewMemberBuilder } from './stage/index.js';
|
|
15
|
+
import { StageManager } from './stage/index.js';
|
|
15
16
|
import { Stage } from './stage/Stage.js';
|
|
16
|
-
import { StageManager } from './stage/StageManager.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @group Serenity
|
|
@@ -34,11 +34,13 @@ export class Serenity implements EmitsDomainEvents {
|
|
|
34
34
|
* @param clock
|
|
35
35
|
* @param cwd
|
|
36
36
|
* @param sceneIdFactory
|
|
37
|
+
* @param actorLifecycleManager - Optional custom ActorLifecycleManager instance
|
|
37
38
|
*/
|
|
38
39
|
constructor(
|
|
39
40
|
clock: Clock = new Clock(),
|
|
40
41
|
cwd: string = process.cwd(),
|
|
41
42
|
sceneIdFactory: CorrelationIdFactory = CorrelationId,
|
|
43
|
+
actorLifecycleManager?: ActorLifecycleManager,
|
|
42
44
|
) {
|
|
43
45
|
this.stage = new Stage(
|
|
44
46
|
Serenity.defaultActors,
|
|
@@ -47,6 +49,7 @@ export class Serenity implements EmitsDomainEvents {
|
|
|
47
49
|
clock,
|
|
48
50
|
Serenity.defaultInteractionTimeout,
|
|
49
51
|
sceneIdFactory,
|
|
52
|
+
actorLifecycleManager,
|
|
50
53
|
);
|
|
51
54
|
|
|
52
55
|
this.classLoader = new ClassLoader(
|
package/src/screenplay/Actor.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { ValueInspector } from '../io/index.js';
|
|
|
4
4
|
import type { Artifact } from '../model/index.js';
|
|
5
5
|
import { Name, } from '../model/index.js';
|
|
6
6
|
import type { Stage } from '../stage/index.js';
|
|
7
|
-
import type { AbilityType, CanHaveAbilities,
|
|
8
|
-
import { Ability, AnswerQuestions, PerformActivities } from './abilities/index.js';
|
|
7
|
+
import type { AbilityType, CanHaveAbilities, UsesAbilities } from './abilities/index.js';
|
|
8
|
+
import { Ability, AnswerQuestions, Discardable, Initialisable, PerformActivities } from './abilities/index.js';
|
|
9
9
|
import type { PerformsActivities } from './activities/index.js';
|
|
10
10
|
import type { Activity } from './Activity.js';
|
|
11
11
|
import type { Answerable } from './Answerable.js';
|
|
@@ -194,7 +194,7 @@ export class Actor implements PerformsActivities,
|
|
|
194
194
|
* [discardable](https://serenity-js.org/api/core/interface/Discardable/) [ability](https://serenity-js.org/api/core/class/Ability/) it's been configured with.
|
|
195
195
|
*/
|
|
196
196
|
dismiss(): Promise<void> {
|
|
197
|
-
return this.
|
|
197
|
+
return this.findAbilitiesWhere(Discardable.isDiscardable)
|
|
198
198
|
.reduce(
|
|
199
199
|
(previous: Promise<void>, ability: (Discardable & Ability)) =>
|
|
200
200
|
previous.then(() => ability.discard()),
|
|
@@ -227,7 +227,7 @@ export class Actor implements PerformsActivities,
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
private initialiseAbilities(): Promise<void> {
|
|
230
|
-
return this.
|
|
230
|
+
return this.findAbilitiesWhere(Initialisable.isInitialisable)
|
|
231
231
|
.filter(ability => !ability.isInitialised())
|
|
232
232
|
.reduce(
|
|
233
233
|
(previous: Promise<void>, ability: (Initialisable & Ability)) =>
|
|
@@ -240,15 +240,12 @@ export class Actor implements PerformsActivities,
|
|
|
240
240
|
)
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
private
|
|
243
|
+
private findAbilitiesWhere<T>(filter: (ability: Ability) => ability is Ability & T): Array<Ability & T> {
|
|
244
244
|
const abilitiesFrom = (map: Map<string, Ability>): Ability[] =>
|
|
245
245
|
Array.from(map.values());
|
|
246
246
|
|
|
247
|
-
const abilitiesWithDesiredMethods = (ability: Ability & T): boolean =>
|
|
248
|
-
methodNames.every(methodName => typeof (ability[methodName]) === 'function');
|
|
249
|
-
|
|
250
247
|
return abilitiesFrom(this.abilities)
|
|
251
|
-
.filter(
|
|
248
|
+
.filter(filter) as Array<Ability & T>;
|
|
252
249
|
}
|
|
253
250
|
|
|
254
251
|
private findAbilityTo<T extends Ability>(doSomething: AbilityType<T>): T | undefined {
|
|
@@ -17,10 +17,15 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @group Abilities
|
|
19
19
|
*/
|
|
20
|
-
export
|
|
20
|
+
export abstract class Discardable {
|
|
21
|
+
|
|
22
|
+
static isDiscardable<T>(value: T): value is T & Discardable {
|
|
23
|
+
return typeof (value['discard']) === 'function'
|
|
24
|
+
&& value['discard'].length === 0;
|
|
25
|
+
}
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Discards the resources associated with this ability.
|
|
24
29
|
*/
|
|
25
|
-
discard(): Promise<void> | void;
|
|
30
|
+
abstract discard(): Promise<void> | void;
|
|
26
31
|
}
|
|
@@ -12,7 +12,14 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @group Abilities
|
|
14
14
|
*/
|
|
15
|
-
export
|
|
15
|
+
export abstract class Initialisable {
|
|
16
|
+
|
|
17
|
+
static isInitialisable<T>(value: T): value is T & Initialisable {
|
|
18
|
+
return typeof (value['initialise']) === 'function'
|
|
19
|
+
&& value['initialise'].length === 0
|
|
20
|
+
&& typeof value['isInitialised'] === 'function'
|
|
21
|
+
&& value['isInitialised'].length === 0;
|
|
22
|
+
}
|
|
16
23
|
|
|
17
24
|
/**
|
|
18
25
|
* Initialises the ability. Invoked whenever [`Actor.attemptsTo`](https://serenity-js.org/api/core/class/Actor/#attemptsTo) method is called,
|
|
@@ -21,7 +28,7 @@ export interface Initialisable {
|
|
|
21
28
|
* Make sure to implement [`Initialisable.isInitialised`](https://serenity-js.org/api/core/interface/Initialisable/#isInitialised) so that it returns `true`
|
|
22
29
|
* when the ability has been successfully initialised.
|
|
23
30
|
*/
|
|
24
|
-
initialise(): Promise<void> | void;
|
|
31
|
+
abstract initialise(): Promise<void> | void;
|
|
25
32
|
|
|
26
33
|
/**
|
|
27
34
|
* Should return `true` when all the resources that the given ability needs
|
|
@@ -30,5 +37,5 @@ export interface Initialisable {
|
|
|
30
37
|
*
|
|
31
38
|
* @returns {boolean}
|
|
32
39
|
*/
|
|
33
|
-
isInitialised(): boolean;
|
|
40
|
+
abstract isInitialised(): boolean;
|
|
34
41
|
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { ensure, isDefined, property } from 'tiny-types';
|
|
2
|
+
|
|
3
|
+
import { ConfigurationError, LogicError, RaiseErrors } from '../errors/index.js';
|
|
4
|
+
import { ActorEntersStage, ActorSpotlighted, } from '../events/index.js';
|
|
5
|
+
import { CorrelationId } from '../model/index.js';
|
|
6
|
+
import type { Clock, Duration } from '../screenplay/index.js';
|
|
7
|
+
import { Actor, ScheduleWork } from '../screenplay/index.js';
|
|
8
|
+
import type { Cast } from './Cast.js';
|
|
9
|
+
import type { Stage } from './Stage.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents the focus area where actors are tracked.
|
|
13
|
+
*
|
|
14
|
+
* - `'foreground'` - Scene-scoped actors that are dismissed when a scene finishes
|
|
15
|
+
* - `'background'` - Test run-scoped actors that persist across scenes and are dismissed when the test run finishes
|
|
16
|
+
*
|
|
17
|
+
* @group Stage
|
|
18
|
+
*/
|
|
19
|
+
export type StageFocus = 'foreground' | 'background';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Manages the lifecycle of [actors](https://serenity-js.org/api/core/class/Actor/) on the [stage](https://serenity-js.org/api/core/class/Stage/),
|
|
23
|
+
* including their creation, retrieval, and tracking of which actors are in the foreground (scene-scoped)
|
|
24
|
+
* versus background (test run-scoped).
|
|
25
|
+
*
|
|
26
|
+
* The `ActorLifecycleManager` is responsible for:
|
|
27
|
+
* - Instantiating and caching actors via the configured [cast](https://serenity-js.org/api/core/class/Cast/)
|
|
28
|
+
* - Tracking which actor is currently in the spotlight (active)
|
|
29
|
+
* - Managing the focus area (foreground vs background) where new actors are created
|
|
30
|
+
* - Providing access to actors for dismissal when scenes or test runs finish
|
|
31
|
+
*
|
|
32
|
+
* ## Default behaviour
|
|
33
|
+
*
|
|
34
|
+
* By default, actors created before the actual test scenario starts, e.g. in beforeAll hooks, are placed in the `'background'` focus area.
|
|
35
|
+
* When a [`SceneStarts`](https://serenity-js.org/api/core-events/class/SceneStarts/) event is announced,
|
|
36
|
+
* the focus switches to `'foreground'`. When a [`SceneFinishes`](https://serenity-js.org/api/core-events/class/SceneFinishes/)
|
|
37
|
+
* event is announced, foreground actors are dismissed, their abilities [discarded](https://serenity-js.org/api/core/interface/Discardable/)
|
|
38
|
+
* and focus returns to `'background'`.
|
|
39
|
+
*
|
|
40
|
+
* ## Custom lifecycle management
|
|
41
|
+
*
|
|
42
|
+
* Test runner adapters like [`@serenity-js/playwright-test`](https://serenity-js.org/api/playwright-test/),
|
|
43
|
+
* where test execution and reporting happen in separate processes, can inject a custom `ActorLifecycleManager` instance
|
|
44
|
+
* to control actor lifecycle programmatically.
|
|
45
|
+
*
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const actorLifecycleManager = new ActorLifecycleManager(cast, clock, interactionTimeout);
|
|
48
|
+
* const serenity = new Serenity(clock, cueTimeout, actorLifecycleManager);
|
|
49
|
+
*
|
|
50
|
+
* // At the start of each test:
|
|
51
|
+
* actorLifecycleManager.switchFocus('foreground');
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* ## Learn more
|
|
55
|
+
* - [`Stage`](https://serenity-js.org/api/core/class/Stage/)
|
|
56
|
+
* - [`Cast`](https://serenity-js.org/api/core/class/Cast/)
|
|
57
|
+
* - [`Actor`](https://serenity-js.org/api/core/class/Actor/)
|
|
58
|
+
*
|
|
59
|
+
* @group Stage
|
|
60
|
+
*/
|
|
61
|
+
export class ActorLifecycleManager {
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The most recent actor referenced via the {@apilink actor} method
|
|
65
|
+
*/
|
|
66
|
+
private currentActor?: Actor;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The scene in which the spotlight was last set.
|
|
70
|
+
* Used to detect when the spotlight shifts to a different scene context.
|
|
71
|
+
*/
|
|
72
|
+
private currentActorScene: CorrelationId = new CorrelationId('unknown');
|
|
73
|
+
|
|
74
|
+
private currentFocusValue: StageFocus = 'background';
|
|
75
|
+
|
|
76
|
+
private actors: Record<StageFocus, Map<string, Actor>> = {
|
|
77
|
+
'foreground': new Map<string, Actor>(),
|
|
78
|
+
'background': new Map<string, Actor>(),
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
protected stage: Stage;
|
|
82
|
+
|
|
83
|
+
constructor(
|
|
84
|
+
protected cast: Cast,
|
|
85
|
+
protected readonly clock: Clock,
|
|
86
|
+
protected interactionTimeout: Duration,
|
|
87
|
+
) {
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Configures the manager with new settings.
|
|
92
|
+
*
|
|
93
|
+
* @param options - Configuration options
|
|
94
|
+
* @param options.interactionTimeout - The maximum time to wait for an interaction to complete
|
|
95
|
+
*/
|
|
96
|
+
configure({ interactionTimeout }: { interactionTimeout: Duration }): void {
|
|
97
|
+
this.interactionTimeout = interactionTimeout;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Associates this manager with a [`Stage`](https://serenity-js.org/api/core/class/Stage/) instance.
|
|
102
|
+
*
|
|
103
|
+
* This method is called automatically by the `Stage` during construction.
|
|
104
|
+
* It establishes the bidirectional relationship between the manager and the stage,
|
|
105
|
+
* allowing the manager to emit [domain events](https://serenity-js.org/api/core-events/class/DomainEvent/)
|
|
106
|
+
* when actors enter the stage or are spotlighted.
|
|
107
|
+
*
|
|
108
|
+
* @param stage - The Stage instance to associate with this manager
|
|
109
|
+
*/
|
|
110
|
+
assignTo(stage: Stage): void {
|
|
111
|
+
this.stage = stage;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Configures the manager to use the provided [cast](https://serenity-js.org/api/core/class/Cast/) for preparing actors.
|
|
116
|
+
*
|
|
117
|
+
* @param actors - The cast to use for preparing new actors
|
|
118
|
+
*
|
|
119
|
+
* @throws [`ConfigurationError`](https://serenity-js.org/api/core/class/ConfigurationError/)
|
|
120
|
+
* If the provided cast is not defined or doesn't have a `prepare` method
|
|
121
|
+
*/
|
|
122
|
+
engage(actors: Cast): void {
|
|
123
|
+
this.cast = ensure('actors', actors, isDefined(), property('prepare', isDefined()));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Returns the current [cast](https://serenity-js.org/api/core/class/Cast/) used for preparing actors.
|
|
128
|
+
*
|
|
129
|
+
* @returns The currently configured cast
|
|
130
|
+
*/
|
|
131
|
+
currentCast(): Cast {
|
|
132
|
+
return this.cast;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Instantiates a new [`Actor`](https://serenity-js.org/api/core/class/Actor/) or fetches an existing one
|
|
137
|
+
* identified by their name if they've already been instantiated.
|
|
138
|
+
*
|
|
139
|
+
* When a new actor is instantiated, an [`ActorEntersStage`](https://serenity-js.org/api/core-events/class/ActorEntersStage/)
|
|
140
|
+
* event is announced. When the spotlight shifts to a different actor (or the same actor in a different scene),
|
|
141
|
+
* an [`ActorSpotlighted`](https://serenity-js.org/api/core-events/class/ActorSpotlighted/) event is announced.
|
|
142
|
+
*
|
|
143
|
+
* Actors are first looked up in the `'background'` focus area, then in `'foreground'`.
|
|
144
|
+
* New actors are always created in the current focus area.
|
|
145
|
+
*
|
|
146
|
+
* @param name - Case-sensitive name of the Actor, e.g. `Alice`
|
|
147
|
+
* @returns The actor with the given name
|
|
148
|
+
*/
|
|
149
|
+
public actor(name: string): Actor {
|
|
150
|
+
if (! this.existingActorCalled(name)) {
|
|
151
|
+
const actor = this.prepareActor(new Actor(name, this.stage, [
|
|
152
|
+
new RaiseErrors(this.stage),
|
|
153
|
+
new ScheduleWork(this.clock, this.interactionTimeout)
|
|
154
|
+
]));
|
|
155
|
+
|
|
156
|
+
this.actors[this.currentFocusValue].set(actor.name, actor);
|
|
157
|
+
|
|
158
|
+
this.stage.announce(
|
|
159
|
+
new ActorEntersStage(
|
|
160
|
+
this.stage.currentSceneId(),
|
|
161
|
+
actor.toJSON(),
|
|
162
|
+
this.stage.currentTime(),
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const previousActorInSpotlight = this.currentActor;
|
|
168
|
+
const previousSceneOfSpotlightedActor = this.currentActorScene;
|
|
169
|
+
|
|
170
|
+
this.currentActor = this.existingActorCalled(name);
|
|
171
|
+
this.currentActorScene = this.stage.currentSceneId();
|
|
172
|
+
|
|
173
|
+
const spotlightShifted = this.currentActor !== previousActorInSpotlight
|
|
174
|
+
|| ! this.stage.currentSceneId().equals(previousSceneOfSpotlightedActor);
|
|
175
|
+
|
|
176
|
+
if (spotlightShifted) {
|
|
177
|
+
this.stage.announce(
|
|
178
|
+
new ActorSpotlighted(
|
|
179
|
+
this.stage.currentSceneId(),
|
|
180
|
+
this.currentActor.toJSON(),
|
|
181
|
+
this.stage.currentTime(),
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return this.currentActor;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private prepareActor(actor: Actor): Actor {
|
|
190
|
+
|
|
191
|
+
let preparedActor: Actor;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
preparedActor = this.cast.prepare(actor);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
throw new ConfigurationError(`${ this.typeOf(this.cast) } encountered a problem when preparing actor "${ actor.name }" for stage`, error);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (! (preparedActor instanceof Actor)) {
|
|
201
|
+
throw new ConfigurationError(`Instead of a new instance of actor "${ actor.name }", ${ this.typeOf(this.cast) } returned ${ preparedActor }`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return preparedActor;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private typeOf(cast: Cast): string {
|
|
208
|
+
return cast.constructor === Object
|
|
209
|
+
? 'Cast'
|
|
210
|
+
: cast.constructor.name;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private existingActorCalled(name: string): Actor {
|
|
214
|
+
return this.actors['background'].has(name)
|
|
215
|
+
? this.actors['background'].get(name)
|
|
216
|
+
: this.actors['foreground'].get(name);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Returns `true` if there is an [`Actor`](https://serenity-js.org/api/core/class/Actor/) in the spotlight, `false` otherwise.
|
|
221
|
+
*
|
|
222
|
+
* @returns `true` if an actor is currently spotlighted
|
|
223
|
+
*/
|
|
224
|
+
public hasActorInTheSpotlight(): boolean {
|
|
225
|
+
return Boolean(this.currentActor);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Returns the last [`Actor`](https://serenity-js.org/api/core/class/Actor/) instantiated
|
|
230
|
+
* via [`actor`](https://serenity-js.org/api/core/class/ActorLifecycleManager/#actor).
|
|
231
|
+
*
|
|
232
|
+
* @returns The currently spotlighted actor
|
|
233
|
+
*
|
|
234
|
+
* @throws [`LogicError`](https://serenity-js.org/api/core/class/LogicError/)
|
|
235
|
+
* If no [`Actor`](https://serenity-js.org/api/core/class/Actor/) has been activated yet
|
|
236
|
+
*/
|
|
237
|
+
public actorInTheSpotlight(): Actor {
|
|
238
|
+
if (! this.currentActor) {
|
|
239
|
+
throw new LogicError(`There is no actor in the spotlight yet. Make sure you instantiate one with stage.actor(actorName) before calling this method.`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return this.currentActor;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Switches the focus to the specified stage area.
|
|
247
|
+
*
|
|
248
|
+
* Actors created after this call will be added to the specified area.
|
|
249
|
+
* This method is typically called automatically by the [`Stage`](https://serenity-js.org/api/core/class/Stage/)
|
|
250
|
+
* in response to [`SceneStarts`](https://serenity-js.org/api/core-events/class/SceneStarts/) and
|
|
251
|
+
* [`SceneFinishes`](https://serenity-js.org/api/core-events/class/SceneFinishes/) events.
|
|
252
|
+
*
|
|
253
|
+
* Test runner adapters can also call this method directly to control actor lifecycle
|
|
254
|
+
* when scene events are not available (e.g., in Playwright Test where the reporter
|
|
255
|
+
* runs in a separate process).
|
|
256
|
+
*
|
|
257
|
+
* @param focus - The focus area to switch to: `'foreground'` for scene-scoped actors,
|
|
258
|
+
* `'background'` for test run-scoped actors
|
|
259
|
+
*/
|
|
260
|
+
switchFocus(focus: StageFocus): void {
|
|
261
|
+
this.currentFocusValue = focus;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Returns the current focus area.
|
|
266
|
+
*
|
|
267
|
+
* @returns The current focus: `'foreground'` or `'background'`
|
|
268
|
+
*/
|
|
269
|
+
currentFocus(): StageFocus {
|
|
270
|
+
return this.currentFocusValue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Returns all actors in the specified focus area.
|
|
275
|
+
*
|
|
276
|
+
* This method is used by the [`Stage`](https://serenity-js.org/api/core/class/Stage/) to retrieve
|
|
277
|
+
* actors for dismissal when scenes or test runs finish.
|
|
278
|
+
*
|
|
279
|
+
* @param focus - The focus area to retrieve actors from
|
|
280
|
+
* @returns An array of actors in the specified focus area
|
|
281
|
+
*/
|
|
282
|
+
actorsIn(focus: StageFocus): Actor[] {
|
|
283
|
+
return Array.from(this.actors[focus].values());
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Clears the spotlight if the current actor is in the specified focus area.
|
|
288
|
+
*
|
|
289
|
+
* This ensures that after actors in a focus area are dismissed, the spotlight
|
|
290
|
+
* doesn't reference a dismissed actor.
|
|
291
|
+
*
|
|
292
|
+
* @param focus - The focus area to check
|
|
293
|
+
*/
|
|
294
|
+
clearSpotlightIfIn(focus: StageFocus): void {
|
|
295
|
+
|
|
296
|
+
const actors = this.actorsIn(focus);
|
|
297
|
+
|
|
298
|
+
if (actors.includes(this.currentActor)) {
|
|
299
|
+
this.currentActor = undefined;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Clears all actors from the specified focus area.
|
|
305
|
+
*
|
|
306
|
+
* This method is called by the [`Stage`](https://serenity-js.org/api/core/class/Stage/) after
|
|
307
|
+
* actors have been dismissed to remove them from the internal tracking maps.
|
|
308
|
+
*
|
|
309
|
+
* @param focus - The focus area to clear
|
|
310
|
+
*/
|
|
311
|
+
clearActorsIn(focus: StageFocus): void {
|
|
312
|
+
this.actors[focus].clear();
|
|
313
|
+
}
|
|
314
|
+
}
|