codeceptjs 4.0.0-beta.2 → 4.0.0-beta.4

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 (152) hide show
  1. package/README.md +2 -2
  2. package/bin/codecept.js +84 -81
  3. package/lib/actor.js +13 -13
  4. package/lib/ai.js +10 -13
  5. package/lib/assert/empty.js +20 -21
  6. package/lib/assert/equal.js +37 -39
  7. package/lib/assert/error.js +14 -14
  8. package/lib/assert/include.js +46 -47
  9. package/lib/assert/throws.js +13 -11
  10. package/lib/assert/truth.js +19 -22
  11. package/lib/assert.js +4 -2
  12. package/lib/cli.js +56 -49
  13. package/lib/codecept.js +145 -155
  14. package/lib/colorUtils.js +3 -3
  15. package/lib/command/configMigrate.js +58 -52
  16. package/lib/command/definitions.js +88 -89
  17. package/lib/command/dryRun.js +79 -81
  18. package/lib/command/generate.js +197 -188
  19. package/lib/command/gherkin/init.js +27 -16
  20. package/lib/command/gherkin/snippets.js +21 -21
  21. package/lib/command/gherkin/steps.js +8 -8
  22. package/lib/command/info.js +40 -38
  23. package/lib/command/init.js +290 -288
  24. package/lib/command/interactive.js +32 -32
  25. package/lib/command/list.js +26 -26
  26. package/lib/command/run-multiple/chunk.js +5 -5
  27. package/lib/command/run-multiple/collection.js +3 -3
  28. package/lib/command/run-multiple/run.js +6 -2
  29. package/lib/command/run-multiple.js +113 -93
  30. package/lib/command/run-rerun.js +20 -25
  31. package/lib/command/run-workers.js +64 -66
  32. package/lib/command/run.js +26 -29
  33. package/lib/command/utils.js +80 -65
  34. package/lib/command/workers/runTests.js +11 -12
  35. package/lib/config.js +10 -9
  36. package/lib/container.js +40 -48
  37. package/lib/data/context.js +60 -59
  38. package/lib/data/dataScenarioConfig.js +47 -47
  39. package/lib/data/dataTableArgument.js +29 -29
  40. package/lib/data/table.js +26 -20
  41. package/lib/event.js +163 -167
  42. package/lib/heal.js +14 -18
  43. package/lib/helper/AI.js +130 -41
  44. package/lib/helper/ApiDataFactory.js +74 -70
  45. package/lib/helper/Appium.js +416 -388
  46. package/lib/helper/ExpectHelper.js +40 -48
  47. package/lib/helper/FileSystem.js +80 -79
  48. package/lib/helper/GraphQL.js +44 -43
  49. package/lib/helper/GraphQLDataFactory.js +51 -51
  50. package/lib/helper/JSONResponse.js +65 -62
  51. package/lib/helper/Mochawesome.js +28 -28
  52. package/lib/helper/Nightmare.js +664 -571
  53. package/lib/helper/Playwright.js +1367 -1222
  54. package/lib/helper/Protractor.js +663 -635
  55. package/lib/helper/Puppeteer.js +1232 -1132
  56. package/lib/helper/REST.js +183 -68
  57. package/lib/helper/SoftExpectHelper.js +2 -2
  58. package/lib/helper/TestCafe.js +490 -486
  59. package/lib/helper/WebDriver.js +1246 -1297
  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 +4 -4
  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 +4 -3
  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 +7 -8
  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 +7 -11
  97. package/lib/mochaFactory.js +18 -15
  98. package/lib/output.js +19 -15
  99. package/lib/parser.js +15 -12
  100. package/lib/pause.js +45 -38
  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 +112 -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 -3
  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 -33
  136. package/package.json +67 -68
  137. package/translations/de-DE.js +2 -1
  138. package/translations/fr-FR.js +2 -2
  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 +423 -65
  148. package/typings/promiseBasedTypes.d.ts +41 -172
  149. package/typings/types.d.ts +43 -178
  150. package/lib/dirname.js +0 -5
  151. package/lib/helper/Expect.js +0 -425
  152. package/lib/helper/MockServer.js +0 -223
package/lib/output.js CHANGED
@@ -1,5 +1,6 @@
1
- import colors from 'chalk';
2
- import figures from 'figures';
1
+ const colors = require('chalk');
2
+ const figures = require('figures');
3
+ const { maskSensitiveData } = require('invisi-data')
3
4
 
4
5
  const styles = {
5
6
  error: colors.bgRed.white.bold,
@@ -19,7 +20,7 @@ let newline = true;
19
20
  * @alias output
20
21
  * @namespace
21
22
  */
22
- export const output = {
23
+ module.exports = {
23
24
  colors,
24
25
  styles,
25
26
  print,
@@ -57,22 +58,20 @@ export const output = {
57
58
  * @param {string} msg
58
59
  */
59
60
  debug(msg) {
61
+ const _msg = isMaskedData() ? maskSensitiveData(msg) : msg
60
62
  if (outputLevel >= 2) {
61
- print(' '.repeat(this.stepShift), styles.debug(`${figures.pointerSmall} ${msg}`));
63
+ print(' '.repeat(this.stepShift), styles.debug(`${figures.pointerSmall} ${_msg}`));
62
64
  }
63
65
  },
64
66
 
65
- debugSection(section, msg) {
66
- this.debug(`[${section}] ${msg}`);
67
- },
68
-
69
67
  /**
70
68
  * Print information in --verbose mode
71
69
  * @param {string} msg
72
70
  */
73
71
  log(msg) {
72
+ const _msg = isMaskedData() ? maskSensitiveData(msg) : msg
74
73
  if (outputLevel >= 3) {
75
- print(' '.repeat(this.stepShift), styles.log(truncate(` ${msg}`, this.spaceShift)));
74
+ print(' '.repeat(this.stepShift), styles.log(truncate(` ${_msg}`, this.spaceShift)));
76
75
  }
77
76
  },
78
77
 
@@ -117,14 +116,15 @@ export const output = {
117
116
 
118
117
  let stepLine = step.toString();
119
118
  if (step.metaStep && outputLevel >= 1) {
120
- this.stepShift += 2;
119
+ // this.stepShift += 2;
121
120
  stepLine = colors.green(truncate(stepLine, this.spaceShift));
122
121
  }
123
122
  if (step.comment) {
124
- stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4))); // eslint-disable-line
123
+ stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4)));
125
124
  }
126
125
 
127
- print(' '.repeat(this.stepShift), truncate(stepLine, this.spaceShift));
126
+ const _stepLine = isMaskedData() ? maskSensitiveData(stepLine) : stepLine
127
+ print(' '.repeat(this.stepShift), truncate(_stepLine, this.spaceShift));
128
128
  },
129
129
 
130
130
  /** @namespace */
@@ -172,9 +172,9 @@ export const output = {
172
172
  /**
173
173
  * @param {Mocha.Test} test
174
174
  */
175
- /* eslint-disable */
175
+
176
176
  started(test) {},
177
- /* eslint-enable */
177
+
178
178
  /**
179
179
  * @param {Mocha.Test} test
180
180
  */
@@ -236,7 +236,7 @@ export const output = {
236
236
  },
237
237
  };
238
238
 
239
- export function print(...msg) {
239
+ function print(...msg) {
240
240
  if (outputProcess) {
241
241
  msg.unshift(outputProcess);
242
242
  }
@@ -258,3 +258,7 @@ function truncate(msg, gap = 0) {
258
258
  }
259
259
  return msg;
260
260
  }
261
+
262
+ function isMaskedData() {
263
+ return global.maskSensitiveData === true || false
264
+ }
package/lib/parser.js CHANGED
@@ -1,20 +1,21 @@
1
- import { parse as acornParse } from 'acorn';
2
- import parseFunction from 'parse-function';
3
- import * as output from './output.js';
1
+ function _interopDefault(ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex.default : ex; }
2
+ const acorn = require('acorn');
3
+ const parser = _interopDefault(require('parse-function'))({ parse: acorn.parse, ecmaVersion: 11, plugins: ['objectRestSpread'] });
4
+ const { error } = require('./output');
4
5
 
5
- const app = parseFunction({ parse: acornParse, ecmaVersion: 11, plugins: ['objectRestSpread'] });
6
- app.use(destructuredArgs);
7
- export function getParamsToString(fn) {
6
+ parser.use(destructuredArgs);
7
+
8
+ module.exports.getParamsToString = function (fn) {
8
9
  const newFn = fn.toString().replace(/^async/, 'async function');
9
10
  return getParams(newFn).join(', ');
10
- }
11
+ };
11
12
 
12
- export function getParams(fn) {
13
+ function getParams(fn) {
13
14
  if (fn.isSinonProxy) return [];
14
15
  try {
15
- const reflected = app.parse(fn);
16
+ const reflected = parser.parse(fn);
16
17
  if (reflected.args.length > 1 || reflected.args[0] === 'I') {
17
- output.output.error('Error: old CodeceptJS v2 format detected. Upgrade your project to the new format -> https://bit.ly/codecept3Up');
18
+ error('Error: old CodeceptJS v2 format detected. Upgrade your project to the new format -> https://bit.ly/codecept3Up');
18
19
  }
19
20
  if (reflected.destructuredArgs.length > 0) reflected.args = [...reflected.destructuredArgs];
20
21
  const params = reflected.args.map((p) => {
@@ -27,11 +28,13 @@ export function getParams(fn) {
27
28
  return params;
28
29
  } catch (err) {
29
30
  console.log(`Error in ${fn.toString()}`);
30
- output.output.error(err);
31
+ error(err);
31
32
  }
32
33
  }
33
34
 
34
- export function destructuredArgs() {
35
+ module.exports.getParams = getParams;
36
+
37
+ function destructuredArgs() {
35
38
  return (node, result) => {
36
39
  result.destructuredArgs = result.destructuredArgs || [];
37
40
 
package/lib/pause.js CHANGED
@@ -1,18 +1,16 @@
1
- import colors from 'chalk';
2
- import readline from 'readline';
3
- import ora from 'ora-classic';
4
- import debug from 'debug';
5
-
6
- import container from './container.js';
7
- import history from './history.js';
8
- import { store } from './store.js';
9
- import AiAssistant from './ai.js';
10
- import recorder from './recorder.js';
11
- import * as event from './event.js';
12
- import * as output from './output.js';
13
- import { methodsOfObject } from './utils.js';
14
-
15
- debug('codeceptjs:pause');
1
+ const colors = require('chalk');
2
+ const readline = require('readline');
3
+ const ora = require('ora-classic');
4
+ const debug = require('debug')('codeceptjs:pause');
5
+
6
+ const container = require('./container');
7
+ const history = require('./history');
8
+ const store = require('./store');
9
+ const aiAssistant = require('./ai');
10
+ const recorder = require('./recorder');
11
+ const event = require('./event');
12
+ const output = require('./output');
13
+ const { methodsOfObject } = require('./utils');
16
14
 
17
15
  // npm install colors
18
16
  let rl;
@@ -20,7 +18,6 @@ let nextStep;
20
18
  let finish;
21
19
  let next;
22
20
  let registeredVariables = {};
23
- let aiAssistant;
24
21
  /**
25
22
  * Pauses test execution and starts interactive shell
26
23
  * @param {Object<string, *>} [passedObject]
@@ -46,8 +43,6 @@ function pauseSession(passedObject = {}) {
46
43
  let vars = Object.keys(registeredVariables).join(', ');
47
44
  if (vars) vars = `(vars: ${vars})`;
48
45
 
49
- aiAssistant = AiAssistant.getInstance();
50
-
51
46
  output.print(colors.yellow(' Interactive shell started'));
52
47
  output.print(colors.yellow(' Use JavaScript syntax to try steps in action'));
53
48
  output.print(colors.yellow(` - Press ${colors.bold('ENTER')} to run the next step`));
@@ -56,14 +51,20 @@ function pauseSession(passedObject = {}) {
56
51
  output.print(colors.yellow(` - Prefix ${colors.bold('=>')} to run js commands ${colors.bold(vars)}`));
57
52
 
58
53
  if (aiAssistant.isEnabled) {
59
- output.print(colors.blue(` ${colors.bold('OpenAI is enabled! (experimental)')} Write what you want and make OpenAI run it`));
60
- output.print(colors.blue(' Please note, only HTML fragments with interactive elements are sent to OpenAI'));
54
+ output.print(colors.blue(` ${colors.bold('AI is enabled! (experimental)')} Write what you want and make AI run it`));
55
+ output.print(colors.blue(' Please note, only HTML fragments with interactive elements are sent to AI provider'));
61
56
  output.print(colors.blue(' Ideas: ask it to fill forms for you or to click'));
62
- } else {
63
- output.print(colors.blue(` Enable OpenAI assistant by setting ${colors.bold('OPENAI_API_KEY')} env variable`));
64
57
  }
65
58
  }
66
- rl = readline.createInterface(process.stdin, process.stdout, completer);
59
+
60
+ rl = readline.createInterface({
61
+ input: process.stdin,
62
+ output: process.stdout,
63
+ terminal: true,
64
+ completer,
65
+ history: history.load(),
66
+ historySize: 50, // Adjust the history size as needed
67
+ });
67
68
 
68
69
  rl.on('line', parseInput);
69
70
  rl.on('close', () => {
@@ -90,7 +91,7 @@ async function parseInput(cmd) {
90
91
  return nextStep();
91
92
  }
92
93
  for (const k of Object.keys(registeredVariables)) {
93
- eval(`var ${k} = registeredVariables['${k}'];`); // eslint-disable-line no-eval
94
+ eval(`var ${k} = registeredVariables['${k}'];`);
94
95
  }
95
96
 
96
97
  let executeCommand = Promise.resolve();
@@ -105,14 +106,14 @@ async function parseInput(cmd) {
105
106
  let isAiCommand = false;
106
107
  let $res;
107
108
  try {
108
- // eslint-disable-next-line
109
+
109
110
  const locate = global.locate; // enable locate in this context
110
- // eslint-disable-next-line
111
+
111
112
  const I = container.support('I');
112
113
  if (cmd.trim().startsWith('=>')) {
113
114
  isCustomCommand = true;
114
115
  cmd = cmd.trim().substring(2, cmd.length);
115
- } else if (aiAssistant.isEnabled && !cmd.match(/^\w+\(/) && cmd.includes(' ')) {
116
+ } else if (aiAssistant.isEnabled && cmd.trim() && !cmd.match(/^\w+\(/) && cmd.includes(' ')) {
116
117
  const currentOutputLevel = output.level();
117
118
  output.level(0);
118
119
  const res = I.grabSource();
@@ -122,13 +123,13 @@ async function parseInput(cmd) {
122
123
  const html = await res;
123
124
  await aiAssistant.setHtmlContext(html);
124
125
  } catch (err) {
125
- output.print(output.output.styles.error(' ERROR '), 'Can\'t get HTML context', err.stack);
126
+ output.print(output.styles.error(' ERROR '), 'Can\'t get HTML context', err.stack);
126
127
  return;
127
128
  } finally {
128
129
  output.level(currentOutputLevel);
129
130
  }
130
- // aiAssistant.mockResponse("```js\nI.click('Sign in');\n```");
131
- const spinner = ora("Processing OpenAI request...").start();
131
+
132
+ const spinner = ora("Processing AI request...").start();
132
133
  cmd = await aiAssistant.writeSteps(cmd);
133
134
  spinner.stop();
134
135
  output.print('');
@@ -142,11 +143,11 @@ async function parseInput(cmd) {
142
143
  executeCommand = executeCommand.then(async () => {
143
144
  const cmd = getCmd();
144
145
  if (!cmd) return;
145
- return eval(cmd); // eslint-disable-line no-eval
146
+ return eval(cmd);
146
147
  }).catch((err) => {
147
148
  debug(err);
148
149
  if (isAiCommand) return;
149
- if (!lastError) output.print(output.output.styles.error(' ERROR '), err.message);
150
+ if (!lastError) output.print(output.styles.error(' ERROR '), err.message);
150
151
  debug(err.stack)
151
152
 
152
153
  lastError = err.message;
@@ -155,20 +156,20 @@ async function parseInput(cmd) {
155
156
  const val = await executeCommand;
156
157
 
157
158
  if (isCustomCommand) {
158
- if (val !== undefined) console.log('Result', '$res=', val); // eslint-disable-line
159
+ if (val !== undefined) console.log('Result', '$res=', val);
159
160
  $res = val;
160
161
  }
161
162
 
162
163
  if (cmd?.startsWith('I.see') || cmd?.startsWith('I.dontSee')) {
163
- output.print(output.output.styles.success(' OK '), cmd);
164
+ output.print(output.styles.success(' OK '), cmd);
164
165
  }
165
166
  if (cmd?.startsWith('I.grab')) {
166
- output.print(output.output.styles.debug(val));
167
+ output.print(output.styles.debug(val));
167
168
  }
168
169
 
169
170
  history.push(cmd); // add command to history when successful
170
171
  } catch (err) {
171
- if (!lastError) output.print(output.output.styles.error(' ERROR '), err.message);
172
+ if (!lastError) output.print(output.styles.error(' ERROR '), err.message);
172
173
  lastError = err.message;
173
174
  }
174
175
  recorder.session.catch((err) => {
@@ -178,7 +179,7 @@ async function parseInput(cmd) {
178
179
  history.pop();
179
180
 
180
181
  if (isAiCommand) return;
181
- if (!lastError) output.print(output.output.styles.error(' FAIL '), msg);
182
+ if (!lastError) output.print(output.styles.error(' FAIL '), msg);
182
183
  lastError = err.message;
183
184
  });
184
185
  recorder.add('ask for next step', askForStep);
@@ -207,4 +208,10 @@ function completer(line) {
207
208
  return [hits && hits.length ? hits : completions, line];
208
209
  }
209
210
 
210
- export default pause;
211
+ function registerVariable(name, value) {
212
+ registeredVariables[name] = value;
213
+ }
214
+
215
+ module.exports = pause;
216
+
217
+ module.exports.registerVariable = registerVariable;
@@ -1,15 +1,15 @@
1
- export default () => {
2
- console.log('Allure plugin was moved to @codeceptjs/allure-legacy. Please install it and update your config');
3
- console.log();
4
- console.log('npm install @codeceptjs/allure-legacy --save-dev');
5
- console.log();
6
- console.log('Then update your config to use it:');
7
- console.log();
8
- console.log('plugins: {');
9
- console.log(' allure: {');
10
- console.log(' enabled: true,');
11
- console.log(' require: \'@codeceptjs/allure-legacy\',');
12
- console.log(' }');
13
- console.log('}');
14
- console.log();
15
- };
1
+ module.exports = () => {
2
+ console.log('Allure plugin was moved to @codeceptjs/allure-legacy. Please install it and update your config')
3
+ console.log()
4
+ console.log('npm install @codeceptjs/allure-legacy --save-dev')
5
+ console.log()
6
+ console.log('Then update your config to use it:')
7
+ console.log()
8
+ console.log('plugins: {')
9
+ console.log(' allure: {')
10
+ console.log(' enabled: true,')
11
+ console.log(" require: '@codeceptjs/allure-legacy',")
12
+ console.log(' }')
13
+ console.log('}')
14
+ console.log()
15
+ }
@@ -1,25 +1,17 @@
1
- import Container from '../container.js';
2
- import { store } from '../store.js';
3
- import recorder from '../recorder.js';
4
- import * as event from '../event.js';
5
- import { log } from '../output.js';
1
+ const Container = require('../container')
2
+ const store = require('../store')
3
+ const recorder = require('../recorder')
4
+ const event = require('../event')
5
+ const log = require('../output').log
6
+ const supportedHelpers = require('./standardActingHelpers').slice()
6
7
 
7
- const supportedHelpers = require('./standardActingHelpers.js').slice();
8
-
9
- const methodsToDelay = [
10
- 'click',
11
- 'fillField',
12
- 'checkOption',
13
- 'pressKey',
14
- 'doubleClick',
15
- 'rightClick',
16
- ];
8
+ const methodsToDelay = ['click', 'fillField', 'checkOption', 'pressKey', 'doubleClick', 'rightClick']
17
9
 
18
10
  const defaultConfig = {
19
11
  methods: methodsToDelay,
20
12
  delayBefore: 100,
21
13
  delayAfter: 200,
22
- };
14
+ }
23
15
 
24
16
  /**
25
17
  *
@@ -59,42 +51,42 @@ const defaultConfig = {
59
51
  * * `delayAfter`: put a delay after a command. 200ms by default
60
52
  *
61
53
  */
62
- export default function (config) {
63
- supportedHelpers.push('REST');
64
- const helpers = Container.helpers();
65
- let helper;
54
+ module.exports = function (config) {
55
+ supportedHelpers.push('REST')
56
+ const helpers = Container.helpers()
57
+ let helper
66
58
 
67
- config = Object.assign(defaultConfig, config);
59
+ config = Object.assign(defaultConfig, config)
68
60
 
69
61
  for (const helperName of supportedHelpers) {
70
62
  if (Object.keys(helpers).indexOf(helperName) > -1) {
71
- helper = helpers[helperName];
63
+ helper = helpers[helperName]
72
64
  }
73
65
  }
74
66
 
75
- if (!helper) return; // no helpers for auto-delay
67
+ if (!helper) return // no helpers for auto-delay
76
68
 
77
69
  event.dispatcher.on(event.step.before, (step) => {
78
- if (config.methods.indexOf(step.helperMethod) < 0) return; // skip non-actions
70
+ if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
79
71
 
80
72
  recorder.add('auto-delay', async () => {
81
- if (store.debugMode) return; // no need to delay in debug
82
- log(`Delaying for ${config.delayBefore}ms`);
73
+ if (store.debugMode) return // no need to delay in debug
74
+ log(`Delaying for ${config.delayBefore}ms`)
83
75
  return new Promise((resolve) => {
84
- setTimeout(resolve, config.delayBefore);
85
- });
86
- });
87
- });
76
+ setTimeout(resolve, config.delayBefore)
77
+ })
78
+ })
79
+ })
88
80
 
89
81
  event.dispatcher.on(event.step.after, (step) => {
90
- if (config.methods.indexOf(step.helperMethod) < 0) return; // skip non-actions
82
+ if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
91
83
 
92
84
  recorder.add('auto-delay', async () => {
93
- if (store.debugMode) return; // no need to delay in debug
94
- log(`Delaying for ${config.delayAfter}ms`);
85
+ if (store.debugMode) return // no need to delay in debug
86
+ log(`Delaying for ${config.delayAfter}ms`)
95
87
  return new Promise((resolve) => {
96
- setTimeout(resolve, config.delayAfter);
97
- });
98
- });
99
- });
88
+ setTimeout(resolve, config.delayAfter)
89
+ })
90
+ })
91
+ })
100
92
  }
@@ -1,24 +1,25 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { fileExists, isAsyncFunction } from '../utils.js';
4
- import container from '../container.js';
5
- import { store } from '../store.js';
6
- import recorder from '../recorder.js';
7
- import { debug } from '../output.js';
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const { fileExists } = require('../utils')
4
+ const container = require('../container')
5
+ const store = require('../store')
6
+ const recorder = require('../recorder')
7
+ const { debug } = require('../output')
8
+ const isAsyncFunction = require('../utils').isAsyncFunction
8
9
 
9
10
  const defaultUser = {
10
- fetch: I => I.grabCookie(),
11
+ fetch: (I) => I.grabCookie(),
11
12
  check: () => {},
12
13
  restore: (I, cookies) => {
13
- I.amOnPage('/'); // open a page
14
- I.setCookie(cookies);
14
+ I.amOnPage('/') // open a page
15
+ I.setCookie(cookies)
15
16
  },
16
- };
17
+ }
17
18
 
18
19
  const defaultConfig = {
19
20
  saveToFile: false,
20
21
  inject: 'login',
21
- };
22
+ }
22
23
 
23
24
  /**
24
25
  * Logs user in for the first test and reuses session for next tests.
@@ -248,88 +249,92 @@ const defaultConfig = {
248
249
  * })
249
250
  *
250
251
  *
251
- */
252
- export default function (config) {
253
- config = Object.assign(defaultConfig, config);
254
- Object.keys(config.users).map(u => config.users[u] = {
255
- ...defaultUser,
256
- ...config.users[u],
257
- });
252
+ */
253
+ module.exports = function (config) {
254
+ config = Object.assign(defaultConfig, config)
255
+ Object.keys(config.users).map(
256
+ (u) =>
257
+ (config.users[u] = {
258
+ ...defaultUser,
259
+ ...config.users[u],
260
+ }),
261
+ )
258
262
 
259
263
  if (config.saveToFile) {
260
264
  // loading from file
261
265
  for (const name in config.users) {
262
- const fileName = path.join(global.output_dir, `${name}_session.json`);
263
- if (!fileExists(fileName)) continue;
264
- const data = fs.readFileSync(fileName).toString();
266
+ const fileName = path.join(global.output_dir, `${name}_session.json`)
267
+ if (!fileExists(fileName)) continue
268
+ const data = fs.readFileSync(fileName).toString()
265
269
  try {
266
- store[`${name}_session`] = JSON.parse(data);
270
+ store[`${name}_session`] = JSON.parse(data)
267
271
  } catch (err) {
268
- throw new Error(`Could not load session from ${fileName}\n${err}`);
272
+ throw new Error(`Could not load session from ${fileName}\n${err}`)
269
273
  }
270
- debug(`Loaded user session for ${name}`);
274
+ debug(`Loaded user session for ${name}`)
271
275
  }
272
276
  }
273
277
 
274
278
  const loginFunction = async (name) => {
275
- const userSession = config.users[name];
276
- const I = container.support('I');
277
- const cookies = store[`${name}_session`];
278
- const shouldAwait = isAsyncFunction(userSession.login)
279
- || isAsyncFunction(userSession.restore)
280
- || isAsyncFunction(userSession.check);
279
+ const userSession = config.users[name]
280
+ const I = container.support('I')
281
+ const cookies = store[`${name}_session`]
282
+ const shouldAwait =
283
+ isAsyncFunction(userSession.login) || isAsyncFunction(userSession.restore) || isAsyncFunction(userSession.check)
281
284
 
282
285
  const loginAndSave = async () => {
283
286
  if (shouldAwait) {
284
- await userSession.login(I);
287
+ await userSession.login(I)
285
288
  } else {
286
- userSession.login(I);
289
+ userSession.login(I)
287
290
  }
288
291
 
289
- const cookies = await userSession.fetch(I);
292
+ const cookies = await userSession.fetch(I)
290
293
  if (!cookies) {
291
- debug('Cannot save user session with empty cookies from auto login\'s fetch method');
292
- return;
294
+ debug("Cannot save user session with empty cookies from auto login's fetch method")
295
+ return
293
296
  }
294
297
  if (config.saveToFile) {
295
- debug(`Saved user session into file for ${name}`);
296
- fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies));
298
+ debug(`Saved user session into file for ${name}`)
299
+ fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies))
297
300
  }
298
- store[`${name}_session`] = cookies;
299
- };
301
+ store[`${name}_session`] = cookies
302
+ }
300
303
 
301
- if (!cookies) return loginAndSave();
304
+ if (!cookies) return loginAndSave()
302
305
 
303
- recorder.session.start('check login');
306
+ recorder.session.start('check login')
304
307
  if (shouldAwait) {
305
- await userSession.restore(I, cookies);
306
- await userSession.check(I, cookies);
308
+ await userSession.restore(I, cookies)
309
+ await userSession.check(I, cookies)
307
310
  } else {
308
- userSession.restore(I, cookies);
309
- userSession.check(I, cookies);
311
+ userSession.restore(I, cookies)
312
+ userSession.check(I, cookies)
310
313
  }
311
314
  recorder.session.catch((err) => {
312
- debug(`Failed auto login for ${name} due to ${err}`);
313
- debug('Logging in again');
314
- recorder.session.start('auto login');
315
- return loginAndSave().then(() => {
316
- recorder.add(() => recorder.session.restore('auto login'));
317
- recorder.catch(() => debug('continue'));
318
- }).catch((err) => {
319
- recorder.session.restore('auto login');
320
- recorder.session.restore('check login');
321
- recorder.throw(err);
322
- });
323
- });
315
+ debug(`Failed auto login for ${name} due to ${err}`)
316
+ debug('Logging in again')
317
+ recorder.session.start('auto login')
318
+ return loginAndSave()
319
+ .then(() => {
320
+ recorder.add(() => recorder.session.restore('auto login'))
321
+ recorder.catch(() => debug('continue'))
322
+ })
323
+ .catch((err) => {
324
+ recorder.session.restore('auto login')
325
+ recorder.session.restore('check login')
326
+ recorder.throw(err)
327
+ })
328
+ })
324
329
  recorder.add(() => {
325
- recorder.session.restore('check login');
326
- });
330
+ recorder.session.restore('check login')
331
+ })
327
332
 
328
- return recorder.promise();
329
- };
333
+ return recorder.promise()
334
+ }
330
335
 
331
336
  // adding this to DI container
332
- const support = {};
333
- support[config.inject] = loginFunction;
334
- container.append({ support });
337
+ const support = {}
338
+ support[config.inject] = loginFunction
339
+ container.append({ support })
335
340
  }