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
package/lib/output.js CHANGED
@@ -1,5 +1,5 @@
1
- import colors from 'chalk';
2
- import figures from 'figures';
1
+ const colors = require('chalk');
2
+ const figures = require('figures');
3
3
 
4
4
  const styles = {
5
5
  error: colors.bgRed.white.bold,
@@ -19,7 +19,7 @@ let newline = true;
19
19
  * @alias output
20
20
  * @namespace
21
21
  */
22
- export const output = {
22
+ module.exports = {
23
23
  colors,
24
24
  styles,
25
25
  print,
@@ -62,10 +62,6 @@ export const output = {
62
62
  }
63
63
  },
64
64
 
65
- debugSection(section, msg) {
66
- this.debug(`[${section}] ${msg}`);
67
- },
68
-
69
65
  /**
70
66
  * Print information in --verbose mode
71
67
  * @param {string} msg
@@ -117,7 +113,7 @@ export const output = {
117
113
 
118
114
  let stepLine = step.toString();
119
115
  if (step.metaStep && outputLevel >= 1) {
120
- this.stepShift += 2;
116
+ // this.stepShift += 2;
121
117
  stepLine = colors.green(truncate(stepLine, this.spaceShift));
122
118
  }
123
119
  if (step.comment) {
@@ -171,7 +167,7 @@ export const output = {
171
167
  scenario: {
172
168
  /**
173
169
  * @param {Mocha.Test} test
174
- */
170
+ */
175
171
  /* eslint-disable */
176
172
  started(test) {},
177
173
  /* eslint-enable */
@@ -236,7 +232,7 @@ export const output = {
236
232
  },
237
233
  };
238
234
 
239
- export function print(...msg) {
235
+ function print(...msg) {
240
236
  if (outputProcess) {
241
237
  msg.unshift(outputProcess);
242
238
  }
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', () => {
@@ -112,7 +113,7 @@ async function parseInput(cmd) {
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('');
@@ -146,7 +147,7 @@ async function parseInput(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;
@@ -160,15 +161,15 @@ async function parseInput(cmd) {
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
  }
@@ -1,10 +1,10 @@
1
- import * as event from '../event.js';
2
- import recorder from '../recorder.js';
3
- import { MetaStep } from '../step.js';
1
+ const event = require('../event')
2
+ const recorder = require('../recorder')
3
+ const { MetaStep } = require('../step')
4
4
 
5
- let currentCommentStep;
5
+ let currentCommentStep
6
6
 
7
- const defaultGlobalName = '__';
7
+ const defaultGlobalName = '__'
8
8
 
9
9
  /**
10
10
  * Add descriptive nested steps for your tests:
@@ -99,38 +99,38 @@ const defaultGlobalName = '__';
99
99
  * });
100
100
  * ```
101
101
  */
102
- export default function commentStep(config) {
102
+ module.exports = function (config) {
103
103
  event.dispatcher.on(event.test.started, () => {
104
- currentCommentStep = null;
105
- });
104
+ currentCommentStep = null
105
+ })
106
106
 
107
107
  event.dispatcher.on(event.step.started, (step) => {
108
108
  if (currentCommentStep) {
109
- const metaStep = getRootMetaStep(step);
109
+ const metaStep = getRootMetaStep(step)
110
110
 
111
111
  if (metaStep !== currentCommentStep) {
112
- metaStep.metaStep = currentCommentStep;
112
+ metaStep.metaStep = currentCommentStep
113
113
  }
114
114
  }
115
- });
115
+ })
116
116
 
117
117
  if (config.registerGlobal) {
118
118
  if (config.registerGlobal === true) {
119
- config.registerGlobal = defaultGlobalName;
119
+ config.registerGlobal = defaultGlobalName
120
120
  }
121
- global[config.registerGlobal] = setCommentString;
121
+ global[config.registerGlobal] = setCommentString
122
122
  }
123
123
 
124
- return setCommentString;
124
+ return setCommentString
125
125
  }
126
126
 
127
127
  function getRootMetaStep(step) {
128
- if (step.metaStep) return getRootMetaStep(step.metaStep);
129
- return step;
128
+ if (step.metaStep) return getRootMetaStep(step.metaStep)
129
+ return step
130
130
  }
131
131
 
132
132
  function setCommentString(string) {
133
133
  recorder.add('set comment metastep', () => {
134
- currentCommentStep = new MetaStep(String.raw(string), '');
135
- });
134
+ currentCommentStep = new MetaStep(String.raw(string), '')
135
+ })
136
136
  }