@serenity-js/core 3.23.2 → 3.24.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 +24 -0
- package/lib/errors/ErrorFactory.js +4 -4
- package/lib/errors/ErrorFactory.js.map +1 -1
- package/lib/errors/RaiseErrors.d.ts +2 -2
- package/lib/errors/RaiseErrors.js +2 -2
- package/lib/io/index.d.ts +0 -1
- package/lib/io/index.d.ts.map +1 -1
- package/lib/io/index.js +0 -1
- package/lib/io/index.js.map +1 -1
- package/lib/io/inspectedObject.js +1 -1
- package/lib/io/inspectedObject.js.map +1 -1
- package/lib/io/reflection/ValueInspector.d.ts +56 -0
- package/lib/io/reflection/ValueInspector.d.ts.map +1 -0
- package/lib/io/reflection/ValueInspector.js +149 -0
- package/lib/io/reflection/ValueInspector.js.map +1 -0
- package/lib/io/reflection/index.d.ts +1 -2
- package/lib/io/reflection/index.d.ts.map +1 -1
- package/lib/io/reflection/index.js +1 -2
- package/lib/io/reflection/index.js.map +1 -1
- package/lib/io/stringified.js +7 -90
- package/lib/io/stringified.js.map +1 -1
- package/lib/screenplay/Activity.d.ts +5 -12
- package/lib/screenplay/Activity.d.ts.map +1 -1
- package/lib/screenplay/Activity.js +3 -14
- package/lib/screenplay/Activity.js.map +1 -1
- package/lib/screenplay/Actor.js +1 -1
- package/lib/screenplay/Actor.js.map +1 -1
- package/lib/screenplay/Interaction.d.ts +4 -3
- package/lib/screenplay/Interaction.d.ts.map +1 -1
- package/lib/screenplay/Interaction.js +2 -2
- package/lib/screenplay/Interaction.js.map +1 -1
- package/lib/screenplay/Question.d.ts +73 -21
- package/lib/screenplay/Question.d.ts.map +1 -1
- package/lib/screenplay/Question.js +237 -30
- package/lib/screenplay/Question.js.map +1 -1
- package/lib/screenplay/Task.d.ts +16 -15
- package/lib/screenplay/Task.d.ts.map +1 -1
- package/lib/screenplay/Task.js +14 -14
- package/lib/screenplay/Task.js.map +1 -1
- package/lib/screenplay/abilities/Ability.d.ts +8 -6
- package/lib/screenplay/abilities/Ability.d.ts.map +1 -1
- package/lib/screenplay/abilities/Ability.js +8 -6
- package/lib/screenplay/abilities/Ability.js.map +1 -1
- package/lib/screenplay/abilities/AbilityType.d.ts +3 -3
- package/lib/screenplay/abilities/AnswerQuestions.d.ts +0 -1
- package/lib/screenplay/abilities/AnswerQuestions.d.ts.map +1 -1
- package/lib/screenplay/abilities/AnswerQuestions.js +2 -4
- package/lib/screenplay/abilities/AnswerQuestions.js.map +1 -1
- package/lib/screenplay/abilities/PerformActivities.d.ts +5 -3
- package/lib/screenplay/abilities/PerformActivities.d.ts.map +1 -1
- package/lib/screenplay/abilities/PerformActivities.js +12 -10
- package/lib/screenplay/abilities/PerformActivities.js.map +1 -1
- package/lib/screenplay/artifacts/CollectsArtifacts.d.ts +2 -2
- package/lib/screenplay/notes/NotepadAdapter.d.ts.map +1 -1
- package/lib/screenplay/notes/NotepadAdapter.js +44 -4
- package/lib/screenplay/notes/NotepadAdapter.js.map +1 -1
- package/lib/screenplay/questions/Describable.d.ts +27 -0
- package/lib/screenplay/questions/Describable.d.ts.map +1 -0
- package/lib/screenplay/questions/Describable.js +40 -0
- package/lib/screenplay/questions/Describable.js.map +1 -0
- package/lib/screenplay/questions/DescriptionFormattingOptions.d.ts +14 -0
- package/lib/screenplay/questions/DescriptionFormattingOptions.d.ts.map +1 -0
- package/lib/screenplay/questions/DescriptionFormattingOptions.js +3 -0
- package/lib/screenplay/questions/DescriptionFormattingOptions.js.map +1 -0
- package/lib/screenplay/questions/Expectation.d.ts +6 -10
- package/lib/screenplay/questions/Expectation.d.ts.map +1 -1
- package/lib/screenplay/questions/Expectation.js +12 -15
- package/lib/screenplay/questions/Expectation.js.map +1 -1
- package/lib/screenplay/questions/List.d.ts +1 -3
- package/lib/screenplay/questions/List.d.ts.map +1 -1
- package/lib/screenplay/questions/List.js +6 -31
- package/lib/screenplay/questions/List.js.map +1 -1
- package/lib/screenplay/questions/Unanswered.d.ts +1 -0
- package/lib/screenplay/questions/Unanswered.d.ts.map +1 -1
- package/lib/screenplay/questions/Unanswered.js +3 -0
- package/lib/screenplay/questions/Unanswered.js.map +1 -1
- package/lib/screenplay/questions/expectations/ExpectationDetails.js +1 -1
- package/lib/screenplay/questions/expectations/ExpectationDetails.js.map +1 -1
- package/lib/screenplay/questions/index.d.ts +3 -1
- package/lib/screenplay/questions/index.d.ts.map +1 -1
- package/lib/screenplay/questions/index.js +3 -1
- package/lib/screenplay/questions/index.js.map +1 -1
- package/lib/screenplay/questions/tag-functions.d.ts +228 -0
- package/lib/screenplay/questions/tag-functions.d.ts.map +1 -0
- package/lib/screenplay/questions/tag-functions.js +115 -0
- package/lib/screenplay/questions/tag-functions.js.map +1 -0
- package/lib/screenplay/time/activities/Wait.d.ts.map +1 -1
- package/lib/screenplay/time/activities/Wait.js +4 -3
- package/lib/screenplay/time/activities/Wait.js.map +1 -1
- package/package.json +4 -4
- package/src/errors/ErrorFactory.ts +5 -5
- package/src/errors/RaiseErrors.ts +2 -2
- package/src/io/index.ts +0 -1
- package/src/io/inspectedObject.ts +2 -2
- package/src/io/reflection/ValueInspector.ts +165 -0
- package/src/io/reflection/index.ts +1 -2
- package/src/io/stringified.ts +7 -103
- package/src/screenplay/Activity.ts +6 -17
- package/src/screenplay/Actor.ts +2 -2
- package/src/screenplay/Interaction.ts +5 -4
- package/src/screenplay/Question.ts +299 -49
- package/src/screenplay/Task.ts +18 -17
- package/src/screenplay/abilities/Ability.ts +8 -6
- package/src/screenplay/abilities/AbilityType.ts +3 -3
- package/src/screenplay/abilities/AnswerQuestions.ts +2 -5
- package/src/screenplay/abilities/PerformActivities.ts +35 -18
- package/src/screenplay/artifacts/CollectsArtifacts.ts +2 -2
- package/src/screenplay/notes/NotepadAdapter.ts +57 -6
- package/src/screenplay/questions/Describable.ts +48 -0
- package/src/screenplay/questions/DescriptionFormattingOptions.ts +13 -0
- package/src/screenplay/questions/Expectation.ts +19 -19
- package/src/screenplay/questions/List.ts +7 -41
- package/src/screenplay/questions/Unanswered.ts +4 -0
- package/src/screenplay/questions/expectations/ExpectationDetails.ts +2 -2
- package/src/screenplay/questions/index.ts +3 -1
- package/src/screenplay/questions/tag-functions.ts +313 -0
- package/src/screenplay/time/activities/Wait.ts +4 -3
- package/lib/io/isPlainObject.d.ts +0 -7
- package/lib/io/isPlainObject.d.ts.map +0 -1
- package/lib/io/isPlainObject.js +0 -25
- package/lib/io/isPlainObject.js.map +0 -1
- package/lib/io/reflection/isPrimitive.d.ts +0 -8
- package/lib/io/reflection/isPrimitive.d.ts.map +0 -1
- package/lib/io/reflection/isPrimitive.js +0 -24
- package/lib/io/reflection/isPrimitive.js.map +0 -1
- package/lib/io/reflection/typeOf.d.ts +0 -7
- package/lib/io/reflection/typeOf.d.ts.map +0 -1
- package/lib/io/reflection/typeOf.js +0 -35
- package/lib/io/reflection/typeOf.js.map +0 -1
- package/lib/screenplay/questions/q.d.ts +0 -66
- package/lib/screenplay/questions/q.d.ts.map +0 -1
- package/lib/screenplay/questions/q.js +0 -77
- package/lib/screenplay/questions/q.js.map +0 -1
- package/src/io/isPlainObject.ts +0 -24
- package/src/io/reflection/isPrimitive.ts +0 -20
- package/src/io/reflection/typeOf.ts +0 -31
- package/src/screenplay/questions/q.ts +0 -82
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.q = exports.the = void 0;
|
|
4
|
+
const io_1 = require("../../io");
|
|
5
|
+
const Question_1 = require("../Question");
|
|
6
|
+
const Describable_1 = require("./Describable");
|
|
7
|
+
function the(...args) {
|
|
8
|
+
if (io_1.ValueInspector.isPlainObject(args[0])) {
|
|
9
|
+
const descriptionFormattingOptions = args[0];
|
|
10
|
+
return (templates, ...parameters) => templateToQuestion(templates, parameters, createParameterToDescriptionMapper(descriptionFormattingOptions), createParameterValueToDescriptionMapper(descriptionFormattingOptions));
|
|
11
|
+
}
|
|
12
|
+
return templateToQuestion(args[0], args.slice(1), createParameterToDescriptionMapper(), createParameterValueToDescriptionMapper());
|
|
13
|
+
}
|
|
14
|
+
exports.the = the;
|
|
15
|
+
/**
|
|
16
|
+
* A Serenity/JS Screenplay Pattern-flavour
|
|
17
|
+
* of a [tagged template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates),
|
|
18
|
+
* `q` is a tag function capable of resolving any `Answerable<string>` or `Answerable<number>`
|
|
19
|
+
* you parametrise it with, and returning a `QuestionAdapter<string>`.
|
|
20
|
+
*
|
|
21
|
+
* Use `q` to concatenate `string` and `number` values returned from synchronous an asynchronous sources.
|
|
22
|
+
*
|
|
23
|
+
* ## Interpolating questions
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { q, actorCalled } from '@serenity-js/core'
|
|
27
|
+
* import { Send, DeleteRequest } from '@serenity-js/rest'
|
|
28
|
+
* import { Text } from '@serenity-js/web'
|
|
29
|
+
*
|
|
30
|
+
* await actorCalled('Alice').attemptsTo(
|
|
31
|
+
* Send.a(DeleteRequest.to(
|
|
32
|
+
* q `/articles/${ Text.of(Article.id()) }`
|
|
33
|
+
* ))
|
|
34
|
+
* )
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ## Using a custom description
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { q, actorCalled } from '@serenity-js/core'
|
|
41
|
+
* import { Send, DeleteRequest } from '@serenity-js/rest'
|
|
42
|
+
*
|
|
43
|
+
* await actorCalled('Alice').attemptsTo(
|
|
44
|
+
* Send.a(DeleteRequest.to(
|
|
45
|
+
* q `/articles/${ Text.of(Article.id()) }`.describedAs('/articles/:id')
|
|
46
|
+
* ))
|
|
47
|
+
* )
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* ## Transforming the interpolated string
|
|
51
|
+
*
|
|
52
|
+
* The mechanism presented below relies on {@apilink QuestionAdapter}.
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { q, actorCalled } from '@serenity-js/core'
|
|
56
|
+
* import { Send, DeleteRequest } from '@serenity-js/rest'
|
|
57
|
+
*
|
|
58
|
+
* await actorCalled('Alice').attemptsTo(
|
|
59
|
+
* Send.a(DeleteRequest.to(
|
|
60
|
+
* q `/articles/${ Text.of(Article.id()) }`.toLocaleLowerCase()
|
|
61
|
+
* ))
|
|
62
|
+
* )
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* ## Learn more
|
|
66
|
+
*
|
|
67
|
+
* - {@apilink Answerable}
|
|
68
|
+
* - {@apilink Question}
|
|
69
|
+
* - {@apilink Question.describedAs}
|
|
70
|
+
* - {@apilink QuestionAdapter}
|
|
71
|
+
*
|
|
72
|
+
* @group Questions
|
|
73
|
+
*
|
|
74
|
+
* @param templates
|
|
75
|
+
* @param parameters
|
|
76
|
+
*/
|
|
77
|
+
function q(templates, ...parameters) {
|
|
78
|
+
return templateToQuestion(templates, parameters, (parameter) => {
|
|
79
|
+
// return static string and number parameter values as is
|
|
80
|
+
if (typeof parameter === 'string' || typeof parameter === 'number') {
|
|
81
|
+
return String(parameter);
|
|
82
|
+
}
|
|
83
|
+
// for Questions, Promises and other Answerables, return their description
|
|
84
|
+
return `{${createParameterToDescriptionMapper()(parameter)}}`;
|
|
85
|
+
}, createParameterValueMapper());
|
|
86
|
+
}
|
|
87
|
+
exports.q = q;
|
|
88
|
+
function createParameterToDescriptionMapper(options) {
|
|
89
|
+
return (parameter) => parameter === undefined
|
|
90
|
+
? 'undefined'
|
|
91
|
+
: Question_1.Question.formattedValue(options).of(parameter).toString();
|
|
92
|
+
}
|
|
93
|
+
function createParameterValueToDescriptionMapper(options) {
|
|
94
|
+
return async (actor, parameter) => parameter instanceof Describable_1.Describable
|
|
95
|
+
? parameter.describedBy(actor)
|
|
96
|
+
: actor.answer(Question_1.Question.formattedValue(options).of(parameter));
|
|
97
|
+
}
|
|
98
|
+
function createParameterValueMapper() {
|
|
99
|
+
return async (actor, parameter) => actor.answer(parameter);
|
|
100
|
+
}
|
|
101
|
+
function templateToQuestion(templates, parameters, descriptionMapper, valueMapper) {
|
|
102
|
+
const description = interpolate(templates, parameters.map(parameter => descriptionMapper(parameter)));
|
|
103
|
+
return Question_1.Question.about(description, async (actor) => {
|
|
104
|
+
const descriptions = await (0, io_1.asyncMap)(parameters, parameter => valueMapper(actor, parameter));
|
|
105
|
+
return interpolate(templates, descriptions);
|
|
106
|
+
}, (context) => templateToQuestion(templates, parameters.map(parameter => Question_1.Question.isAMetaQuestion(parameter)
|
|
107
|
+
? parameter.of(context)
|
|
108
|
+
: parameter), descriptionMapper, valueMapper));
|
|
109
|
+
}
|
|
110
|
+
function interpolate(templates, parameters) {
|
|
111
|
+
return templates.flatMap((template, i) => i < parameters.length
|
|
112
|
+
? [template, parameters[i]]
|
|
113
|
+
: [template]).join('');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=tag-functions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-functions.js","sourceRoot":"","sources":["../../../src/screenplay/questions/tag-functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Wait.d.ts","sourceRoot":"","sources":["../../../../src/screenplay/time/activities/Wait.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"Wait.d.ts","sourceRoot":"","sources":["../../../../src/screenplay/time/activities/Wait.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAqB,MAAM,iBAAiB,CAAC;AAIxF,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuHG;AACH,qBAAa,IAAI;IAEb;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,cAAc,WAAgC;IAE9D;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,CAAC,sBAAsB,WAAgC;IAEtE;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,sBAAsB,WAA+B;IAErE;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,WAAW;IAIvD;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG;QAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,CAAA;KAAE;IAOtI;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;CAGxG;AAiBD;;;;;;;;;;;GAWG;AACH,qBAAa,SAAS,CAAC,MAAM,CAAE,SAAQ,WAAW;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAHR,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAC1B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,EAChC,eAAe,EAAE,QAAQ,EACzB,OAAO,CAAC,EAAE,QAAQ;IAYvC;;;;;;;;OAQG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW;IAI7C;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAmC1E"}
|
|
@@ -6,6 +6,7 @@ const errors_1 = require("../../../errors");
|
|
|
6
6
|
const io_1 = require("../../../io");
|
|
7
7
|
const Interaction_1 = require("../../Interaction");
|
|
8
8
|
const questions_1 = require("../../questions");
|
|
9
|
+
const questions_2 = require("../../questions");
|
|
9
10
|
const abilities_1 = require("../abilities");
|
|
10
11
|
const models_1 = require("../models");
|
|
11
12
|
/**
|
|
@@ -194,7 +195,7 @@ exports.Wait = Wait;
|
|
|
194
195
|
class WaitFor extends Interaction_1.Interaction {
|
|
195
196
|
duration;
|
|
196
197
|
constructor(duration) {
|
|
197
|
-
super((0,
|
|
198
|
+
super((0, questions_1.the) `#actor waits for ${duration}`);
|
|
198
199
|
this.duration = duration;
|
|
199
200
|
}
|
|
200
201
|
async performAs(actor) {
|
|
@@ -220,7 +221,7 @@ class WaitUntil extends Interaction_1.Interaction {
|
|
|
220
221
|
pollingInterval;
|
|
221
222
|
timeout;
|
|
222
223
|
constructor(actual, expectation, pollingInterval, timeout) {
|
|
223
|
-
super((0,
|
|
224
|
+
super((0, questions_1.the) `#actor waits until ${actual} does ${expectation}`);
|
|
224
225
|
this.actual = actual;
|
|
225
226
|
this.expectation = expectation;
|
|
226
227
|
this.pollingInterval = pollingInterval;
|
|
@@ -248,7 +249,7 @@ class WaitUntil extends Interaction_1.Interaction {
|
|
|
248
249
|
*/
|
|
249
250
|
async performAs(actor) {
|
|
250
251
|
await abilities_1.ScheduleWork.as(actor).repeatUntil(() => actor.answer(this.expectation.isMetFor(this.actual)), {
|
|
251
|
-
exitCondition: outcome => outcome instanceof
|
|
252
|
+
exitCondition: outcome => outcome instanceof questions_2.ExpectationMet,
|
|
252
253
|
delayBetweenInvocations: (invocation) => invocation === 0
|
|
253
254
|
? models_1.Duration.ofMilliseconds(0)
|
|
254
255
|
: this.pollingInterval,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Wait.js","sourceRoot":"","sources":["../../../../src/screenplay/time/activities/Wait.ts"],"names":[],"mappings":";;;AAAA,2CAAuE;AAEvE,4CAA0G;AAC1G,oCAAgC;AAGhC,mDAAgD;AAEhD,+CAAiD;AACjD,4CAA4C;AAC5C,sCAAqC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuHG;AACH,MAAa,IAAI;IAEb;;;OAGG;IACH,MAAM,CAAU,cAAc,GAAG,iBAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IAE9D;;;;;;;OAOG;IACH,MAAM,CAAU,sBAAsB,GAAG,iBAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IAEtE;;OAEG;IACH,MAAM,CAAU,sBAAsB,GAAG,iBAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAErE;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,CAAC,QAA8B;QACrC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,OAAiB;QACzB,OAAO;YACH,KAAK,EAAE,CAAS,MAA0B,EAAE,WAAgC,EAAqB,EAAE,CAC/F,IAAI,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;SAC3I,CAAC;IACN,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,CAAS,MAA0B,EAAE,WAAgC;QAC7E,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC3E,CAAC;;AAhEL,oBAiEC;AAED;;GAEG;AACH,MAAM,OAAQ,SAAQ,yBAAW;IACA;IAA7B,YAA6B,QAA8B;QACvD,KAAK,CAAC,IAAA,
|
|
1
|
+
{"version":3,"file":"Wait.js","sourceRoot":"","sources":["../../../../src/screenplay/time/activities/Wait.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serenity-js/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.24.0",
|
|
4
4
|
"description": "Serenity/JS Screenplay, reporting engine and core interfaces.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jan Molak",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"@types/semver": "7.5.8",
|
|
54
54
|
"@types/validate-npm-package-name": "4.0.2",
|
|
55
55
|
"assertion-error-formatter": "3.0.0",
|
|
56
|
-
"c8": "
|
|
57
|
-
"memfs": "4.9.
|
|
56
|
+
"c8": "10.1.2",
|
|
57
|
+
"memfs": "4.9.3",
|
|
58
58
|
"mocha": "10.4.0",
|
|
59
59
|
"mocha-multi": "1.1.7",
|
|
60
60
|
"ts-node": "10.9.2",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"engines": {
|
|
72
72
|
"node": "^16.13 || ^18.12 || ^20"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "174876f2ab2b96bce79ac825ba8c784beae2f63c"
|
|
75
75
|
}
|
|
@@ -3,7 +3,7 @@ import { diffArrays, diffJson } from 'diff';
|
|
|
3
3
|
import { equal } from 'tiny-types/lib/objects';
|
|
4
4
|
import { types } from 'util';
|
|
5
5
|
|
|
6
|
-
import { inspected,
|
|
6
|
+
import { inspected, ValueInspector } from '../io';
|
|
7
7
|
import { Unanswered } from '../screenplay/questions/Unanswered';
|
|
8
8
|
import type { DiffFormatter } from './diff';
|
|
9
9
|
import { AnsiDiffFormatter } from './diff/AnsiDiffFormatter';
|
|
@@ -121,7 +121,7 @@ class DiffValue {
|
|
|
121
121
|
name: string,
|
|
122
122
|
public readonly value: unknown,
|
|
123
123
|
) {
|
|
124
|
-
this.nameAndType = `${ name } ${ typeOf(value) }`;
|
|
124
|
+
this.nameAndType = `${ name } ${ ValueInspector.typeOf(value) }`;
|
|
125
125
|
this.desiredNameFieldLength = this.nameAndType.length;
|
|
126
126
|
this.summary = this.summaryOf(value);
|
|
127
127
|
}
|
|
@@ -136,7 +136,7 @@ class DiffValue {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
type(): string {
|
|
139
|
-
return typeOf(this.value);
|
|
139
|
+
return ValueInspector.typeOf(this.value);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
isComplex(): boolean {
|
|
@@ -154,7 +154,7 @@ class DiffValue {
|
|
|
154
154
|
return false;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
return isPlainObject(this.value)
|
|
157
|
+
return ValueInspector.isPlainObject(this.value)
|
|
158
158
|
|| this.value['toJSON'];
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -178,7 +178,7 @@ class DiffValue {
|
|
|
178
178
|
|
|
179
179
|
const isDefined = value !== undefined && value !== null;
|
|
180
180
|
|
|
181
|
-
if (isDefined && (isPrimitive(value) || value instanceof RegExp)) {
|
|
181
|
+
if (isDefined && (ValueInspector.isPrimitive(value) || value instanceof RegExp)) {
|
|
182
182
|
return String(value);
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -17,12 +17,12 @@ import type { RuntimeError } from './model/RuntimeError';
|
|
|
17
17
|
* ## Raising an error
|
|
18
18
|
*
|
|
19
19
|
* ```typescript
|
|
20
|
-
* import { Interaction, LogicError, RaiseErrors } from '@serenity-js/core'
|
|
20
|
+
* import { Interaction, LogicError, RaiseErrors, the } from '@serenity-js/core'
|
|
21
21
|
* import isPathInside from 'is-path-inside'
|
|
22
22
|
* import { unlink } from 'fs/promises'
|
|
23
23
|
*
|
|
24
24
|
* const RemoveFile = (pathToFile: string) =>
|
|
25
|
-
* Interaction.where(`#actor removes a file at ${ pathToFile }`, async actor => {
|
|
25
|
+
* Interaction.where(the`#actor removes a file at ${ pathToFile }`, async actor => {
|
|
26
26
|
*
|
|
27
27
|
* if (! isPathInside(pathToFile, process.cwd())) {
|
|
28
28
|
*
|
package/src/io/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as util from 'util'; // eslint-disable-line unicorn/import-style
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ValueInspector } from './reflection';
|
|
4
4
|
|
|
5
5
|
export function inspectedObject<T>(value: T, allowFields?: Array<keyof T>): (depth: number, options: util.InspectOptionsStylized, inspect: typeof util.inspect) => string {
|
|
6
6
|
return function (depth: number, options: util.InspectOptionsStylized, inspect: typeof util.inspect = util.inspect): string {
|
|
7
|
-
const typeName = options.stylize(typeOf(value), 'special');
|
|
7
|
+
const typeName = options.stylize(ValueInspector.typeOf(value), 'special');
|
|
8
8
|
|
|
9
9
|
if (depth < 0) {
|
|
10
10
|
return typeName;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { types } from 'node:util';
|
|
2
|
+
|
|
3
|
+
export class ValueInspector {
|
|
4
|
+
static isPromise(value: unknown): value is Promise<unknown> {
|
|
5
|
+
return value instanceof Promise
|
|
6
|
+
|| (Object.prototype.hasOwnProperty.call(value, 'then'));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static isDate(value: unknown): value is Date {
|
|
10
|
+
return value instanceof Date;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Checks if the value is a named {@apilink Function}
|
|
15
|
+
*
|
|
16
|
+
* @param value
|
|
17
|
+
*/
|
|
18
|
+
static isFunction(value: unknown): value is Function { // eslint-disable-line @typescript-eslint/ban-types
|
|
19
|
+
return Object.prototype.toString.call(value) === '[object Function]';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the value has a good chance of being a plain JavaScript object
|
|
24
|
+
*
|
|
25
|
+
* @param value
|
|
26
|
+
*/
|
|
27
|
+
static isPlainObject(value: unknown): value is object { // eslint-disable-line @typescript-eslint/ban-types
|
|
28
|
+
|
|
29
|
+
// Basic check for Type object that's not null
|
|
30
|
+
if (typeof value === 'object' && value !== null) {
|
|
31
|
+
|
|
32
|
+
// If Object.getPrototypeOf supported, use it
|
|
33
|
+
if (typeof Object.getPrototypeOf === 'function') {
|
|
34
|
+
const proto = Object.getPrototypeOf(value);
|
|
35
|
+
return proto === Object.prototype || proto === null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Otherwise, use internal class
|
|
39
|
+
// This should be reliable as if getPrototypeOf not supported, is pre-ES5
|
|
40
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Not an object
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns true if `value` is a [JavaScript primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive),
|
|
49
|
+
* false otherwise.
|
|
50
|
+
*
|
|
51
|
+
* @param value
|
|
52
|
+
*/
|
|
53
|
+
static isPrimitive(value: unknown): boolean {
|
|
54
|
+
if (value === null) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return [
|
|
59
|
+
'string',
|
|
60
|
+
'number',
|
|
61
|
+
'bigint',
|
|
62
|
+
'boolean',
|
|
63
|
+
'undefined',
|
|
64
|
+
'symbol'
|
|
65
|
+
].includes(typeof value);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the value defines its own `toString` method
|
|
70
|
+
*
|
|
71
|
+
* @param value
|
|
72
|
+
*/
|
|
73
|
+
static hasItsOwnToString(value: unknown): boolean {
|
|
74
|
+
return typeof value === 'object'
|
|
75
|
+
&& !! (value as any).toString
|
|
76
|
+
&& typeof (value as any).toString === 'function'
|
|
77
|
+
&& ! ValueInspector.isNative((value as any).toString);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Describes the type of the provided value.
|
|
82
|
+
*
|
|
83
|
+
* @param value
|
|
84
|
+
*/
|
|
85
|
+
static typeOf(value: unknown): string {
|
|
86
|
+
switch (true) {
|
|
87
|
+
case value === null:
|
|
88
|
+
return 'null';
|
|
89
|
+
case types.isProxy(value):
|
|
90
|
+
return `Proxy<${ Reflect.getPrototypeOf(value as object).constructor.name }>`;
|
|
91
|
+
case typeof value !== 'object':
|
|
92
|
+
return typeof value;
|
|
93
|
+
case value instanceof Date:
|
|
94
|
+
return `Date`;
|
|
95
|
+
case Array.isArray(value):
|
|
96
|
+
return `Array`;
|
|
97
|
+
case value instanceof RegExp:
|
|
98
|
+
return `RegExp`
|
|
99
|
+
case value instanceof Set:
|
|
100
|
+
return 'Set';
|
|
101
|
+
case value instanceof Map:
|
|
102
|
+
return 'Map';
|
|
103
|
+
case !! value.constructor && value.constructor !== Object:
|
|
104
|
+
return value.constructor.name
|
|
105
|
+
default:
|
|
106
|
+
return 'object';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Inspired by https://davidwalsh.name/detect-native-function
|
|
112
|
+
*
|
|
113
|
+
* @param value
|
|
114
|
+
*/
|
|
115
|
+
static isNative(value: unknown): value is Function { // eslint-disable-line @typescript-eslint/ban-types
|
|
116
|
+
|
|
117
|
+
const
|
|
118
|
+
toString = Object.prototype.toString, // Used to resolve the internal `{@apilink Class}` of values
|
|
119
|
+
fnToString = Function.prototype.toString, // Used to resolve the decompiled source of functions
|
|
120
|
+
hostConstructor = /^\[object .+?Constructor]$/; // Used to detect host constructors (Safari > 4; really typed array specific)
|
|
121
|
+
|
|
122
|
+
// Compile a regexp using a common native method as a template.
|
|
123
|
+
// We chose `Object#toString` because there's a good chance it is not being mucked with.
|
|
124
|
+
const nativeFunctionTemplate = new RegExp(
|
|
125
|
+
'^' +
|
|
126
|
+
// Coerce `Object#toString` to a string
|
|
127
|
+
String(toString)
|
|
128
|
+
// Escape any special regexp characters
|
|
129
|
+
.replaceAll(/[$()*+./?[\\\]^{|}]/g, '\\$&')
|
|
130
|
+
// Replace mentions of `toString` with `.*?` to keep the template generic.
|
|
131
|
+
// Replace thing like `for ...` to support environments like Rhino which add extra info
|
|
132
|
+
// such as method arity.
|
|
133
|
+
.replaceAll(/toString|(function).*?(?=\\\()| for .+?(?=\\])/g, '$1.*?') +
|
|
134
|
+
'$',
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const type = typeof value;
|
|
138
|
+
return type === 'function'
|
|
139
|
+
// Use `Function#toString` to bypass the value's own `toString` method
|
|
140
|
+
// and avoid being faked out.
|
|
141
|
+
? nativeFunctionTemplate.test(fnToString.call(value))
|
|
142
|
+
// Fallback to a host object check because some environments will represent
|
|
143
|
+
// things like typed arrays as DOM methods which may not conform to the
|
|
144
|
+
// normal native pattern.
|
|
145
|
+
: (value && type === 'object' && hostConstructor.test(toString.call(value))) || false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Checks if the value defines its own `inspect` method
|
|
150
|
+
*
|
|
151
|
+
* @param value
|
|
152
|
+
*/
|
|
153
|
+
static isInspectable(value: unknown): value is { inspect: () => string } {
|
|
154
|
+
return !! (value as any).inspect && typeof (value as any).inspect === 'function';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Checks if the value defines its own [`inspect` method](https://nodejs.org/api/util.html#util_util_inspect_custom)
|
|
159
|
+
*
|
|
160
|
+
* @param value
|
|
161
|
+
*/
|
|
162
|
+
static hasCustomInspectionFunction(value: unknown): value is object { // eslint-disable-line @typescript-eslint/ban-types
|
|
163
|
+
return value && value[Symbol.for('nodejs.util.inspect.custom')];
|
|
164
|
+
}
|
|
165
|
+
}
|
package/src/io/stringified.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { inspect } from 'util';
|
|
|
2
2
|
|
|
3
3
|
import type { Answerable } from '../screenplay/Answerable';
|
|
4
4
|
import { Question } from '../screenplay/Question';
|
|
5
|
-
import {
|
|
5
|
+
import { ValueInspector } from './reflection/ValueInspector';
|
|
6
6
|
|
|
7
7
|
const indentationPrefix = ' ';
|
|
8
8
|
|
|
@@ -33,7 +33,7 @@ export function stringified(value: Answerable<any>, config?: StringifyConfig): s
|
|
|
33
33
|
return stringifiedArray(value, { indentationLevel, inline, markQuestions });
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (
|
|
36
|
+
if (ValueInspector.isPromise(value)) {
|
|
37
37
|
return markAs('Promise', markQuestions);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -41,25 +41,25 @@ export function stringified(value: Answerable<any>, config?: StringifyConfig): s
|
|
|
41
41
|
return markAs(value.toString(), markQuestions);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if (
|
|
44
|
+
if (ValueInspector.isDate(value)) {
|
|
45
45
|
return value.toISOString();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
if (hasItsOwnToString(value)) {
|
|
48
|
+
if (ValueInspector.hasItsOwnToString(value)) {
|
|
49
49
|
return value.toString();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (isInspectable(value)) {
|
|
52
|
+
if (ValueInspector.isInspectable(value)) {
|
|
53
53
|
return value.inspect();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
if (
|
|
56
|
+
if (ValueInspector.isFunction(value)) {
|
|
57
57
|
return hasName(value)
|
|
58
58
|
? value.name
|
|
59
59
|
: markAs(`Function`, true);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
if (! hasCustomInspectionFunction(value) && isPlainObject(value) && isSerialisableAsJSON(value)) {
|
|
62
|
+
if (! ValueInspector.hasCustomInspectionFunction(value) && ValueInspector.isPlainObject(value) && isSerialisableAsJSON(value)) {
|
|
63
63
|
return stringifiedToJson(value, { indentationLevel, inline, markQuestions });
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -121,55 +121,6 @@ function isDefined(v: Answerable<any>) {
|
|
|
121
121
|
return !! v;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
* Checks if the value defines its own `toString` method
|
|
126
|
-
*
|
|
127
|
-
* @param v
|
|
128
|
-
*/
|
|
129
|
-
function hasItsOwnToString(v: Answerable<any>): v is { toString: () => string } {
|
|
130
|
-
return typeof v === 'object'
|
|
131
|
-
&& !! (v as any).toString
|
|
132
|
-
&& typeof (v as any).toString === 'function'
|
|
133
|
-
&& ! isNative((v as any).toString);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Checks if the value defines its own `inspect` method
|
|
138
|
-
*
|
|
139
|
-
* @param v
|
|
140
|
-
*/
|
|
141
|
-
function isInspectable(v: Answerable<any>): v is { inspect: () => string } {
|
|
142
|
-
return !! (v as any).inspect && typeof (v as any).inspect === 'function';
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Checks if the value is a {@apilink Date}
|
|
147
|
-
*
|
|
148
|
-
* @param v
|
|
149
|
-
*/
|
|
150
|
-
function isADate(v: Answerable<any>): v is Date {
|
|
151
|
-
return v instanceof Date;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Checks if the value is a {@apilink Promise}
|
|
156
|
-
*
|
|
157
|
-
* @param v
|
|
158
|
-
*/
|
|
159
|
-
function isAPromise<T>(v: Answerable<T>): v is Promise<T> {
|
|
160
|
-
return typeof v === 'object'
|
|
161
|
-
&& 'then' in v;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Checks if the value is a named {@apilink Function}
|
|
166
|
-
*
|
|
167
|
-
* @param v
|
|
168
|
-
*/
|
|
169
|
-
function isAFunction(v: any): v is Function { // eslint-disable-line @typescript-eslint/ban-types
|
|
170
|
-
return Object.prototype.toString.call(v) === '[object Function]';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
124
|
/**
|
|
174
125
|
* Checks if the value is has a property called 'name' with a non-empty value.
|
|
175
126
|
*
|
|
@@ -179,15 +130,6 @@ function hasName(v: any): v is { name: string } {
|
|
|
179
130
|
return typeof (v as any).name === 'string' && (v as any).name !== '';
|
|
180
131
|
}
|
|
181
132
|
|
|
182
|
-
/**
|
|
183
|
-
* Checks if the value defines its own [`inspect` method](https://nodejs.org/api/util.html#util_util_inspect_custom)
|
|
184
|
-
*
|
|
185
|
-
* @param v
|
|
186
|
-
*/
|
|
187
|
-
function hasCustomInspectionFunction(v: Answerable<any>): v is object { // eslint-disable-line @typescript-eslint/ban-types
|
|
188
|
-
return v && v[Symbol.for('nodejs.util.inspect.custom')];
|
|
189
|
-
}
|
|
190
|
-
|
|
191
133
|
/**
|
|
192
134
|
* Checks if the value is a JSON object that can be stringified
|
|
193
135
|
*
|
|
@@ -202,41 +144,3 @@ function isSerialisableAsJSON(v: any): v is object { // eslint-disable-line @
|
|
|
202
144
|
return false;
|
|
203
145
|
}
|
|
204
146
|
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Inspired by https://davidwalsh.name/detect-native-function
|
|
208
|
-
*
|
|
209
|
-
* @param v
|
|
210
|
-
*/
|
|
211
|
-
function isNative(v: any): v is Function { // eslint-disable-line @typescript-eslint/ban-types
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
toString = Object.prototype.toString, // Used to resolve the internal `{@apilink Class}` of values
|
|
215
|
-
fnToString = Function.prototype.toString, // Used to resolve the decompiled source of functions
|
|
216
|
-
hostConstructor = /^\[object .+?Constructor]$/; // Used to detect host constructors (Safari > 4; really typed array specific)
|
|
217
|
-
|
|
218
|
-
// Compile a regexp using a common native method as a template.
|
|
219
|
-
// We chose `Object#toString` because there's a good chance it is not being mucked with.
|
|
220
|
-
const nativeFunctionTemplate = new RegExp(
|
|
221
|
-
'^' +
|
|
222
|
-
// Coerce `Object#toString` to a string
|
|
223
|
-
String(toString)
|
|
224
|
-
// Escape any special regexp characters
|
|
225
|
-
.replaceAll(/[$()*+./?[\\\]^{|}]/g, '\\$&')
|
|
226
|
-
// Replace mentions of `toString` with `.*?` to keep the template generic.
|
|
227
|
-
// Replace thing like `for ...` to support environments like Rhino which add extra info
|
|
228
|
-
// such as method arity.
|
|
229
|
-
.replaceAll(/toString|(function).*?(?=\\\()| for .+?(?=\\])/g, '$1.*?') +
|
|
230
|
-
'$',
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
const type = typeof v;
|
|
234
|
-
return type === 'function'
|
|
235
|
-
// Use `Function#toString` to bypass the value's own `toString` method
|
|
236
|
-
// and avoid being faked out.
|
|
237
|
-
? nativeFunctionTemplate.test(fnToString.call(v))
|
|
238
|
-
// Fallback to a host object check because some environments will represent
|
|
239
|
-
// things like typed arrays as DOM methods which may not conform to the
|
|
240
|
-
// normal native pattern.
|
|
241
|
-
: (v && type === 'object' && hostConstructor.test(toString.call(v))) || false;
|
|
242
|
-
}
|