@serenity-js/web 3.22.4 → 3.23.1

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 CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.23.1](https://github.com/serenity-js/serenity-js/compare/v3.23.0...v3.23.1) (2024-05-20)
7
+
8
+ **Note:** Version bump only for package @serenity-js/web
9
+
10
+
11
+
12
+
13
+
14
+ # [3.23.0](https://github.com/serenity-js/serenity-js/compare/v3.22.4...v3.23.0) (2024-05-12)
15
+
16
+
17
+ ### Features
18
+
19
+ * **webdriverio:** support for injecting scripts parameterised with complex data structures ([e920e67](https://github.com/serenity-js/serenity-js/commit/e920e6709262c8249c992ac02a01f49d5789a35d))
20
+ * **web:** scripts injected into the browser accept data structures containing PageElement objects ([2fbddf5](https://github.com/serenity-js/serenity-js/commit/2fbddf5d78d2965aecd6786b020c93ea079bdaf1))
21
+
22
+
23
+
24
+
25
+
6
26
  ## [3.22.4](https://github.com/serenity-js/serenity-js/compare/v3.22.3...v3.22.4) (2024-05-07)
7
27
 
8
28
  **Note:** Version bump only for package @serenity-js/web
@@ -2,7 +2,7 @@ import type { Answerable, AnswersQuestions, CollectsArtifacts, UsesAbilities } f
2
2
  import { Interaction } from '@serenity-js/core';
3
3
  /**
4
4
  * Instructs an {@apilink Actor|actor} who has the {@apilink Ability|ability} to {@apilink BrowseTheWeb}
5
- * to execute a script within the context of the current browser tab.
5
+ * to inject a script into the browser and execute it in the context of the current browser tab.
6
6
  *
7
7
  * ## Learn more
8
8
  *
@@ -63,6 +63,24 @@ export declare class ExecuteScript {
63
63
  * )
64
64
  * ```
65
65
  *
66
+ * #### Executing async script as function
67
+ *
68
+ * ```ts
69
+ * import { actorCalled } from '@serenity-js/core'
70
+ * import { ExecuteScript } from '@serenity-js/web'
71
+ *
72
+ * const MyPage = {
73
+ * header: () =>
74
+ * PageElement.located(By.css('h1')).describedAs('header'),
75
+ * }
76
+ *
77
+ * await actorCalled('Esti').attemptsTo(
78
+ * ExecuteScript.async(function getText(header, callback) {
79
+ * callback(header.innerText)
80
+ * }).withArguments(MyPage.header())
81
+ * )
82
+ * ```
83
+ *
66
84
  * #### Passing arguments to an async script
67
85
  *
68
86
  * ```ts
@@ -82,32 +100,58 @@ export declare class ExecuteScript {
82
100
  * )
83
101
  * ```
84
102
  *
85
- * #### Passing Target arguments to an async script
103
+ * #### Passing PageElement arguments to an async script
104
+ *
105
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
106
+ * into their corresponding DOM elements.
86
107
  *
87
108
  * ```ts
88
109
  * import { actorCalled } from '@serenity-js/core'
89
- * import { ExecuteScript } from '@serenity-js/web'
110
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
111
+ *
112
+ * const MyPage = {
113
+ * header: () =>
114
+ * PageElement.located(By.css('h1')).describedAs('header'),
115
+ * }
90
116
  *
91
117
  * await actorCalled('Esti').attemptsTo(
92
118
  * ExecuteScript.async(`
93
- * var header = arguments[0] // PageElement object gets converted to a WebElement
119
+ * var header = arguments[0]
94
120
  * var callback = arguments[arguments.length - 1]
95
121
  *
96
122
  * callback(header.innerText)
97
- * `).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
123
+ * `).withArguments(MyPage.header())
98
124
  * )
99
125
  * ```
100
126
  *
101
- * #### Executing async script as function
127
+ * #### Using nested data structures containing PageElement objects
128
+ *
129
+ * Serenity/JS automatically converts any {@link PageElement} objects
130
+ * contained in nested data structures passed to the script
131
+ * into their corresponding DOM elements.
102
132
  *
103
133
  * ```ts
104
134
  * import { actorCalled } from '@serenity-js/core'
105
- * import { ExecuteScript } from '@serenity-js/web'
135
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
136
+ *
137
+ * const MyPage = {
138
+ * header: () =>
139
+ * PageElement.located(By.css('h1')).describedAs('header'),
140
+ *
141
+ * article: () =>
142
+ * PageElement.located(By.css('article')).describedAs('article'),
143
+ * }
106
144
  *
107
145
  * await actorCalled('Esti').attemptsTo(
108
- * ExecuteScript.async(function getText(header, callback) {
109
- * callback(header.innerText)
110
- * }).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
146
+ * ExecuteScript.async(`
147
+ * var { include, exclude } = arguments[0]
148
+ * var callback = arguments[arguments.length - 1]
149
+ *
150
+ * callback(include[0].innerText)
151
+ * `).withArguments({
152
+ * include: [ MyPage.article() ],
153
+ * exclude: [ MyPage.header() ],
154
+ * })
111
155
  * )
112
156
  * ```
113
157
  *
@@ -138,34 +182,85 @@ export declare class ExecuteScript {
138
182
  * )
139
183
  * ```
140
184
  *
141
- * #### Executing a sync script as function and reading the result
185
+ * #### Executing a sync script as function and retrieving the result
142
186
  *
143
187
  * ```ts
144
188
  * import { actorCalled } from '@serenity-js/core'
145
189
  * import { By, Enter, ExecuteScript, LastScriptExecution, PageElement } from '@serenity-js/web'
146
190
  *
147
- * const someOfferField = () =>
148
- * PageElement.located(By.id('offer-code'))
149
- * .describedAs('offer code')
191
+ * const Checkout = {
192
+ * someOfferField: () =>
193
+ * PageElement.located(By.id('offer-code'))
194
+ * .describedAs('offer code')
150
195
  *
151
- * const applyOfferCodeField = () =>
152
- * PageElement.located(By.id('apply-offer-code'))
153
- * .describedAs('apply offer field')
196
+ * applyOfferCodeField = () =>
197
+ * PageElement.located(By.id('apply-offer-code'))
198
+ * .describedAs('apply offer field')
199
+ * }
154
200
  *
155
201
  * await actorCalled('Joseph')
156
202
  * .attemptsTo(
157
203
  * // inject JavaScript to read some property of an element
158
204
  * ExecuteScript.sync(function getValue(element) {
159
205
  * return element.value;
160
- * }).withArguments(someOfferField),
206
+ * }).withArguments(Checkout.someOfferField()),
161
207
  *
162
208
  * // use LastScriptExecution.result() to read the value
163
209
  * // returned from the injected script
164
210
  * // and pass it to another interaction
165
- * Enter.theValue(LastScriptExecution.result<string>()).into(applyOfferCodeField),
211
+ * Enter.theValue(LastScriptExecution.result<string>()).into(Checkout.applyOfferCodeField()),
166
212
  * )
167
213
  * ```
168
214
  *
215
+ * #### Passing PageElement arguments to a sync script
216
+ *
217
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
218
+ * into their corresponding DOM elements.
219
+ *
220
+ * ```ts
221
+ * import { actorCalled } from '@serenity-js/core'
222
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
223
+ *
224
+ * const MyPage = {
225
+ * header: () =>
226
+ * PageElement.located(By.css('h1')).describedAs('header'),
227
+ * }
228
+ *
229
+ * await actorCalled('Esti').attemptsTo(
230
+ * ExecuteScript.sync(function getInnerHtml(element) {
231
+ * return element.innerHTML;
232
+ * }).withArguments(MyPage.header())
233
+ * )
234
+ * ```
235
+ *
236
+ * #### Using nested data structures containing PageElement objects
237
+ *
238
+ * Serenity/JS automatically converts any {@link PageElement} objects
239
+ * contained in nested data structures passed to the script
240
+ * into their corresponding DOM elements.
241
+ *
242
+ * ```ts
243
+ * import { actorCalled } from '@serenity-js/core'
244
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
245
+ *
246
+ * const MyPage = {
247
+ * header: () =>
248
+ * PageElement.located(By.css('h1')).describedAs('header'),
249
+ *
250
+ * article: () =>
251
+ * PageElement.located(By.css('article')).describedAs('article'),
252
+ * }
253
+ *
254
+ * await actorCalled('Esti').attemptsTo(
255
+ * ExecuteScript.async(function getInnerHtml(scope) {
256
+ * return scope.include[0].innerHTML;
257
+ * `).withArguments({
258
+ * include: [ MyPage.article() ],
259
+ * exclude: [ MyPage.header() ],
260
+ * })
261
+ * )
262
+ * ```
263
+ *
169
264
  * #### Learn more
170
265
  * - {@apilink LastScriptExecution.result}
171
266
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ExecuteScript.d.ts","sourceRoot":"","sources":["../../../src/screenplay/interactions/ExecuteScript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAK,WAAW,EAAc,MAAM,mBAAmB,CAAC;AAM/D;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IAEtB;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,WAAW;IAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgGG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,0BAA0B;IAOnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqDG;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,0BAA0B;CAMrE;AAED;;;;;;;GAOG;AACH,8BAAsB,0BAA2B,SAAQ,WAAW;IAI5D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAC5C,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAF/C,WAAW,EAAE,MAAM,EACA,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAY,mDAAmD;IACxF,IAAI,GAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAM;IAKxD;;;;;OAKG;aACa,aAAa,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW;IAE3E;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3F,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;CACnG"}
1
+ {"version":3,"file":"ExecuteScript.d.ts","sourceRoot":"","sources":["../../../src/screenplay/interactions/ExecuteScript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAK,WAAW,EAAc,MAAM,mBAAmB,CAAC;AAM/D;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IAEtB;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,WAAW;IAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4IG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,0BAA0B;IAOnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwGG;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,0BAA0B;CAMrE;AAED;;;;;;;GAOG;AACH,8BAAsB,0BAA2B,SAAQ,WAAW;IAI5D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAC5C,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAF/C,WAAW,EAAE,MAAM,EACA,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAY,mDAAmD;IACxF,IAAI,GAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAM;IAKxD;;;;;OAKG;aACa,aAAa,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW;IAE3E;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3F,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;CACnG"}
@@ -7,7 +7,7 @@ const model_1 = require("@serenity-js/core/lib/model");
7
7
  const abilities_1 = require("../abilities");
8
8
  /**
9
9
  * Instructs an {@apilink Actor|actor} who has the {@apilink Ability|ability} to {@apilink BrowseTheWeb}
10
- * to execute a script within the context of the current browser tab.
10
+ * to inject a script into the browser and execute it in the context of the current browser tab.
11
11
  *
12
12
  * ## Learn more
13
13
  *
@@ -70,6 +70,24 @@ class ExecuteScript {
70
70
  * )
71
71
  * ```
72
72
  *
73
+ * #### Executing async script as function
74
+ *
75
+ * ```ts
76
+ * import { actorCalled } from '@serenity-js/core'
77
+ * import { ExecuteScript } from '@serenity-js/web'
78
+ *
79
+ * const MyPage = {
80
+ * header: () =>
81
+ * PageElement.located(By.css('h1')).describedAs('header'),
82
+ * }
83
+ *
84
+ * await actorCalled('Esti').attemptsTo(
85
+ * ExecuteScript.async(function getText(header, callback) {
86
+ * callback(header.innerText)
87
+ * }).withArguments(MyPage.header())
88
+ * )
89
+ * ```
90
+ *
73
91
  * #### Passing arguments to an async script
74
92
  *
75
93
  * ```ts
@@ -89,32 +107,58 @@ class ExecuteScript {
89
107
  * )
90
108
  * ```
91
109
  *
92
- * #### Passing Target arguments to an async script
110
+ * #### Passing PageElement arguments to an async script
111
+ *
112
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
113
+ * into their corresponding DOM elements.
93
114
  *
94
115
  * ```ts
95
116
  * import { actorCalled } from '@serenity-js/core'
96
- * import { ExecuteScript } from '@serenity-js/web'
117
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
118
+ *
119
+ * const MyPage = {
120
+ * header: () =>
121
+ * PageElement.located(By.css('h1')).describedAs('header'),
122
+ * }
97
123
  *
98
124
  * await actorCalled('Esti').attemptsTo(
99
125
  * ExecuteScript.async(`
100
- * var header = arguments[0] // PageElement object gets converted to a WebElement
126
+ * var header = arguments[0]
101
127
  * var callback = arguments[arguments.length - 1]
102
128
  *
103
129
  * callback(header.innerText)
104
- * `).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
130
+ * `).withArguments(MyPage.header())
105
131
  * )
106
132
  * ```
107
133
  *
108
- * #### Executing async script as function
134
+ * #### Using nested data structures containing PageElement objects
135
+ *
136
+ * Serenity/JS automatically converts any {@link PageElement} objects
137
+ * contained in nested data structures passed to the script
138
+ * into their corresponding DOM elements.
109
139
  *
110
140
  * ```ts
111
141
  * import { actorCalled } from '@serenity-js/core'
112
- * import { ExecuteScript } from '@serenity-js/web'
142
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
143
+ *
144
+ * const MyPage = {
145
+ * header: () =>
146
+ * PageElement.located(By.css('h1')).describedAs('header'),
147
+ *
148
+ * article: () =>
149
+ * PageElement.located(By.css('article')).describedAs('article'),
150
+ * }
113
151
  *
114
152
  * await actorCalled('Esti').attemptsTo(
115
- * ExecuteScript.async(function getText(header, callback) {
116
- * callback(header.innerText)
117
- * }).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
153
+ * ExecuteScript.async(`
154
+ * var { include, exclude } = arguments[0]
155
+ * var callback = arguments[arguments.length - 1]
156
+ *
157
+ * callback(include[0].innerText)
158
+ * `).withArguments({
159
+ * include: [ MyPage.article() ],
160
+ * exclude: [ MyPage.header() ],
161
+ * })
118
162
  * )
119
163
  * ```
120
164
  *
@@ -147,34 +191,85 @@ class ExecuteScript {
147
191
  * )
148
192
  * ```
149
193
  *
150
- * #### Executing a sync script as function and reading the result
194
+ * #### Executing a sync script as function and retrieving the result
151
195
  *
152
196
  * ```ts
153
197
  * import { actorCalled } from '@serenity-js/core'
154
198
  * import { By, Enter, ExecuteScript, LastScriptExecution, PageElement } from '@serenity-js/web'
155
199
  *
156
- * const someOfferField = () =>
157
- * PageElement.located(By.id('offer-code'))
158
- * .describedAs('offer code')
200
+ * const Checkout = {
201
+ * someOfferField: () =>
202
+ * PageElement.located(By.id('offer-code'))
203
+ * .describedAs('offer code')
159
204
  *
160
- * const applyOfferCodeField = () =>
161
- * PageElement.located(By.id('apply-offer-code'))
162
- * .describedAs('apply offer field')
205
+ * applyOfferCodeField = () =>
206
+ * PageElement.located(By.id('apply-offer-code'))
207
+ * .describedAs('apply offer field')
208
+ * }
163
209
  *
164
210
  * await actorCalled('Joseph')
165
211
  * .attemptsTo(
166
212
  * // inject JavaScript to read some property of an element
167
213
  * ExecuteScript.sync(function getValue(element) {
168
214
  * return element.value;
169
- * }).withArguments(someOfferField),
215
+ * }).withArguments(Checkout.someOfferField()),
170
216
  *
171
217
  * // use LastScriptExecution.result() to read the value
172
218
  * // returned from the injected script
173
219
  * // and pass it to another interaction
174
- * Enter.theValue(LastScriptExecution.result<string>()).into(applyOfferCodeField),
220
+ * Enter.theValue(LastScriptExecution.result<string>()).into(Checkout.applyOfferCodeField()),
175
221
  * )
176
222
  * ```
177
223
  *
224
+ * #### Passing PageElement arguments to a sync script
225
+ *
226
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
227
+ * into their corresponding DOM elements.
228
+ *
229
+ * ```ts
230
+ * import { actorCalled } from '@serenity-js/core'
231
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
232
+ *
233
+ * const MyPage = {
234
+ * header: () =>
235
+ * PageElement.located(By.css('h1')).describedAs('header'),
236
+ * }
237
+ *
238
+ * await actorCalled('Esti').attemptsTo(
239
+ * ExecuteScript.sync(function getInnerHtml(element) {
240
+ * return element.innerHTML;
241
+ * }).withArguments(MyPage.header())
242
+ * )
243
+ * ```
244
+ *
245
+ * #### Using nested data structures containing PageElement objects
246
+ *
247
+ * Serenity/JS automatically converts any {@link PageElement} objects
248
+ * contained in nested data structures passed to the script
249
+ * into their corresponding DOM elements.
250
+ *
251
+ * ```ts
252
+ * import { actorCalled } from '@serenity-js/core'
253
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
254
+ *
255
+ * const MyPage = {
256
+ * header: () =>
257
+ * PageElement.located(By.css('h1')).describedAs('header'),
258
+ *
259
+ * article: () =>
260
+ * PageElement.located(By.css('article')).describedAs('article'),
261
+ * }
262
+ *
263
+ * await actorCalled('Esti').attemptsTo(
264
+ * ExecuteScript.async(function getInnerHtml(scope) {
265
+ * return scope.include[0].innerHTML;
266
+ * `).withArguments({
267
+ * include: [ MyPage.article() ],
268
+ * exclude: [ MyPage.header() ],
269
+ * })
270
+ * )
271
+ * ```
272
+ *
178
273
  * #### Learn more
179
274
  * - {@apilink LastScriptExecution.result}
180
275
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ExecuteScript.js","sourceRoot":"","sources":["../../../src/screenplay/interactions/ExecuteScript.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExecuteScript.js","sourceRoot":"","sources":["../../../src/screenplay/interactions/ExecuteScript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare class ArgumentDehydrator<T, U> {
2
+ private readonly shouldReference;
3
+ private readonly transformation;
4
+ constructor(shouldReference: (item: any) => item is T, transformation: (item: T) => U | Promise<U>);
5
+ dehydrate(inputArgs: Array<any>): Promise<[{
6
+ argsCount: number;
7
+ refsCount: number;
8
+ }, ...any[]]>;
9
+ private dehydrateRecursively;
10
+ }
11
+ //# sourceMappingURL=ArgumentDehydrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArgumentDehydrator.d.ts","sourceRoot":"","sources":["../../../src/screenplay/models/ArgumentDehydrator.ts"],"names":[],"mappings":"AAWA,qBAAa,kBAAkB,CAAC,CAAC,EAAE,CAAC;IAE5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,IAAI,CAAC,EACzC,cAAc,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAInD,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,EAAE,GAAG,GAAG,EAAE,CAAE,CAAC;YAU/F,oBAAoB;CA+BrC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ArgumentDehydrator = void 0;
4
+ const io_1 = require("@serenity-js/core/lib/io");
5
+ class ArgumentDehydrator {
6
+ shouldReference;
7
+ transformation;
8
+ constructor(shouldReference, transformation) {
9
+ this.shouldReference = shouldReference;
10
+ this.transformation = transformation;
11
+ }
12
+ async dehydrate(inputArgs) {
13
+ const result = await this.dehydrateRecursively(inputArgs);
14
+ return [
15
+ { argsCount: result.args.length, refsCount: result.refsCount },
16
+ ...result.args,
17
+ ...result.refs
18
+ ];
19
+ }
20
+ async dehydrateRecursively(inputArgs, refsCount = 0) {
21
+ return inputArgs.reduce(async (acc, arg) => {
22
+ const { args, refs, refsCount } = await acc;
23
+ if (Array.isArray(arg)) {
24
+ const { args: nestedArgs, refs: nestedRefs, refsCount: currentRefsCount } = await this.dehydrateRecursively(arg, refsCount);
25
+ return {
26
+ args: [...args, nestedArgs,],
27
+ refs: [...refs, ...nestedRefs],
28
+ refsCount: currentRefsCount,
29
+ };
30
+ }
31
+ if ((0, io_1.isPlainObject)(arg)) {
32
+ const { args: nestedArgs, refs: nestedRefs, refsCount: currentRefsCount } = await this.dehydrateRecursively(Object.values(arg), refsCount);
33
+ return {
34
+ args: [...args, Object.fromEntries(Object.keys(arg).map((key, i) => [key, nestedArgs[i]]))],
35
+ refs: [...refs, ...nestedRefs],
36
+ refsCount: currentRefsCount,
37
+ };
38
+ }
39
+ return this.shouldReference(arg)
40
+ ? { args: [...args, `$ref${refsCount}`], refs: [...refs, await this.transformation(arg)], refsCount: refsCount + 1 }
41
+ : { args: [...args, arg], refs, refsCount };
42
+ }, Promise.resolve({ args: [], refs: [], refsCount }));
43
+ }
44
+ }
45
+ exports.ArgumentDehydrator = ArgumentDehydrator;
46
+ //# sourceMappingURL=ArgumentDehydrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArgumentDehydrator.js","sourceRoot":"","sources":["../../../src/screenplay/models/ArgumentDehydrator.ts"],"names":[],"mappings":";;;AAAA,iDAAyD;AAWzD,MAAa,kBAAkB;IAEN;IACA;IAFrB,YACqB,eAAyC,EACzC,cAA2C;QAD3C,oBAAe,GAAf,eAAe,CAA0B;QACzC,mBAAc,GAAd,cAAc,CAA6B;IAEhE,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,SAAqB;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAE1D,OAAO;YACH,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE;YAC9D,GAAG,MAAM,CAAC,IAAI;YACd,GAAG,MAAM,CAAC,IAAI;SACjB,CAAC;IACN,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,SAAqB,EAAE,SAAS,GAAG,CAAC;QAKnE,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,CAAC;YAE5C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACpB,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC5H,OAAO;oBACH,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,UAAU,EAAG;oBAC9B,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAE;oBAChC,SAAS,EAAE,gBAAgB;iBAC9B,CAAC;aACL;YAED,IAAI,IAAA,kBAAa,EAAC,GAAG,CAAC,EAAE;gBACpB,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC3I,OAAO;oBACH,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE;oBAC/F,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAE;oBAChC,SAAS,EAAE,gBAAgB;iBAC9B,CAAC;aACL;YAED,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC;gBAC5B,CAAC,CAAC,EAAE,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,OAAQ,SAAU,EAAE,CAAE,EAAE,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAE,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,EAAE;gBAC1H,CAAC,CAAC,EAAE,IAAI,EAAE,CAAE,GAAG,IAAI,EAAE,GAAG,CAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtD,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACJ;AAhDD,gDAgDC"}
@@ -1,3 +1,4 @@
1
+ export * from './ArgumentDehydrator';
1
2
  export * from './BrowserCapabilities';
2
3
  export * from './BrowsingSession';
3
4
  export * from './Cookie';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
@@ -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("./ArgumentDehydrator"), exports);
17
18
  __exportStar(require("./BrowserCapabilities"), exports);
18
19
  __exportStar(require("./BrowsingSession"), exports);
19
20
  __exportStar(require("./Cookie"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,oDAAkC;AAClC,2CAAyB;AACzB,+CAA6B;AAC7B,4CAA0B;AAC1B,wCAAsB;AACtB,4CAA0B;AAC1B,yCAAuB;AACvB,gDAA8B;AAC9B,iDAA+B;AAC/B,wDAAsC;AACtC,gDAA8B;AAC9B,iDAA+B;AAC/B,8CAA4B;AAC5B,+CAA6B;AAC7B,qDAAmC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,wDAAsC;AACtC,oDAAkC;AAClC,2CAAyB;AACzB,+CAA6B;AAC7B,4CAA0B;AAC1B,wCAAsB;AACtB,4CAA0B;AAC1B,yCAAuB;AACvB,gDAA8B;AAC9B,iDAA+B;AAC/B,wDAAsC;AACtC,gDAA8B;AAC9B,iDAA+B;AAC/B,8CAA4B;AAC5B,+CAA6B;AAC7B,qDAAmC"}
@@ -1,2 +1,3 @@
1
1
  export * from './isVisible';
2
+ export * from './rehydrate';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./isVisible"), exports);
18
+ __exportStar(require("./rehydrate"), exports);
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,8CAA4B"}
@@ -0,0 +1,5 @@
1
+ export declare function rehydrate(...result: [{
2
+ argsCount: number;
3
+ refsCount: number;
4
+ }, ...any[]]): Array<any>;
5
+ //# sourceMappingURL=rehydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehydrate.d.ts","sourceRoot":"","sources":["../../src/scripts/rehydrate.ts"],"names":[],"mappings":"AAEA,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,CAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,GAAG,EAAE,CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAmCvG"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rehydrate = void 0;
4
+ /* eslint-disable unicorn/consistent-function-scoping */
5
+ // todo: instead of manually including isPlainObject, each script from web/lib/scripts should be pre-built and included in the global browser scope
6
+ function rehydrate(...result) {
7
+ function isPlainObject(v) {
8
+ if (typeof v === 'object' && v !== null) {
9
+ if (typeof Object.getPrototypeOf === 'function') {
10
+ const proto = Object.getPrototypeOf(v);
11
+ return proto === Object.prototype || proto === null;
12
+ }
13
+ return Object.prototype.toString.call(v) === '[object Object]';
14
+ }
15
+ return false;
16
+ }
17
+ function rehydrateRecursively(arg, refs) {
18
+ if (Array.isArray(arg)) {
19
+ return arg.map(item => rehydrateRecursively(item, refs));
20
+ }
21
+ if (isPlainObject(arg)) {
22
+ return Object.fromEntries(Object.entries(arg)
23
+ .map(([key, value]) => [key, rehydrateRecursively(value, refs)]));
24
+ }
25
+ if (typeof arg === 'string' && arg.startsWith('$ref')) {
26
+ return refs[Number.parseInt(arg.replace('$ref', ''), 10)];
27
+ }
28
+ return arg;
29
+ }
30
+ const [{ argsCount }, ...items] = result;
31
+ const args = items.slice(0, argsCount);
32
+ const refs = items.slice(argsCount);
33
+ return args.map(arg => rehydrateRecursively(arg, refs));
34
+ }
35
+ exports.rehydrate = rehydrate;
36
+ //# sourceMappingURL=rehydrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehydrate.js","sourceRoot":"","sources":["../../src/scripts/rehydrate.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AACxD,mJAAmJ;AACnJ,SAAgB,SAAS,CAAC,GAAG,MAA8D;IACvF,SAAS,aAAa,CAAC,CAAU;QAC7B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE;YACrC,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,UAAU,EAAE;gBAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;gBACvC,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;aACvD;YACD,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,iBAAiB,CAAC;SAClE;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,SAAS,oBAAoB,CAAC,GAAQ,EAAE,IAAW;QAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACpB,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;SAC5D;QACD,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE;YACpB,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;iBACd,GAAG,CAAC,CAAC,CAAE,GAAG,EAAE,KAAK,CAAE,EAAE,EAAE,CAAC,CAAE,GAAG,EAAE,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAE,CAAC,CAC3E,CAAC;SACL;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;YACnD,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAC7D;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED,MAAM,CAAE,EAAE,SAAS,EAAE,EAAE,GAAG,KAAK,CAAE,GAAG,MAAM,CAAC;IAE3C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEpC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5D,CAAC;AAnCD,8BAmCC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/web",
3
- "version": "3.22.4",
3
+ "version": "3.23.1",
4
4
  "description": "Serenity/JS Screenplay Pattern APIs for the Web",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -45,8 +45,8 @@
45
45
  "node": "^16.13 || ^18.12 || ^20"
46
46
  },
47
47
  "dependencies": {
48
- "@serenity-js/assertions": "3.22.4",
49
- "@serenity-js/core": "3.22.4",
48
+ "@serenity-js/assertions": "3.23.1",
49
+ "@serenity-js/core": "3.23.1",
50
50
  "tiny-types": "1.22.0"
51
51
  },
52
52
  "devDependencies": {
@@ -59,5 +59,5 @@
59
59
  "ts-node": "10.9.2",
60
60
  "typescript": "5.2.2"
61
61
  },
62
- "gitHead": "f5db024cf16bf75489b55253dec6ef6e66114728"
62
+ "gitHead": "6bb08ce04a5590660704eed74334396ccca42a33"
63
63
  }
@@ -7,7 +7,7 @@ import { BrowseTheWeb } from '../abilities';
7
7
 
8
8
  /**
9
9
  * Instructs an {@apilink Actor|actor} who has the {@apilink Ability|ability} to {@apilink BrowseTheWeb}
10
- * to execute a script within the context of the current browser tab.
10
+ * to inject a script into the browser and execute it in the context of the current browser tab.
11
11
  *
12
12
  * ## Learn more
13
13
  *
@@ -72,6 +72,24 @@ export class ExecuteScript {
72
72
  * )
73
73
  * ```
74
74
  *
75
+ * #### Executing async script as function
76
+ *
77
+ * ```ts
78
+ * import { actorCalled } from '@serenity-js/core'
79
+ * import { ExecuteScript } from '@serenity-js/web'
80
+ *
81
+ * const MyPage = {
82
+ * header: () =>
83
+ * PageElement.located(By.css('h1')).describedAs('header'),
84
+ * }
85
+ *
86
+ * await actorCalled('Esti').attemptsTo(
87
+ * ExecuteScript.async(function getText(header, callback) {
88
+ * callback(header.innerText)
89
+ * }).withArguments(MyPage.header())
90
+ * )
91
+ * ```
92
+ *
75
93
  * #### Passing arguments to an async script
76
94
  *
77
95
  * ```ts
@@ -91,32 +109,58 @@ export class ExecuteScript {
91
109
  * )
92
110
  * ```
93
111
  *
94
- * #### Passing Target arguments to an async script
112
+ * #### Passing PageElement arguments to an async script
113
+ *
114
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
115
+ * into their corresponding DOM elements.
95
116
  *
96
117
  * ```ts
97
118
  * import { actorCalled } from '@serenity-js/core'
98
- * import { ExecuteScript } from '@serenity-js/web'
119
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
120
+ *
121
+ * const MyPage = {
122
+ * header: () =>
123
+ * PageElement.located(By.css('h1')).describedAs('header'),
124
+ * }
99
125
  *
100
126
  * await actorCalled('Esti').attemptsTo(
101
127
  * ExecuteScript.async(`
102
- * var header = arguments[0] // PageElement object gets converted to a WebElement
128
+ * var header = arguments[0]
103
129
  * var callback = arguments[arguments.length - 1]
104
130
  *
105
131
  * callback(header.innerText)
106
- * `).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
132
+ * `).withArguments(MyPage.header())
107
133
  * )
108
134
  * ```
109
135
  *
110
- * #### Executing async script as function
136
+ * #### Using nested data structures containing PageElement objects
137
+ *
138
+ * Serenity/JS automatically converts any {@link PageElement} objects
139
+ * contained in nested data structures passed to the script
140
+ * into their corresponding DOM elements.
111
141
  *
112
142
  * ```ts
113
143
  * import { actorCalled } from '@serenity-js/core'
114
- * import { ExecuteScript } from '@serenity-js/web'
144
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
145
+ *
146
+ * const MyPage = {
147
+ * header: () =>
148
+ * PageElement.located(By.css('h1')).describedAs('header'),
149
+ *
150
+ * article: () =>
151
+ * PageElement.located(By.css('article')).describedAs('article'),
152
+ * }
115
153
  *
116
154
  * await actorCalled('Esti').attemptsTo(
117
- * ExecuteScript.async(function getText(header, callback) {
118
- * callback(header.innerText)
119
- * }).withArguments(PageElement.located(By.css('h1')).describedAs('header'))
155
+ * ExecuteScript.async(`
156
+ * var { include, exclude } = arguments[0]
157
+ * var callback = arguments[arguments.length - 1]
158
+ *
159
+ * callback(include[0].innerText)
160
+ * `).withArguments({
161
+ * include: [ MyPage.article() ],
162
+ * exclude: [ MyPage.header() ],
163
+ * })
120
164
  * )
121
165
  * ```
122
166
  *
@@ -153,34 +197,85 @@ export class ExecuteScript {
153
197
  * )
154
198
  * ```
155
199
  *
156
- * #### Executing a sync script as function and reading the result
200
+ * #### Executing a sync script as function and retrieving the result
157
201
  *
158
202
  * ```ts
159
203
  * import { actorCalled } from '@serenity-js/core'
160
204
  * import { By, Enter, ExecuteScript, LastScriptExecution, PageElement } from '@serenity-js/web'
161
205
  *
162
- * const someOfferField = () =>
163
- * PageElement.located(By.id('offer-code'))
164
- * .describedAs('offer code')
206
+ * const Checkout = {
207
+ * someOfferField: () =>
208
+ * PageElement.located(By.id('offer-code'))
209
+ * .describedAs('offer code')
165
210
  *
166
- * const applyOfferCodeField = () =>
167
- * PageElement.located(By.id('apply-offer-code'))
168
- * .describedAs('apply offer field')
211
+ * applyOfferCodeField = () =>
212
+ * PageElement.located(By.id('apply-offer-code'))
213
+ * .describedAs('apply offer field')
214
+ * }
169
215
  *
170
216
  * await actorCalled('Joseph')
171
217
  * .attemptsTo(
172
218
  * // inject JavaScript to read some property of an element
173
219
  * ExecuteScript.sync(function getValue(element) {
174
220
  * return element.value;
175
- * }).withArguments(someOfferField),
221
+ * }).withArguments(Checkout.someOfferField()),
176
222
  *
177
223
  * // use LastScriptExecution.result() to read the value
178
224
  * // returned from the injected script
179
225
  * // and pass it to another interaction
180
- * Enter.theValue(LastScriptExecution.result<string>()).into(applyOfferCodeField),
226
+ * Enter.theValue(LastScriptExecution.result<string>()).into(Checkout.applyOfferCodeField()),
181
227
  * )
182
228
  * ```
183
229
  *
230
+ * #### Passing PageElement arguments to a sync script
231
+ *
232
+ * Serenity/JS automatically converts {@link PageElement} objects passed as arguments to the script
233
+ * into their corresponding DOM elements.
234
+ *
235
+ * ```ts
236
+ * import { actorCalled } from '@serenity-js/core'
237
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
238
+ *
239
+ * const MyPage = {
240
+ * header: () =>
241
+ * PageElement.located(By.css('h1')).describedAs('header'),
242
+ * }
243
+ *
244
+ * await actorCalled('Esti').attemptsTo(
245
+ * ExecuteScript.sync(function getInnerHtml(element) {
246
+ * return element.innerHTML;
247
+ * }).withArguments(MyPage.header())
248
+ * )
249
+ * ```
250
+ *
251
+ * #### Using nested data structures containing PageElement objects
252
+ *
253
+ * Serenity/JS automatically converts any {@link PageElement} objects
254
+ * contained in nested data structures passed to the script
255
+ * into their corresponding DOM elements.
256
+ *
257
+ * ```ts
258
+ * import { actorCalled } from '@serenity-js/core'
259
+ * import { ExecuteScript, PageElement } from '@serenity-js/web'
260
+ *
261
+ * const MyPage = {
262
+ * header: () =>
263
+ * PageElement.located(By.css('h1')).describedAs('header'),
264
+ *
265
+ * article: () =>
266
+ * PageElement.located(By.css('article')).describedAs('article'),
267
+ * }
268
+ *
269
+ * await actorCalled('Esti').attemptsTo(
270
+ * ExecuteScript.async(function getInnerHtml(scope) {
271
+ * return scope.include[0].innerHTML;
272
+ * `).withArguments({
273
+ * include: [ MyPage.article() ],
274
+ * exclude: [ MyPage.header() ],
275
+ * })
276
+ * )
277
+ * ```
278
+ *
184
279
  * #### Learn more
185
280
  * - {@apilink LastScriptExecution.result}
186
281
  *
@@ -0,0 +1,60 @@
1
+ import { isPlainObject } from '@serenity-js/core/lib/io';
2
+
3
+ /* eslint-disable @typescript-eslint/indent */
4
+ type TransformedArgument<T, U> =
5
+ T extends Array<infer E> ? Array<TransformedArgument<E, U>> :
6
+ T extends object ? { [K in keyof T]: TransformedArgument<T[K], U> }
7
+ : U;
8
+ /* eslint-enable */
9
+
10
+ type RefId = `$ref${number}`;
11
+
12
+ export class ArgumentDehydrator<T, U> {
13
+ constructor(
14
+ private readonly shouldReference: (item: any) => item is T,
15
+ private readonly transformation: (item: T) => U | Promise<U>,
16
+ ) {
17
+ }
18
+
19
+ public async dehydrate(inputArgs: Array<any>): Promise<[ { argsCount: number, refsCount: number}, ...any[] ]> {
20
+ const result = await this.dehydrateRecursively(inputArgs);
21
+
22
+ return [
23
+ { argsCount: result.args.length, refsCount: result.refsCount },
24
+ ...result.args,
25
+ ...result.refs
26
+ ];
27
+ }
28
+
29
+ private async dehydrateRecursively(inputArgs: Array<any>, refsCount = 0): Promise<{
30
+ args: Array<TransformedArgument<T, RefId>>;
31
+ refs: Array<U>;
32
+ refsCount: number;
33
+ }> {
34
+ return inputArgs.reduce(async (acc, arg) => {
35
+ const { args, refs, refsCount } = await acc;
36
+
37
+ if (Array.isArray(arg)) {
38
+ const { args: nestedArgs, refs: nestedRefs, refsCount: currentRefsCount } = await this.dehydrateRecursively(arg, refsCount);
39
+ return {
40
+ args: [ ...args, nestedArgs, ],
41
+ refs: [ ...refs, ...nestedRefs ],
42
+ refsCount: currentRefsCount,
43
+ };
44
+ }
45
+
46
+ if (isPlainObject(arg)) {
47
+ const { args: nestedArgs, refs: nestedRefs, refsCount: currentRefsCount } = await this.dehydrateRecursively(Object.values(arg), refsCount);
48
+ return {
49
+ args: [ ...args, Object.fromEntries(Object.keys(arg).map((key, i) => [ key, nestedArgs[i] ])) ],
50
+ refs: [ ...refs, ...nestedRefs ],
51
+ refsCount: currentRefsCount,
52
+ };
53
+ }
54
+
55
+ return this.shouldReference(arg)
56
+ ? { args: [ ...args, `$ref${ refsCount }` ], refs: [ ...refs, await this.transformation(arg) ], refsCount: refsCount + 1 }
57
+ : { args: [ ...args, arg ], refs, refsCount };
58
+ }, Promise.resolve({ args: [], refs: [], refsCount }));
59
+ }
60
+ }
@@ -1,3 +1,4 @@
1
+ export * from './ArgumentDehydrator';
1
2
  export * from './BrowserCapabilities';
2
3
  export * from './BrowsingSession';
3
4
  export * from './Cookie';
@@ -1 +1,2 @@
1
1
  export * from './isVisible';
2
+ export * from './rehydrate';
@@ -0,0 +1,38 @@
1
+ /* eslint-disable unicorn/consistent-function-scoping */
2
+ // todo: instead of manually including isPlainObject, each script from web/lib/scripts should be pre-built and included in the global browser scope
3
+ export function rehydrate(...result: [ { argsCount: number; refsCount: number }, ...any[] ]): Array<any> {
4
+ function isPlainObject(v: unknown): v is object { // eslint-disable-line @typescript-eslint/ban-types
5
+ if (typeof v === 'object' && v !== null) {
6
+ if (typeof Object.getPrototypeOf === 'function') {
7
+ const proto = Object.getPrototypeOf(v);
8
+ return proto === Object.prototype || proto === null;
9
+ }
10
+ return Object.prototype.toString.call(v) === '[object Object]';
11
+ }
12
+ return false;
13
+ }
14
+
15
+ function rehydrateRecursively(arg: any, refs: any[]): any {
16
+ if (Array.isArray(arg)) {
17
+ return arg.map(item => rehydrateRecursively(item, refs));
18
+ }
19
+ if (isPlainObject(arg)) {
20
+ return Object.fromEntries(
21
+ Object.entries(arg)
22
+ .map(([ key, value ]) => [ key, rehydrateRecursively(value, refs) ])
23
+ );
24
+ }
25
+ if (typeof arg === 'string' && arg.startsWith('$ref')) {
26
+ return refs[Number.parseInt(arg.replace('$ref', ''), 10)];
27
+ }
28
+
29
+ return arg;
30
+ }
31
+
32
+ const [ { argsCount }, ...items ] = result;
33
+
34
+ const args = items.slice(0, argsCount);
35
+ const refs = items.slice(argsCount);
36
+
37
+ return args.map(arg => rehydrateRecursively(arg, refs));
38
+ }