codeceptjs 4.0.0-beta.2 → 4.0.0-beta.3

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 (151) hide show
  1. package/bin/codecept.js +84 -81
  2. package/lib/actor.js +13 -13
  3. package/lib/ai.js +10 -13
  4. package/lib/assert/empty.js +20 -21
  5. package/lib/assert/equal.js +37 -39
  6. package/lib/assert/error.js +14 -14
  7. package/lib/assert/include.js +46 -47
  8. package/lib/assert/throws.js +13 -11
  9. package/lib/assert/truth.js +19 -22
  10. package/lib/assert.js +4 -2
  11. package/lib/cli.js +57 -49
  12. package/lib/codecept.js +142 -155
  13. package/lib/colorUtils.js +3 -3
  14. package/lib/command/configMigrate.js +58 -52
  15. package/lib/command/definitions.js +88 -89
  16. package/lib/command/dryRun.js +71 -68
  17. package/lib/command/generate.js +197 -188
  18. package/lib/command/gherkin/init.js +27 -16
  19. package/lib/command/gherkin/snippets.js +20 -20
  20. package/lib/command/gherkin/steps.js +8 -8
  21. package/lib/command/info.js +40 -38
  22. package/lib/command/init.js +290 -288
  23. package/lib/command/interactive.js +32 -32
  24. package/lib/command/list.js +26 -26
  25. package/lib/command/run-multiple/chunk.js +5 -5
  26. package/lib/command/run-multiple/collection.js +3 -3
  27. package/lib/command/run-multiple/run.js +6 -2
  28. package/lib/command/run-multiple.js +113 -93
  29. package/lib/command/run-rerun.js +20 -25
  30. package/lib/command/run-workers.js +64 -66
  31. package/lib/command/run.js +26 -29
  32. package/lib/command/utils.js +80 -65
  33. package/lib/command/workers/runTests.js +10 -10
  34. package/lib/config.js +10 -9
  35. package/lib/container.js +40 -48
  36. package/lib/data/context.js +60 -59
  37. package/lib/data/dataScenarioConfig.js +47 -47
  38. package/lib/data/dataTableArgument.js +29 -29
  39. package/lib/data/table.js +26 -20
  40. package/lib/event.js +163 -167
  41. package/lib/heal.js +13 -17
  42. package/lib/helper/AI.js +130 -41
  43. package/lib/helper/ApiDataFactory.js +73 -69
  44. package/lib/helper/Appium.js +413 -382
  45. package/lib/helper/ExpectHelper.js +40 -48
  46. package/lib/helper/FileSystem.js +80 -79
  47. package/lib/helper/GraphQL.js +44 -43
  48. package/lib/helper/GraphQLDataFactory.js +50 -50
  49. package/lib/helper/JSONResponse.js +65 -62
  50. package/lib/helper/Mochawesome.js +28 -28
  51. package/lib/helper/MockServer.js +12 -14
  52. package/lib/helper/Nightmare.js +662 -566
  53. package/lib/helper/Playwright.js +1361 -1216
  54. package/lib/helper/Protractor.js +663 -627
  55. package/lib/helper/Puppeteer.js +1231 -1128
  56. package/lib/helper/REST.js +159 -68
  57. package/lib/helper/SoftExpectHelper.js +2 -2
  58. package/lib/helper/TestCafe.js +490 -484
  59. package/lib/helper/WebDriver.js +1297 -1156
  60. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  61. package/lib/helper/errors/ConnectionRefused.js +1 -1
  62. package/lib/helper/errors/ElementAssertion.js +2 -2
  63. package/lib/helper/errors/ElementNotFound.js +2 -2
  64. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
  65. package/lib/helper/extras/Console.js +1 -1
  66. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  67. package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
  68. package/lib/helper/extras/PlaywrightRestartOpts.js +21 -18
  69. package/lib/helper/extras/Popup.js +1 -1
  70. package/lib/helper/extras/React.js +3 -3
  71. package/lib/helper/network/actions.js +14 -7
  72. package/lib/helper/network/utils.js +3 -2
  73. package/lib/helper/scripts/blurElement.js +1 -1
  74. package/lib/helper/scripts/focusElement.js +1 -1
  75. package/lib/helper/scripts/highlightElement.js +1 -1
  76. package/lib/helper/scripts/isElementClickable.js +1 -1
  77. package/lib/helper/testcafe/testControllerHolder.js +1 -1
  78. package/lib/helper/testcafe/testcafe-utils.js +6 -7
  79. package/lib/helper.js +1 -3
  80. package/lib/history.js +6 -5
  81. package/lib/hooks.js +6 -6
  82. package/lib/html.js +7 -7
  83. package/lib/index.js +25 -41
  84. package/lib/interfaces/bdd.js +47 -64
  85. package/lib/interfaces/featureConfig.js +19 -19
  86. package/lib/interfaces/gherkin.js +124 -118
  87. package/lib/interfaces/scenarioConfig.js +29 -29
  88. package/lib/listener/artifacts.js +9 -9
  89. package/lib/listener/config.js +24 -24
  90. package/lib/listener/exit.js +12 -12
  91. package/lib/listener/helpers.js +42 -42
  92. package/lib/listener/mocha.js +11 -11
  93. package/lib/listener/retry.js +32 -30
  94. package/lib/listener/steps.js +50 -53
  95. package/lib/listener/timeout.js +54 -54
  96. package/lib/locator.js +6 -10
  97. package/lib/mochaFactory.js +18 -15
  98. package/lib/output.js +6 -10
  99. package/lib/parser.js +15 -12
  100. package/lib/pause.js +40 -33
  101. package/lib/plugin/allure.js +15 -15
  102. package/lib/plugin/autoDelay.js +29 -37
  103. package/lib/plugin/autoLogin.js +70 -65
  104. package/lib/plugin/commentStep.js +18 -18
  105. package/lib/plugin/coverage.js +115 -67
  106. package/lib/plugin/customLocator.js +21 -20
  107. package/lib/plugin/debugErrors.js +24 -24
  108. package/lib/plugin/eachElement.js +38 -38
  109. package/lib/plugin/fakerTransform.js +6 -6
  110. package/lib/plugin/heal.js +67 -108
  111. package/lib/plugin/pauseOnFail.js +11 -11
  112. package/lib/plugin/retryFailedStep.js +32 -39
  113. package/lib/plugin/retryTo.js +46 -40
  114. package/lib/plugin/screenshotOnFail.js +109 -87
  115. package/lib/plugin/selenoid.js +131 -118
  116. package/lib/plugin/standardActingHelpers.js +2 -8
  117. package/lib/plugin/stepByStepReport.js +110 -91
  118. package/lib/plugin/stepTimeout.js +24 -23
  119. package/lib/plugin/subtitles.js +34 -35
  120. package/lib/plugin/tryTo.js +40 -30
  121. package/lib/plugin/wdio.js +78 -75
  122. package/lib/recorder.js +14 -17
  123. package/lib/rerun.js +11 -10
  124. package/lib/scenario.js +25 -23
  125. package/lib/secret.js +4 -2
  126. package/lib/session.js +10 -10
  127. package/lib/step.js +12 -9
  128. package/lib/store.js +2 -3
  129. package/lib/transform.js +1 -1
  130. package/lib/translation.js +7 -8
  131. package/lib/ui.js +12 -14
  132. package/lib/utils.js +70 -72
  133. package/lib/within.js +10 -10
  134. package/lib/workerStorage.js +27 -25
  135. package/lib/workers.js +29 -32
  136. package/package.json +56 -57
  137. package/translations/de-DE.js +1 -1
  138. package/translations/fr-FR.js +1 -1
  139. package/translations/index.js +9 -13
  140. package/translations/it-IT.js +1 -1
  141. package/translations/ja-JP.js +1 -1
  142. package/translations/pl-PL.js +1 -1
  143. package/translations/pt-BR.js +1 -1
  144. package/translations/ru-RU.js +1 -1
  145. package/translations/zh-CN.js +1 -1
  146. package/translations/zh-TW.js +1 -1
  147. package/typings/index.d.ts +415 -65
  148. package/typings/promiseBasedTypes.d.ts +32 -0
  149. package/typings/types.d.ts +32 -0
  150. package/lib/dirname.js +0 -5
  151. package/lib/helper/Expect.js +0 -425
@@ -1,25 +1,24 @@
1
- import path from 'path';
1
+ const path = require('path')
2
2
 
3
- import { resolve as urlResolve } from 'url';
3
+ const urlResolve = require('url').resolve
4
4
 
5
- import Helper from '@codeceptjs/helper';
6
- import { includes as stringIncludes } from '../assert/include.js';
7
- import { urlEquals, equals } from '../assert/equal.js';
8
- import empty from '../assert/empty.js';
9
- import { truth } from '../assert/truth';
10
- import Locator from '../locator.js';
11
- import ElementNotFound from './errors/ElementNotFound.js';
12
- import {
13
- xpathLocator, fileExists, screenshotOutputFolder, toCamelCase,
14
- } from '../utils.js';
5
+ const Helper = require('@codeceptjs/helper')
6
+ const { includes: stringIncludes } = require('../assert/include')
7
+ const { urlEquals } = require('../assert/equal')
8
+ const { equals } = require('../assert/equal')
9
+ const { empty } = require('../assert/empty')
10
+ const { truth } = require('../assert/truth')
11
+ const Locator = require('../locator')
12
+ const ElementNotFound = require('./errors/ElementNotFound')
13
+ const { xpathLocator, fileExists, screenshotOutputFolder, toCamelCase } = require('../utils')
15
14
 
16
15
  const specialKeys = {
17
16
  Backspace: '\u0008',
18
17
  Enter: '\u000d',
19
18
  Delete: '\u007f',
20
- };
19
+ }
21
20
 
22
- let withinStatus = false;
21
+ let withinStatus = false
23
22
 
24
23
  /**
25
24
  * Nightmare helper wraps [Nightmare](https://github.com/segmentio/nightmare) library to provide
@@ -50,12 +49,12 @@ let withinStatus = false;
50
49
  */
51
50
  class Nightmare extends Helper {
52
51
  constructor(config) {
53
- super(config);
52
+ super(config)
54
53
 
55
- this.isRunning = false;
54
+ this.isRunning = false
56
55
 
57
56
  // override defaults with config
58
- this._setConfig(config);
57
+ this._setConfig(config)
59
58
  }
60
59
 
61
60
  _validateConfig(config) {
@@ -71,235 +70,268 @@ class Nightmare extends Helper {
71
70
  keepCookies: false,
72
71
  js_errors: null,
73
72
  enableHAR: false,
74
- };
73
+ }
75
74
 
76
- return Object.assign(defaults, config);
75
+ return Object.assign(defaults, config)
77
76
  }
78
77
 
79
78
  static _config() {
80
79
  return [
81
80
  { name: 'url', message: 'Base url of site to be tested', default: 'http://localhost' },
82
81
  {
83
- name: 'show', message: 'Show browser window', default: true, type: 'confirm',
82
+ name: 'show',
83
+ message: 'Show browser window',
84
+ default: true,
85
+ type: 'confirm',
84
86
  },
85
- ];
87
+ ]
86
88
  }
87
89
 
88
90
  static _checkRequirements() {
89
91
  try {
90
- require('nightmare');
92
+ require('nightmare')
91
93
  } catch (e) {
92
- return ['nightmare'];
94
+ return ['nightmare']
93
95
  }
94
96
  }
95
97
 
96
98
  async _init() {
97
- this.Nightmare = require('nightmare');
99
+ this.Nightmare = require('nightmare')
98
100
 
99
101
  if (this.options.enableHAR) {
100
- require('nightmare-har-plugin').install(this.Nightmare);
102
+ require('nightmare-har-plugin').install(this.Nightmare)
101
103
  }
102
104
 
103
105
  this.Nightmare.action('findElements', function (locator, contextEl, done) {
104
106
  if (!done) {
105
- done = contextEl;
106
- contextEl = null;
107
+ done = contextEl
108
+ contextEl = null
107
109
  }
108
110
 
109
- const by = Object.keys(locator)[0];
110
- const value = locator[by];
111
+ const by = Object.keys(locator)[0]
112
+ const value = locator[by]
111
113
 
112
- this.evaluate_now((by, locator, contextEl) => window.codeceptjs.findAndStoreElements(by, locator, contextEl), done, by, value, contextEl);
113
- });
114
+ this.evaluate_now(
115
+ (by, locator, contextEl) => window.codeceptjs.findAndStoreElements(by, locator, contextEl),
116
+ done,
117
+ by,
118
+ value,
119
+ contextEl,
120
+ )
121
+ })
114
122
 
115
123
  this.Nightmare.action('findElement', function (locator, contextEl, done) {
116
124
  if (!done) {
117
- done = contextEl;
118
- contextEl = null;
125
+ done = contextEl
126
+ contextEl = null
119
127
  }
120
128
 
121
- const by = Object.keys(locator)[0];
122
- const value = locator[by];
129
+ const by = Object.keys(locator)[0]
130
+ const value = locator[by]
123
131
 
124
- this.evaluate_now((by, locator, contextEl) => {
125
- const res = window.codeceptjs.findAndStoreElement(by, locator, contextEl);
126
- if (res === null) {
127
- throw new Error(`Element ${(new Locator(locator))} couldn't be located by ${by}`);
128
- }
129
- return res;
130
- }, done, by, value, contextEl);
131
- });
132
+ this.evaluate_now(
133
+ (by, locator, contextEl) => {
134
+ const res = window.codeceptjs.findAndStoreElement(by, locator, contextEl)
135
+ if (res === null) {
136
+ throw new Error(`Element ${new Locator(locator)} couldn't be located by ${by}`)
137
+ }
138
+ return res
139
+ },
140
+ done,
141
+ by,
142
+ value,
143
+ contextEl,
144
+ )
145
+ })
132
146
 
133
147
  this.Nightmare.action('asyncScript', function () {
134
- let args = Array.prototype.slice.call(arguments);
135
- const done = args.pop();
136
- args = args.splice(1, 0, done);
137
- this.evaluate_now.apply(this, args);
138
- });
148
+ let args = Array.prototype.slice.call(arguments)
149
+ const done = args.pop()
150
+ args = args.splice(1, 0, done)
151
+ this.evaluate_now.apply(this, args)
152
+ })
139
153
 
140
154
  this.Nightmare.action('enterText', function (el, text, clean, done) {
141
- const child = this.child;
142
- const typeFn = () => child.call('type', text, done);
143
-
144
- this.evaluate_now((el, clean) => {
145
- const element = window.codeceptjs.fetchElement(el);
146
- if (clean) element.value = '';
147
- element.focus();
148
- }, () => {
149
- if (clean) return typeFn();
150
- child.call('pressKey', 'End', typeFn); // type End before
151
- }, el, clean);
152
- });
153
-
154
- this.Nightmare.action('pressKey', (ns, options, parent, win, renderer, done) => {
155
- parent.respondTo('pressKey', (ch, done) => {
156
- win.webContents.sendInputEvent({
157
- type: 'keyDown',
158
- keyCode: ch,
159
- });
160
-
161
- win.webContents.sendInputEvent({
162
- type: 'char',
163
- keyCode: ch,
164
- });
165
-
166
- win.webContents.sendInputEvent({
167
- type: 'keyUp',
168
- keyCode: ch,
169
- });
170
- done();
171
- });
172
- done();
173
- }, function (key, done) {
174
- this.child.call('pressKey', key, done);
175
- });
176
-
177
- this.Nightmare.action('triggerMouseEvent', (ns, options, parent, win, renderer, done) => {
178
- parent.respondTo('triggerMouseEvent', (evt, done) => {
179
- win.webContents.sendInputEvent(evt);
180
- done();
181
- });
182
- done();
183
- }, function (event, done) {
184
- this.child.call('triggerMouseEvent', event, done);
185
- });
155
+ const child = this.child
156
+ const typeFn = () => child.call('type', text, done)
157
+
158
+ this.evaluate_now(
159
+ (el, clean) => {
160
+ const element = window.codeceptjs.fetchElement(el)
161
+ if (clean) element.value = ''
162
+ element.focus()
163
+ },
164
+ () => {
165
+ if (clean) return typeFn()
166
+ child.call('pressKey', 'End', typeFn) // type End before
167
+ },
168
+ el,
169
+ clean,
170
+ )
171
+ })
172
+
173
+ this.Nightmare.action(
174
+ 'pressKey',
175
+ (ns, options, parent, win, renderer, done) => {
176
+ parent.respondTo('pressKey', (ch, done) => {
177
+ win.webContents.sendInputEvent({
178
+ type: 'keyDown',
179
+ keyCode: ch,
180
+ })
181
+
182
+ win.webContents.sendInputEvent({
183
+ type: 'char',
184
+ keyCode: ch,
185
+ })
186
+
187
+ win.webContents.sendInputEvent({
188
+ type: 'keyUp',
189
+ keyCode: ch,
190
+ })
191
+ done()
192
+ })
193
+ done()
194
+ },
195
+ function (key, done) {
196
+ this.child.call('pressKey', key, done)
197
+ },
198
+ )
199
+
200
+ this.Nightmare.action(
201
+ 'triggerMouseEvent',
202
+ (ns, options, parent, win, renderer, done) => {
203
+ parent.respondTo('triggerMouseEvent', (evt, done) => {
204
+ win.webContents.sendInputEvent(evt)
205
+ done()
206
+ })
207
+ done()
208
+ },
209
+ function (event, done) {
210
+ this.child.call('triggerMouseEvent', event, done)
211
+ },
212
+ )
186
213
 
187
214
  this.Nightmare.action(
188
215
  'upload',
189
216
  (ns, options, parent, win, renderer, done) => {
190
217
  parent.respondTo('upload', (selector, pathsToUpload, done) => {
191
- parent.emit('log', 'paths', pathsToUpload);
218
+ parent.emit('log', 'paths', pathsToUpload)
192
219
  try {
193
- // attach the debugger
194
- // NOTE: this will fail if devtools is open
195
- win.webContents.debugger.attach('1.1');
220
+ // attach the debugger
221
+ // NOTE: this will fail if devtools is open
222
+ win.webContents.debugger.attach('1.1')
196
223
  } catch (e) {
197
- parent.emit('log', 'problem attaching', e);
198
- return done(e);
224
+ parent.emit('log', 'problem attaching', e)
225
+ return done(e)
199
226
  }
200
227
 
201
228
  win.webContents.debugger.sendCommand('DOM.getDocument', {}, (err, domDocument) => {
202
- win.webContents.debugger.sendCommand('DOM.querySelector', {
203
- nodeId: domDocument.root.nodeId,
204
- selector,
205
- }, (err, queryResult) => {
206
- // HACK: chromium errors appear to be unpopulated objects?
207
- if (Object.keys(err)
208
- .length > 0) {
209
- parent.emit('log', 'problem selecting', err);
210
- return done(err);
211
- }
212
- win.webContents.debugger.sendCommand('DOM.setFileInputFiles', {
213
- nodeId: queryResult.nodeId,
214
- files: pathsToUpload,
215
- }, (err) => {
216
- if (Object.keys(err)
217
- .length > 0) {
218
- parent.emit('log', 'problem setting input', err);
219
- return done(err);
229
+ win.webContents.debugger.sendCommand(
230
+ 'DOM.querySelector',
231
+ {
232
+ nodeId: domDocument.root.nodeId,
233
+ selector,
234
+ },
235
+ (err, queryResult) => {
236
+ // HACK: chromium errors appear to be unpopulated objects?
237
+ if (Object.keys(err).length > 0) {
238
+ parent.emit('log', 'problem selecting', err)
239
+ return done(err)
220
240
  }
221
- win.webContents.debugger.detach();
222
- done(null, pathsToUpload);
223
- });
224
- });
225
- });
226
- });
227
- done();
241
+ win.webContents.debugger.sendCommand(
242
+ 'DOM.setFileInputFiles',
243
+ {
244
+ nodeId: queryResult.nodeId,
245
+ files: pathsToUpload,
246
+ },
247
+ (err) => {
248
+ if (Object.keys(err).length > 0) {
249
+ parent.emit('log', 'problem setting input', err)
250
+ return done(err)
251
+ }
252
+ win.webContents.debugger.detach()
253
+ done(null, pathsToUpload)
254
+ },
255
+ )
256
+ },
257
+ )
258
+ })
259
+ })
260
+ done()
228
261
  },
229
262
  function (selector, pathsToUpload, done) {
230
263
  if (!Array.isArray(pathsToUpload)) {
231
- pathsToUpload = [pathsToUpload];
264
+ pathsToUpload = [pathsToUpload]
232
265
  }
233
266
  this.child.call('upload', selector, pathsToUpload, (err, stuff) => {
234
- done(err, stuff);
235
- });
267
+ done(err, stuff)
268
+ })
236
269
  },
237
- );
270
+ )
238
271
 
239
- return Promise.resolve();
272
+ return Promise.resolve()
240
273
  }
241
274
 
242
275
  async _beforeSuite() {
243
276
  if (!this.options.restart && !this.isRunning) {
244
- this.debugSection('Session', 'Starting singleton browser session');
245
- return this._startBrowser();
277
+ this.debugSection('Session', 'Starting singleton browser session')
278
+ return this._startBrowser()
246
279
  }
247
280
  }
248
281
 
249
282
  async _before() {
250
- if (this.options.restart) return this._startBrowser();
251
- if (!this.isRunning) return this._startBrowser();
252
- return this.browser;
283
+ if (this.options.restart) return this._startBrowser()
284
+ if (!this.isRunning) return this._startBrowser()
285
+ return this.browser
253
286
  }
254
287
 
255
288
  async _after() {
256
- if (!this.isRunning) return;
289
+ if (!this.isRunning) return
257
290
  if (this.options.restart) {
258
- this.isRunning = false;
259
- return this._stopBrowser();
291
+ this.isRunning = false
292
+ return this._stopBrowser()
260
293
  }
261
294
  if (this.options.enableHAR) {
262
- await this.browser.resetHAR();
295
+ await this.browser.resetHAR()
263
296
  }
264
- if (this.options.keepBrowserState) return;
297
+ if (this.options.keepBrowserState) return
265
298
  if (this.options.keepCookies) {
266
- await this.browser.cookies.clearAll();
299
+ await this.browser.cookies.clearAll()
267
300
  }
268
- this.debugSection('Session', 'cleaning up');
269
- return this.executeScript(() => localStorage.clear());
301
+ this.debugSection('Session', 'cleaning up')
302
+ return this.executeScript(() => localStorage.clear())
270
303
  }
271
304
 
272
- _afterSuite() {
273
- }
305
+ _afterSuite() {}
274
306
 
275
307
  _finishTest() {
276
308
  if (!this.options.restart && this.isRunning) {
277
- this._stopBrowser();
309
+ this._stopBrowser()
278
310
  }
279
311
  }
280
312
 
281
313
  async _startBrowser() {
282
- this.context = this.options.rootElement;
314
+ this.context = this.options.rootElement
283
315
  if (this.options.enableHAR) {
284
- this.browser = this.Nightmare(Object.assign(require('nightmare-har-plugin').getDevtoolsOptions(), this.options));
285
- await this.browser;
286
- await this.browser.waitForDevtools();
316
+ this.browser = this.Nightmare(Object.assign(require('nightmare-har-plugin').getDevtoolsOptions(), this.options))
317
+ await this.browser
318
+ await this.browser.waitForDevtools()
287
319
  } else {
288
- this.browser = this.Nightmare(this.options);
289
- await this.browser;
320
+ this.browser = this.Nightmare(this.options)
321
+ await this.browser
290
322
  }
291
- await this.browser.goto('about:blank'); // Load a blank page so .saveScreenshot (/evaluate) will work
292
- this.isRunning = true;
293
- this.browser.on('dom-ready', () => this._injectClientScripts());
294
- this.browser.on('did-start-loading', () => this._injectClientScripts());
295
- this.browser.on('will-navigate', () => this._injectClientScripts());
323
+ await this.browser.goto('about:blank') // Load a blank page so .saveScreenshot (/evaluate) will work
324
+ this.isRunning = true
325
+ this.browser.on('dom-ready', () => this._injectClientScripts())
326
+ this.browser.on('did-start-loading', () => this._injectClientScripts())
327
+ this.browser.on('will-navigate', () => this._injectClientScripts())
296
328
  this.browser.on('console', (type, message) => {
297
- this.debug(`${type}: ${message}`);
298
- });
329
+ this.debug(`${type}: ${message}`)
330
+ })
299
331
 
300
332
  if (this.options.windowSize) {
301
- const size = this.options.windowSize.split('x');
302
- return this.browser.viewport(parseInt(size[0], 10), parseInt(size[1], 10));
333
+ const size = this.options.windowSize.split('x')
334
+ return this.browser.viewport(parseInt(size[0], 10), parseInt(size[1], 10))
303
335
  }
304
336
  }
305
337
 
@@ -312,45 +344,49 @@ class Nightmare extends Helper {
312
344
  * ```
313
345
  */
314
346
  async grabHAR() {
315
- return this.browser.getHAR();
347
+ return this.browser.getHAR()
316
348
  }
317
349
 
318
350
  async saveHAR(fileName) {
319
- const outputFile = path.join(global.output_dir, fileName);
320
- this.debug(`HAR is saving to ${outputFile}`);
351
+ const outputFile = path.join(global.output_dir, fileName)
352
+ this.debug(`HAR is saving to ${outputFile}`)
321
353
 
322
354
  await this.browser.getHAR().then((har) => {
323
- require('fs').writeFileSync(outputFile, JSON.stringify({ log: har }));
324
- });
355
+ require('fs').writeFileSync(outputFile, JSON.stringify({ log: har }))
356
+ })
325
357
  }
326
358
 
327
359
  async resetHAR() {
328
- await this.browser.resetHAR();
360
+ await this.browser.resetHAR()
329
361
  }
330
362
 
331
363
  async _stopBrowser() {
332
364
  return this.browser.end().catch((error) => {
333
- this.debugSection('Error on End', error);
334
- });
365
+ this.debugSection('Error on End', error)
366
+ })
335
367
  }
336
368
 
337
369
  async _withinBegin(locator) {
338
- this.context = locator;
339
- locator = new Locator(locator, 'css');
340
- withinStatus = true;
341
- return this.browser.evaluate((by, locator) => {
342
- const el = window.codeceptjs.findElement(by, locator);
343
- if (!el) throw new Error(`Element by ${by}: ${locator} not found`);
344
- window.codeceptjs.within = el;
345
- }, locator.type, locator.value);
370
+ this.context = locator
371
+ locator = new Locator(locator, 'css')
372
+ withinStatus = true
373
+ return this.browser.evaluate(
374
+ (by, locator) => {
375
+ const el = window.codeceptjs.findElement(by, locator)
376
+ if (!el) throw new Error(`Element by ${by}: ${locator} not found`)
377
+ window.codeceptjs.within = el
378
+ },
379
+ locator.type,
380
+ locator.value,
381
+ )
346
382
  }
347
383
 
348
384
  _withinEnd() {
349
- this.context = this.options.rootElement;
350
- withinStatus = false;
385
+ this.context = this.options.rootElement
386
+ withinStatus = false
351
387
  return this.browser.evaluate(() => {
352
- window.codeceptjs.within = null;
353
- });
388
+ window.codeceptjs.within = null
389
+ })
354
390
  }
355
391
 
356
392
  /**
@@ -373,10 +409,14 @@ class Nightmare extends Helper {
373
409
  * ```
374
410
  */
375
411
  _locate(locator) {
376
- locator = new Locator(locator, 'css');
377
- return this.browser.evaluate((by, locator) => {
378
- return window.codeceptjs.findAndStoreElements(by, locator);
379
- }, locator.type, locator.value);
412
+ locator = new Locator(locator, 'css')
413
+ return this.browser.evaluate(
414
+ (by, locator) => {
415
+ return window.codeceptjs.findAndStoreElements(by, locator)
416
+ },
417
+ locator.type,
418
+ locator.value,
419
+ )
380
420
  }
381
421
 
382
422
  /**
@@ -388,7 +428,7 @@ class Nightmare extends Helper {
388
428
  * ```
389
429
  */
390
430
  haveHeader(header, value) {
391
- return this.browser.header(header, value);
431
+ return this.browser.header(header, value)
392
432
  }
393
433
 
394
434
  /**
@@ -397,223 +437,237 @@ class Nightmare extends Helper {
397
437
  *
398
438
  */
399
439
  async amOnPage(url, headers = null) {
400
- if (!(/^\w+\:\/\//.test(url))) {
401
- url = urlResolve(this.options.url, url);
440
+ if (!/^\w+\:\/\//.test(url)) {
441
+ url = urlResolve(this.options.url, url)
402
442
  }
403
- const currentUrl = await this.browser.url();
443
+ const currentUrl = await this.browser.url()
404
444
  if (url === currentUrl) {
405
445
  // navigating to the same url will cause an error in nightmare, so don't do it
406
- return;
446
+ return
407
447
  }
408
448
  return this.browser.goto(url, headers).then((res) => {
409
- this.debugSection('URL', res.url);
410
- this.debugSection('Code', res.code);
411
- this.debugSection('Headers', JSON.stringify(res.headers));
412
- });
449
+ this.debugSection('URL', res.url)
450
+ this.debugSection('Code', res.code)
451
+ this.debugSection('Headers', JSON.stringify(res.headers))
452
+ })
413
453
  }
414
454
 
415
455
  /**
416
456
  * {{> seeInTitle }}
417
457
  */
418
458
  async seeInTitle(text) {
419
- const title = await this.browser.title();
420
- stringIncludes('web page title').assert(text, title);
459
+ const title = await this.browser.title()
460
+ stringIncludes('web page title').assert(text, title)
421
461
  }
422
462
 
423
463
  /**
424
464
  * {{> dontSeeInTitle }}
425
465
  */
426
466
  async dontSeeInTitle(text) {
427
- const title = await this.browser.title();
428
- stringIncludes('web page title').negate(text, title);
467
+ const title = await this.browser.title()
468
+ stringIncludes('web page title').negate(text, title)
429
469
  }
430
470
 
431
471
  /**
432
472
  * {{> grabTitle }}
433
473
  */
434
474
  async grabTitle() {
435
- return this.browser.title();
475
+ return this.browser.title()
436
476
  }
437
477
 
438
478
  /**
439
479
  * {{> grabCurrentUrl }}
440
480
  */
441
481
  async grabCurrentUrl() {
442
- return this.browser.url();
482
+ return this.browser.url()
443
483
  }
444
484
 
445
485
  /**
446
486
  * {{> seeInCurrentUrl }}
447
487
  */
448
488
  async seeInCurrentUrl(url) {
449
- const currentUrl = await this.browser.url();
450
- stringIncludes('url').assert(url, currentUrl);
489
+ const currentUrl = await this.browser.url()
490
+ stringIncludes('url').assert(url, currentUrl)
451
491
  }
452
492
 
453
493
  /**
454
494
  * {{> dontSeeInCurrentUrl }}
455
495
  */
456
496
  async dontSeeInCurrentUrl(url) {
457
- const currentUrl = await this.browser.url();
458
- stringIncludes('url').negate(url, currentUrl);
497
+ const currentUrl = await this.browser.url()
498
+ stringIncludes('url').negate(url, currentUrl)
459
499
  }
460
500
 
461
501
  /**
462
502
  * {{> seeCurrentUrlEquals }}
463
503
  */
464
504
  async seeCurrentUrlEquals(url) {
465
- const currentUrl = await this.browser.url();
466
- urlEquals(this.options.url).assert(url, currentUrl);
505
+ const currentUrl = await this.browser.url()
506
+ urlEquals(this.options.url).assert(url, currentUrl)
467
507
  }
468
508
 
469
509
  /**
470
510
  * {{> dontSeeCurrentUrlEquals }}
471
511
  */
472
512
  async dontSeeCurrentUrlEquals(url) {
473
- const currentUrl = await this.browser.url();
474
- urlEquals(this.options.url).negate(url, currentUrl);
513
+ const currentUrl = await this.browser.url()
514
+ urlEquals(this.options.url).negate(url, currentUrl)
475
515
  }
476
516
 
477
517
  /**
478
518
  * {{> see }}
479
519
  */
480
520
  async see(text, context = null) {
481
- return proceedSee.call(this, 'assert', text, context);
521
+ return proceedSee.call(this, 'assert', text, context)
482
522
  }
483
523
 
484
524
  /**
485
525
  * {{> dontSee }}
486
526
  */
487
527
  dontSee(text, context = null) {
488
- return proceedSee.call(this, 'negate', text, context);
528
+ return proceedSee.call(this, 'negate', text, context)
489
529
  }
490
530
 
491
531
  /**
492
532
  * {{> seeElement }}
493
533
  */
494
534
  async seeElement(locator) {
495
- locator = new Locator(locator, 'css');
496
- const num = await this.browser.evaluate((by, locator) => {
497
- return window.codeceptjs.findElements(by, locator).filter(e => e.offsetWidth > 0 && e.offsetHeight > 0).length;
498
- }, locator.type, locator.value);
499
- equals('number of elements on a page').negate(0, num);
535
+ locator = new Locator(locator, 'css')
536
+ const num = await this.browser.evaluate(
537
+ (by, locator) => {
538
+ return window.codeceptjs.findElements(by, locator).filter((e) => e.offsetWidth > 0 && e.offsetHeight > 0).length
539
+ },
540
+ locator.type,
541
+ locator.value,
542
+ )
543
+ equals('number of elements on a page').negate(0, num)
500
544
  }
501
545
 
502
546
  /**
503
547
  * {{> dontSeeElement }}
504
548
  */
505
549
  async dontSeeElement(locator) {
506
- locator = new Locator(locator, 'css');
507
- locator = new Locator(locator, 'css');
508
- const num = await this.browser.evaluate((by, locator) => {
509
- return window.codeceptjs.findElements(by, locator).filter(e => e.offsetWidth > 0 && e.offsetHeight > 0).length;
510
- }, locator.type, locator.value);
511
- equals('number of elements on a page').assert(0, num);
550
+ locator = new Locator(locator, 'css')
551
+ locator = new Locator(locator, 'css')
552
+ const num = await this.browser.evaluate(
553
+ (by, locator) => {
554
+ return window.codeceptjs.findElements(by, locator).filter((e) => e.offsetWidth > 0 && e.offsetHeight > 0).length
555
+ },
556
+ locator.type,
557
+ locator.value,
558
+ )
559
+ equals('number of elements on a page').assert(0, num)
512
560
  }
513
561
 
514
562
  /**
515
563
  * {{> seeElementInDOM }}
516
564
  */
517
565
  async seeElementInDOM(locator) {
518
- locator = new Locator(locator, 'css');
519
- const els = await this.browser.findElements(locator.toStrict());
520
- empty('elements').negate(els.fill('ELEMENT'));
566
+ locator = new Locator(locator, 'css')
567
+ const els = await this.browser.findElements(locator.toStrict())
568
+ empty('elements').negate(els.fill('ELEMENT'))
521
569
  }
522
570
 
523
571
  /**
524
572
  * {{> dontSeeElementInDOM }}
525
573
  */
526
574
  async dontSeeElementInDOM(locator) {
527
- locator = new Locator(locator, 'css');
528
- const els = await this.browser.findElements(locator.toStrict());
529
- empty('elements').assert(els.fill('ELEMENT'));
575
+ locator = new Locator(locator, 'css')
576
+ const els = await this.browser.findElements(locator.toStrict())
577
+ empty('elements').assert(els.fill('ELEMENT'))
530
578
  }
531
579
 
532
580
  /**
533
581
  * {{> seeInSource }}
534
582
  */
535
583
  async seeInSource(text) {
536
- const source = await this.browser.evaluate(() => document.documentElement.outerHTML);
537
- stringIncludes('HTML source of a page').assert(text, source);
584
+ const source = await this.browser.evaluate(() => document.documentElement.outerHTML)
585
+ stringIncludes('HTML source of a page').assert(text, source)
538
586
  }
539
587
 
540
588
  /**
541
589
  * {{> dontSeeInSource }}
542
590
  */
543
591
  async dontSeeInSource(text) {
544
- const source = await this.browser.evaluate(() => document.documentElement.outerHTML);
545
- stringIncludes('HTML source of a page').negate(text, source);
592
+ const source = await this.browser.evaluate(() => document.documentElement.outerHTML)
593
+ stringIncludes('HTML source of a page').negate(text, source)
546
594
  }
547
595
 
548
596
  /**
549
597
  * {{> seeNumberOfElements }}
550
598
  */
551
599
  async seeNumberOfElements(locator, num) {
552
- const elements = await this._locate(locator);
553
- return equals(`expected number of elements (${(new Locator(locator))}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
600
+ const elements = await this._locate(locator)
601
+ return equals(
602
+ `expected number of elements (${new Locator(locator)}) is ${num}, but found ${elements.length}`,
603
+ ).assert(elements.length, num)
554
604
  }
555
605
 
556
606
  /**
557
607
  * {{> seeNumberOfVisibleElements }}
558
608
  */
559
609
  async seeNumberOfVisibleElements(locator, num) {
560
- const res = await this.grabNumberOfVisibleElements(locator);
561
- return equals(`expected number of visible elements (${(new Locator(locator))}) is ${num}, but found ${res}`).assert(res, num);
610
+ const res = await this.grabNumberOfVisibleElements(locator)
611
+ return equals(`expected number of visible elements (${new Locator(locator)}) is ${num}, but found ${res}`).assert(
612
+ res,
613
+ num,
614
+ )
562
615
  }
563
616
 
564
617
  /**
565
618
  * {{> grabNumberOfVisibleElements }}
566
619
  */
567
620
  async grabNumberOfVisibleElements(locator) {
568
- locator = new Locator(locator, 'css');
621
+ locator = new Locator(locator, 'css')
569
622
 
570
- const num = await this.browser.evaluate((by, locator) => {
571
- return window.codeceptjs.findElements(by, locator)
572
- .filter(e => e.offsetWidth > 0 && e.offsetHeight > 0).length;
573
- }, locator.type, locator.value);
623
+ const num = await this.browser.evaluate(
624
+ (by, locator) => {
625
+ return window.codeceptjs.findElements(by, locator).filter((e) => e.offsetWidth > 0 && e.offsetHeight > 0).length
626
+ },
627
+ locator.type,
628
+ locator.value,
629
+ )
574
630
 
575
- return num;
631
+ return num
576
632
  }
577
633
 
578
634
  /**
579
635
  * {{> click }}
580
636
  */
581
637
  async click(locator, context = null) {
582
- const el = await findClickable.call(this, locator, context);
583
- assertElementExists(el, locator, 'Clickable');
584
- return this.browser.evaluate(el => window.codeceptjs.clickEl(el), el)
585
- .wait(this.options.waitForAction);
638
+ const el = await findClickable.call(this, locator, context)
639
+ assertElementExists(el, locator, 'Clickable')
640
+ return this.browser.evaluate((el) => window.codeceptjs.clickEl(el), el).wait(this.options.waitForAction)
586
641
  }
587
642
 
588
643
  /**
589
644
  * {{> doubleClick }}
590
645
  */
591
646
  async doubleClick(locator, context = null) {
592
- const el = await findClickable.call(this, locator, context);
593
- assertElementExists(el, locator, 'Clickable');
594
- return this.browser.evaluate(el => window.codeceptjs.doubleClickEl(el), el)
595
- .wait(this.options.waitForAction);
647
+ const el = await findClickable.call(this, locator, context)
648
+ assertElementExists(el, locator, 'Clickable')
649
+ return this.browser.evaluate((el) => window.codeceptjs.doubleClickEl(el), el).wait(this.options.waitForAction)
596
650
  }
597
651
 
598
652
  /**
599
653
  * {{> rightClick }}
600
654
  */
601
655
  async rightClick(locator, context = null) {
602
- const el = await findClickable.call(this, locator, context);
603
- assertElementExists(el, locator, 'Clickable');
604
- return this.browser.evaluate(el => window.codeceptjs.rightClickEl(el), el)
605
- .wait(this.options.waitForAction);
656
+ const el = await findClickable.call(this, locator, context)
657
+ assertElementExists(el, locator, 'Clickable')
658
+ return this.browser.evaluate((el) => window.codeceptjs.rightClickEl(el), el).wait(this.options.waitForAction)
606
659
  }
607
660
 
608
661
  /**
609
662
  * {{> moveCursorTo }}
610
663
  */
611
664
  async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
612
- locator = new Locator(locator, 'css');
613
- const el = await this.browser.findElement(locator.toStrict());
614
- assertElementExists(el, locator);
615
- return this.browser.evaluate((el, x, y) => window.codeceptjs.hoverEl(el, x, y), el, offsetX, offsetY)
616
- .wait(this.options.waitForAction); // wait for hover event to happen
665
+ locator = new Locator(locator, 'css')
666
+ const el = await this.browser.findElement(locator.toStrict())
667
+ assertElementExists(el, locator)
668
+ return this.browser
669
+ .evaluate((el, x, y) => window.codeceptjs.hoverEl(el, x, y), el, offsetX, offsetY)
670
+ .wait(this.options.waitForAction) // wait for hover event to happen
617
671
  }
618
672
 
619
673
  /**
@@ -622,8 +676,7 @@ class Nightmare extends Helper {
622
676
  * Wrapper for synchronous [evaluate](https://github.com/segmentio/nightmare#evaluatefn-arg1-arg2)
623
677
  */
624
678
  async executeScript(...args) {
625
- return this.browser.evaluate.apply(this.browser, args)
626
- .catch(err => err); // Nightmare's first argument is error :(
679
+ return this.browser.evaluate.apply(this.browser, args).catch((err) => err) // Nightmare's first argument is error :(
627
680
  }
628
681
 
629
682
  /**
@@ -633,8 +686,7 @@ class Nightmare extends Helper {
633
686
  * Unlike NightmareJS implementation calling `done` will return its first argument.
634
687
  */
635
688
  async executeAsyncScript(...args) {
636
- return this.browser.evaluate.apply(this.browser, args)
637
- .catch(err => err); // Nightmare's first argument is error :(
689
+ return this.browser.evaluate.apply(this.browser, args).catch((err) => err) // Nightmare's first argument is error :(
638
690
  }
639
691
 
640
692
  /**
@@ -642,72 +694,68 @@ class Nightmare extends Helper {
642
694
  */
643
695
  async resizeWindow(width, height) {
644
696
  if (width === 'maximize') {
645
- throw new Error('Nightmare doesn\'t support resizeWindow to maximum!');
697
+ throw new Error("Nightmare doesn't support resizeWindow to maximum!")
646
698
  }
647
- return this.browser.viewport(width, height).wait(this.options.waitForAction);
699
+ return this.browser.viewport(width, height).wait(this.options.waitForAction)
648
700
  }
649
701
 
650
702
  /**
651
703
  * {{> checkOption }}
652
704
  */
653
705
  async checkOption(field, context = null) {
654
- const els = await findCheckable.call(this, field, context);
655
- assertElementExists(els[0], field, 'Checkbox or radio');
656
- return this.browser.evaluate(els => window.codeceptjs.checkEl(els[0]), els)
657
- .wait(this.options.waitForAction);
706
+ const els = await findCheckable.call(this, field, context)
707
+ assertElementExists(els[0], field, 'Checkbox or radio')
708
+ return this.browser.evaluate((els) => window.codeceptjs.checkEl(els[0]), els).wait(this.options.waitForAction)
658
709
  }
659
710
 
660
711
  /**
661
712
  * {{> uncheckOption }}
662
713
  */
663
714
  async uncheckOption(field, context = null) {
664
- const els = await findCheckable.call(this, field, context);
665
- assertElementExists(els[0], field, 'Checkbox or radio');
666
- return this.browser.evaluate(els => window.codeceptjs.unCheckEl(els[0]), els)
667
- .wait(this.options.waitForAction);
715
+ const els = await findCheckable.call(this, field, context)
716
+ assertElementExists(els[0], field, 'Checkbox or radio')
717
+ return this.browser.evaluate((els) => window.codeceptjs.unCheckEl(els[0]), els).wait(this.options.waitForAction)
668
718
  }
669
719
 
670
720
  /**
671
721
  * {{> fillField }}
672
722
  */
673
723
  async fillField(field, value) {
674
- const el = await findField.call(this, field);
675
- assertElementExists(el, field, 'Field');
676
- return this.browser.enterText(el, value.toString(), true)
677
- .wait(this.options.waitForAction);
724
+ const el = await findField.call(this, field)
725
+ assertElementExists(el, field, 'Field')
726
+ return this.browser.enterText(el, value.toString(), true).wait(this.options.waitForAction)
678
727
  }
679
728
 
680
729
  /**
681
730
  * {{> clearField }}
682
731
  */
683
732
  async clearField(field) {
684
- return this.fillField(field, '');
733
+ return this.fillField(field, '')
685
734
  }
686
735
 
687
736
  /**
688
737
  * {{> appendField }}
689
738
  */
690
739
  async appendField(field, value) {
691
- const el = await findField.call(this, field);
692
- assertElementExists(el, field, 'Field');
693
- return this.browser.enterText(el, value.toString(), false)
694
- .wait(this.options.waitForAction);
740
+ const el = await findField.call(this, field)
741
+ assertElementExists(el, field, 'Field')
742
+ return this.browser.enterText(el, value.toString(), false).wait(this.options.waitForAction)
695
743
  }
696
744
 
697
745
  /**
698
746
  * {{> seeInField }}
699
747
  */
700
748
  async seeInField(field, value) {
701
- const _value = (typeof value === 'boolean') ? value : value.toString();
702
- return proceedSeeInField.call(this, 'assert', field, _value);
749
+ const _value = typeof value === 'boolean' ? value : value.toString()
750
+ return proceedSeeInField.call(this, 'assert', field, _value)
703
751
  }
704
752
 
705
753
  /**
706
754
  * {{> dontSeeInField }}
707
755
  */
708
756
  async dontSeeInField(field, value) {
709
- const _value = (typeof value === 'boolean') ? value : value.toString();
710
- return proceedSeeInField.call(this, 'negate', field, _value);
757
+ const _value = typeof value === 'boolean' ? value : value.toString()
758
+ return proceedSeeInField.call(this, 'negate', field, _value)
711
759
  }
712
760
 
713
761
  /**
@@ -716,12 +764,12 @@ class Nightmare extends Helper {
716
764
  */
717
765
  async pressKey(key) {
718
766
  if (Array.isArray(key)) {
719
- key = key.join('+'); // should work with accelerators...
767
+ key = key.join('+') // should work with accelerators...
720
768
  }
721
769
  if (Object.keys(specialKeys).indexOf(key) >= 0) {
722
- key = specialKeys[key];
770
+ key = specialKeys[key]
723
771
  }
724
- return this.browser.pressKey(key).wait(this.options.waitForAction);
772
+ return this.browser.pressKey(key).wait(this.options.waitForAction)
725
773
  }
726
774
 
727
775
  /**
@@ -735,21 +783,21 @@ class Nightmare extends Helper {
735
783
  }
736
784
  */
737
785
  async triggerMouseEvent(event) {
738
- return this.browser.triggerMouseEvent(event).wait(this.options.waitForAction);
786
+ return this.browser.triggerMouseEvent(event).wait(this.options.waitForAction)
739
787
  }
740
788
 
741
789
  /**
742
790
  * {{> seeCheckboxIsChecked }}
743
791
  */
744
792
  async seeCheckboxIsChecked(field) {
745
- return proceedIsChecked.call(this, 'assert', field);
793
+ return proceedIsChecked.call(this, 'assert', field)
746
794
  }
747
795
 
748
796
  /**
749
797
  * {{> dontSeeCheckboxIsChecked }}
750
798
  */
751
799
  async dontSeeCheckboxIsChecked(field) {
752
- return proceedIsChecked.call(this, 'negate', field);
800
+ return proceedIsChecked.call(this, 'negate', field)
753
801
  }
754
802
 
755
803
  /**
@@ -758,167 +806,171 @@ class Nightmare extends Helper {
758
806
  * Doesn't work if the Chromium DevTools panel is open (as Chromium allows only one attachment to the debugger at a time. [See more](https://github.com/rosshinkley/nightmare-upload#important-note-about-setting-file-upload-inputs))
759
807
  */
760
808
  async attachFile(locator, pathToFile) {
761
- const file = path.join(global.codecept_dir, pathToFile);
809
+ const file = path.join(global.codecept_dir, pathToFile)
762
810
 
763
- locator = new Locator(locator, 'css');
811
+ locator = new Locator(locator, 'css')
764
812
  if (!locator.isCSS()) {
765
- throw new Error('Only CSS locator allowed for attachFile in Nightmare helper');
813
+ throw new Error('Only CSS locator allowed for attachFile in Nightmare helper')
766
814
  }
767
815
 
768
816
  if (!fileExists(file)) {
769
- throw new Error(`File at ${file} can not be found on local system`);
817
+ throw new Error(`File at ${file} can not be found on local system`)
770
818
  }
771
- return this.browser.upload(locator.value, file);
819
+ return this.browser.upload(locator.value, file)
772
820
  }
773
821
 
774
822
  /**
775
823
  * {{> grabTextFromAll }}
776
824
  */
777
825
  async grabTextFromAll(locator) {
778
- locator = new Locator(locator, 'css');
779
- const els = await this.browser.findElements(locator.toStrict());
780
- const texts = [];
781
- const getText = el => window.codeceptjs.fetchElement(el).innerText;
826
+ locator = new Locator(locator, 'css')
827
+ const els = await this.browser.findElements(locator.toStrict())
828
+ const texts = []
829
+ const getText = (el) => window.codeceptjs.fetchElement(el).innerText
782
830
  for (const el of els) {
783
- texts.push(await this.browser.evaluate(getText, el));
831
+ texts.push(await this.browser.evaluate(getText, el))
784
832
  }
785
- return texts;
833
+ return texts
786
834
  }
787
835
 
788
836
  /**
789
837
  * {{> grabTextFrom }}
790
838
  */
791
839
  async grabTextFrom(locator) {
792
- locator = new Locator(locator, 'css');
793
- const els = await this.browser.findElement(locator.toStrict());
794
- assertElementExists(els, locator);
795
- const texts = await this.grabTextFromAll(locator);
840
+ locator = new Locator(locator, 'css')
841
+ const els = await this.browser.findElement(locator.toStrict())
842
+ assertElementExists(els, locator)
843
+ const texts = await this.grabTextFromAll(locator)
796
844
  if (texts.length > 1) {
797
- this.debugSection('GrabText', `Using first element out of ${texts.length}`);
845
+ this.debugSection('GrabText', `Using first element out of ${texts.length}`)
798
846
  }
799
847
 
800
- return texts[0];
848
+ return texts[0]
801
849
  }
802
850
 
803
851
  /**
804
852
  * {{> grabValueFromAll }}
805
853
  */
806
854
  async grabValueFromAll(locator) {
807
- locator = new Locator(locator, 'css');
808
- const els = await this.browser.findElements(locator.toStrict());
809
- const values = [];
810
- const getValues = el => window.codeceptjs.fetchElement(el).value;
855
+ locator = new Locator(locator, 'css')
856
+ const els = await this.browser.findElements(locator.toStrict())
857
+ const values = []
858
+ const getValues = (el) => window.codeceptjs.fetchElement(el).value
811
859
  for (const el of els) {
812
- values.push(await this.browser.evaluate(getValues, el));
860
+ values.push(await this.browser.evaluate(getValues, el))
813
861
  }
814
862
 
815
- return values;
863
+ return values
816
864
  }
817
865
 
818
866
  /**
819
867
  * {{> grabValueFrom }}
820
868
  */
821
869
  async grabValueFrom(locator) {
822
- const el = await findField.call(this, locator);
823
- assertElementExists(el, locator, 'Field');
824
- const values = await this.grabValueFromAll(locator);
870
+ const el = await findField.call(this, locator)
871
+ assertElementExists(el, locator, 'Field')
872
+ const values = await this.grabValueFromAll(locator)
825
873
  if (values.length > 1) {
826
- this.debugSection('GrabValue', `Using first element out of ${values.length}`);
874
+ this.debugSection('GrabValue', `Using first element out of ${values.length}`)
827
875
  }
828
876
 
829
- return values[0];
877
+ return values[0]
830
878
  }
831
879
 
832
880
  /**
833
881
  * {{> grabAttributeFromAll }}
834
882
  */
835
883
  async grabAttributeFromAll(locator, attr) {
836
- locator = new Locator(locator, 'css');
837
- const els = await this.browser.findElements(locator.toStrict());
838
- const array = [];
884
+ locator = new Locator(locator, 'css')
885
+ const els = await this.browser.findElements(locator.toStrict())
886
+ const array = []
839
887
 
840
888
  for (let index = 0; index < els.length; index++) {
841
- const el = els[index];
842
- array.push(await this.browser.evaluate((el, attr) => window.codeceptjs.fetchElement(el).getAttribute(attr), el, attr));
889
+ const el = els[index]
890
+ array.push(
891
+ await this.browser.evaluate((el, attr) => window.codeceptjs.fetchElement(el).getAttribute(attr), el, attr),
892
+ )
843
893
  }
844
894
 
845
- return array;
895
+ return array
846
896
  }
847
897
 
848
898
  /**
849
899
  * {{> grabAttributeFrom }}
850
900
  */
851
901
  async grabAttributeFrom(locator, attr) {
852
- locator = new Locator(locator, 'css');
853
- const els = await this.browser.findElement(locator.toStrict());
854
- assertElementExists(els, locator);
902
+ locator = new Locator(locator, 'css')
903
+ const els = await this.browser.findElement(locator.toStrict())
904
+ assertElementExists(els, locator)
855
905
 
856
- const attrs = await this.grabAttributeFromAll(locator, attr);
906
+ const attrs = await this.grabAttributeFromAll(locator, attr)
857
907
  if (attrs.length > 1) {
858
- this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`);
908
+ this.debugSection('GrabAttribute', `Using first element out of ${attrs.length}`)
859
909
  }
860
910
 
861
- return attrs[0];
911
+ return attrs[0]
862
912
  }
863
913
 
864
914
  /**
865
915
  * {{> grabHTMLFromAll }}
866
916
  */
867
917
  async grabHTMLFromAll(locator) {
868
- locator = new Locator(locator, 'css');
869
- const els = await this.browser.findElements(locator.toStrict());
870
- const array = [];
918
+ locator = new Locator(locator, 'css')
919
+ const els = await this.browser.findElements(locator.toStrict())
920
+ const array = []
871
921
 
872
922
  for (let index = 0; index < els.length; index++) {
873
- const el = els[index];
874
- array.push(await this.browser.evaluate(el => window.codeceptjs.fetchElement(el).innerHTML, el));
923
+ const el = els[index]
924
+ array.push(await this.browser.evaluate((el) => window.codeceptjs.fetchElement(el).innerHTML, el))
875
925
  }
876
- this.debugSection('GrabHTML', array);
926
+ this.debugSection('GrabHTML', array)
877
927
 
878
- return array;
928
+ return array
879
929
  }
880
930
 
881
931
  /**
882
932
  * {{> grabHTMLFrom }}
883
933
  */
884
934
  async grabHTMLFrom(locator) {
885
- locator = new Locator(locator, 'css');
886
- const els = await this.browser.findElement(locator.toStrict());
887
- assertElementExists(els, locator);
888
- const html = await this.grabHTMLFromAll(locator);
935
+ locator = new Locator(locator, 'css')
936
+ const els = await this.browser.findElement(locator.toStrict())
937
+ assertElementExists(els, locator)
938
+ const html = await this.grabHTMLFromAll(locator)
889
939
  if (html.length > 1) {
890
- this.debugSection('GrabHTML', `Using first element out of ${html.length}`);
940
+ this.debugSection('GrabHTML', `Using first element out of ${html.length}`)
891
941
  }
892
942
 
893
- return html[0];
943
+ return html[0]
894
944
  }
895
945
 
896
946
  /**
897
947
  * {{> grabCssPropertyFrom }}
898
948
  */
899
949
  async grabCssPropertyFrom(locator, cssProperty) {
900
- locator = new Locator(locator, 'css');
901
- const els = await this.browser.findElements(locator.toStrict());
902
- const array = [];
950
+ locator = new Locator(locator, 'css')
951
+ const els = await this.browser.findElements(locator.toStrict())
952
+ const array = []
903
953
 
904
954
  const getCssPropForElement = async (el, prop) => {
905
- return (await this.browser.evaluate((el) => {
906
- return window.getComputedStyle(window.codeceptjs.fetchElement(el));
907
- }, el))[toCamelCase(prop)];
908
- };
955
+ return (
956
+ await this.browser.evaluate((el) => {
957
+ return window.getComputedStyle(window.codeceptjs.fetchElement(el))
958
+ }, el)
959
+ )[toCamelCase(prop)]
960
+ }
909
961
 
910
962
  for (const el of els) {
911
- assertElementExists(el, locator);
912
- const cssValue = await getCssPropForElement(el, cssProperty);
913
- array.push(cssValue);
963
+ assertElementExists(el, locator)
964
+ const cssValue = await getCssPropForElement(el, cssProperty)
965
+ array.push(cssValue)
914
966
  }
915
- this.debugSection('HTML', array);
967
+ this.debugSection('HTML', array)
916
968
 
917
- return array.length > 1 ? array : array[0];
969
+ return array.length > 1 ? array : array[0]
918
970
  }
919
971
 
920
972
  _injectClientScripts() {
921
- return this.browser.inject('js', path.join(__dirname, 'clientscripts', 'nightmare.js'));
973
+ return this.browser.inject('js', path.join(__dirname, 'clientscripts', 'nightmare.js'))
922
974
  }
923
975
 
924
976
  /**
@@ -926,41 +978,41 @@ class Nightmare extends Helper {
926
978
  */
927
979
  async selectOption(select, option) {
928
980
  const fetchAndCheckOption = function (el, locator) {
929
- el = window.codeceptjs.fetchElement(el);
930
- const found = document.evaluate(locator, el, null, 5, null);
931
- let current = null;
932
- const items = [];
933
- while (current = found.iterateNext()) {
934
- items.push(current);
981
+ el = window.codeceptjs.fetchElement(el)
982
+ const found = document.evaluate(locator, el, null, 5, null)
983
+ let current = null
984
+ const items = []
985
+ while ((current = found.iterateNext())) {
986
+ items.push(current)
935
987
  }
936
988
  for (let i = 0; i < items.length; i++) {
937
- current = items[i];
989
+ current = items[i]
938
990
  if (current instanceof HTMLOptionElement) {
939
- current.selected = true;
940
- if (!el.multiple) el.value = current.value;
991
+ current.selected = true
992
+ if (!el.multiple) el.value = current.value
941
993
  }
942
- const event = document.createEvent('HTMLEvents');
943
- event.initEvent('change', true, true);
944
- el.dispatchEvent(event);
994
+ const event = document.createEvent('HTMLEvents')
995
+ event.initEvent('change', true, true)
996
+ el.dispatchEvent(event)
945
997
  }
946
- return !!current;
947
- };
998
+ return !!current
999
+ }
948
1000
 
949
- const el = await findField.call(this, select);
950
- assertElementExists(el, select, 'Selectable field');
1001
+ const el = await findField.call(this, select)
1002
+ assertElementExists(el, select, 'Selectable field')
951
1003
  if (!Array.isArray(option)) {
952
- option = [option];
1004
+ option = [option]
953
1005
  }
954
1006
 
955
1007
  for (const key in option) {
956
- const opt = xpathLocator.literal(option[key]);
957
- const checked = await this.browser.evaluate(fetchAndCheckOption, el, Locator.select.byVisibleText(opt));
1008
+ const opt = xpathLocator.literal(option[key])
1009
+ const checked = await this.browser.evaluate(fetchAndCheckOption, el, Locator.select.byVisibleText(opt))
958
1010
 
959
1011
  if (!checked) {
960
- await this.browser.evaluate(fetchAndCheckOption, el, Locator.select.byValue(opt));
1012
+ await this.browser.evaluate(fetchAndCheckOption, el, Locator.select.byValue(opt))
961
1013
  }
962
1014
  }
963
- return this.browser.wait(this.options.waitForAction);
1015
+ return this.browser.wait(this.options.waitForAction)
964
1016
  }
965
1017
 
966
1018
  /**
@@ -970,7 +1022,7 @@ class Nightmare extends Helper {
970
1022
  * [See more](https://github.com/segmentio/nightmare/blob/master/Readme.md#cookiessetcookie)
971
1023
  */
972
1024
  async setCookie(cookie) {
973
- return this.browser.cookies.set(cookie);
1025
+ return this.browser.cookies.set(cookie)
974
1026
  }
975
1027
 
976
1028
  /**
@@ -978,16 +1030,16 @@ class Nightmare extends Helper {
978
1030
  *
979
1031
  */
980
1032
  async seeCookie(name) {
981
- const res = await this.browser.cookies.get(name);
982
- truth(`cookie ${name}`, 'to be set').assert(res);
1033
+ const res = await this.browser.cookies.get(name)
1034
+ truth(`cookie ${name}`, 'to be set').assert(res)
983
1035
  }
984
1036
 
985
1037
  /**
986
1038
  * {{> dontSeeCookie }}
987
1039
  */
988
1040
  async dontSeeCookie(name) {
989
- const res = await this.browser.cookies.get(name);
990
- truth(`cookie ${name}`, 'to be set').negate(res);
1041
+ const res = await this.browser.cookies.get(name)
1042
+ truth(`cookie ${name}`, 'to be set').negate(res)
991
1043
  }
992
1044
 
993
1045
  /**
@@ -998,7 +1050,7 @@ class Nightmare extends Helper {
998
1050
  * Multiple cookies can be received by passing query object `I.grabCookie({ secure: true});`. If you'd like get all cookies for all urls, use: `.grabCookie({ url: null }).`
999
1051
  */
1000
1052
  async grabCookie(name) {
1001
- return this.browser.cookies.get(name);
1053
+ return this.browser.cookies.get(name)
1002
1054
  }
1003
1055
 
1004
1056
  /**
@@ -1006,34 +1058,34 @@ class Nightmare extends Helper {
1006
1058
  */
1007
1059
  async clearCookie(cookie) {
1008
1060
  if (!cookie) {
1009
- return this.browser.cookies.clearAll();
1061
+ return this.browser.cookies.clearAll()
1010
1062
  }
1011
- return this.browser.cookies.clear(cookie);
1063
+ return this.browser.cookies.clear(cookie)
1012
1064
  }
1013
1065
 
1014
1066
  /**
1015
1067
  * {{> waitForFunction }}
1016
1068
  */
1017
1069
  async waitForFunction(fn, argsOrSec = null, sec = null) {
1018
- let args = [];
1070
+ let args = []
1019
1071
  if (argsOrSec) {
1020
1072
  if (Array.isArray(argsOrSec)) {
1021
- args = argsOrSec;
1073
+ args = argsOrSec
1022
1074
  } else if (typeof argsOrSec === 'number') {
1023
- sec = argsOrSec;
1075
+ sec = argsOrSec
1024
1076
  }
1025
1077
  }
1026
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1027
- return this.browser.wait(fn, ...args);
1078
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1079
+ return this.browser.wait(fn, ...args)
1028
1080
  }
1029
1081
 
1030
1082
  /**
1031
1083
  * {{> wait }}
1032
1084
  */
1033
1085
  async wait(sec) {
1034
- return new Promise(((done) => {
1035
- setTimeout(done, sec * 1000);
1036
- }));
1086
+ return new Promise((done) => {
1087
+ setTimeout(done, sec * 1000)
1088
+ })
1037
1089
  }
1038
1090
 
1039
1091
  /**
@@ -1041,113 +1093,136 @@ class Nightmare extends Helper {
1041
1093
  */
1042
1094
  async waitForText(text, sec, context = null) {
1043
1095
  if (!context) {
1044
- context = this.context;
1096
+ context = this.context
1045
1097
  }
1046
- const locator = new Locator(context, 'css');
1047
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1048
- return this.browser.wait((by, locator, text) => {
1049
- return window.codeceptjs.findElement(by, locator).innerText.indexOf(text) > -1;
1050
- }, locator.type, locator.value, text).catch((err) => {
1051
- if (err.message.indexOf('Cannot read property') > -1) {
1052
- throw new Error(`element (${JSON.stringify(context)}) is not in DOM. Unable to wait text.`);
1053
- } else if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1054
- throw new Error(`there is no element(${JSON.stringify(context)}) with text "${text}" after ${sec} sec`);
1055
- } else throw err;
1056
- });
1098
+ const locator = new Locator(context, 'css')
1099
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1100
+ return this.browser
1101
+ .wait(
1102
+ (by, locator, text) => {
1103
+ return window.codeceptjs.findElement(by, locator).innerText.indexOf(text) > -1
1104
+ },
1105
+ locator.type,
1106
+ locator.value,
1107
+ text,
1108
+ )
1109
+ .catch((err) => {
1110
+ if (err.message.indexOf('Cannot read property') > -1) {
1111
+ throw new Error(`element (${JSON.stringify(context)}) is not in DOM. Unable to wait text.`)
1112
+ } else if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1113
+ throw new Error(`there is no element(${JSON.stringify(context)}) with text "${text}" after ${sec} sec`)
1114
+ } else throw err
1115
+ })
1057
1116
  }
1058
1117
 
1059
1118
  /**
1060
1119
  * {{> waitForVisible }}
1061
1120
  */
1062
1121
  waitForVisible(locator, sec) {
1063
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1064
- locator = new Locator(locator, 'css');
1065
-
1066
- return this.browser.wait((by, locator) => {
1067
- const el = window.codeceptjs.findElement(by, locator);
1068
- if (!el) return false;
1069
- return el.offsetWidth > 0 && el.offsetHeight > 0;
1070
- }, locator.type, locator.value).catch((err) => {
1071
- if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1072
- throw new Error(`element (${JSON.stringify(locator)}) still not visible on page after ${sec} sec`);
1073
- } else throw err;
1074
- });
1122
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1123
+ locator = new Locator(locator, 'css')
1124
+
1125
+ return this.browser
1126
+ .wait(
1127
+ (by, locator) => {
1128
+ const el = window.codeceptjs.findElement(by, locator)
1129
+ if (!el) return false
1130
+ return el.offsetWidth > 0 && el.offsetHeight > 0
1131
+ },
1132
+ locator.type,
1133
+ locator.value,
1134
+ )
1135
+ .catch((err) => {
1136
+ if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1137
+ throw new Error(`element (${JSON.stringify(locator)}) still not visible on page after ${sec} sec`)
1138
+ } else throw err
1139
+ })
1075
1140
  }
1076
1141
 
1077
1142
  /**
1078
1143
  * {{> waitToHide }}
1079
1144
  */
1080
1145
  async waitToHide(locator, sec = null) {
1081
- return this.waitForInvisible(locator, sec);
1146
+ return this.waitForInvisible(locator, sec)
1082
1147
  }
1083
1148
 
1084
1149
  /**
1085
1150
  * {{> waitForInvisible }}
1086
1151
  */
1087
1152
  waitForInvisible(locator, sec) {
1088
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1089
- locator = new Locator(locator, 'css');
1090
-
1091
- return this.browser.wait((by, locator) => {
1092
- const el = window.codeceptjs.findElement(by, locator);
1093
- if (!el) return true;
1094
- return !(el.offsetWidth > 0 && el.offsetHeight > 0);
1095
- }, locator.type, locator.value).catch((err) => {
1096
- if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1097
- throw new Error(`element (${JSON.stringify(locator)}) still visible after ${sec} sec`);
1098
- } else throw err;
1099
- });
1153
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1154
+ locator = new Locator(locator, 'css')
1155
+
1156
+ return this.browser
1157
+ .wait(
1158
+ (by, locator) => {
1159
+ const el = window.codeceptjs.findElement(by, locator)
1160
+ if (!el) return true
1161
+ return !(el.offsetWidth > 0 && el.offsetHeight > 0)
1162
+ },
1163
+ locator.type,
1164
+ locator.value,
1165
+ )
1166
+ .catch((err) => {
1167
+ if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1168
+ throw new Error(`element (${JSON.stringify(locator)}) still visible after ${sec} sec`)
1169
+ } else throw err
1170
+ })
1100
1171
  }
1101
1172
 
1102
1173
  /**
1103
1174
  * {{> waitForElement }}
1104
1175
  */
1105
1176
  async waitForElement(locator, sec) {
1106
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1107
- locator = new Locator(locator, 'css');
1177
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1178
+ locator = new Locator(locator, 'css')
1108
1179
 
1109
- return this.browser.wait((by, locator) => window.codeceptjs.findElement(by, locator) !== null, locator.type, locator.value).catch((err) => {
1110
- if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1111
- throw new Error(`element (${JSON.stringify(locator)}) still not present on page after ${sec} sec`);
1112
- } else throw err;
1113
- });
1180
+ return this.browser
1181
+ .wait((by, locator) => window.codeceptjs.findElement(by, locator) !== null, locator.type, locator.value)
1182
+ .catch((err) => {
1183
+ if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1184
+ throw new Error(`element (${JSON.stringify(locator)}) still not present on page after ${sec} sec`)
1185
+ } else throw err
1186
+ })
1114
1187
  }
1115
1188
 
1116
1189
  async waitUntilExists(locator, sec) {
1117
1190
  console.log(`waitUntilExists deprecated:
1118
1191
  * use 'waitForElement' to wait for element to be attached
1119
- * use 'waitForDetached to wait for element to be removed'`);
1120
- return this.waitForDetached(locator, sec);
1192
+ * use 'waitForDetached to wait for element to be removed'`)
1193
+ return this.waitForDetached(locator, sec)
1121
1194
  }
1122
1195
 
1123
1196
  /**
1124
1197
  * {{> waitForDetached }}
1125
1198
  */
1126
1199
  async waitForDetached(locator, sec) {
1127
- this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
1128
- sec = this.browser.options.waitForTimeout / 1000;
1129
- locator = new Locator(locator, 'css');
1200
+ this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
1201
+ sec = this.browser.options.waitForTimeout / 1000
1202
+ locator = new Locator(locator, 'css')
1130
1203
 
1131
- return this.browser.wait((by, locator) => window.codeceptjs.findElement(by, locator) === null, locator.type, locator.value).catch((err) => {
1132
- if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1133
- throw new Error(`element (${JSON.stringify(locator)}) still on page after ${sec} sec`);
1134
- } else throw err;
1135
- });
1204
+ return this.browser
1205
+ .wait((by, locator) => window.codeceptjs.findElement(by, locator) === null, locator.type, locator.value)
1206
+ .catch((err) => {
1207
+ if (err.message && err.message.indexOf('.wait() timed out after') > -1) {
1208
+ throw new Error(`element (${JSON.stringify(locator)}) still on page after ${sec} sec`)
1209
+ } else throw err
1210
+ })
1136
1211
  }
1137
1212
 
1138
1213
  /**
1139
1214
  * {{> refreshPage }}
1140
1215
  */
1141
1216
  async refreshPage() {
1142
- return this.browser.refresh();
1217
+ return this.browser.refresh()
1143
1218
  }
1144
1219
 
1145
1220
  /**
1146
1221
  * Reload the page
1147
1222
  */
1148
1223
  refresh() {
1149
- console.log('Deprecated in favor of refreshPage');
1150
- return this.browser.refresh();
1224
+ console.log('Deprecated in favor of refreshPage')
1225
+ return this.browser.refresh()
1151
1226
  }
1152
1227
 
1153
1228
  /**
@@ -1155,70 +1230,74 @@ class Nightmare extends Helper {
1155
1230
  *
1156
1231
  */
1157
1232
  async saveElementScreenshot(locator, fileName) {
1158
- const outputFile = screenshotOutputFolder(fileName);
1233
+ const outputFile = screenshotOutputFolder(fileName)
1159
1234
 
1160
- const rect = await this.grabElementBoundingRect(locator);
1235
+ const rect = await this.grabElementBoundingRect(locator)
1161
1236
 
1162
1237
  const button_clip = {
1163
1238
  x: Math.floor(rect.x),
1164
1239
  y: Math.floor(rect.y),
1165
1240
  width: Math.floor(rect.width),
1166
1241
  height: Math.floor(rect.height),
1167
- };
1242
+ }
1168
1243
 
1169
- this.debug(`Screenshot of ${(new Locator(locator))} element has been saved to ${outputFile}`);
1244
+ this.debug(`Screenshot of ${new Locator(locator)} element has been saved to ${outputFile}`)
1170
1245
  // take the screenshot
1171
- await this.browser.screenshot(outputFile, button_clip);
1246
+ await this.browser.screenshot(outputFile, button_clip)
1172
1247
  }
1173
1248
 
1174
1249
  /**
1175
1250
  * {{> grabElementBoundingRect }}
1176
1251
  */
1177
1252
  async grabElementBoundingRect(locator, prop) {
1178
- locator = new Locator(locator, 'css');
1253
+ locator = new Locator(locator, 'css')
1179
1254
 
1180
- const rect = await this.browser.evaluate(async (by, locator) => {
1181
- // store the button in a variable
1255
+ const rect = await this.browser.evaluate(
1256
+ async (by, locator) => {
1257
+ // store the button in a variable
1182
1258
 
1183
- const build_cluster_btn = await window.codeceptjs.findElement(by, locator);
1259
+ const build_cluster_btn = await window.codeceptjs.findElement(by, locator)
1184
1260
 
1185
- // use the getClientRects() function on the button to determine
1186
- // the size and location
1187
- const rect = build_cluster_btn.getBoundingClientRect();
1261
+ // use the getClientRects() function on the button to determine
1262
+ // the size and location
1263
+ const rect = build_cluster_btn.getBoundingClientRect()
1188
1264
 
1189
- // convert the rectangle to a clip object and return it
1190
- return {
1191
- x: rect.left,
1192
- y: rect.top,
1193
- width: rect.width,
1194
- height: rect.height,
1195
- };
1196
- }, locator.type, locator.value);
1265
+ // convert the rectangle to a clip object and return it
1266
+ return {
1267
+ x: rect.left,
1268
+ y: rect.top,
1269
+ width: rect.width,
1270
+ height: rect.height,
1271
+ }
1272
+ },
1273
+ locator.type,
1274
+ locator.value,
1275
+ )
1197
1276
 
1198
- if (prop) return rect[prop];
1199
- return rect;
1277
+ if (prop) return rect[prop]
1278
+ return rect
1200
1279
  }
1201
1280
 
1202
1281
  /**
1203
1282
  * {{> saveScreenshot }}
1204
1283
  */
1205
1284
  async saveScreenshot(fileName, fullPage = this.options.fullPageScreenshots) {
1206
- const outputFile = screenshotOutputFolder(fileName);
1285
+ const outputFile = screenshotOutputFolder(fileName)
1207
1286
 
1208
- this.debug(`Screenshot is saving to ${outputFile}`);
1287
+ this.debug(`Screenshot is saving to ${outputFile}`)
1209
1288
 
1210
1289
  if (!fullPage) {
1211
- return this.browser.screenshot(outputFile);
1290
+ return this.browser.screenshot(outputFile)
1212
1291
  }
1213
1292
  const { height, width } = await this.browser.evaluate(() => {
1214
- return { height: document.body.scrollHeight, width: document.body.scrollWidth };
1215
- });
1216
- await this.browser.viewport(width, height);
1217
- return this.browser.screenshot(outputFile);
1293
+ return { height: document.body.scrollHeight, width: document.body.scrollWidth }
1294
+ })
1295
+ await this.browser.viewport(width, height)
1296
+ return this.browser.screenshot(outputFile)
1218
1297
  }
1219
1298
 
1220
1299
  async _failed() {
1221
- if (withinStatus !== false) await this._withinEnd();
1300
+ if (withinStatus !== false) await this._withinEnd()
1222
1301
  }
1223
1302
 
1224
1303
  /**
@@ -1226,28 +1305,40 @@ class Nightmare extends Helper {
1226
1305
  */
1227
1306
  async scrollTo(locator, offsetX = 0, offsetY = 0) {
1228
1307
  if (typeof locator === 'number' && typeof offsetX === 'number') {
1229
- offsetY = offsetX;
1230
- offsetX = locator;
1231
- locator = null;
1308
+ offsetY = offsetX
1309
+ offsetX = locator
1310
+ locator = null
1232
1311
  }
1233
1312
  if (locator) {
1234
- locator = new Locator(locator, 'css');
1235
- return this.browser.evaluate((by, locator, offsetX, offsetY) => {
1236
- const el = window.codeceptjs.findElement(by, locator);
1237
- if (!el) throw new Error(`Element not found ${by}: ${locator}`);
1238
- const rect = el.getBoundingClientRect();
1239
- window.scrollTo(rect.left + offsetX, rect.top + offsetY);
1240
- }, locator.type, locator.value, offsetX, offsetY);
1313
+ locator = new Locator(locator, 'css')
1314
+ return this.browser.evaluate(
1315
+ (by, locator, offsetX, offsetY) => {
1316
+ const el = window.codeceptjs.findElement(by, locator)
1317
+ if (!el) throw new Error(`Element not found ${by}: ${locator}`)
1318
+ const rect = el.getBoundingClientRect()
1319
+ window.scrollTo(rect.left + offsetX, rect.top + offsetY)
1320
+ },
1321
+ locator.type,
1322
+ locator.value,
1323
+ offsetX,
1324
+ offsetY,
1325
+ )
1241
1326
  }
1242
1327
  // eslint-disable-next-line prefer-arrow-callback
1243
- return this.executeScript(function (x, y) { return window.scrollTo(x, y); }, offsetX, offsetY);
1328
+ return this.executeScript(
1329
+ function (x, y) {
1330
+ return window.scrollTo(x, y)
1331
+ },
1332
+ offsetX,
1333
+ offsetY,
1334
+ )
1244
1335
  }
1245
1336
 
1246
1337
  /**
1247
1338
  * {{> scrollPageToTop }}
1248
1339
  */
1249
1340
  async scrollPageToTop() {
1250
- return this.executeScript(() => window.scrollTo(0, 0));
1341
+ return this.executeScript(() => window.scrollTo(0, 0))
1251
1342
  }
1252
1343
 
1253
1344
  /**
@@ -1256,16 +1347,13 @@ class Nightmare extends Helper {
1256
1347
  async scrollPageToBottom() {
1257
1348
  /* eslint-disable prefer-arrow-callback, comma-dangle */
1258
1349
  return this.executeScript(function () {
1259
- const body = document.body;
1260
- const html = document.documentElement;
1261
- window.scrollTo(0, Math.max(
1262
- body.scrollHeight,
1263
- body.offsetHeight,
1264
- html.clientHeight,
1265
- html.scrollHeight,
1266
- html.offsetHeight
1267
- ));
1268
- });
1350
+ const body = document.body
1351
+ const html = document.documentElement
1352
+ window.scrollTo(
1353
+ 0,
1354
+ Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
1355
+ )
1356
+ })
1269
1357
  /* eslint-enable */
1270
1358
  }
1271
1359
 
@@ -1277,135 +1365,143 @@ class Nightmare extends Helper {
1277
1365
  function getScrollPosition() {
1278
1366
  return {
1279
1367
  x: window.pageXOffset,
1280
- y: window.pageYOffset
1281
- };
1368
+ y: window.pageYOffset,
1369
+ }
1282
1370
  }
1283
1371
  /* eslint-enable comma-dangle */
1284
- return this.executeScript(getScrollPosition);
1372
+ return this.executeScript(getScrollPosition)
1285
1373
  }
1286
1374
  }
1287
1375
 
1288
- export default Nightmare;
1376
+ module.exports = Nightmare
1289
1377
 
1290
1378
  async function proceedSee(assertType, text, context) {
1291
- let description;
1292
- let locator;
1379
+ let description
1380
+ let locator
1293
1381
  if (!context) {
1294
1382
  if (this.context === this.options.rootElement) {
1295
- locator = new Locator(this.context, 'css');
1296
- description = 'web application';
1383
+ locator = new Locator(this.context, 'css')
1384
+ description = 'web application'
1297
1385
  } else {
1298
- description = `current context ${this.context}`;
1299
- locator = new Locator({ xpath: './/*' });
1386
+ description = `current context ${this.context}`
1387
+ locator = new Locator({ xpath: './/*' })
1300
1388
  }
1301
1389
  } else {
1302
- locator = new Locator(context, 'css');
1303
- description = `element ${locator.toString()}`;
1304
- }
1305
-
1306
- const texts = await this.browser.evaluate((by, locator) => {
1307
- return window.codeceptjs.findElements(by, locator).map(el => el.innerText);
1308
- }, locator.type, locator.value);
1309
- const allText = texts.join(' | ');
1310
- return stringIncludes(description)[assertType](text, allText);
1390
+ locator = new Locator(context, 'css')
1391
+ description = `element ${locator.toString()}`
1392
+ }
1393
+
1394
+ const texts = await this.browser.evaluate(
1395
+ (by, locator) => {
1396
+ return window.codeceptjs.findElements(by, locator).map((el) => el.innerText)
1397
+ },
1398
+ locator.type,
1399
+ locator.value,
1400
+ )
1401
+ const allText = texts.join(' | ')
1402
+ return stringIncludes(description)[assertType](text, allText)
1311
1403
  }
1312
1404
 
1313
1405
  async function proceedSeeInField(assertType, field, value) {
1314
- const el = await findField.call(this, field);
1315
- assertElementExists(el, field, 'Field');
1316
- const tag = await this.browser.evaluate(el => window.codeceptjs.fetchElement(el).tagName, el);
1317
- const fieldVal = await this.browser.evaluate(el => window.codeceptjs.fetchElement(el).value, el);
1406
+ const el = await findField.call(this, field)
1407
+ assertElementExists(el, field, 'Field')
1408
+ const tag = await this.browser.evaluate((el) => window.codeceptjs.fetchElement(el).tagName, el)
1409
+ const fieldVal = await this.browser.evaluate((el) => window.codeceptjs.fetchElement(el).value, el)
1318
1410
  if (tag === 'select') {
1319
1411
  // locate option by values and check them
1320
- const text = await this.browser.evaluate((el, val) => {
1321
- return el.querySelector(`option[value="${val}"]`).innerText;
1322
- }, el, xpathLocator.literal(fieldVal));
1323
- return equals(`select option by ${field}`)[assertType](value, text);
1412
+ const text = await this.browser.evaluate(
1413
+ (el, val) => {
1414
+ return el.querySelector(`option[value="${val}"]`).innerText
1415
+ },
1416
+ el,
1417
+ xpathLocator.literal(fieldVal),
1418
+ )
1419
+ return equals(`select option by ${field}`)[assertType](value, text)
1324
1420
  }
1325
- return stringIncludes(`field by ${field}`)[assertType](value, fieldVal);
1421
+ return stringIncludes(`field by ${field}`)[assertType](value, fieldVal)
1326
1422
  }
1327
1423
 
1328
1424
  async function proceedIsChecked(assertType, option) {
1329
- const els = await findCheckable.call(this, option);
1330
- assertElementExists(els, option, 'Checkable');
1425
+ const els = await findCheckable.call(this, option)
1426
+ assertElementExists(els, option, 'Checkable')
1331
1427
  const selected = await this.browser.evaluate((els) => {
1332
- return els.map(el => window.codeceptjs.fetchElement(el).checked).reduce((prev, cur) => prev || cur);
1333
- }, els);
1334
- return truth(`checkable ${option}`, 'to be checked')[assertType](selected);
1428
+ return els.map((el) => window.codeceptjs.fetchElement(el).checked).reduce((prev, cur) => prev || cur)
1429
+ }, els)
1430
+ return truth(`checkable ${option}`, 'to be checked')[assertType](selected)
1335
1431
  }
1336
1432
 
1337
1433
  async function findCheckable(locator, context) {
1338
- let contextEl = null;
1434
+ let contextEl = null
1339
1435
  if (context) {
1340
- contextEl = await this.browser.findElement((new Locator(context, 'css')).toStrict());
1436
+ contextEl = await this.browser.findElement(new Locator(context, 'css').toStrict())
1341
1437
  }
1342
1438
 
1343
- const matchedLocator = new Locator(locator);
1439
+ const matchedLocator = new Locator(locator)
1344
1440
  if (!matchedLocator.isFuzzy()) {
1345
- return this.browser.findElements(matchedLocator.toStrict(), contextEl);
1441
+ return this.browser.findElements(matchedLocator.toStrict(), contextEl)
1346
1442
  }
1347
1443
 
1348
- const literal = xpathLocator.literal(locator);
1349
- let els = await this.browser.findElements({ xpath: Locator.checkable.byText(literal) }, contextEl);
1444
+ const literal = xpathLocator.literal(locator)
1445
+ let els = await this.browser.findElements({ xpath: Locator.checkable.byText(literal) }, contextEl)
1350
1446
  if (els.length) {
1351
- return els;
1447
+ return els
1352
1448
  }
1353
- els = await this.browser.findElements({ xpath: Locator.checkable.byName(literal) }, contextEl);
1449
+ els = await this.browser.findElements({ xpath: Locator.checkable.byName(literal) }, contextEl)
1354
1450
  if (els.length) {
1355
- return els;
1451
+ return els
1356
1452
  }
1357
- return this.browser.findElements({ css: locator }, contextEl);
1453
+ return this.browser.findElements({ css: locator }, contextEl)
1358
1454
  }
1359
1455
 
1360
1456
  async function findClickable(locator, context) {
1361
- let contextEl = null;
1457
+ let contextEl = null
1362
1458
  if (context) {
1363
- contextEl = await this.browser.findElement((new Locator(context, 'css')).toStrict());
1459
+ contextEl = await this.browser.findElement(new Locator(context, 'css').toStrict())
1364
1460
  }
1365
1461
 
1366
- const matchedLocator = new Locator(locator);
1462
+ const matchedLocator = new Locator(locator)
1367
1463
  if (!matchedLocator.isFuzzy()) {
1368
- return this.browser.findElement(matchedLocator.toStrict(), contextEl);
1464
+ return this.browser.findElement(matchedLocator.toStrict(), contextEl)
1369
1465
  }
1370
1466
 
1371
- const literal = xpathLocator.literal(locator);
1467
+ const literal = xpathLocator.literal(locator)
1372
1468
 
1373
- let els = await this.browser.findElements({ xpath: Locator.clickable.narrow(literal) }, contextEl);
1469
+ let els = await this.browser.findElements({ xpath: Locator.clickable.narrow(literal) }, contextEl)
1374
1470
  if (els.length) {
1375
- return els[0];
1471
+ return els[0]
1376
1472
  }
1377
1473
 
1378
- els = await this.browser.findElements({ xpath: Locator.clickable.wide(literal) }, contextEl);
1474
+ els = await this.browser.findElements({ xpath: Locator.clickable.wide(literal) }, contextEl)
1379
1475
  if (els.length) {
1380
- return els[0];
1476
+ return els[0]
1381
1477
  }
1382
1478
 
1383
- return this.browser.findElement({ css: locator }, contextEl);
1479
+ return this.browser.findElement({ css: locator }, contextEl)
1384
1480
  }
1385
1481
 
1386
1482
  async function findField(locator) {
1387
- const matchedLocator = new Locator(locator);
1483
+ const matchedLocator = new Locator(locator)
1388
1484
  if (!matchedLocator.isFuzzy()) {
1389
- return this.browser.findElements(matchedLocator.toStrict());
1485
+ return this.browser.findElements(matchedLocator.toStrict())
1390
1486
  }
1391
- const literal = xpathLocator.literal(locator);
1487
+ const literal = xpathLocator.literal(locator)
1392
1488
 
1393
- let els = await this.browser.findElements({ xpath: Locator.field.labelEquals(literal) });
1489
+ let els = await this.browser.findElements({ xpath: Locator.field.labelEquals(literal) })
1394
1490
  if (els.length) {
1395
- return els[0];
1491
+ return els[0]
1396
1492
  }
1397
1493
 
1398
- els = await this.browser.findElements({ xpath: Locator.field.labelContains(literal) });
1494
+ els = await this.browser.findElements({ xpath: Locator.field.labelContains(literal) })
1399
1495
  if (els.length) {
1400
- return els[0];
1496
+ return els[0]
1401
1497
  }
1402
- els = await this.browser.findElements({ xpath: Locator.field.byName(literal) });
1498
+ els = await this.browser.findElements({ xpath: Locator.field.byName(literal) })
1403
1499
  if (els.length) {
1404
- return els[0];
1500
+ return els[0]
1405
1501
  }
1406
- return this.browser.findElement({ css: locator });
1502
+ return this.browser.findElement({ css: locator })
1407
1503
  }
1408
1504
 
1409
1505
  function assertElementExists(el, locator, prefix, suffix) {
1410
- if (el === null) throw new ElementNotFound(locator, prefix, suffix);
1506
+ if (el === null) throw new ElementNotFound(locator, prefix, suffix)
1411
1507
  }