codeceptjs 4.0.0-rc.22 → 4.0.0-rc.24

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.
Files changed (82) hide show
  1. package/README.md +9 -10
  2. package/docs/ai.md +3 -51
  3. package/docs/architecture.md +16 -0
  4. package/docs/bootstrap.md +1 -1
  5. package/docs/continuous-integration.md +16 -44
  6. package/docs/custom-helpers.md +1 -1
  7. package/docs/detox.md +1 -1
  8. package/docs/docker.md +1 -30
  9. package/docs/examples.md +0 -1
  10. package/docs/helpers/Appium.md +16 -2
  11. package/docs/helpers/Playwright.md +161 -160
  12. package/docs/helpers/Puppeteer.md +143 -250
  13. package/docs/helpers/WebDriver.md +134 -177
  14. package/docs/hooks.md +11 -1
  15. package/docs/index.md +1 -1
  16. package/docs/installation.md +2 -19
  17. package/docs/locators.md +1 -1
  18. package/docs/migrate-from-cypress.md +98 -0
  19. package/docs/migrate-from-java.md +108 -0
  20. package/docs/migrate-from-protractor.md +101 -0
  21. package/docs/migrate-from-testcafe.md +99 -0
  22. package/docs/migration-4.md +195 -8
  23. package/docs/plugins/aiTrace.md +49 -0
  24. package/docs/plugins/analyze.md +66 -0
  25. package/docs/plugins/auth.md +241 -0
  26. package/docs/plugins/autoDelay.md +48 -0
  27. package/docs/plugins/browser.md +41 -0
  28. package/docs/plugins/coverage.md +39 -0
  29. package/docs/plugins/customLocator.md +119 -0
  30. package/docs/plugins/customReporter.md +16 -0
  31. package/docs/plugins/expose.md +75 -0
  32. package/docs/plugins/heal.md +44 -0
  33. package/docs/plugins/junitReporter.md +51 -0
  34. package/docs/plugins/pageInfo.md +34 -0
  35. package/docs/plugins/pause.md +43 -0
  36. package/docs/plugins/pauseOnFail.md +18 -0
  37. package/docs/plugins/retryFailedStep.md +75 -0
  38. package/docs/plugins/screencast.md +55 -0
  39. package/docs/plugins/screenshot.md +58 -0
  40. package/docs/plugins/screenshotOnFail.md +18 -0
  41. package/docs/plugins/stepTimeout.md +65 -0
  42. package/docs/plugins.md +40 -862
  43. package/docs/reports.md +18 -4
  44. package/docs/retry.md +48 -18
  45. package/docs/store.md +94 -0
  46. package/docs/timeouts.md +1 -1
  47. package/docs/tutorial.md +207 -155
  48. package/docs/webdriver.md +6 -73
  49. package/lib/actor.js +1 -36
  50. package/lib/command/run-multiple.js +1 -2
  51. package/lib/heal.js +2 -2
  52. package/lib/helper/Playwright.js +1 -15
  53. package/lib/helper/Puppeteer.js +0 -103
  54. package/lib/helper/WebDriver.js +1 -28
  55. package/lib/helper/extras/PlaywrightLocator.js +10 -0
  56. package/lib/locator.js +0 -13
  57. package/lib/plugin/aiTrace.js +4 -3
  58. package/lib/plugin/analyze.js +3 -4
  59. package/lib/plugin/junitReporter.js +1 -1
  60. package/lib/plugin/pauseOnFail.js +3 -1
  61. package/lib/plugin/retryFailedStep.js +11 -10
  62. package/lib/plugin/screencast.js +1 -1
  63. package/lib/plugin/screenshot.js +2 -7
  64. package/lib/plugin/screenshotOnFail.js +3 -1
  65. package/lib/plugin/stepTimeout.js +3 -2
  66. package/lib/recorder.js +1 -1
  67. package/lib/step/base.js +7 -7
  68. package/lib/step/comment.js +2 -2
  69. package/lib/step/helper.js +4 -4
  70. package/lib/step/meta.js +3 -3
  71. package/lib/step/record.js +3 -3
  72. package/lib/workers.js +0 -4
  73. package/package.json +3 -4
  74. package/docs/helpers/Mochawesome.md +0 -8
  75. package/docs/helpers/MockServer.md +0 -212
  76. package/docs/helpers/Polly.md +0 -44
  77. package/docs/helpers/Protractor.md +0 -1769
  78. package/docs/helpers/SoftExpectHelper.md +0 -352
  79. package/docs/react.md +0 -70
  80. package/lib/helper/Mochawesome.js +0 -96
  81. package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -61
  82. package/lib/helper/extras/React.js +0 -65
@@ -1,352 +0,0 @@
1
- ---
2
- permalink: /helpers/SoftExpectHelper
3
- editLink: false
4
- sidebar: auto
5
- title: SoftExpectHelper
6
- ---
7
-
8
- <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
9
-
10
- ## SoftAssertHelper
11
-
12
- **Extends ExpectHelper**
13
-
14
- SoftAssertHelper is a utility class for performing soft assertions.
15
- Unlike traditional assertions that stop the execution on failure,
16
- soft assertions allow the execution to continue and report all failures at the end.
17
-
18
- ### Examples
19
-
20
- Zero-configuration when paired with other helpers like REST, Playwright:
21
-
22
- ```js
23
- // inside codecept.conf.js
24
- {
25
- helpers: {
26
- Playwright: {...},
27
- SoftExpectHelper: {},
28
- }
29
- }
30
- ```
31
-
32
- ```js
33
- // in scenario
34
- I.softExpectEqual('a', 'b')
35
- I.flushSoftAssertions() // Throws an error if any soft assertions have failed. The error message contains all the accumulated failures.
36
- ```
37
-
38
- ## Methods
39
-
40
- ### flushSoftAssertions
41
-
42
- Throws an error if any soft assertions have failed.
43
- The error message contains all the accumulated failures.
44
-
45
- - Throws **[Error][1]** If there are any soft assertion failures.
46
-
47
- ### softAssert
48
-
49
- Performs a soft assertion by executing the provided assertion function.
50
- If the assertion fails, the error is caught and stored without halting the execution.
51
-
52
- #### Parameters
53
-
54
- - `assertionFn` **[Function][2]** The assertion function to execute.
55
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
56
-
57
- ### softExpectAbove
58
-
59
- Softly asserts that the target data is above a specified value.
60
-
61
- #### Parameters
62
-
63
- - `targetData` **any** The data to check.
64
- - `aboveThan` **any** The value that the target data should be above.
65
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
66
-
67
- ### softExpectBelow
68
-
69
- Softly asserts that the target data is below a specified value.
70
-
71
- #### Parameters
72
-
73
- - `targetData` **any** The data to check.
74
- - `belowThan` **any** The value that the target data should be below.
75
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
76
-
77
- ### softExpectContain
78
-
79
- Softly asserts that a value contains the expected value.
80
-
81
- #### Parameters
82
-
83
- - `actualValue` **any** The actual value.
84
- - `expectedValueToContain` **any** The value that should be contained within the actual value.
85
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
86
-
87
- ### softExpectDeepEqual
88
-
89
- Softly asserts that two values are deeply equal.
90
-
91
- #### Parameters
92
-
93
- - `actualValue` **any** The actual value.
94
- - `expectedValue` **any** The expected value.
95
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
96
-
97
- ### softExpectDeepEqualExcluding
98
-
99
- Softly asserts that two objects are deeply equal, excluding specified fields.
100
-
101
- #### Parameters
102
-
103
- - `actualValue` **[Object][4]** The actual object.
104
- - `expectedValue` **[Object][4]** The expected object.
105
- - `fieldsToExclude` **[Array][5]<[string][3]>** The fields to exclude from the comparison.
106
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
107
-
108
- ### softExpectDeepIncludeMembers
109
-
110
- Softly asserts that an array (superset) deeply includes all members of another array (set).
111
-
112
- #### Parameters
113
-
114
- - `superset` **[Array][5]** The array that should contain the expected members.
115
- - `set` **[Array][5]** The array with members that should be included.
116
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
117
-
118
- ### softExpectDeepMembers
119
-
120
- Softly asserts that two arrays have deep equality, considering members in any order.
121
-
122
- #### Parameters
123
-
124
- - `actualValue` **[Array][5]** The actual array.
125
- - `expectedValue` **[Array][5]** The expected array.
126
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
127
-
128
- ### softExpectEmpty
129
-
130
- Softly asserts that the target data is empty.
131
-
132
- #### Parameters
133
-
134
- - `targetData` **any** The data to check.
135
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
136
-
137
- ### softExpectEndsWith
138
-
139
- Softly asserts that a value ends with the expected value.
140
-
141
- #### Parameters
142
-
143
- - `actualValue` **any** The actual value.
144
- - `expectedValueToEndWith` **any** The value that the actual value should end with.
145
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
146
-
147
- ### softExpectEqual
148
-
149
- Softly asserts that two values are equal.
150
-
151
- #### Parameters
152
-
153
- - `actualValue` **any** The actual value.
154
- - `expectedValue` **any** The expected value.
155
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
156
-
157
- ### softExpectEqualIgnoreCase
158
-
159
- Softly asserts that two values are equal, ignoring case.
160
-
161
- #### Parameters
162
-
163
- - `actualValue` **[string][3]** The actual string value.
164
- - `expectedValue` **[string][3]** The expected string value.
165
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
166
-
167
- ### softExpectFalse
168
-
169
- Softly asserts that the target data is false.
170
-
171
- #### Parameters
172
-
173
- - `targetData` **any** The data to check.
174
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
175
-
176
- ### softExpectHasAProperty
177
-
178
- Softly asserts that the target data has a property with the specified name.
179
-
180
- #### Parameters
181
-
182
- - `targetData` **any** The data to check.
183
- - `propertyName` **[string][3]** The property name to check for.
184
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
185
-
186
- ### softExpectHasProperty
187
-
188
- Softly asserts that the target data has the specified property.
189
-
190
- #### Parameters
191
-
192
- - `targetData` **any** The data to check.
193
- - `propertyName` **[string][3]** The property name to check for.
194
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion
195
- fails.
196
-
197
- ### softExpectJsonSchema
198
-
199
- Softly asserts that the target data matches the given JSON schema.
200
-
201
- #### Parameters
202
-
203
- - `targetData` **any** The data to validate.
204
- - `jsonSchema` **[Object][4]** The JSON schema to validate against.
205
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
206
-
207
- ### softExpectJsonSchemaUsingAJV
208
-
209
- Softly asserts that the target data matches the given JSON schema using AJV.
210
-
211
- #### Parameters
212
-
213
- - `targetData` **any** The data to validate.
214
- - `jsonSchema` **[Object][4]** The JSON schema to validate against.
215
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
216
- - `ajvOptions` **[Object][4]** Options to pass to AJV.
217
-
218
- ### softExpectLengthAboveThan
219
-
220
- Softly asserts that the length of the target data is above a specified value.
221
-
222
- #### Parameters
223
-
224
- - `targetData` **any** The data to check.
225
- - `lengthAboveThan` **[number][6]** The length that the target data should be above.
226
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
227
-
228
- ### softExpectLengthBelowThan
229
-
230
- Softly asserts that the length of the target data is below a specified value.
231
-
232
- #### Parameters
233
-
234
- - `targetData` **any** The data to check.
235
- - `lengthBelowThan` **[number][6]** The length that the target data should be below.
236
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
237
-
238
- ### softExpectLengthOf
239
-
240
- Softly asserts that the target data has a specified length.
241
-
242
- #### Parameters
243
-
244
- - `targetData` **any** The data to check.
245
- - `length` **[number][6]** The expected length.
246
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
247
-
248
- ### softExpectMatchesPattern
249
-
250
- Softly asserts that a value matches the expected pattern.
251
-
252
- #### Parameters
253
-
254
- - `actualValue` **any** The actual value.
255
- - `expectedPattern` **any** The pattern the value should match.
256
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
257
-
258
- ### softExpectNotContain
259
-
260
- Softly asserts that a value does not contain the expected value.
261
-
262
- #### Parameters
263
-
264
- - `actualValue` **any** The actual value.
265
- - `expectedValueToNotContain` **any** The value that should not be contained within the actual value.
266
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
267
-
268
- ### softExpectNotDeepEqual
269
-
270
- Softly asserts that two values are not deeply equal.
271
-
272
- #### Parameters
273
-
274
- - `actualValue` **any** The actual value.
275
- - `expectedValue` **any** The expected value.
276
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
277
-
278
- ### softExpectNotEndsWith
279
-
280
- Softly asserts that a value does not end with the expected value.
281
-
282
- #### Parameters
283
-
284
- - `actualValue` **any** The actual value.
285
- - `expectedValueToNotEndWith` **any** The value that the actual value should not end with.
286
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
287
-
288
- ### softExpectNotEqual
289
-
290
- Softly asserts that two values are not equal.
291
-
292
- #### Parameters
293
-
294
- - `actualValue` **any** The actual value.
295
- - `expectedValue` **any** The expected value.
296
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
297
-
298
- ### softExpectNotStartsWith
299
-
300
- Softly asserts that a value does not start with the expected value.
301
-
302
- #### Parameters
303
-
304
- - `actualValue` **any** The actual value.
305
- - `expectedValueToNotStartWith` **any** The value that the actual value should not start with.
306
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
307
-
308
- ### softExpectStartsWith
309
-
310
- Softly asserts that a value starts with the expected value.
311
-
312
- #### Parameters
313
-
314
- - `actualValue` **any** The actual value.
315
- - `expectedValueToStartWith` **any** The value that the actual value should start with.
316
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
317
-
318
- ### softExpectToBeA
319
-
320
- Softly asserts that the target data is of a specific type.
321
-
322
- #### Parameters
323
-
324
- - `targetData` **any** The data to check.
325
- - `type` **[string][3]** The expected type (e.g., 'string', 'number').
326
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
327
-
328
- ### softExpectToBeAn
329
-
330
- Softly asserts that the target data is of a specific type (alternative for articles).
331
-
332
- #### Parameters
333
-
334
- - `targetData` **any** The data to check.
335
- - `type` **[string][3]** The expected type (e.g., 'string', 'number').
336
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
337
-
338
- ### softExpectTrue
339
-
340
- Softly asserts that the target data is true.
341
-
342
- #### Parameters
343
-
344
- - `targetData` **any** The data to check.
345
- - `customErrorMsg` **[string][3]** A custom error message to display if the assertion fails.
346
-
347
- [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
348
- [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
349
- [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
350
- [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
351
- [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
352
- [6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
package/docs/react.md DELETED
@@ -1,70 +0,0 @@
1
- ---
2
- permalink: /react
3
- title: Testing React Applications
4
- ---
5
-
6
- # Testing React Applications
7
-
8
- React applications require some additional love for end to end testing.
9
- At first, it is very hard to test an application which was never designed to be tested!
10
- This happens to many React application. While building components developers often forget to keep the element's semantic.
11
-
12
- Generated HTML code may often look like this:
13
-
14
- ```js
15
- <div class="jss607 jss869 jss618 jss871 jss874 jss876" tabindex="0" role="tab" aria-selected="true" style="pointer-events: auto;">
16
- <span class="jss877">
17
- <span class="jss878">
18
- <span class="jss879">Click Me!</span>
19
- </span>
20
- </span>
21
- <span class="jss610"></span></div>
22
- ```
23
-
24
- It's quite common that clickable elements are not actual `a` or `button` elements. This way `I.click('Click Me!');` won't work, as well as `fillField('name', 'value)`. Finding a correct locator for such cases turns to be almost impossible.
25
-
26
- In this case test engineers have two options:
27
-
28
- 1. Update JSX files to change output HTML and rebuild the application
29
- 1. Test the application how it is.
30
-
31
- We recommend for long-running projects to go with the first option. The better you write your initial HTML the cleaner and less fragile will be your tests. Replace divs with correct HTML elements, add `data-` attributes, add labels, and names to input fields to make all CodeceptJS magic like clicking link by a text to work.
32
-
33
- However, if you can't update the code you can go to the second option. In this case, you should bind your locators to visible text on page and available semantic attribues. For instance, instead of using generated locator as this one:
34
-
35
- ```
36
- //*[@id="document"]/div[2]/div/div[2]/div
37
- ```
38
-
39
- use [Locator Builder](/locators#locator-builder) to make clean semantic locator:
40
-
41
- ```js
42
- locate('[role=tab]').withText('Click Me!');
43
- ```
44
-
45
- This way you can build very flexible and stable locators even on application never designed for testing.
46
-
47
- ## Locators
48
-
49
- For React apps a special `react` locator is available. It allows to select an element by its component name, props and state.
50
-
51
- ```js
52
- { react: 'MyComponent' }
53
- { react: 'Button', props: { title: 'Click Me' }}
54
- { react: 'Button', state: { some: 'state' }}
55
- { react: 'Input', state: 'valid'}
56
- ```
57
-
58
- In WebDriver, Puppeteer, and Playwright you can use React locators in any method where locator is required:
59
-
60
- ```js
61
- I.click({ react: 'Tab', props: { title: 'Click Me!' }});
62
- I.seeElement({ react: 't', props: { title: 'Clicked' }});
63
- ```
64
-
65
- To find React element names and props in a tree use [React DevTools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) extension.
66
-
67
- > Turn off minification for application builds otherwise component names will be uglified as well
68
-
69
- - With WebDriver and Puppeteer, React locators work via [resq](https://github.com/baruchvlz/resq) library, which handles React 16 and above.
70
- - With Playwright, React locators work via [Playwright React Locator](https://playwright.dev/docs/other-locators#react-locator).
@@ -1,96 +0,0 @@
1
- let currentTest
2
- let currentSuite
3
-
4
- import Helper from '@codeceptjs/helper'
5
- import { createRequire } from 'module'
6
- import { clearString } from '../utils.js'
7
- import { testToFileName } from '../mocha/test.js'
8
-
9
- class Mochawesome extends Helper {
10
- constructor(config) {
11
- super(config)
12
-
13
- // set defaults
14
- this.options = {
15
- uniqueScreenshotNames: false,
16
- disableScreenshots: false,
17
- }
18
-
19
- // ESM-compatible require for CommonJS module
20
- const require = createRequire(import.meta.url)
21
- this._addContext = require('mochawesome/addContext')
22
-
23
- this._createConfig(config)
24
- }
25
-
26
- _createConfig(config) {
27
- // override defaults with config
28
- Object.assign(this.options, config)
29
- }
30
-
31
- _beforeSuite(suite) {
32
- currentSuite = suite
33
- currentTest = ''
34
- }
35
-
36
- _before() {
37
- if (currentSuite && currentSuite.ctx) {
38
- currentTest = { test: currentSuite.ctx.currentTest }
39
- }
40
- }
41
-
42
- _test(test) {
43
- // If this is a retried test, we want to add context to the retried test
44
- // but also potentially preserve context from the original test
45
- const originalTest = test.retriedTest && test.retriedTest()
46
- if (originalTest) {
47
- // This is a retried test - use the retried test for context
48
- currentTest = { test }
49
-
50
- // Optionally copy context from original test if it exists
51
- // Note: mochawesome context is stored in test.ctx, but we need to be careful
52
- // not to break the mocha context structure
53
- } else {
54
- // Normal test (not a retry)
55
- currentTest = { test }
56
- }
57
- }
58
-
59
- _failed(test) {
60
- if (this.options.disableScreenshots) return
61
- let fileName
62
- // Get proper name if we are fail on hook
63
- if (test.ctx?.test?.type === 'hook') {
64
- currentTest = { test: test.ctx.test }
65
- // ignore retries if we are in hook
66
- test._retries = -1
67
- fileName = clearString(`${test.title}_${currentTest.test.title}`)
68
- } else {
69
- currentTest = { test }
70
- fileName = testToFileName(test)
71
- }
72
- if (this.options.uniqueScreenshotNames) {
73
- fileName = testToFileName(test, { unique: true })
74
- }
75
- if (test._retries < 1 || test._retries === test.retryNum) {
76
- fileName = `${fileName}.failed.png`
77
- return this._addContext(currentTest, fileName)
78
- }
79
- }
80
-
81
- addMochawesomeContext(context) {
82
- if (currentTest === '') currentTest = { test: currentSuite.ctx.test }
83
-
84
- // For retried tests, make sure we're adding context to the current (retried) test
85
- // not the original test
86
- let targetTest = currentTest
87
- if (currentTest.test && currentTest.test.retriedTest && currentTest.test.retriedTest()) {
88
- // This test has been retried, make sure we're using the current test for context
89
- targetTest = { test: currentTest.test }
90
- }
91
-
92
- return this._addContext(targetTest, context)
93
- }
94
- }
95
-
96
- export default Mochawesome
@@ -1,61 +0,0 @@
1
- import fs from 'fs'
2
- import { fileURLToPath } from 'url'
3
-
4
- let resqScript
5
-
6
- async function findReact(matcher, locator) {
7
- const reactLocator = locator.locator || locator
8
- const page = typeof matcher.page === 'function' ? matcher.page() : matcher
9
-
10
- if (!resqScript) {
11
- resqScript = fs.readFileSync(fileURLToPath(import.meta.resolve('resq'))).toString()
12
- }
13
- await page.evaluate(resqScript)
14
- await page.evaluate(() => window.resq.waitToLoadReact())
15
-
16
- const arrayHandle = await page.evaluateHandle(
17
- ({ selector, props, state }) => {
18
- let elements = window.resq.resq$$(selector)
19
- if (Object.keys(props).length) elements = elements.byProps(props)
20
- if (Object.keys(state).length) elements = elements.byState(state)
21
- if (!elements.length) return []
22
-
23
- let nodes = []
24
- elements.forEach(element => {
25
- let { node, isFragment } = element
26
- if (!node) {
27
- isFragment = true
28
- node = element.children
29
- }
30
- if (isFragment) nodes = nodes.concat(node)
31
- else nodes.push(node)
32
- })
33
- return [...nodes]
34
- },
35
- {
36
- selector: reactLocator.react,
37
- props: reactLocator.props || {},
38
- state: reactLocator.state || {},
39
- },
40
- )
41
-
42
- const properties = await arrayHandle.getProperties()
43
- await arrayHandle.dispose()
44
- const result = []
45
- for (const property of properties.values()) {
46
- const elementHandle = property.asElement()
47
- if (elementHandle) result.push(elementHandle)
48
- }
49
- return result
50
- }
51
-
52
- async function findByPlaywrightLocator(matcher, locator) {
53
- const pwLocator = locator.locator || locator
54
- if (pwLocator && pwLocator.toString && pwLocator.toString().includes(process.env.testIdAttribute)) {
55
- return matcher.getByTestId(pwLocator.pw.value.split('=')[1])
56
- }
57
- const pwValue = typeof pwLocator.pw === 'string' ? pwLocator.pw : pwLocator.pw
58
- return matcher.locator(pwValue).all()
59
- }
60
-
61
- export { findReact, findByPlaywrightLocator }
@@ -1,65 +0,0 @@
1
- import fs from 'fs'
2
-
3
- let resqScript
4
-
5
- export default async function findReact(matcher, locator) {
6
- if (!resqScript) resqScript = fs.readFileSync(new URL('resq', import.meta.resolve('resq')).pathname)
7
- await matcher.evaluate(resqScript.toString())
8
- await matcher.evaluate(() => window.resq.waitToLoadReact())
9
- const arrayHandle = await matcher.evaluateHandle(
10
- obj => {
11
- const { selector, props, state } = obj
12
-
13
- let elements = window.resq.resq$$(selector)
14
- if (Object.keys(props).length) {
15
- elements = elements.byProps(props)
16
- }
17
- if (Object.keys(state).length) {
18
- elements = elements.byState(state)
19
- }
20
-
21
- if (!elements.length) {
22
- return []
23
- }
24
-
25
- // resq returns an array of HTMLElements if the React component is a fragment
26
- // this avoids having nested arrays of nodes which the driver does not understand
27
- // [[div, div], [div, div]] => [div, div, div, div]
28
- let nodes = []
29
-
30
- elements.forEach(element => {
31
- let { node, isFragment } = element
32
-
33
- if (!node) {
34
- isFragment = true
35
- node = element.children
36
- }
37
-
38
- if (isFragment) {
39
- nodes = nodes.concat(node)
40
- } else {
41
- nodes.push(node)
42
- }
43
- })
44
-
45
- return [...nodes]
46
- },
47
- {
48
- selector: locator.react,
49
- props: locator.props || {},
50
- state: locator.state || {},
51
- },
52
- )
53
-
54
- const properties = await arrayHandle.getProperties()
55
- await arrayHandle.dispose()
56
- const result = []
57
- for (const property of properties.values()) {
58
- const elementHandle = property.asElement()
59
- if (elementHandle) {
60
- result.push(elementHandle)
61
- }
62
- }
63
-
64
- return result
65
- }