@serenity-js/core 2.32.2 → 3.0.0-rc.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 +64 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/io/ErrorSerialiser.js +4 -1
- package/lib/io/ErrorSerialiser.js.map +1 -1
- package/lib/io/collections/index.d.ts +0 -1
- package/lib/io/collections/index.js +0 -1
- package/lib/io/collections/index.js.map +1 -1
- package/lib/io/format.d.ts +37 -0
- package/lib/io/format.js +49 -0
- package/lib/io/format.js.map +1 -0
- package/lib/io/formatted.d.ts +5 -1
- package/lib/io/formatted.js +6 -13
- package/lib/io/formatted.js.map +1 -1
- package/lib/io/index.d.ts +1 -0
- package/lib/io/index.js +1 -0
- package/lib/io/index.js.map +1 -1
- package/lib/io/inspected.d.ts +9 -1
- package/lib/io/inspected.js +50 -14
- package/lib/io/inspected.js.map +1 -1
- package/lib/model/Timestamp.d.ts +4 -2
- package/lib/model/Timestamp.js +8 -2
- package/lib/model/Timestamp.js.map +1 -1
- package/lib/screenplay/Question.d.ts +6 -83
- package/lib/screenplay/Question.js +14 -98
- package/lib/screenplay/Question.js.map +1 -1
- package/lib/screenplay/actor/Actor.js +2 -2
- package/lib/screenplay/actor/Actor.js.map +1 -1
- package/lib/screenplay/index.d.ts +1 -1
- package/lib/screenplay/index.js +1 -1
- package/lib/screenplay/index.js.map +1 -1
- package/lib/screenplay/model/Adapter.d.ts +8 -0
- package/lib/screenplay/{questions/proxies/PropertyPathKey.js → model/Adapter.js} +1 -1
- package/lib/screenplay/model/Adapter.js.map +1 -0
- package/lib/screenplay/model/createAdapter.d.ts +3 -0
- package/lib/screenplay/model/createAdapter.js +112 -0
- package/lib/screenplay/model/createAdapter.js.map +1 -0
- package/lib/screenplay/model/index.d.ts +2 -0
- package/lib/screenplay/{tasks → model}/index.js +2 -1
- package/lib/screenplay/model/index.js.map +1 -0
- package/lib/screenplay/questions/Expectation.d.ts +11 -0
- package/lib/screenplay/questions/Expectation.js +18 -1
- package/lib/screenplay/questions/Expectation.js.map +1 -1
- package/lib/screenplay/questions/List.d.ts +10 -0
- package/lib/screenplay/questions/List.js +16 -1
- package/lib/screenplay/questions/List.js.map +1 -1
- package/lib/screenplay/questions/Note.d.ts +10 -0
- package/lib/screenplay/questions/Note.js +17 -1
- package/lib/screenplay/questions/Note.js.map +1 -1
- package/lib/screenplay/questions/index.d.ts +0 -3
- package/lib/screenplay/questions/index.js +0 -5
- package/lib/screenplay/questions/index.js.map +1 -1
- package/lib/screenplay/questions/lists/ArrayListAdapter.js +20 -5
- package/lib/screenplay/questions/lists/ArrayListAdapter.js.map +1 -1
- package/package.json +10 -10
- package/src/index.ts +2 -1
- package/src/io/ErrorSerialiser.ts +5 -1
- package/src/io/collections/index.ts +0 -1
- package/src/io/format.ts +46 -0
- package/src/io/formatted.ts +7 -15
- package/src/io/index.ts +1 -0
- package/src/io/inspected.ts +66 -14
- package/src/model/Timestamp.ts +10 -2
- package/src/screenplay/Question.ts +21 -119
- package/src/screenplay/actor/Actor.ts +2 -2
- package/src/screenplay/index.ts +1 -1
- package/src/screenplay/model/Adapter.ts +14 -0
- package/src/screenplay/model/createAdapter.ts +142 -0
- package/src/screenplay/model/index.ts +2 -0
- package/src/screenplay/questions/Expectation.ts +20 -1
- package/src/screenplay/questions/List.ts +19 -1
- package/src/screenplay/questions/Note.ts +21 -1
- package/src/screenplay/questions/index.ts +0 -3
- package/src/screenplay/questions/lists/ArrayListAdapter.ts +21 -2
- package/lib/decorators/pending.d.ts +0 -0
- package/lib/decorators/pending.js +0 -2
- package/lib/decorators/pending.js.map +0 -1
- package/lib/decorators/step.d.ts +0 -0
- package/lib/decorators/step.js +0 -2
- package/lib/decorators/step.js.map +0 -1
- package/lib/io/collections/mappable.d.ts +0 -52
- package/lib/io/collections/mappable.js +0 -28
- package/lib/io/collections/mappable.js.map +0 -1
- package/lib/screenplay/questions/Property.d.ts +0 -91
- package/lib/screenplay/questions/Property.js +0 -99
- package/lib/screenplay/questions/Property.js.map +0 -1
- package/lib/screenplay/questions/Transform.d.ts +0 -31
- package/lib/screenplay/questions/Transform.js +0 -46
- package/lib/screenplay/questions/Transform.js.map +0 -1
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.d.ts +0 -11
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.js +0 -3
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.js.map +0 -1
- package/lib/screenplay/questions/mappings/index.d.ts +0 -2
- package/lib/screenplay/questions/mappings/index.js +0 -15
- package/lib/screenplay/questions/mappings/index.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/append.d.ts +0 -14
- package/lib/screenplay/questions/mappings/string/append.js +0 -25
- package/lib/screenplay/questions/mappings/string/append.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/index.d.ts +0 -11
- package/lib/screenplay/questions/mappings/string/index.js +0 -24
- package/lib/screenplay/questions/mappings/string/index.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/normalize.d.ts +0 -20
- package/lib/screenplay/questions/mappings/string/normalize.js +0 -30
- package/lib/screenplay/questions/mappings/string/normalize.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/replace.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/replace.js +0 -30
- package/lib/screenplay/questions/mappings/string/replace.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/slice.d.ts +0 -28
- package/lib/screenplay/questions/mappings/string/slice.js +0 -47
- package/lib/screenplay/questions/mappings/string/slice.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/split.d.ts +0 -19
- package/lib/screenplay/questions/mappings/string/split.js +0 -36
- package/lib/screenplay/questions/mappings/string/split.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.js +0 -28
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.js +0 -29
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLowerCase.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toLowerCase.js +0 -19
- package/lib/screenplay/questions/mappings/string/toLowerCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toNumber.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toNumber.js +0 -18
- package/lib/screenplay/questions/mappings/string/toNumber.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toUpperCase.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toUpperCase.js +0 -19
- package/lib/screenplay/questions/mappings/string/toUpperCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/trim.d.ts +0 -12
- package/lib/screenplay/questions/mappings/string/trim.js +0 -21
- package/lib/screenplay/questions/mappings/string/trim.js.map +0 -1
- package/lib/screenplay/questions/proxies/PropertyPathKey.d.ts +0 -4
- package/lib/screenplay/questions/proxies/PropertyPathKey.js.map +0 -1
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.d.ts +0 -14
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.js +0 -35
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.js.map +0 -1
- package/lib/screenplay/questions/proxies/createQuestionProxy.d.ts +0 -13
- package/lib/screenplay/questions/proxies/createQuestionProxy.js +0 -34
- package/lib/screenplay/questions/proxies/createQuestionProxy.js.map +0 -1
- package/lib/screenplay/questions/proxies/describePath.d.ts +0 -5
- package/lib/screenplay/questions/proxies/describePath.js +0 -19
- package/lib/screenplay/questions/proxies/describePath.js.map +0 -1
- package/lib/screenplay/questions/proxies/index.d.ts +0 -2
- package/lib/screenplay/questions/proxies/index.js +0 -15
- package/lib/screenplay/questions/proxies/index.js.map +0 -1
- package/lib/screenplay/questions/proxies/key.d.ts +0 -8
- package/lib/screenplay/questions/proxies/key.js +0 -16
- package/lib/screenplay/questions/proxies/key.js.map +0 -1
- package/lib/screenplay/tasks/Loop.d.ts +0 -198
- package/lib/screenplay/tasks/Loop.js +0 -222
- package/lib/screenplay/tasks/Loop.js.map +0 -1
- package/lib/screenplay/tasks/index.d.ts +0 -1
- package/lib/screenplay/tasks/index.js.map +0 -1
- package/src/decorators/pending.ts +0 -1
- package/src/decorators/step.ts +0 -1
- package/src/io/collections/mappable.ts +0 -60
- package/src/screenplay/questions/Property.ts +0 -98
- package/src/screenplay/questions/Transform.ts +0 -50
- package/src/screenplay/questions/mappings/AnswerMappingFunction.ts +0 -13
- package/src/screenplay/questions/mappings/index.ts +0 -2
- package/src/screenplay/questions/mappings/string/append.ts +0 -28
- package/src/screenplay/questions/mappings/string/index.ts +0 -11
- package/src/screenplay/questions/mappings/string/normalize.ts +0 -33
- package/src/screenplay/questions/mappings/string/replace.ts +0 -34
- package/src/screenplay/questions/mappings/string/slice.ts +0 -53
- package/src/screenplay/questions/mappings/string/split.ts +0 -38
- package/src/screenplay/questions/mappings/string/toLocaleLowerCase.ts +0 -31
- package/src/screenplay/questions/mappings/string/toLocaleUpperCase.ts +0 -30
- package/src/screenplay/questions/mappings/string/toLowerCase.ts +0 -20
- package/src/screenplay/questions/mappings/string/toNumber.ts +0 -19
- package/src/screenplay/questions/mappings/string/toUpperCase.ts +0 -20
- package/src/screenplay/questions/mappings/string/trim.ts +0 -22
- package/src/screenplay/questions/proxies/PropertyPathKey.ts +0 -4
- package/src/screenplay/questions/proxies/createMetaQuestionProxy.ts +0 -51
- package/src/screenplay/questions/proxies/createQuestionProxy.ts +0 -49
- package/src/screenplay/questions/proxies/describePath.ts +0 -23
- package/src/screenplay/questions/proxies/index.ts +0 -2
- package/src/screenplay/questions/proxies/key.ts +0 -14
- package/src/screenplay/tasks/Loop.ts +0 -240
- package/src/screenplay/tasks/index.ts +0 -1
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { Reducible } from '../../io';
|
|
2
|
-
import { Activity } from '../Activity';
|
|
3
|
-
import { AnswersQuestions, PerformsActivities, UsesAbilities } from '../actor';
|
|
4
|
-
import { Answerable } from '../Answerable';
|
|
5
|
-
import { Question } from '../Question';
|
|
6
|
-
import { Task } from '../Task';
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Enables the {@link Actor} to iterate over a list of items produced by any {@link Answerable}.
|
|
10
|
-
*
|
|
11
|
-
* You can think of `Loop` as a more sophisticated Screenplay-style equivalent of
|
|
12
|
-
* [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach).
|
|
13
|
-
* `Loop` is capable of working with both synchronous data structures,
|
|
14
|
-
* such as [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
|
15
|
-
* and `Question<Array<T>>`,
|
|
16
|
-
* as well as asynchronous ones, so `Promise<Array<T>>` and `Question<Promise<Array<T>>>`.
|
|
17
|
-
*
|
|
18
|
-
* Use {@link Loop.item} to access the current item being processed by {@link Loop}, and {@link Loop.index}
|
|
19
|
-
* to access the index of {@link Loop.item} in the list.
|
|
20
|
-
*
|
|
21
|
-
* @example <caption>Basic scenario - Iterating over a static list of items</caption>
|
|
22
|
-
* import { actorCalled, Loop, Log } from '@serenity-js/core';
|
|
23
|
-
*
|
|
24
|
-
* actorCalled('Joe').attemptsTo(
|
|
25
|
-
* Loop.over([ 'apple', 'banana', 'candy' ]).to(
|
|
26
|
-
* Log.the('current element', Loop.item<string>()),
|
|
27
|
-
* Log.the('current index', Loop.index()),
|
|
28
|
-
* ),
|
|
29
|
-
* );
|
|
30
|
-
*
|
|
31
|
-
* @example <caption>API scenario - Iterating over items in an API response</caption>
|
|
32
|
-
*
|
|
33
|
-
* import { actorCalled, Loop } from '@serenity-js/core';
|
|
34
|
-
* import { Send, GetRequest, CallAnApi, LastResponse } from '@serenity-js/rest';
|
|
35
|
-
* import { Ensure, property, isGreaterThan } from '@serenity-js/assertions';
|
|
36
|
-
*
|
|
37
|
-
* interface TodoItem {
|
|
38
|
-
* userId: number;
|
|
39
|
-
* id: number;
|
|
40
|
-
* title: string;
|
|
41
|
-
* completed: boolean;
|
|
42
|
-
* }
|
|
43
|
-
*
|
|
44
|
-
* actorCalled('Joe').whoCan(
|
|
45
|
-
* CallAnApi.at('https://jsonplaceholder.typicode.com')
|
|
46
|
-
* ).attemptsTo(
|
|
47
|
-
* Send.a(GetRequest.to('/todos')),
|
|
48
|
-
* Loop.over(LastResponse.body<TodoItem[]>()).to(
|
|
49
|
-
* Ensure.that(
|
|
50
|
-
* Loop.item<TodoItem>(),
|
|
51
|
-
* property('userId', isGreaterThan(0)),
|
|
52
|
-
* ),
|
|
53
|
-
* )
|
|
54
|
-
* );
|
|
55
|
-
*
|
|
56
|
-
* @example <caption>UI scenario - Example widget</caption>
|
|
57
|
-
* <nav>
|
|
58
|
-
* <div data-test="cookies">
|
|
59
|
-
* <label for="functional-cookies">
|
|
60
|
-
* <input type="checkbox" id="functional-cookies" />Allow functional cookies
|
|
61
|
-
* </label>
|
|
62
|
-
* <label for="performance-cookies">
|
|
63
|
-
* <input type="checkbox" id="performance-cookies" />Allow performance cookies
|
|
64
|
-
* </label>
|
|
65
|
-
* <label for="advertising-cookies">
|
|
66
|
-
* <input type="checkbox" id="advertising-cookies" />Allow advertising cookies
|
|
67
|
-
* </label>
|
|
68
|
-
* </div>
|
|
69
|
-
* </nav>
|
|
70
|
-
*
|
|
71
|
-
* @example <caption>UI scenario - Lean Page Object</caption>
|
|
72
|
-
* import { Target } from '@serenity-js/protractor';
|
|
73
|
-
* import { browser, by } from 'protractor';
|
|
74
|
-
*
|
|
75
|
-
* class Cookies {
|
|
76
|
-
* static labels = Target.all('cookie options')
|
|
77
|
-
* .located(by.css('[data-test="cookies"]'));
|
|
78
|
-
*
|
|
79
|
-
* static checkbox = Target.the('checkbox')
|
|
80
|
-
* .located(by.tagName('input')),
|
|
81
|
-
* }
|
|
82
|
-
*
|
|
83
|
-
* @example <caption>UI scenario - Performing the same set of activities with each element</caption>
|
|
84
|
-
* import { actorCalled, Loop } from '@serenity-js/core';
|
|
85
|
-
* import { Click, Text, isSelected } from '@serenity-js/protractor';
|
|
86
|
-
* import { Ensure, startsWith } from '@serenity-js/assertions';
|
|
87
|
-
* import { protractor } from 'protractor';
|
|
88
|
-
*
|
|
89
|
-
* actorCalled('Joe')
|
|
90
|
-
* .whoCan(BrowseTheWeb.using(protractor.browser))
|
|
91
|
-
* .attemptsTo(
|
|
92
|
-
* Loop.over(Cookies.labels).to(
|
|
93
|
-
* Ensure.that(
|
|
94
|
-
* Text.of(Loop.item<ElementFinder>()),
|
|
95
|
-
* startsWith('Allow'),
|
|
96
|
-
* ),
|
|
97
|
-
*
|
|
98
|
-
* Click.on(Loop.item<ElementFinder>()),
|
|
99
|
-
* Ensure.that(
|
|
100
|
-
* Cookies.checkbox.of(Loop.item<ElementFinder>()),
|
|
101
|
-
* isSelected(),
|
|
102
|
-
* ),
|
|
103
|
-
* ),
|
|
104
|
-
* );
|
|
105
|
-
*
|
|
106
|
-
* @extends {Task}
|
|
107
|
-
*
|
|
108
|
-
* @see {@link Loop.item}
|
|
109
|
-
* @see {@link Loop.index}
|
|
110
|
-
* @see {@link Question}
|
|
111
|
-
*/
|
|
112
|
-
export declare class Loop<Item> extends Task {
|
|
113
|
-
private readonly items;
|
|
114
|
-
private readonly activities;
|
|
115
|
-
private static currentItem;
|
|
116
|
-
private static currentIndex;
|
|
117
|
-
/**
|
|
118
|
-
* @desc
|
|
119
|
-
* Instantiates a {@link Task} to {@link Loop}
|
|
120
|
-
* that enables the {@link Actor} to iterate over `items`
|
|
121
|
-
* to perform some `activities`.
|
|
122
|
-
*
|
|
123
|
-
* @param {items: Answerable<ReducibleCollection>} items
|
|
124
|
-
* @returns {LoopBuilder}
|
|
125
|
-
*/
|
|
126
|
-
static over<T>(items: Answerable<Reducible>): {
|
|
127
|
-
to: (...activities: Activity[]) => Loop<T>;
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* @desc
|
|
131
|
-
* Returns the current item being processed by {@link Loop.over}.
|
|
132
|
-
*
|
|
133
|
-
* **Please note** that in order for the TypeScript transpiler to understand the exact `ExpectedType`
|
|
134
|
-
* of the {@link Question} produced by this method you can optionally configure it with
|
|
135
|
-
* a [_type variable_](https://www.typescriptlang.org/docs/handbook/generics.html).
|
|
136
|
-
*
|
|
137
|
-
* For example, configuring the method with type variable of `string`, so `Loop.item<string>()`,
|
|
138
|
-
* tells the transpiler that a `Question<string>` will be returned.
|
|
139
|
-
*
|
|
140
|
-
* If the type variable is not configured, the transpiler assumes that returned type is a
|
|
141
|
-
* `Question<any>`. This means that while your code could still work, you'd miss out
|
|
142
|
-
* on checking provided by TypeScript.
|
|
143
|
-
*
|
|
144
|
-
* @returns {Question<ExpectedType>}
|
|
145
|
-
*/
|
|
146
|
-
static item<ExpectedType = any>(): Question<ExpectedType>;
|
|
147
|
-
/**
|
|
148
|
-
* @desc
|
|
149
|
-
* Returns the index of current {@link Loop.item} in the `Answerable<Array>` given to {@link Loop.over}.
|
|
150
|
-
*
|
|
151
|
-
* The index starts at `0`.
|
|
152
|
-
*
|
|
153
|
-
* @returns {Question<number>}
|
|
154
|
-
*/
|
|
155
|
-
static index(): Question<number>;
|
|
156
|
-
/**
|
|
157
|
-
* @param {Answerable<Reducible>} items
|
|
158
|
-
* @param {Activity[]} activities
|
|
159
|
-
*/
|
|
160
|
-
constructor(items: Answerable<Reducible>, activities: Activity[]);
|
|
161
|
-
/**
|
|
162
|
-
* @desc
|
|
163
|
-
* Makes the provided {@link Actor}
|
|
164
|
-
* perform this {@link Task}.
|
|
165
|
-
*
|
|
166
|
-
* @param {PerformsActivities & UsesAbilities & AnswersQuestions} actor
|
|
167
|
-
* @returns {Promise<void>}
|
|
168
|
-
*
|
|
169
|
-
* @see {@link Actor}
|
|
170
|
-
* @see {@link PerformsActivities}
|
|
171
|
-
* @see {@link UsesAbilities}
|
|
172
|
-
* @see {@link AnswersQuestions}
|
|
173
|
-
*/
|
|
174
|
-
performAs(actor: PerformsActivities & UsesAbilities & AnswersQuestions): PromiseLike<void> | PromiseLike<any>;
|
|
175
|
-
/**
|
|
176
|
-
* @desc
|
|
177
|
-
* Generates a description to be used when reporting this {@link Activity}.
|
|
178
|
-
*
|
|
179
|
-
* @returns {string}
|
|
180
|
-
*/
|
|
181
|
-
toString(): string;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* @typedef {Object} LoopBuilder
|
|
185
|
-
* @property {function(...activities: Activity[]): Loop} to
|
|
186
|
-
*
|
|
187
|
-
* @example <caption>Basic scenario - Iterating over a static list of items</caption>
|
|
188
|
-
* import { actorCalled, Loop, Log } from '@serenity-js/core';
|
|
189
|
-
*
|
|
190
|
-
* actorCalled('Joe').attemptsTo(
|
|
191
|
-
* Loop.over([ 'apple', 'banana', 'candy' ]).to(
|
|
192
|
-
* Log.the('current element', Loop.item<string>()),
|
|
193
|
-
* ),
|
|
194
|
-
* );
|
|
195
|
-
*
|
|
196
|
-
* @see {@link Loop}
|
|
197
|
-
* @see {@link Loop.over}
|
|
198
|
-
*/
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Loop = void 0;
|
|
4
|
-
const io_1 = require("../../io");
|
|
5
|
-
const Question_1 = require("../Question");
|
|
6
|
-
const Task_1 = require("../Task");
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Enables the {@link Actor} to iterate over a list of items produced by any {@link Answerable}.
|
|
10
|
-
*
|
|
11
|
-
* You can think of `Loop` as a more sophisticated Screenplay-style equivalent of
|
|
12
|
-
* [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach).
|
|
13
|
-
* `Loop` is capable of working with both synchronous data structures,
|
|
14
|
-
* such as [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
|
15
|
-
* and `Question<Array<T>>`,
|
|
16
|
-
* as well as asynchronous ones, so `Promise<Array<T>>` and `Question<Promise<Array<T>>>`.
|
|
17
|
-
*
|
|
18
|
-
* Use {@link Loop.item} to access the current item being processed by {@link Loop}, and {@link Loop.index}
|
|
19
|
-
* to access the index of {@link Loop.item} in the list.
|
|
20
|
-
*
|
|
21
|
-
* @example <caption>Basic scenario - Iterating over a static list of items</caption>
|
|
22
|
-
* import { actorCalled, Loop, Log } from '@serenity-js/core';
|
|
23
|
-
*
|
|
24
|
-
* actorCalled('Joe').attemptsTo(
|
|
25
|
-
* Loop.over([ 'apple', 'banana', 'candy' ]).to(
|
|
26
|
-
* Log.the('current element', Loop.item<string>()),
|
|
27
|
-
* Log.the('current index', Loop.index()),
|
|
28
|
-
* ),
|
|
29
|
-
* );
|
|
30
|
-
*
|
|
31
|
-
* @example <caption>API scenario - Iterating over items in an API response</caption>
|
|
32
|
-
*
|
|
33
|
-
* import { actorCalled, Loop } from '@serenity-js/core';
|
|
34
|
-
* import { Send, GetRequest, CallAnApi, LastResponse } from '@serenity-js/rest';
|
|
35
|
-
* import { Ensure, property, isGreaterThan } from '@serenity-js/assertions';
|
|
36
|
-
*
|
|
37
|
-
* interface TodoItem {
|
|
38
|
-
* userId: number;
|
|
39
|
-
* id: number;
|
|
40
|
-
* title: string;
|
|
41
|
-
* completed: boolean;
|
|
42
|
-
* }
|
|
43
|
-
*
|
|
44
|
-
* actorCalled('Joe').whoCan(
|
|
45
|
-
* CallAnApi.at('https://jsonplaceholder.typicode.com')
|
|
46
|
-
* ).attemptsTo(
|
|
47
|
-
* Send.a(GetRequest.to('/todos')),
|
|
48
|
-
* Loop.over(LastResponse.body<TodoItem[]>()).to(
|
|
49
|
-
* Ensure.that(
|
|
50
|
-
* Loop.item<TodoItem>(),
|
|
51
|
-
* property('userId', isGreaterThan(0)),
|
|
52
|
-
* ),
|
|
53
|
-
* )
|
|
54
|
-
* );
|
|
55
|
-
*
|
|
56
|
-
* @example <caption>UI scenario - Example widget</caption>
|
|
57
|
-
* <nav>
|
|
58
|
-
* <div data-test="cookies">
|
|
59
|
-
* <label for="functional-cookies">
|
|
60
|
-
* <input type="checkbox" id="functional-cookies" />Allow functional cookies
|
|
61
|
-
* </label>
|
|
62
|
-
* <label for="performance-cookies">
|
|
63
|
-
* <input type="checkbox" id="performance-cookies" />Allow performance cookies
|
|
64
|
-
* </label>
|
|
65
|
-
* <label for="advertising-cookies">
|
|
66
|
-
* <input type="checkbox" id="advertising-cookies" />Allow advertising cookies
|
|
67
|
-
* </label>
|
|
68
|
-
* </div>
|
|
69
|
-
* </nav>
|
|
70
|
-
*
|
|
71
|
-
* @example <caption>UI scenario - Lean Page Object</caption>
|
|
72
|
-
* import { Target } from '@serenity-js/protractor';
|
|
73
|
-
* import { browser, by } from 'protractor';
|
|
74
|
-
*
|
|
75
|
-
* class Cookies {
|
|
76
|
-
* static labels = Target.all('cookie options')
|
|
77
|
-
* .located(by.css('[data-test="cookies"]'));
|
|
78
|
-
*
|
|
79
|
-
* static checkbox = Target.the('checkbox')
|
|
80
|
-
* .located(by.tagName('input')),
|
|
81
|
-
* }
|
|
82
|
-
*
|
|
83
|
-
* @example <caption>UI scenario - Performing the same set of activities with each element</caption>
|
|
84
|
-
* import { actorCalled, Loop } from '@serenity-js/core';
|
|
85
|
-
* import { Click, Text, isSelected } from '@serenity-js/protractor';
|
|
86
|
-
* import { Ensure, startsWith } from '@serenity-js/assertions';
|
|
87
|
-
* import { protractor } from 'protractor';
|
|
88
|
-
*
|
|
89
|
-
* actorCalled('Joe')
|
|
90
|
-
* .whoCan(BrowseTheWeb.using(protractor.browser))
|
|
91
|
-
* .attemptsTo(
|
|
92
|
-
* Loop.over(Cookies.labels).to(
|
|
93
|
-
* Ensure.that(
|
|
94
|
-
* Text.of(Loop.item<ElementFinder>()),
|
|
95
|
-
* startsWith('Allow'),
|
|
96
|
-
* ),
|
|
97
|
-
*
|
|
98
|
-
* Click.on(Loop.item<ElementFinder>()),
|
|
99
|
-
* Ensure.that(
|
|
100
|
-
* Cookies.checkbox.of(Loop.item<ElementFinder>()),
|
|
101
|
-
* isSelected(),
|
|
102
|
-
* ),
|
|
103
|
-
* ),
|
|
104
|
-
* );
|
|
105
|
-
*
|
|
106
|
-
* @extends {Task}
|
|
107
|
-
*
|
|
108
|
-
* @see {@link Loop.item}
|
|
109
|
-
* @see {@link Loop.index}
|
|
110
|
-
* @see {@link Question}
|
|
111
|
-
*/
|
|
112
|
-
class Loop extends Task_1.Task {
|
|
113
|
-
/**
|
|
114
|
-
* @param {Answerable<Reducible>} items
|
|
115
|
-
* @param {Activity[]} activities
|
|
116
|
-
*/
|
|
117
|
-
constructor(items, activities) {
|
|
118
|
-
super();
|
|
119
|
-
this.items = items;
|
|
120
|
-
this.activities = activities;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* @desc
|
|
124
|
-
* Instantiates a {@link Task} to {@link Loop}
|
|
125
|
-
* that enables the {@link Actor} to iterate over `items`
|
|
126
|
-
* to perform some `activities`.
|
|
127
|
-
*
|
|
128
|
-
* @param {items: Answerable<ReducibleCollection>} items
|
|
129
|
-
* @returns {LoopBuilder}
|
|
130
|
-
*/
|
|
131
|
-
static over(items) {
|
|
132
|
-
return {
|
|
133
|
-
to: (...activities) => new Loop(items, activities)
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* @desc
|
|
138
|
-
* Returns the current item being processed by {@link Loop.over}.
|
|
139
|
-
*
|
|
140
|
-
* **Please note** that in order for the TypeScript transpiler to understand the exact `ExpectedType`
|
|
141
|
-
* of the {@link Question} produced by this method you can optionally configure it with
|
|
142
|
-
* a [_type variable_](https://www.typescriptlang.org/docs/handbook/generics.html).
|
|
143
|
-
*
|
|
144
|
-
* For example, configuring the method with type variable of `string`, so `Loop.item<string>()`,
|
|
145
|
-
* tells the transpiler that a `Question<string>` will be returned.
|
|
146
|
-
*
|
|
147
|
-
* If the type variable is not configured, the transpiler assumes that returned type is a
|
|
148
|
-
* `Question<any>`. This means that while your code could still work, you'd miss out
|
|
149
|
-
* on checking provided by TypeScript.
|
|
150
|
-
*
|
|
151
|
-
* @returns {Question<ExpectedType>}
|
|
152
|
-
*/
|
|
153
|
-
static item() {
|
|
154
|
-
return Question_1.Question.about(`current loop item`, actor => Loop.currentItem);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* @desc
|
|
158
|
-
* Returns the index of current {@link Loop.item} in the `Answerable<Array>` given to {@link Loop.over}.
|
|
159
|
-
*
|
|
160
|
-
* The index starts at `0`.
|
|
161
|
-
*
|
|
162
|
-
* @returns {Question<number>}
|
|
163
|
-
*/
|
|
164
|
-
static index() {
|
|
165
|
-
return Question_1.Question.about(`current loop index`, actor => Loop.currentIndex);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* @desc
|
|
169
|
-
* Makes the provided {@link Actor}
|
|
170
|
-
* perform this {@link Task}.
|
|
171
|
-
*
|
|
172
|
-
* @param {PerformsActivities & UsesAbilities & AnswersQuestions} actor
|
|
173
|
-
* @returns {Promise<void>}
|
|
174
|
-
*
|
|
175
|
-
* @see {@link Actor}
|
|
176
|
-
* @see {@link PerformsActivities}
|
|
177
|
-
* @see {@link UsesAbilities}
|
|
178
|
-
* @see {@link AnswersQuestions}
|
|
179
|
-
*/
|
|
180
|
-
performAs(actor) {
|
|
181
|
-
return actor.answer(this.items)
|
|
182
|
-
.then(items => items.reduce((previous, current, index) => {
|
|
183
|
-
return previous.then(() => {
|
|
184
|
-
Loop.currentIndex = index;
|
|
185
|
-
Loop.currentItem = current;
|
|
186
|
-
return actor.attemptsTo(...this.activities);
|
|
187
|
-
});
|
|
188
|
-
}, Promise.resolve(void 0)));
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* @desc
|
|
192
|
-
* Generates a description to be used when reporting this {@link Activity}.
|
|
193
|
-
*
|
|
194
|
-
* @returns {string}
|
|
195
|
-
*/
|
|
196
|
-
toString() {
|
|
197
|
-
const description = Array.isArray(this.items)
|
|
198
|
-
? `a list of ${this.items.length} item${this.items.length !== 1 ? 's' : ''}`
|
|
199
|
-
: (0, io_1.formatted) `${this.items}`;
|
|
200
|
-
return `#actor loops over ${description}`;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
exports.Loop = Loop;
|
|
204
|
-
Loop.currentItem = undefined;
|
|
205
|
-
Loop.currentIndex = 0;
|
|
206
|
-
/**
|
|
207
|
-
* @typedef {Object} LoopBuilder
|
|
208
|
-
* @property {function(...activities: Activity[]): Loop} to
|
|
209
|
-
*
|
|
210
|
-
* @example <caption>Basic scenario - Iterating over a static list of items</caption>
|
|
211
|
-
* import { actorCalled, Loop, Log } from '@serenity-js/core';
|
|
212
|
-
*
|
|
213
|
-
* actorCalled('Joe').attemptsTo(
|
|
214
|
-
* Loop.over([ 'apple', 'banana', 'candy' ]).to(
|
|
215
|
-
* Log.the('current element', Loop.item<string>()),
|
|
216
|
-
* ),
|
|
217
|
-
* );
|
|
218
|
-
*
|
|
219
|
-
* @see {@link Loop}
|
|
220
|
-
* @see {@link Loop.over}
|
|
221
|
-
*/
|
|
222
|
-
//# sourceMappingURL=Loop.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Loop.js","sourceRoot":"","sources":["../../../src/screenplay/tasks/Loop.ts"],"names":[],"mappings":";;;AAAA,iCAAgD;AAIhD,0CAAuC;AACvC,kCAA+B;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwGG;AACH,MAAa,IAAW,SAAQ,WAAI;IAyDhC;;;OAGG;IACH,YACqB,KAA4B,EAC5B,UAAsB;QAEvC,KAAK,EAAE,CAAC;QAHS,UAAK,GAAL,KAAK,CAAuB;QAC5B,eAAU,GAAV,UAAU,CAAY;IAG3C,CAAC;IA9DD;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAI,CAAI,KAA4B;QACvC,OAAO;YACH,EAAE,EAAE,CAAC,GAAG,UAAsB,EAAE,EAAE,CAC9B,IAAI,IAAI,CAAI,KAAK,EAAE,UAAU,CAAC;SACrC,CAAA;IACL,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,IAAI;QACP,OAAO,mBAAQ,CAAC,KAAK,CAAe,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAC7D,IAAI,CAAC,WAA2B,CACnC,CAAC;IACN,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,KAAK;QACR,OAAO,mBAAQ,CAAC,KAAK,CAAS,oBAAoB,EAAE,KAAK,CAAC,EAAE,CACxD,IAAI,CAAC,YAAY,CACpB,CAAC;IACN,CAAC;IAaD;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,KAA4D;QAClE,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aAC1B,IAAI,CAAC,KAAK,CAAC,EAAE,CACV,KAAK,CAAC,MAAM,CAAC,CAAC,QAAuB,EAAE,OAAa,EAAE,KAAa,EAAE,EAAE;YACnE,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE;gBACtB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;gBAC1B,IAAI,CAAC,WAAW,GAAI,OAAO,CAAC;gBAE5B,OAAO,KAAK,CAAC,UAAU,CACnB,GAAG,IAAI,CAAC,UAAU,CACrB,CAAC;YACN,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAC9B,CAAC;IACV,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACJ,MAAM,WAAW,GAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1C,CAAC,CAAC,aAAc,IAAI,CAAC,KAAK,CAAC,MAAO,QAAS,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAG,EAAE;YAChF,CAAC,CAAC,IAAA,cAAS,EAAC,GAAI,IAAI,CAAC,KAAM,EAAE,CAAC;QAElC,OAAO,qBAAsB,WAAY,EAAE,CAAC;IAChD,CAAC;;AA7GL,oBA8GC;AA7GkB,gBAAW,GAAY,SAAS,CAAC;AACjC,iBAAY,GAAG,CAAC,CAAC;AA8GpC;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './Loop';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/tasks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAuB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// class-level
|
package/src/decorators/step.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// performAs level; sets a toString; deprecated
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @desc
|
|
3
|
-
* Describes a collection providing
|
|
4
|
-
* a [`map`-like interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
|
|
5
|
-
*
|
|
6
|
-
* @interface
|
|
7
|
-
*
|
|
8
|
-
* @see {@link Question#map}
|
|
9
|
-
* @see {@link ElementArrayFinder}
|
|
10
|
-
*/
|
|
11
|
-
export interface Mappable<Item> {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @desc
|
|
15
|
-
* Applies a {@link MappingFunction} function to each element of a {@link Mappable} collection.
|
|
16
|
-
*
|
|
17
|
-
* The callback receives an item from the collection as the first argument
|
|
18
|
-
* and its index as the second argument.
|
|
19
|
-
*
|
|
20
|
-
* @abstract
|
|
21
|
-
*
|
|
22
|
-
* @type {function<U>(callback: (item?: Item, index?: number) => U): PromiseLike<U[]> | U[]}
|
|
23
|
-
*/
|
|
24
|
-
map: <U>(callback: (item?: Item, index?: number) => U) => PromiseLike<U[]> | U[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @desc
|
|
29
|
-
* A mapping function converting one type into another.
|
|
30
|
-
*
|
|
31
|
-
* @public
|
|
32
|
-
*
|
|
33
|
-
* @typedef {function(item?: V, index?: number) => Promise<O> | O} Mapping<V,O>
|
|
34
|
-
*/
|
|
35
|
-
export type MappingFunction<V, O> =
|
|
36
|
-
(item?: V, index?: number) => O;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @desc
|
|
40
|
-
* Checks if the value is a {@link Mappable} collection of items.
|
|
41
|
-
*
|
|
42
|
-
* @example <caption>An Array</caption>
|
|
43
|
-
* import { Mappable } from '@serenity-js/core/lib/io';
|
|
44
|
-
*
|
|
45
|
-
* Mappable.isMappable([ 1, 2, 3 ]) === true
|
|
46
|
-
*
|
|
47
|
-
* @example <caption>Protractor's ElementArrayFinder</caption>
|
|
48
|
-
* import { Mappable } from '@serenity-js/core/lib/io';
|
|
49
|
-
* import { element } from 'protractor';
|
|
50
|
-
*
|
|
51
|
-
* Mappable.isMappable(element.all(by.tagName('li')) === true
|
|
52
|
-
*
|
|
53
|
-
* @param {Mappable<Item> | any} maybeCollection
|
|
54
|
-
* @returns {boolean}
|
|
55
|
-
*/
|
|
56
|
-
export function isMappable<Item>(maybeCollection: Mappable<Item> | any): maybeCollection is Mappable<Item> {
|
|
57
|
-
return !! maybeCollection
|
|
58
|
-
&& !! maybeCollection.map
|
|
59
|
-
&& typeof maybeCollection.map === 'function';
|
|
60
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { Answerable } from '../Answerable';
|
|
2
|
-
import { createMetaQuestionProxy, createQuestionProxy, WithPropertiesAsMetaQuestions, WithPropertiesAsQuestions } from './proxies';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @desc
|
|
6
|
-
* Enables easy access to properties of the value of a given {@link Answerable}.
|
|
7
|
-
*
|
|
8
|
-
* @example <caption>Example API response</caption>
|
|
9
|
-
* interface EnvironmentDetails {
|
|
10
|
-
* name: string;
|
|
11
|
-
* url: string;
|
|
12
|
-
* }
|
|
13
|
-
*
|
|
14
|
-
* interface EnvironmentsResponse {
|
|
15
|
-
* environments: EnvironmentDetails[];
|
|
16
|
-
* }
|
|
17
|
-
*
|
|
18
|
-
* const response: EnvironmentsResponse = {
|
|
19
|
-
* "environments": [
|
|
20
|
-
* {
|
|
21
|
-
* "name": "dev",
|
|
22
|
-
* "url": "https://dev.example.com"
|
|
23
|
-
* },
|
|
24
|
-
* {
|
|
25
|
-
* "name": "sit",
|
|
26
|
-
* "url": "https://sit.example.com"
|
|
27
|
-
* }
|
|
28
|
-
* ]
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* @example <caption>Combining Property.of and Property.at</caption>
|
|
32
|
-
* import { actorCalled, List, Property } from '@serenity-js/core';
|
|
33
|
-
* import { Ensure, equals } from '@serenity-js/assertions';
|
|
34
|
-
*
|
|
35
|
-
* actorCalled('Lisa').attemptsTo(
|
|
36
|
-
* Ensure.that(
|
|
37
|
-
* Property.of(
|
|
38
|
-
* List.of(response.environments)
|
|
39
|
-
* .where(Property.at<EnvironmentDetails>().name, equals('dev'))
|
|
40
|
-
* .first(),
|
|
41
|
-
* ).url,
|
|
42
|
-
* equals('https://dev.example.com')
|
|
43
|
-
* )
|
|
44
|
-
* )
|
|
45
|
-
*
|
|
46
|
-
* @see {@link Question}
|
|
47
|
-
* @see {@link List}
|
|
48
|
-
*/
|
|
49
|
-
export class Property {
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @desc
|
|
53
|
-
* Generates a {@link Proxy} around a given {@link Answerable} `subject`
|
|
54
|
-
* to turn the properties of the value it will resolve to into {@link Question}s.
|
|
55
|
-
*
|
|
56
|
-
* @example <caption>Reading a property</caption>
|
|
57
|
-
* import { actorCalled, Property } from '@serenity-js/core';
|
|
58
|
-
* import { Ensure, equals } from '@serenity-js/assertions';
|
|
59
|
-
*
|
|
60
|
-
* actorCalled('Lisa').attemptsTo(
|
|
61
|
-
* Ensure.that(
|
|
62
|
-
* Property.of(response).environments[0].name,
|
|
63
|
-
* equals('dev')
|
|
64
|
-
* )
|
|
65
|
-
* )
|
|
66
|
-
*
|
|
67
|
-
* @param {Answerable<Subject>} subject
|
|
68
|
-
* @returns {Proxy<Subject>}
|
|
69
|
-
*/
|
|
70
|
-
static of<Subject extends object>(subject: Answerable<Subject>): WithPropertiesAsQuestions<Subject> { // eslint-disable-line @typescript-eslint/ban-types
|
|
71
|
-
return createQuestionProxy<Subject>(subject);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @desc
|
|
76
|
-
* Generates a {@link Proxy} around a given {@link Answerable} `subject`
|
|
77
|
-
* to turn any of its properties into {@link MetaQuestion}s
|
|
78
|
-
* to be used when filtering a {@link List},
|
|
79
|
-
*
|
|
80
|
-
* @example <caption>Reading a property</caption>
|
|
81
|
-
* import { actorCalled, Property } from '@serenity-js/core';
|
|
82
|
-
* import { Ensure, equals } from '@serenity-js/assertions';
|
|
83
|
-
*
|
|
84
|
-
* actorCalled('Lisa').attemptsTo(
|
|
85
|
-
* Ensure.that(
|
|
86
|
-
* List.of(response.environments)
|
|
87
|
-
* .where(Property.at<EnvironmentDetails>().name, equals('dev'))
|
|
88
|
-
* .first(),
|
|
89
|
-
* equals(response.environments[0])
|
|
90
|
-
* )
|
|
91
|
-
* )
|
|
92
|
-
*
|
|
93
|
-
* @returns {Proxy<Subject>}
|
|
94
|
-
*/
|
|
95
|
-
static at<Subject extends object>(): WithPropertiesAsMetaQuestions<Subject> { // eslint-disable-line @typescript-eslint/ban-types
|
|
96
|
-
return createMetaQuestionProxy<Subject>();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { AnswersQuestions, UsesAbilities } from '../actor';
|
|
2
|
-
import { Answerable } from '../Answerable';
|
|
3
|
-
import { Question } from '../Question';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @experimental
|
|
7
|
-
*/
|
|
8
|
-
export class Transform<Answer_Type extends any, Output_Type> extends Question<Promise<Output_Type>> {
|
|
9
|
-
static the<AT extends any, OT>(questions: Answerable<AT> | Array<Answerable<AT>>, transformation: (...answers: AT[]) => OT): Transform<AT, OT> {
|
|
10
|
-
return new Transform<AT, OT>([].concat(questions), transformation);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
constructor(
|
|
14
|
-
private readonly questions: Array<Answerable<Answer_Type>>,
|
|
15
|
-
private readonly transformation: (...answers: Answer_Type[]) => Output_Type,
|
|
16
|
-
private readonly description: string = `a transformed answer`,
|
|
17
|
-
) {
|
|
18
|
-
super(description);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @deprecated
|
|
23
|
-
* Please use {@link Transform#describedAs} instead
|
|
24
|
-
*
|
|
25
|
-
* @desc
|
|
26
|
-
* Overrides the default {@link Transform#toString} representation of this object.
|
|
27
|
-
*
|
|
28
|
-
* @param {string} description
|
|
29
|
-
* @returns {Transform<Answer_Type, Output_Type>}
|
|
30
|
-
*/
|
|
31
|
-
as(description: string): Transform<Answer_Type, Output_Type> {
|
|
32
|
-
return this.describedAs(description);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Changes the description of this question's subject.
|
|
37
|
-
*
|
|
38
|
-
* @param subject
|
|
39
|
-
*/
|
|
40
|
-
describedAs(subject: string): this {
|
|
41
|
-
this.subject = subject;
|
|
42
|
-
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<Output_Type> {
|
|
47
|
-
return Promise.all(this.questions.map(question => actor.answer(question)))
|
|
48
|
-
.then(answers => this.transformation(...answers));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { MappingFunction } from '../../../io/collections';
|
|
2
|
-
import { AnswersQuestions } from '../../actor';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @desc
|
|
6
|
-
* A mapping function converting one type into another.
|
|
7
|
-
*
|
|
8
|
-
* @public
|
|
9
|
-
*
|
|
10
|
-
* @typedef {function(actor: AnswersQuestions) => MappingFunction<V,O>} AnswerMappingFunction<V, O>
|
|
11
|
-
*/
|
|
12
|
-
export type AnswerMappingFunction<V, O> =
|
|
13
|
-
(actor: AnswersQuestions) => MappingFunction<V, Promise<O> | O>
|