codeceptjs 3.6.4-beta.2 → 3.6.5-beta.1

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 (92) hide show
  1. package/bin/codecept.js +84 -63
  2. package/lib/ai.js +47 -1
  3. package/lib/assert/empty.js +19 -19
  4. package/lib/assert/equal.js +32 -30
  5. package/lib/assert/error.js +14 -14
  6. package/lib/assert/include.js +42 -42
  7. package/lib/assert/throws.js +13 -11
  8. package/lib/assert/truth.js +17 -18
  9. package/lib/command/configMigrate.js +57 -52
  10. package/lib/command/definitions.js +88 -88
  11. package/lib/command/dryRun.js +65 -63
  12. package/lib/command/generate.js +191 -181
  13. package/lib/command/info.js +39 -37
  14. package/lib/command/init.js +289 -286
  15. package/lib/command/interactive.js +32 -32
  16. package/lib/command/list.js +26 -26
  17. package/lib/command/run-multiple.js +113 -93
  18. package/lib/command/run-rerun.js +22 -22
  19. package/lib/command/run-workers.js +63 -63
  20. package/lib/command/run.js +24 -26
  21. package/lib/command/utils.js +64 -63
  22. package/lib/data/context.js +60 -60
  23. package/lib/data/dataScenarioConfig.js +47 -47
  24. package/lib/data/dataTableArgument.js +29 -29
  25. package/lib/data/table.js +26 -20
  26. package/lib/helper/AI.js +114 -35
  27. package/lib/helper/ApiDataFactory.js +72 -69
  28. package/lib/helper/Appium.js +409 -379
  29. package/lib/helper/ExpectHelper.js +214 -248
  30. package/lib/helper/FileSystem.js +77 -78
  31. package/lib/helper/GraphQL.js +44 -43
  32. package/lib/helper/GraphQLDataFactory.js +49 -50
  33. package/lib/helper/JSONResponse.js +64 -62
  34. package/lib/helper/Mochawesome.js +28 -28
  35. package/lib/helper/MockServer.js +12 -12
  36. package/lib/helper/Nightmare.js +664 -572
  37. package/lib/helper/Playwright.js +1320 -1211
  38. package/lib/helper/Protractor.js +663 -629
  39. package/lib/helper/Puppeteer.js +1232 -1124
  40. package/lib/helper/REST.js +115 -69
  41. package/lib/helper/TestCafe.js +490 -491
  42. package/lib/helper/WebDriver.js +1294 -1156
  43. package/lib/history.js +16 -3
  44. package/lib/interfaces/bdd.js +38 -51
  45. package/lib/interfaces/featureConfig.js +19 -19
  46. package/lib/interfaces/gherkin.js +122 -111
  47. package/lib/interfaces/scenarioConfig.js +29 -29
  48. package/lib/listener/artifacts.js +9 -9
  49. package/lib/listener/config.js +24 -23
  50. package/lib/listener/exit.js +12 -12
  51. package/lib/listener/helpers.js +42 -42
  52. package/lib/listener/mocha.js +11 -11
  53. package/lib/listener/retry.js +32 -30
  54. package/lib/listener/steps.js +50 -51
  55. package/lib/listener/timeout.js +53 -53
  56. package/lib/pause.js +17 -3
  57. package/lib/plugin/allure.js +14 -14
  58. package/lib/plugin/autoDelay.js +29 -36
  59. package/lib/plugin/autoLogin.js +70 -66
  60. package/lib/plugin/commentStep.js +18 -18
  61. package/lib/plugin/coverage.js +92 -77
  62. package/lib/plugin/customLocator.js +20 -19
  63. package/lib/plugin/debugErrors.js +24 -24
  64. package/lib/plugin/eachElement.js +37 -37
  65. package/lib/plugin/fakerTransform.js +6 -6
  66. package/lib/plugin/heal.js +66 -63
  67. package/lib/plugin/pauseOnFail.js +10 -10
  68. package/lib/plugin/retryFailedStep.js +31 -38
  69. package/lib/plugin/retryTo.js +28 -28
  70. package/lib/plugin/screenshotOnFail.js +107 -86
  71. package/lib/plugin/selenoid.js +131 -117
  72. package/lib/plugin/standardActingHelpers.js +2 -8
  73. package/lib/plugin/stepByStepReport.js +102 -92
  74. package/lib/plugin/stepTimeout.js +23 -22
  75. package/lib/plugin/subtitles.js +34 -34
  76. package/lib/plugin/tryTo.js +39 -29
  77. package/lib/plugin/wdio.js +77 -72
  78. package/lib/template/heal.js +11 -14
  79. package/package.json +5 -3
  80. package/translations/de-DE.js +1 -1
  81. package/translations/fr-FR.js +1 -1
  82. package/translations/index.js +9 -9
  83. package/translations/it-IT.js +1 -1
  84. package/translations/ja-JP.js +1 -1
  85. package/translations/pl-PL.js +1 -1
  86. package/translations/pt-BR.js +1 -1
  87. package/translations/ru-RU.js +1 -1
  88. package/translations/zh-CN.js +1 -1
  89. package/translations/zh-TW.js +1 -1
  90. package/typings/index.d.ts +42 -19
  91. package/typings/promiseBasedTypes.d.ts +280 -1
  92. package/typings/types.d.ts +76 -1
package/lib/history.js CHANGED
@@ -10,6 +10,9 @@ const output = require('./output');
10
10
  */
11
11
  class ReplHistory {
12
12
  constructor() {
13
+ if (global.output_dir) {
14
+ this.historyFile = path.join(global.output_dir, 'cli-history');
15
+ }
13
16
  this.commands = [];
14
17
  }
15
18
 
@@ -21,16 +24,26 @@ class ReplHistory {
21
24
  this.commands.pop();
22
25
  }
23
26
 
27
+ load() {
28
+ if (!this.historyFile) return;
29
+ if (!fs.existsSync(this.historyFile)) {
30
+ return;
31
+ }
32
+
33
+ const history = fs.readFileSync(this.historyFile, 'utf-8');
34
+ return history.split('\n').reverse().filter(line => line.startsWith('I.')).map(line => line.slice(2));
35
+ }
36
+
24
37
  save() {
38
+ if (!this.historyFile) return;
25
39
  if (this.commands.length === 0) {
26
40
  return;
27
41
  }
28
42
 
29
- const historyFile = path.join(global.output_dir, 'cli-history');
30
43
  const commandSnippet = `\n\n<<< Recorded commands on ${new Date()}\n${this.commands.join('\n')}`;
31
- fs.appendFileSync(historyFile, commandSnippet);
44
+ fs.appendFileSync(this.historyFile, commandSnippet);
32
45
 
33
- output.print(colors.yellow(` Commands have been saved to ${historyFile}`));
46
+ output.print(colors.yellow(` Commands have been saved to ${this.historyFile}`));
34
47
 
35
48
  this.commands = [];
36
49
  }
@@ -1,86 +1,73 @@
1
- const { CucumberExpression, ParameterTypeRegistry, ParameterType } = require('@cucumber/cucumber-expressions');
2
- const Config = require('../config');
1
+ const { CucumberExpression, ParameterTypeRegistry, ParameterType } = require('@cucumber/cucumber-expressions')
2
+ const Config = require('../config')
3
3
 
4
- let steps = {};
4
+ let steps = {}
5
5
 
6
- const STACK_POSITION = 2;
6
+ const STACK_POSITION = 2
7
7
 
8
8
  /**
9
9
  * @param {*} step
10
10
  * @param {*} fn
11
11
  */
12
12
  const addStep = (step, fn) => {
13
- const avoidDuplicateSteps = Config.get('gherkin', {}).avoidDuplicateSteps || false;
14
- const stack = (new Error()).stack;
13
+ const avoidDuplicateSteps = Config.get('gherkin', {}).avoidDuplicateSteps || false
14
+ const stack = new Error().stack
15
15
  if (avoidDuplicateSteps && steps[step]) {
16
- throw new Error(`Step '${step}' is already defined`);
16
+ throw new Error(`Step '${step}' is already defined`)
17
17
  }
18
- steps[step] = fn;
19
- fn.line = stack && stack.split('\n')[STACK_POSITION];
18
+ steps[step] = fn
19
+ fn.line = stack && stack.split('\n')[STACK_POSITION]
20
20
  if (fn.line) {
21
21
  fn.line = fn.line
22
22
  .trim()
23
23
  .replace(/^at (.*?)\(/, '(')
24
- .replace(codecept_dir, '.');
24
+ .replace(codecept_dir, '.')
25
25
  }
26
- };
26
+ }
27
27
 
28
- const parameterTypeRegistry = new ParameterTypeRegistry();
28
+ const parameterTypeRegistry = new ParameterTypeRegistry()
29
29
 
30
30
  const matchStep = (step) => {
31
31
  for (const stepName in steps) {
32
32
  if (stepName.indexOf('/') === 0) {
33
- const regExpArr = stepName.match(/^\/(.*?)\/([gimy]*)$/) || [];
34
- const res = step.match(new RegExp(regExpArr[1], regExpArr[2]));
33
+ const regExpArr = stepName.match(/^\/(.*?)\/([gimy]*)$/) || []
34
+ const res = step.match(new RegExp(regExpArr[1], regExpArr[2]))
35
35
  if (res) {
36
- const fn = steps[stepName];
37
- fn.params = res.slice(1);
38
- return fn;
36
+ const fn = steps[stepName]
37
+ fn.params = res.slice(1)
38
+ return fn
39
39
  }
40
- continue;
40
+ continue
41
41
  }
42
- const expression = new CucumberExpression(stepName, parameterTypeRegistry);
43
- const res = expression.match(step);
42
+ const expression = new CucumberExpression(stepName, parameterTypeRegistry)
43
+ const res = expression.match(step)
44
44
  if (res) {
45
- const fn = steps[stepName];
46
- fn.params = res.map(arg => arg.getValue());
47
- return fn;
45
+ const fn = steps[stepName]
46
+ fn.params = res.map((arg) => arg.getValue())
47
+ return fn
48
48
  }
49
49
  }
50
- throw new Error(`No steps matching "${step.toString()}"`);
51
- };
50
+ throw new Error(`No steps matching "${step.toString()}"`)
51
+ }
52
52
 
53
53
  const clearSteps = () => {
54
- steps = {};
55
- };
54
+ steps = {}
55
+ }
56
56
 
57
57
  const getSteps = () => {
58
- return steps;
59
- };
58
+ return steps
59
+ }
60
60
 
61
61
  const defineParameterType = (options) => {
62
- const parameterType = buildParameterType(options);
63
- parameterTypeRegistry.defineParameterType(parameterType);
64
- };
62
+ const parameterType = buildParameterType(options)
63
+ parameterTypeRegistry.defineParameterType(parameterType)
64
+ }
65
65
 
66
- const buildParameterType = ({
67
- name,
68
- regexp,
69
- transformer,
70
- useForSnippets,
71
- preferForRegexpMatch,
72
- }) => {
73
- if (typeof useForSnippets !== 'boolean') useForSnippets = true;
74
- if (typeof preferForRegexpMatch !== 'boolean') preferForRegexpMatch = false;
75
- return new ParameterType(
76
- name,
77
- regexp,
78
- null,
79
- transformer,
80
- useForSnippets,
81
- preferForRegexpMatch,
82
- );
83
- };
66
+ const buildParameterType = ({ name, regexp, transformer, useForSnippets, preferForRegexpMatch }) => {
67
+ if (typeof useForSnippets !== 'boolean') useForSnippets = true
68
+ if (typeof preferForRegexpMatch !== 'boolean') preferForRegexpMatch = false
69
+ return new ParameterType(name, regexp, null, transformer, useForSnippets, preferForRegexpMatch)
70
+ }
84
71
 
85
72
  module.exports = {
86
73
  Given: addStep,
@@ -91,4 +78,4 @@ module.exports = {
91
78
  getSteps,
92
79
  clearSteps,
93
80
  defineParameterType,
94
- };
81
+ }
@@ -1,7 +1,7 @@
1
1
  /** @class */
2
2
  class FeatureConfig {
3
3
  constructor(suite) {
4
- this.suite = suite;
4
+ this.suite = suite
5
5
  }
6
6
 
7
7
  /**
@@ -11,8 +11,8 @@ class FeatureConfig {
11
11
  * @returns {this}
12
12
  */
13
13
  retry(retries) {
14
- this.suite.retries(retries);
15
- return this;
14
+ this.suite.retries(retries)
15
+ return this
16
16
  }
17
17
 
18
18
  /**
@@ -22,11 +22,11 @@ class FeatureConfig {
22
22
  * @deprecated
23
23
  */
24
24
  timeout(timeout) {
25
- console.log(`Feature('${this.suite.title}').timeout(${timeout}) is deprecated!`);
26
- console.log(`Please use Feature('${this.suite.title}', { timeout: ${timeout / 1000} }) instead`);
27
- console.log('Timeout should be set in seconds');
28
- this.suite.timeout(timeout);
29
- return this;
25
+ console.log(`Feature('${this.suite.title}').timeout(${timeout}) is deprecated!`)
26
+ console.log(`Please use Feature('${this.suite.title}', { timeout: ${timeout / 1000} }) instead`)
27
+ console.log('Timeout should be set in seconds')
28
+ this.suite.timeout(timeout)
29
+ return this
30
30
  }
31
31
 
32
32
  /**
@@ -38,17 +38,17 @@ class FeatureConfig {
38
38
  */
39
39
  config(helper, obj) {
40
40
  if (!obj) {
41
- obj = helper;
42
- helper = 0;
41
+ obj = helper
42
+ helper = 0
43
43
  }
44
44
  if (typeof obj === 'function') {
45
- obj = obj(this.suite);
45
+ obj = obj(this.suite)
46
46
  }
47
47
  if (!this.suite.config) {
48
- this.suite.config = {};
48
+ this.suite.config = {}
49
49
  }
50
- this.suite.config[helper] = obj;
51
- return this;
50
+ this.suite.config[helper] = obj
51
+ return this
52
52
  }
53
53
 
54
54
  /**
@@ -58,12 +58,12 @@ class FeatureConfig {
58
58
  */
59
59
  tag(tagName) {
60
60
  if (tagName[0] !== '@') {
61
- tagName = `@${tagName}`;
61
+ tagName = `@${tagName}`
62
62
  }
63
- this.suite.tags.push(tagName);
64
- this.suite.title = `${this.suite.title.trim()} ${tagName}`;
65
- return this;
63
+ this.suite.tags.push(tagName)
64
+ this.suite.title = `${this.suite.title.trim()} ${tagName}`
65
+ return this
66
66
  }
67
67
  }
68
68
 
69
- module.exports = FeatureConfig;
69
+ module.exports = FeatureConfig
@@ -1,190 +1,201 @@
1
- const Gherkin = require('@cucumber/gherkin');
2
- const Messages = require('@cucumber/messages');
3
- const { Context, Suite, Test } = require('mocha');
4
- const debug = require('debug')('codeceptjs:bdd');
5
-
6
- const { matchStep } = require('./bdd');
7
- const event = require('../event');
8
- const scenario = require('../scenario');
9
- const Step = require('../step');
10
- const DataTableArgument = require('../data/dataTableArgument');
11
- const transform = require('../transform');
12
-
13
- const uuidFn = Messages.IdGenerator.uuid();
14
- const builder = new Gherkin.AstBuilder(uuidFn);
15
- const matcher = new Gherkin.GherkinClassicTokenMatcher();
16
- const parser = new Gherkin.Parser(builder, matcher);
17
- parser.stopAtFirstError = false;
1
+ const Gherkin = require('@cucumber/gherkin')
2
+ const Messages = require('@cucumber/messages')
3
+ const { Context, Suite, Test } = require('mocha')
4
+ const debug = require('debug')('codeceptjs:bdd')
5
+
6
+ const { matchStep } = require('./bdd')
7
+ const event = require('../event')
8
+ const scenario = require('../scenario')
9
+ const Step = require('../step')
10
+ const DataTableArgument = require('../data/dataTableArgument')
11
+ const transform = require('../transform')
12
+
13
+ const uuidFn = Messages.IdGenerator.uuid()
14
+ const builder = new Gherkin.AstBuilder(uuidFn)
15
+ const matcher = new Gherkin.GherkinClassicTokenMatcher()
16
+ const parser = new Gherkin.Parser(builder, matcher)
17
+ parser.stopAtFirstError = false
18
18
 
19
19
  module.exports = (text, file) => {
20
- const ast = parser.parse(text);
21
- let currentLanguage;
20
+ const ast = parser.parse(text)
21
+ let currentLanguage
22
22
 
23
23
  if (ast.feature) {
24
- currentLanguage = getTranslation(ast.feature.language);
24
+ currentLanguage = getTranslation(ast.feature.language)
25
25
  }
26
26
 
27
27
  if (!ast.feature) {
28
- throw new Error(`No 'Features' available in Gherkin '${file}' provided!`);
28
+ throw new Error(`No 'Features' available in Gherkin '${file}' provided!`)
29
29
  }
30
- const suite = new Suite(ast.feature.name, new Context());
31
- const tags = ast.feature.tags.map(t => t.name);
32
- suite.title = `${suite.title} ${tags.join(' ')}`.trim();
33
- suite.tags = tags || [];
34
- suite.comment = ast.feature.description;
35
- suite.feature = ast.feature;
36
- suite.file = file;
37
- suite.timeout(0);
38
-
39
- suite.beforeEach('codeceptjs.before', () => scenario.setup(suite));
40
- suite.afterEach('codeceptjs.after', () => scenario.teardown(suite));
41
- suite.beforeAll('codeceptjs.beforeSuite', () => scenario.suiteSetup(suite));
42
- suite.afterAll('codeceptjs.afterSuite', () => scenario.suiteTeardown(suite));
30
+ const suite = new Suite(ast.feature.name, new Context())
31
+ const tags = ast.feature.tags.map((t) => t.name)
32
+ suite.title = `${suite.title} ${tags.join(' ')}`.trim()
33
+ suite.tags = tags || []
34
+ suite.comment = ast.feature.description
35
+ suite.feature = ast.feature
36
+ suite.file = file
37
+ suite.timeout(0)
38
+
39
+ suite.beforeEach('codeceptjs.before', () => scenario.setup(suite))
40
+ suite.afterEach('codeceptjs.after', () => scenario.teardown(suite))
41
+ suite.beforeAll('codeceptjs.beforeSuite', () => scenario.suiteSetup(suite))
42
+ suite.afterAll('codeceptjs.afterSuite', () => scenario.suiteTeardown(suite))
43
43
 
44
44
  const runSteps = async (steps) => {
45
45
  for (const step of steps) {
46
- const metaStep = new Step.MetaStep(null, step.text);
47
- metaStep.actor = step.keyword.trim();
48
- let helperStep;
46
+ const metaStep = new Step.MetaStep(null, step.text)
47
+ metaStep.actor = step.keyword.trim()
48
+ let helperStep
49
49
  const setMetaStep = (step) => {
50
- helperStep = step;
50
+ helperStep = step
51
51
  if (step.metaStep) {
52
52
  if (step.metaStep === metaStep) {
53
- return;
53
+ return
54
54
  }
55
- setMetaStep(step.metaStep);
56
- return;
55
+ setMetaStep(step.metaStep)
56
+ return
57
57
  }
58
- step.metaStep = metaStep;
59
- };
60
- const fn = matchStep(step.text);
58
+ step.metaStep = metaStep
59
+ }
60
+ const fn = matchStep(step.text)
61
61
 
62
62
  if (step.dataTable) {
63
63
  fn.params.push({
64
64
  ...step.dataTable,
65
65
  parse: () => new DataTableArgument(step.dataTable),
66
- });
67
- metaStep.comment = `\n${transformTable(step.dataTable)}`;
66
+ })
67
+ metaStep.comment = `\n${transformTable(step.dataTable)}`
68
68
  }
69
69
 
70
70
  if (step.docString) {
71
- fn.params.push(step.docString);
72
- metaStep.comment = `\n"""\n${step.docString.content}\n"""`;
71
+ fn.params.push(step.docString)
72
+ metaStep.comment = `\n"""\n${step.docString.content}\n"""`
73
73
  }
74
74
 
75
- step.startTime = Date.now();
76
- step.match = fn.line;
77
- event.emit(event.bddStep.before, step);
78
- event.emit(event.bddStep.started, metaStep);
79
- event.dispatcher.prependListener(event.step.before, setMetaStep);
75
+ step.startTime = Date.now()
76
+ step.match = fn.line
77
+ event.emit(event.bddStep.before, step)
78
+ event.emit(event.bddStep.started, metaStep)
79
+ event.dispatcher.prependListener(event.step.before, setMetaStep)
80
80
  try {
81
- debug(`Step '${step.text}' started...`);
82
- await fn(...fn.params);
83
- debug('Step passed');
84
- step.status = 'passed';
81
+ debug(`Step '${step.text}' started...`)
82
+ await fn(...fn.params)
83
+ debug('Step passed')
84
+ step.status = 'passed'
85
85
  } catch (err) {
86
- debug(`Step failed: ${err?.message}`);
87
- step.status = 'failed';
88
- step.err = err;
89
- throw err;
86
+ debug(`Step failed: ${err?.message}`)
87
+ step.status = 'failed'
88
+ step.err = err
89
+ throw err
90
90
  } finally {
91
- step.endTime = Date.now();
92
- event.dispatcher.removeListener(event.step.before, setMetaStep);
91
+ step.endTime = Date.now()
92
+ event.dispatcher.removeListener(event.step.before, setMetaStep)
93
93
  }
94
- event.emit(event.bddStep.finished, metaStep);
95
- event.emit(event.bddStep.after, step);
94
+ event.emit(event.bddStep.finished, metaStep)
95
+ event.emit(event.bddStep.after, step)
96
96
  }
97
- };
97
+ }
98
98
 
99
99
  for (const child of ast.feature.children) {
100
100
  if (child.background) {
101
- suite.beforeEach('Before', scenario.injected(async () => runSteps(child.background.steps), suite, 'before'));
102
- continue;
101
+ suite.beforeEach(
102
+ 'Before',
103
+ scenario.injected(async () => runSteps(child.background.steps), suite, 'before'),
104
+ )
105
+ continue
103
106
  }
104
- if (child.scenario && (currentLanguage ? child.scenario.keyword === currentLanguage.contexts.ScenarioOutline : child.scenario.keyword === 'Scenario Outline')) {
107
+ if (
108
+ child.scenario &&
109
+ (currentLanguage
110
+ ? child.scenario.keyword === currentLanguage.contexts.ScenarioOutline
111
+ : child.scenario.keyword === 'Scenario Outline')
112
+ ) {
105
113
  for (const examples of child.scenario.examples) {
106
- const fields = examples.tableHeader.cells.map(c => c.value);
114
+ const fields = examples.tableHeader.cells.map((c) => c.value)
107
115
  for (const example of examples.tableBody) {
108
- let exampleSteps = [...child.scenario.steps];
109
- const current = {};
116
+ let exampleSteps = [...child.scenario.steps]
117
+ const current = {}
110
118
  for (const index in example.cells) {
111
- const placeholder = fields[index];
112
- const value = transform('gherkin.examples', example.cells[index].value);
113
- example.cells[index].value = value;
114
- current[placeholder] = value;
119
+ const placeholder = fields[index]
120
+ const value = transform('gherkin.examples', example.cells[index].value)
121
+ example.cells[index].value = value
122
+ current[placeholder] = value
115
123
  exampleSteps = exampleSteps.map((step) => {
116
- step = { ...step };
117
- step.text = step.text.split(`<${placeholder}>`).join(value);
118
- return step;
119
- });
124
+ step = { ...step }
125
+ step.text = step.text.split(`<${placeholder}>`).join(value)
126
+ return step
127
+ })
120
128
  }
121
- const tags = child.scenario.tags.map(t => t.name).concat(examples.tags.map(t => t.name));
122
- let title = `${child.scenario.name} ${JSON.stringify(current)} ${tags.join(' ')}`.trim();
129
+ const tags = child.scenario.tags.map((t) => t.name).concat(examples.tags.map((t) => t.name))
130
+ let title = `${child.scenario.name} ${JSON.stringify(current)} ${tags.join(' ')}`.trim()
123
131
 
124
132
  for (const [key, value] of Object.entries(current)) {
125
133
  if (title.includes(`<${key}>`)) {
126
- title = title.replace(JSON.stringify(current), '').replace(`<${key}>`, value);
134
+ title = title.replace(JSON.stringify(current), '').replace(`<${key}>`, value)
127
135
  }
128
136
  }
129
137
 
130
- const test = new Test(title, async () => runSteps(addExampleInTable(exampleSteps, current)));
131
- test.tags = suite.tags.concat(tags);
132
- test.file = file;
133
- suite.addTest(scenario.test(test));
138
+ const test = new Test(title, async () => runSteps(addExampleInTable(exampleSteps, current)))
139
+ test.tags = suite.tags.concat(tags)
140
+ test.file = file
141
+ suite.addTest(scenario.test(test))
134
142
  }
135
143
  }
136
- continue;
144
+ continue
137
145
  }
138
146
 
139
147
  if (child.scenario) {
140
- const tags = child.scenario.tags.map(t => t.name);
141
- const title = `${child.scenario.name} ${tags.join(' ')}`.trim();
142
- const test = new Test(title, async () => runSteps(child.scenario.steps));
143
- test.tags = suite.tags.concat(tags);
144
- test.file = file;
145
- suite.addTest(scenario.test(test));
148
+ const tags = child.scenario.tags.map((t) => t.name)
149
+ const title = `${child.scenario.name} ${tags.join(' ')}`.trim()
150
+ const test = new Test(title, async () => runSteps(child.scenario.steps))
151
+ test.tags = suite.tags.concat(tags)
152
+ test.file = file
153
+ suite.addTest(scenario.test(test))
146
154
  }
147
155
  }
148
156
 
149
- return suite;
150
- };
157
+ return suite
158
+ }
151
159
 
152
160
  function transformTable(table) {
153
- let str = '';
161
+ let str = ''
154
162
  for (const id in table.rows) {
155
- const cells = table.rows[id].cells;
156
- str += cells.map(c => c.value).map(c => c.padEnd(15)).join(' | ');
157
- str += '\n';
163
+ const cells = table.rows[id].cells
164
+ str += cells
165
+ .map((c) => c.value)
166
+ .map((c) => c.padEnd(15))
167
+ .join(' | ')
168
+ str += '\n'
158
169
  }
159
- return str;
170
+ return str
160
171
  }
161
172
  function addExampleInTable(exampleSteps, placeholders) {
162
- const steps = JSON.parse(JSON.stringify(exampleSteps));
173
+ const steps = JSON.parse(JSON.stringify(exampleSteps))
163
174
  for (const placeholder in placeholders) {
164
175
  steps.map((step) => {
165
- step = { ...step };
176
+ step = { ...step }
166
177
  if (step.dataTable) {
167
178
  for (const id in step.dataTable.rows) {
168
- const cells = step.dataTable.rows[id].cells;
169
- cells.map(c => (c.value = c.value.replace(`<${placeholder}>`, placeholders[placeholder])));
179
+ const cells = step.dataTable.rows[id].cells
180
+ cells.map((c) => (c.value = c.value.replace(`<${placeholder}>`, placeholders[placeholder])))
170
181
  }
171
182
  }
172
- return step;
173
- });
183
+ return step
184
+ })
174
185
  }
175
- return steps;
186
+ return steps
176
187
  }
177
188
 
178
189
  function getTranslation(language) {
179
- const translations = Object.keys(require('../../translations'));
190
+ const translations = Object.keys(require('../../translations'))
180
191
 
181
192
  for (const availableTranslation of translations) {
182
193
  if (!language) {
183
- break;
194
+ break
184
195
  }
185
196
 
186
197
  if (availableTranslation.includes(language)) {
187
- return require('../../translations')[availableTranslation];
198
+ return require('../../translations')[availableTranslation]
188
199
  }
189
200
  }
190
201
  }