@serenity-js/web 3.22.4 → 3.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/screenplay/interactions/ExecuteScript.d.ts +114 -19
- package/lib/screenplay/interactions/ExecuteScript.d.ts.map +1 -1
- package/lib/screenplay/interactions/ExecuteScript.js +114 -19
- package/lib/screenplay/interactions/ExecuteScript.js.map +1 -1
- package/lib/screenplay/models/ArgumentDehydrator.d.ts +11 -0
- package/lib/screenplay/models/ArgumentDehydrator.d.ts.map +1 -0
- package/lib/screenplay/models/ArgumentDehydrator.js +46 -0
- package/lib/screenplay/models/ArgumentDehydrator.js.map +1 -0
- package/lib/screenplay/models/index.d.ts +1 -0
- package/lib/screenplay/models/index.d.ts.map +1 -1
- package/lib/screenplay/models/index.js +1 -0
- package/lib/screenplay/models/index.js.map +1 -1
- package/lib/scripts/index.d.ts +1 -0
- package/lib/scripts/index.d.ts.map +1 -1
- package/lib/scripts/index.js +1 -0
- package/lib/scripts/index.js.map +1 -1
- package/lib/scripts/rehydrate.d.ts +5 -0
- package/lib/scripts/rehydrate.d.ts.map +1 -0
- package/lib/scripts/rehydrate.js +36 -0
- package/lib/scripts/rehydrate.js.map +1 -0
- package/package.json +4 -4
- package/src/screenplay/interactions/ExecuteScript.ts +114 -19
- package/src/screenplay/models/ArgumentDehydrator.ts +60 -0
- package/src/screenplay/models/index.ts +1 -0
- package/src/scripts/index.ts +1 -0
- package/src/scripts/rehydrate.ts +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.0](https://github.com/serenity-js/serenity-js/compare/v3.22.4...v3.23.0) (2024-05-12)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **webdriverio:** support for injecting scripts parameterised with complex data structures ([e920e67](https://github.com/serenity-js/serenity-js/commit/e920e6709262c8249c992ac02a01f49d5789a35d))
|
|
12
|
+
* **web:** scripts injected into the browser accept data structures containing PageElement objects ([2fbddf5](https://github.com/serenity-js/serenity-js/commit/2fbddf5d78d2965aecd6786b020c93ea079bdaf1))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
## [3.22.4](https://github.com/serenity-js/serenity-js/compare/v3.22.3...v3.22.4) (2024-05-07)
|
|
7
19
|
|
|
8
20
|
**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
|
|
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
|
|
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]
|
|
119
|
+
* var header = arguments[0]
|
|
94
120
|
* var callback = arguments[arguments.length - 1]
|
|
95
121
|
*
|
|
96
122
|
* callback(header.innerText)
|
|
97
|
-
* `).withArguments(
|
|
123
|
+
* `).withArguments(MyPage.header())
|
|
98
124
|
* )
|
|
99
125
|
* ```
|
|
100
126
|
*
|
|
101
|
-
* ####
|
|
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(
|
|
109
|
-
*
|
|
110
|
-
*
|
|
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
|
|
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
|
|
148
|
-
*
|
|
149
|
-
* .
|
|
191
|
+
* const Checkout = {
|
|
192
|
+
* someOfferField: () =>
|
|
193
|
+
* PageElement.located(By.id('offer-code'))
|
|
194
|
+
* .describedAs('offer code')
|
|
150
195
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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]
|
|
126
|
+
* var header = arguments[0]
|
|
101
127
|
* var callback = arguments[arguments.length - 1]
|
|
102
128
|
*
|
|
103
129
|
* callback(header.innerText)
|
|
104
|
-
* `).withArguments(
|
|
130
|
+
* `).withArguments(MyPage.header())
|
|
105
131
|
* )
|
|
106
132
|
* ```
|
|
107
133
|
*
|
|
108
|
-
* ####
|
|
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(
|
|
116
|
-
*
|
|
117
|
-
*
|
|
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
|
|
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
|
|
157
|
-
*
|
|
158
|
-
* .
|
|
200
|
+
* const Checkout = {
|
|
201
|
+
* someOfferField: () =>
|
|
202
|
+
* PageElement.located(By.id('offer-code'))
|
|
203
|
+
* .describedAs('offer code')
|
|
159
204
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
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":";;;AACA,4CAA+D;AAC/D,iDAAoD;AACpD,uDAA6D;AAE7D,4CAA4C;AAE5C;;;;;;;;;;GAUG;AACH,MAAa,aAAa;IAEtB;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,SAA6B;QACrC,OAAO,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED
|
|
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 +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"}
|
package/lib/scripts/index.d.ts
CHANGED
|
@@ -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"}
|
package/lib/scripts/index.js
CHANGED
|
@@ -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
|
package/lib/scripts/index.js.map
CHANGED
|
@@ -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 @@
|
|
|
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.
|
|
3
|
+
"version": "3.23.0",
|
|
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.
|
|
49
|
-
"@serenity-js/core": "3.
|
|
48
|
+
"@serenity-js/assertions": "3.23.0",
|
|
49
|
+
"@serenity-js/core": "3.23.0",
|
|
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": "
|
|
62
|
+
"gitHead": "be1bb276388c295df01146eb8589a003b3d8214c"
|
|
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
|
|
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
|
|
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]
|
|
128
|
+
* var header = arguments[0]
|
|
103
129
|
* var callback = arguments[arguments.length - 1]
|
|
104
130
|
*
|
|
105
131
|
* callback(header.innerText)
|
|
106
|
-
* `).withArguments(
|
|
132
|
+
* `).withArguments(MyPage.header())
|
|
107
133
|
* )
|
|
108
134
|
* ```
|
|
109
135
|
*
|
|
110
|
-
* ####
|
|
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(
|
|
118
|
-
*
|
|
119
|
-
*
|
|
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
|
|
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
|
|
163
|
-
*
|
|
164
|
-
* .
|
|
206
|
+
* const Checkout = {
|
|
207
|
+
* someOfferField: () =>
|
|
208
|
+
* PageElement.located(By.id('offer-code'))
|
|
209
|
+
* .describedAs('offer code')
|
|
165
210
|
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
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
|
+
}
|
package/src/scripts/index.ts
CHANGED
|
@@ -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
|
+
}
|