codeceptjs 4.0.0-beta.1 → 4.0.0-beta.10.esm-aria

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 (207) hide show
  1. package/README.md +133 -120
  2. package/bin/codecept.js +107 -96
  3. package/bin/test-server.js +64 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/docs/webapi/click.mustache +5 -1
  6. package/lib/actor.js +71 -103
  7. package/lib/ai.js +159 -188
  8. package/lib/assert/empty.js +22 -24
  9. package/lib/assert/equal.js +30 -37
  10. package/lib/assert/error.js +14 -14
  11. package/lib/assert/include.js +43 -48
  12. package/lib/assert/throws.js +11 -11
  13. package/lib/assert/truth.js +22 -22
  14. package/lib/assert.js +20 -18
  15. package/lib/codecept.js +238 -162
  16. package/lib/colorUtils.js +50 -52
  17. package/lib/command/check.js +206 -0
  18. package/lib/command/configMigrate.js +56 -51
  19. package/lib/command/definitions.js +96 -109
  20. package/lib/command/dryRun.js +77 -79
  21. package/lib/command/generate.js +234 -194
  22. package/lib/command/gherkin/init.js +42 -33
  23. package/lib/command/gherkin/snippets.js +76 -74
  24. package/lib/command/gherkin/steps.js +20 -17
  25. package/lib/command/info.js +74 -38
  26. package/lib/command/init.js +300 -290
  27. package/lib/command/interactive.js +41 -32
  28. package/lib/command/list.js +28 -27
  29. package/lib/command/run-multiple/chunk.js +51 -48
  30. package/lib/command/run-multiple/collection.js +5 -5
  31. package/lib/command/run-multiple/run.js +5 -1
  32. package/lib/command/run-multiple.js +97 -97
  33. package/lib/command/run-rerun.js +19 -25
  34. package/lib/command/run-workers.js +68 -92
  35. package/lib/command/run.js +39 -27
  36. package/lib/command/utils.js +80 -64
  37. package/lib/command/workers/runTests.js +388 -226
  38. package/lib/config.js +124 -50
  39. package/lib/container.js +751 -260
  40. package/lib/data/context.js +60 -61
  41. package/lib/data/dataScenarioConfig.js +47 -47
  42. package/lib/data/dataTableArgument.js +32 -32
  43. package/lib/data/table.js +22 -22
  44. package/lib/effects.js +307 -0
  45. package/lib/element/WebElement.js +327 -0
  46. package/lib/els.js +160 -0
  47. package/lib/event.js +173 -163
  48. package/lib/globals.js +141 -0
  49. package/lib/heal.js +89 -85
  50. package/lib/helper/AI.js +131 -41
  51. package/lib/helper/ApiDataFactory.js +107 -75
  52. package/lib/helper/Appium.js +542 -404
  53. package/lib/helper/FileSystem.js +100 -79
  54. package/lib/helper/GraphQL.js +44 -43
  55. package/lib/helper/GraphQLDataFactory.js +52 -52
  56. package/lib/helper/JSONResponse.js +126 -88
  57. package/lib/helper/Mochawesome.js +54 -29
  58. package/lib/helper/Playwright.js +2547 -1316
  59. package/lib/helper/Puppeteer.js +1578 -1181
  60. package/lib/helper/REST.js +209 -68
  61. package/lib/helper/WebDriver.js +1482 -1342
  62. package/lib/helper/errors/ConnectionRefused.js +6 -6
  63. package/lib/helper/errors/ElementAssertion.js +11 -16
  64. package/lib/helper/errors/ElementNotFound.js +5 -9
  65. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  66. package/lib/helper/extras/Console.js +11 -11
  67. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  68. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
  71. package/lib/helper/extras/Popup.js +22 -22
  72. package/lib/helper/extras/React.js +27 -28
  73. package/lib/helper/network/actions.js +36 -42
  74. package/lib/helper/network/utils.js +78 -84
  75. package/lib/helper/scripts/blurElement.js +5 -5
  76. package/lib/helper/scripts/focusElement.js +5 -5
  77. package/lib/helper/scripts/highlightElement.js +8 -8
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -3
  80. package/lib/history.js +23 -19
  81. package/lib/hooks.js +8 -8
  82. package/lib/html.js +94 -104
  83. package/lib/index.js +38 -27
  84. package/lib/listener/config.js +30 -23
  85. package/lib/listener/emptyRun.js +54 -0
  86. package/lib/listener/enhancedGlobalRetry.js +110 -0
  87. package/lib/listener/exit.js +16 -18
  88. package/lib/listener/globalRetry.js +70 -0
  89. package/lib/listener/globalTimeout.js +181 -0
  90. package/lib/listener/helpers.js +76 -51
  91. package/lib/listener/mocha.js +10 -11
  92. package/lib/listener/result.js +11 -0
  93. package/lib/listener/retryEnhancer.js +85 -0
  94. package/lib/listener/steps.js +71 -59
  95. package/lib/listener/store.js +20 -0
  96. package/lib/locator.js +214 -197
  97. package/lib/mocha/asyncWrapper.js +274 -0
  98. package/lib/mocha/bdd.js +167 -0
  99. package/lib/mocha/cli.js +341 -0
  100. package/lib/mocha/factory.js +163 -0
  101. package/lib/mocha/featureConfig.js +89 -0
  102. package/lib/mocha/gherkin.js +231 -0
  103. package/lib/mocha/hooks.js +121 -0
  104. package/lib/mocha/index.js +21 -0
  105. package/lib/mocha/inject.js +46 -0
  106. package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
  107. package/lib/mocha/suite.js +89 -0
  108. package/lib/mocha/test.js +184 -0
  109. package/lib/mocha/types.d.ts +42 -0
  110. package/lib/mocha/ui.js +242 -0
  111. package/lib/output.js +141 -71
  112. package/lib/parser.js +47 -44
  113. package/lib/pause.js +173 -145
  114. package/lib/plugin/analyze.js +403 -0
  115. package/lib/plugin/{autoLogin.js → auth.js} +178 -79
  116. package/lib/plugin/autoDelay.js +36 -40
  117. package/lib/plugin/coverage.js +131 -78
  118. package/lib/plugin/customLocator.js +22 -21
  119. package/lib/plugin/customReporter.js +53 -0
  120. package/lib/plugin/enhancedRetryFailedStep.js +99 -0
  121. package/lib/plugin/heal.js +101 -110
  122. package/lib/plugin/htmlReporter.js +3648 -0
  123. package/lib/plugin/pageInfo.js +140 -0
  124. package/lib/plugin/pauseOnFail.js +12 -11
  125. package/lib/plugin/retryFailedStep.js +82 -47
  126. package/lib/plugin/screenshotOnFail.js +111 -92
  127. package/lib/plugin/stepByStepReport.js +159 -101
  128. package/lib/plugin/stepTimeout.js +20 -25
  129. package/lib/plugin/subtitles.js +38 -38
  130. package/lib/recorder.js +193 -130
  131. package/lib/rerun.js +94 -49
  132. package/lib/result.js +238 -0
  133. package/lib/retryCoordinator.js +207 -0
  134. package/lib/secret.js +20 -18
  135. package/lib/session.js +95 -89
  136. package/lib/step/base.js +239 -0
  137. package/lib/step/comment.js +10 -0
  138. package/lib/step/config.js +50 -0
  139. package/lib/step/func.js +46 -0
  140. package/lib/step/helper.js +50 -0
  141. package/lib/step/meta.js +99 -0
  142. package/lib/step/record.js +74 -0
  143. package/lib/step/retry.js +11 -0
  144. package/lib/step/section.js +55 -0
  145. package/lib/step.js +18 -329
  146. package/lib/steps.js +54 -0
  147. package/lib/store.js +38 -7
  148. package/lib/template/heal.js +3 -12
  149. package/lib/template/prompts/generatePageObject.js +31 -0
  150. package/lib/template/prompts/healStep.js +13 -0
  151. package/lib/template/prompts/writeStep.js +9 -0
  152. package/lib/test-server.js +334 -0
  153. package/lib/timeout.js +60 -0
  154. package/lib/transform.js +8 -8
  155. package/lib/translation.js +34 -21
  156. package/lib/utils/mask_data.js +47 -0
  157. package/lib/utils.js +411 -228
  158. package/lib/workerStorage.js +37 -34
  159. package/lib/workers.js +532 -296
  160. package/package.json +115 -95
  161. package/translations/de-DE.js +5 -3
  162. package/translations/fr-FR.js +5 -4
  163. package/translations/index.js +22 -12
  164. package/translations/it-IT.js +4 -3
  165. package/translations/ja-JP.js +4 -3
  166. package/translations/nl-NL.js +76 -0
  167. package/translations/pl-PL.js +4 -3
  168. package/translations/pt-BR.js +4 -3
  169. package/translations/ru-RU.js +4 -3
  170. package/translations/utils.js +10 -0
  171. package/translations/zh-CN.js +4 -3
  172. package/translations/zh-TW.js +4 -3
  173. package/typings/index.d.ts +546 -185
  174. package/typings/promiseBasedTypes.d.ts +150 -879
  175. package/typings/types.d.ts +547 -996
  176. package/lib/cli.js +0 -249
  177. package/lib/dirname.js +0 -5
  178. package/lib/helper/Expect.js +0 -425
  179. package/lib/helper/ExpectHelper.js +0 -399
  180. package/lib/helper/MockServer.js +0 -223
  181. package/lib/helper/Nightmare.js +0 -1411
  182. package/lib/helper/Protractor.js +0 -1835
  183. package/lib/helper/SoftExpectHelper.js +0 -381
  184. package/lib/helper/TestCafe.js +0 -1410
  185. package/lib/helper/clientscripts/nightmare.js +0 -213
  186. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  187. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  188. package/lib/interfaces/bdd.js +0 -98
  189. package/lib/interfaces/featureConfig.js +0 -69
  190. package/lib/interfaces/gherkin.js +0 -195
  191. package/lib/listener/artifacts.js +0 -19
  192. package/lib/listener/retry.js +0 -68
  193. package/lib/listener/timeout.js +0 -109
  194. package/lib/mochaFactory.js +0 -110
  195. package/lib/plugin/allure.js +0 -15
  196. package/lib/plugin/commentStep.js +0 -136
  197. package/lib/plugin/debugErrors.js +0 -67
  198. package/lib/plugin/eachElement.js +0 -127
  199. package/lib/plugin/fakerTransform.js +0 -49
  200. package/lib/plugin/retryTo.js +0 -121
  201. package/lib/plugin/selenoid.js +0 -371
  202. package/lib/plugin/standardActingHelpers.js +0 -9
  203. package/lib/plugin/tryTo.js +0 -105
  204. package/lib/plugin/wdio.js +0 -246
  205. package/lib/scenario.js +0 -222
  206. package/lib/ui.js +0 -238
  207. package/lib/within.js +0 -70
@@ -1,10 +1,10 @@
1
1
  function ConnectionRefused(err) {
2
- this.message = "Can't connect to WebDriver.\n";
3
- this.message += `${err}\n\n`;
4
- this.message += 'Please make sure Selenium Server is running and accessible';
5
- this.stack = err.stack;
2
+ this.message = "Can't connect to WebDriver.\n"
3
+ this.message += `${err}\n\n`
4
+ this.message += 'Please make sure Selenium Server is running and accessible'
5
+ this.stack = err.stack
6
6
  }
7
7
 
8
- ConnectionRefused.prototype = Object.create(Error.prototype);
8
+ ConnectionRefused.prototype = Object.create(Error.prototype)
9
9
 
10
- export default ConnectionRefused;
10
+ export default ConnectionRefused
@@ -1,38 +1,33 @@
1
- import Locator from '../../locator.js';
1
+ import Locator from '../../locator.js'
2
2
 
3
- const prefixMessage = 'Element';
3
+ const prefixMessage = 'Element'
4
4
 
5
5
  function seeElementError(locator) {
6
6
  if (typeof locator === 'object') {
7
- locator = JSON.stringify(locator);
7
+ locator = JSON.stringify(locator)
8
8
  }
9
- throw new Error(`${prefixMessage} "${(new Locator(locator))}" is still visible on page.`);
9
+ throw new Error(`${prefixMessage} "${new Locator(locator)}" is still visible on page.`)
10
10
  }
11
11
 
12
12
  function seeElementInDOMError(locator) {
13
13
  if (typeof locator === 'object') {
14
- locator = JSON.stringify(locator);
14
+ locator = JSON.stringify(locator)
15
15
  }
16
- throw new Error(`${prefixMessage} "${(new Locator(locator))}" is still seen in DOM.`);
16
+ throw new Error(`${prefixMessage} "${new Locator(locator)}" is still seen in DOM.`)
17
17
  }
18
18
 
19
19
  function dontSeeElementError(locator) {
20
20
  if (typeof locator === 'object') {
21
- locator = JSON.stringify(locator);
21
+ locator = JSON.stringify(locator)
22
22
  }
23
- throw new Error(`${prefixMessage} "${(new Locator(locator))}" is not visible on page.`);
23
+ throw new Error(`${prefixMessage} "${new Locator(locator)}" is not visible on page.`)
24
24
  }
25
25
 
26
26
  function dontSeeElementInDOMError(locator) {
27
27
  if (typeof locator === 'object') {
28
- locator = JSON.stringify(locator);
28
+ locator = JSON.stringify(locator)
29
29
  }
30
- throw new Error(`${prefixMessage} "${(new Locator(locator))}" is not seen in DOM.`);
30
+ throw new Error(`${prefixMessage} "${new Locator(locator)}" is not seen in DOM.`)
31
31
  }
32
32
 
33
- export {
34
- seeElementError,
35
- dontSeeElementError,
36
- seeElementInDOMError,
37
- dontSeeElementInDOMError,
38
- };
33
+ export { seeElementError, dontSeeElementError, seeElementInDOMError, dontSeeElementInDOMError }
@@ -1,19 +1,15 @@
1
- import Locator from '../../locator.js';
1
+ import Locator from '../../locator.js'
2
2
  /**
3
3
  * Uses to throw readable element not found error
4
4
  * Stringify object's locators
5
5
  */
6
6
  class ElementNotFound {
7
- constructor(
8
- locator,
9
- prefixMessage = 'Element',
10
- postfixMessage = 'was not found by text|CSS|XPath',
11
- ) {
7
+ constructor(locator, prefixMessage = 'Element', postfixMessage = 'was not found by text|CSS|XPath') {
12
8
  if (typeof locator === 'object') {
13
- locator = JSON.stringify(locator);
9
+ locator = JSON.stringify(locator)
14
10
  }
15
- throw new Error(`${prefixMessage} "${(new Locator(locator))}" ${postfixMessage}`);
11
+ throw new Error(`${prefixMessage} "${new Locator(locator)}" ${postfixMessage}`)
16
12
  }
17
13
  }
18
14
 
19
- export default ElementNotFound;
15
+ export default ElementNotFound
@@ -1,9 +1,9 @@
1
1
  function RemoteBrowserConnectionRefused(err) {
2
- this.message = 'Cannot connect to websocket endpoint.\n\n';
3
- this.message += 'Please make sure remote browser is running and accessible.';
4
- this.stack = err.error || err;
2
+ this.message = 'Cannot connect to websocket endpoint.\n\n'
3
+ this.message += 'Please make sure remote browser is running and accessible.'
4
+ this.stack = err.error || err
5
5
  }
6
6
 
7
- RemoteBrowserConnectionRefused.prototype = Object.create(Error.prototype);
7
+ RemoteBrowserConnectionRefused.prototype = Object.create(Error.prototype)
8
8
 
9
- export default RemoteBrowserConnectionRefused;
9
+ export default RemoteBrowserConnectionRefused
@@ -3,31 +3,31 @@
3
3
  */
4
4
  class Console {
5
5
  constructor() {
6
- this._logEntries = [];
6
+ this._logEntries = []
7
7
  }
8
8
 
9
9
  get entries() {
10
- return this._logEntries;
10
+ return this._logEntries
11
11
  }
12
12
 
13
13
  clear() {
14
- this._logEntries = [];
14
+ this._logEntries = []
15
15
  }
16
16
 
17
17
  includes(msg) {
18
- const prev = this._logEntries[this._logEntries.length - 1];
19
- if (!prev) return false;
20
- const text = msg.text && msg.text() || msg._text || '';
21
- const prevText = prev.text && prev.text() || prev._text || '';
22
- return text === prevText;
18
+ const prev = this._logEntries[this._logEntries.length - 1]
19
+ if (!prev) return false
20
+ const text = (msg.text && msg.text()) || msg._text || ''
21
+ const prevText = (prev.text && prev.text()) || prev._text || ''
22
+ return text === prevText
23
23
  }
24
24
 
25
25
  add(entry) {
26
26
  if (Array.isArray(entry)) {
27
- this._logEntries = this._logEntries.concat(entry);
27
+ this._logEntries = this._logEntries.concat(entry)
28
28
  }
29
- this._logEntries.push(entry);
29
+ this._logEntries.push(entry)
30
30
  }
31
31
  }
32
32
 
33
- export default Console;
33
+ export default Console
@@ -0,0 +1,110 @@
1
+ import Locator from '../../locator.js'
2
+
3
+ function buildLocatorString(locator) {
4
+ if (locator.isCustom()) {
5
+ return `${locator.type}=${locator.value}`
6
+ }
7
+ if (locator.isXPath()) {
8
+ return `xpath=${locator.value}`
9
+ }
10
+ return locator.simplify()
11
+ }
12
+
13
+ async function findElements(matcher, locator) {
14
+ const matchedLocator = new Locator(locator, 'css')
15
+
16
+ if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
17
+ if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
18
+ if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator)
19
+ if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator)
20
+
21
+ return matcher.locator(buildLocatorString(matchedLocator)).all()
22
+ }
23
+
24
+ async function findElement(matcher, locator) {
25
+ const matchedLocator = new Locator(locator, 'css')
26
+
27
+ if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
28
+ if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
29
+ if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator, { first: true })
30
+ if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator, { first: true })
31
+
32
+ return matcher.locator(buildLocatorString(matchedLocator)).first()
33
+ }
34
+
35
+ async function getVisibleElements(elements) {
36
+ const visibleElements = []
37
+ for (const element of elements) {
38
+ if (await element.isVisible()) {
39
+ visibleElements.push(element)
40
+ }
41
+ }
42
+ if (visibleElements.length === 0) {
43
+ return elements
44
+ }
45
+ return visibleElements
46
+ }
47
+
48
+ async function findReact(matcher, locator) {
49
+ const details = locator.locator ?? { react: locator.value }
50
+ let locatorString = `_react=${details.react}`
51
+
52
+ if (details.props) {
53
+ locatorString += propBuilder(details.props)
54
+ }
55
+
56
+ return matcher.locator(locatorString).all()
57
+ }
58
+
59
+ async function findVue(matcher, locator) {
60
+ const details = locator.locator ?? { vue: locator.value }
61
+ let locatorString = `_vue=${details.vue}`
62
+
63
+ if (details.props) {
64
+ locatorString += propBuilder(details.props)
65
+ }
66
+
67
+ return matcher.locator(locatorString).all()
68
+ }
69
+
70
+ async function findByPlaywrightLocator(matcher, locator, { first = false } = {}) {
71
+ const details = locator.locator ?? { pw: locator.value }
72
+ const locatorValue = details.pw
73
+
74
+ const handle = matcher.locator(locatorValue)
75
+ return first ? handle.first() : handle.all()
76
+ }
77
+
78
+ async function findByRole(matcher, locator, { first = false } = {}) {
79
+ const details = locator.locator ?? { role: locator.value }
80
+ const { role, text, name, exact, includeHidden, ...rest } = details
81
+ const options = { ...rest }
82
+
83
+ if (includeHidden !== undefined) options.includeHidden = includeHidden
84
+
85
+ const accessibleName = name ?? text
86
+ if (accessibleName !== undefined) {
87
+ options.name = accessibleName
88
+ if (exact === true) options.exact = true
89
+ }
90
+
91
+ const roleLocator = matcher.getByRole(role, options)
92
+ return first ? roleLocator.first() : roleLocator.all()
93
+ }
94
+
95
+ function propBuilder(props) {
96
+ let _props = ''
97
+
98
+ for (const [key, value] of Object.entries(props)) {
99
+ if (typeof value === 'object') {
100
+ for (const [k, v] of Object.entries(value)) {
101
+ _props += `[${key}.${k} = "${v}"]`
102
+ }
103
+ } else {
104
+ _props += `[${key} = "${value}"]`
105
+ }
106
+ }
107
+ return _props
108
+ }
109
+
110
+ export { buildLocatorString, findElements, findElement, getVisibleElements, findReact, findVue, findByPlaywrightLocator, findByRole }
@@ -2,54 +2,54 @@ export const createValueEngine = () => {
2
2
  return {
3
3
  // Creates a selector that matches given target when queried at the root.
4
4
  // Can return undefined if unable to create one.
5
- // eslint-disable-next-line no-unused-vars
5
+
6
6
  create(root, target) {
7
- return null;
7
+ return null
8
8
  },
9
9
 
10
10
  // Returns the first element matching given selector in the root's subtree.
11
11
  query(root, selector) {
12
12
  if (!root) {
13
- return null;
13
+ return null
14
14
  }
15
- return `${root.value}`.includes(selector) ? root : null;
15
+ return `${root.value}`.includes(selector) ? root : null
16
16
  },
17
17
 
18
18
  // Returns all elements matching given selector in the root's subtree.
19
19
  queryAll(root, selector) {
20
20
  if (!root) {
21
- return null;
21
+ return null
22
22
  }
23
- return `${root.value}`.includes(selector) ? root : null;
23
+ return `${root.value}`.includes(selector) ? root : null
24
24
  },
25
- };
26
- };
25
+ }
26
+ }
27
27
 
28
28
  export const createDisabledEngine = () => {
29
29
  return {
30
30
  // Creates a selector that matches given target when queried at the root.
31
31
  // Can return undefined if unable to create one.
32
- // eslint-disable-next-line no-unused-vars
32
+
33
33
  create(root, target) {
34
- return null;
34
+ return null
35
35
  },
36
36
 
37
37
  // Returns the first element matching given selector in the root's subtree.
38
38
  query(root, value) {
39
- const bool = value === 'true';
39
+ const bool = value === 'true'
40
40
  if (!root) {
41
- return null;
41
+ return null
42
42
  }
43
- return root.disabled === bool ? root : null;
43
+ return root.disabled === bool ? root : null
44
44
  },
45
45
 
46
46
  // Returns all elements matching given selector in the root's subtree.
47
47
  queryAll(root, value) {
48
- const bool = value === 'true';
48
+ const bool = value === 'true'
49
49
  if (!root) {
50
- return null;
50
+ return null
51
51
  }
52
- return root.disabled === bool ? root : null;
52
+ return root.disabled === bool ? root : null
53
53
  },
54
- };
55
- };
54
+ }
55
+ }
@@ -1,28 +1,37 @@
1
1
  async function findReact(matcher, locator) {
2
- let _locator = `_react=${locator.react}`;
2
+ // Handle both Locator objects and raw locator objects
3
+ const reactLocator = locator.locator || locator
4
+ let _locator = `_react=${reactLocator.react}`;
3
5
  let props = '';
4
6
 
5
- if (locator.props) {
6
- props += propBuilder(locator.props);
7
+ if (reactLocator.props) {
8
+ props += propBuilder(reactLocator.props);
7
9
  _locator += props;
8
10
  }
9
11
  return matcher.locator(_locator).all();
10
12
  }
11
13
 
12
14
  async function findVue(matcher, locator) {
13
- let _locator = `_vue=${locator.vue}`;
15
+ // Handle both Locator objects and raw locator objects
16
+ const vueLocator = locator.locator || locator
17
+ let _locator = `_vue=${vueLocator.vue}`;
14
18
  let props = '';
15
19
 
16
- if (locator.props) {
17
- props += propBuilder(locator.props);
20
+ if (vueLocator.props) {
21
+ props += propBuilder(vueLocator.props);
18
22
  _locator += props;
19
23
  }
20
24
  return matcher.locator(_locator).all();
21
25
  }
22
26
 
23
27
  async function findByPlaywrightLocator(matcher, locator) {
24
- if (locator && locator.toString().includes(process.env.testIdAttribute)) return matcher.getByTestId(locator.pw.value.split('=')[1]);
25
- return matcher.locator(locator.pw).all();
28
+ // Handle both Locator objects and raw locator objects
29
+ const pwLocator = locator.locator || locator
30
+ if (pwLocator && pwLocator.toString && pwLocator.toString().includes(process.env.testIdAttribute)) {
31
+ return matcher.getByTestId(pwLocator.pw.value.split('=')[1]);
32
+ }
33
+ const pwValue = typeof pwLocator.pw === 'string' ? pwLocator.pw : pwLocator.pw
34
+ return matcher.locator(pwValue).all();
26
35
  }
27
36
 
28
37
  function propBuilder(props) {
@@ -1,30 +1,44 @@
1
1
  const RESTART_OPTS = {
2
2
  session: 'keep',
3
- browser: true,
4
3
  context: false,
5
- };
4
+ browser: true,
5
+ }
6
6
 
7
- let restarts = null;
7
+ let restarts = null
8
8
 
9
9
  export function setRestartStrategy(options) {
10
- const { restart } = options;
11
- const stringOpts = Object.keys(RESTART_OPTS);
10
+ const { restart } = options
11
+ const stringOpts = Object.keys(RESTART_OPTS)
12
12
 
13
13
  if (stringOpts.includes(restart)) {
14
- return restarts = restart;
14
+ return (restarts = restart)
15
15
  }
16
16
 
17
- restarts = Object.keys(RESTART_OPTS).find(key => RESTART_OPTS[key] === restart);
17
+ // When restart is false, don't restart anything
18
+ if (restart === false) {
19
+ restarts = null
20
+ return
21
+ }
18
22
 
19
- if (restarts === null || restarts === undefined) throw new Error('No restart strategy set, use the following values for restart: session, context, browser');
23
+ // When restart is true, map to 'browser' restart
24
+ if (restart === true) {
25
+ restarts = 'browser'
26
+ return
27
+ }
28
+
29
+ restarts = Object.keys(RESTART_OPTS).find(key => RESTART_OPTS[key] === restart)
30
+
31
+ if (restarts === null || restarts === undefined) throw new Error('No restart strategy set, use the following values for restart: session, context, browser')
20
32
  }
21
33
 
22
34
  export function restartsSession() {
23
- return restarts === 'session';
35
+ return restarts === 'session'
24
36
  }
37
+
25
38
  export function restartsContext() {
26
- return restarts === 'context';
39
+ return restarts === 'context'
27
40
  }
41
+
28
42
  export function restartsBrowser() {
29
- return restarts === 'browser';
43
+ return restarts === 'browser'
30
44
  }
@@ -2,66 +2,66 @@
2
2
  * Class to handle the interaction with the Dialog (Popup) Class from Puppeteer
3
3
  */
4
4
  class Popup {
5
- constructor(popup, defaultAction) {
6
- this._popup = popup || null;
7
- this._actionType = '';
8
- this._defaultAction = defaultAction || '';
5
+ constructor(popup = null, defaultAction = '') {
6
+ this._popup = popup
7
+ this._actionType = ''
8
+ this._defaultAction = defaultAction
9
9
  }
10
10
 
11
11
  _assertValidActionType(action) {
12
12
  if (['accept', 'cancel'].indexOf(action) === -1) {
13
- throw new Error('Invalid Popup action type. Only "accept" or "cancel" actions are accepted');
13
+ throw new Error('Invalid Popup action type. Only "accept" or "cancel" actions are accepted')
14
14
  }
15
15
  }
16
16
 
17
17
  set defaultAction(action) {
18
- this._assertValidActionType(action);
19
- this._defaultAction = action;
18
+ this._assertValidActionType(action)
19
+ this._defaultAction = action
20
20
  }
21
21
 
22
22
  get defaultAction() {
23
- return this._defaultAction;
23
+ return this._defaultAction
24
24
  }
25
25
 
26
26
  get popup() {
27
- return this._popup;
27
+ return this._popup
28
28
  }
29
29
 
30
30
  set popup(popup) {
31
31
  if (this._popup) {
32
- console.error('Popup already exists and was not closed. Popups must always be closed by calling either I.acceptPopup() or I.cancelPopup()');
32
+ return
33
33
  }
34
- this._popup = popup;
34
+ this._popup = popup
35
35
  }
36
36
 
37
37
  get actionType() {
38
- return this._actionType;
38
+ return this._actionType
39
39
  }
40
40
 
41
41
  set actionType(action) {
42
- this._assertValidActionType(action);
43
- this._actionType = action;
42
+ this._assertValidActionType(action)
43
+ this._actionType = action
44
44
  }
45
45
 
46
46
  clear() {
47
- this._popup = null;
48
- this._actionType = '';
47
+ this._popup = null
48
+ this._actionType = ''
49
49
  }
50
50
 
51
51
  assertPopupVisible() {
52
52
  if (!this._popup) {
53
- throw new Error('There is no Popup visible');
53
+ throw new Error('There is no Popup visible')
54
54
  }
55
55
  }
56
56
 
57
57
  assertPopupActionType(type) {
58
- this.assertPopupVisible();
59
- const expectedAction = this._actionType || this._defaultAction;
58
+ this.assertPopupVisible()
59
+ const expectedAction = this._actionType || this._defaultAction
60
60
  if (expectedAction !== type) {
61
- throw new Error(`Popup action does not fit the expected action type. Expected popup action to be '${expectedAction}' not '${type}`);
61
+ throw new Error(`Popup action does not fit the expected action type. Expected popup action to be '${expectedAction}' not '${type}`)
62
62
  }
63
- this.clear();
63
+ this.clear()
64
64
  }
65
65
  }
66
66
 
67
- export default Popup;
67
+ export default Popup
@@ -1,66 +1,65 @@
1
- import fs from 'fs';
1
+ import fs from 'fs'
2
2
 
3
- let resqScript;
3
+ let resqScript
4
4
 
5
5
  export default async function findReact(matcher, locator) {
6
- if (!resqScript) resqScript = fs.readFileSync(require.resolve('resq'));
7
- await matcher.evaluate(resqScript.toString());
8
- await matcher
9
- .evaluate(() => window.resq.waitToLoadReact());
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())
10
9
  const arrayHandle = await matcher.evaluateHandle(
11
- (obj) => {
12
- const { selector, props, state } = obj;
10
+ obj => {
11
+ const { selector, props, state } = obj
13
12
 
14
- let elements = window.resq.resq$$(selector);
13
+ let elements = window.resq.resq$$(selector)
15
14
  if (Object.keys(props).length) {
16
- elements = elements.byProps(props);
15
+ elements = elements.byProps(props)
17
16
  }
18
17
  if (Object.keys(state).length) {
19
- elements = elements.byState(state);
18
+ elements = elements.byState(state)
20
19
  }
21
20
 
22
21
  if (!elements.length) {
23
- return [];
22
+ return []
24
23
  }
25
24
 
26
25
  // resq returns an array of HTMLElements if the React component is a fragment
27
26
  // this avoids having nested arrays of nodes which the driver does not understand
28
27
  // [[div, div], [div, div]] => [div, div, div, div]
29
- let nodes = [];
28
+ let nodes = []
30
29
 
31
- elements.forEach((element) => {
32
- let { node, isFragment } = element;
30
+ elements.forEach(element => {
31
+ let { node, isFragment } = element
33
32
 
34
33
  if (!node) {
35
- isFragment = true;
36
- node = element.children;
34
+ isFragment = true
35
+ node = element.children
37
36
  }
38
37
 
39
38
  if (isFragment) {
40
- nodes = nodes.concat(node);
39
+ nodes = nodes.concat(node)
41
40
  } else {
42
- nodes.push(node);
41
+ nodes.push(node)
43
42
  }
44
- });
43
+ })
45
44
 
46
- return [...nodes];
45
+ return [...nodes]
47
46
  },
48
47
  {
49
48
  selector: locator.react,
50
49
  props: locator.props || {},
51
50
  state: locator.state || {},
52
51
  },
53
- );
52
+ )
54
53
 
55
- const properties = await arrayHandle.getProperties();
56
- await arrayHandle.dispose();
57
- const result = [];
54
+ const properties = await arrayHandle.getProperties()
55
+ await arrayHandle.dispose()
56
+ const result = []
58
57
  for (const property of properties.values()) {
59
- const elementHandle = property.asElement();
58
+ const elementHandle = property.asElement()
60
59
  if (elementHandle) {
61
- result.push(elementHandle);
60
+ result.push(elementHandle)
62
61
  }
63
62
  }
64
63
 
65
- return result;
64
+ return result
66
65
  }