@zohodesk/testinglibrary 0.1.8-exp-bdd-v2 → 0.1.8-exp-bdd-v4

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 (81) hide show
  1. package/.eslintrc.js +5 -1
  2. package/build/bdd-framework/cli/commands/env.js +2 -3
  3. package/build/bdd-framework/cli/commands/export.js +1 -2
  4. package/build/bdd-framework/cli/commands/test.js +7 -4
  5. package/build/bdd-framework/cli/options.js +1 -2
  6. package/build/bdd-framework/config/env.js +2 -1
  7. package/build/bdd-framework/config/index.js +1 -2
  8. package/build/bdd-framework/config/lang.js +14 -0
  9. package/build/bdd-framework/cucumber/loadSteps.js +8 -3
  10. package/build/bdd-framework/decorators.js +6 -10
  11. package/build/bdd-framework/gen/fixtures.js +48 -0
  12. package/build/bdd-framework/gen/formatter.js +57 -10
  13. package/build/bdd-framework/gen/i18n.js +6 -2
  14. package/build/bdd-framework/gen/index.js +7 -6
  15. package/build/bdd-framework/gen/testFile.js +105 -39
  16. package/build/bdd-framework/gen/testNode.js +16 -3
  17. package/build/bdd-framework/gen/testPoms.js +18 -8
  18. package/build/bdd-framework/hooks/scenario.js +107 -0
  19. package/build/bdd-framework/hooks/worker.js +83 -0
  20. package/build/bdd-framework/playwright/fixtureParameterNames.js +24 -8
  21. package/build/bdd-framework/playwright/getLocationInFile.js +13 -7
  22. package/build/bdd-framework/playwright/testTypeImpl.js +11 -7
  23. package/build/bdd-framework/playwright/transform.js +6 -2
  24. package/build/bdd-framework/playwright/utils.js +1 -4
  25. package/build/bdd-framework/run/StepInvoker.js +73 -0
  26. package/build/bdd-framework/run/bddFixtures.js +119 -57
  27. package/build/bdd-framework/run/bddWorld.js +24 -36
  28. package/build/bdd-framework/snippets/index.js +3 -2
  29. package/build/bdd-framework/snippets/snippetSyntax.js +3 -1
  30. package/build/bdd-framework/stepDefinitions/createBdd.js +28 -11
  31. package/build/bdd-framework/stepDefinitions/decorators/{poms.js → class.js} +7 -3
  32. package/build/bdd-framework/stepDefinitions/decorators/steps.js +8 -3
  33. package/build/bdd-framework/stepDefinitions/defineStep.js +2 -1
  34. package/build/bdd-framework/utils/exit.js +8 -4
  35. package/build/bdd-framework/utils/index.js +27 -1
  36. package/build/bdd-framework/utils/logger.js +4 -3
  37. package/build/bdd-poc/core-runner/main.js +10 -0
  38. package/build/bdd-poc/core-runner/stepDefinitions.js +0 -1
  39. package/build/bdd-poc/index.js +26 -0
  40. package/build/bdd-poc/test/stepGenerate/stepFileGenerate.js +6 -6
  41. package/build/bdd-poc/test/stepGenerate/stepsnippets.js +1 -2
  42. package/build/bdd-poc/test/testDataMap.js +5 -5
  43. package/build/core/jest/preprocessor/jsPreprocessor.js +2 -3
  44. package/build/core/playwright/builtInFixtures/addTags.js +19 -0
  45. package/build/core/playwright/builtInFixtures/cacheLayer.js +13 -0
  46. package/build/core/playwright/builtInFixtures/context.js +15 -0
  47. package/build/core/playwright/builtInFixtures/index.js +26 -0
  48. package/build/core/playwright/builtInFixtures/page.js +51 -0
  49. package/build/core/playwright/clear-caches.js +29 -0
  50. package/build/core/playwright/custom-commands.js +1 -2
  51. package/build/core/playwright/index.js +12 -93
  52. package/build/core/playwright/readConfigFile.js +12 -6
  53. package/build/core/playwright/report-generator.js +2 -1
  54. package/build/core/playwright/setup/config-creator.js +23 -17
  55. package/build/core/playwright/setup/config-utils.js +43 -11
  56. package/build/core/playwright/setup/custom-reporter.js +109 -0
  57. package/build/core/playwright/tag-processor.js +68 -0
  58. package/build/core/playwright/test-runner.js +40 -36
  59. package/build/decorators.d.ts +1 -1
  60. package/build/decorators.js +2 -16
  61. package/build/index.d.ts +59 -4
  62. package/build/index.js +10 -9
  63. package/build/lib/cli.js +10 -1
  64. package/build/parser/parser.js +0 -1
  65. package/build/setup-folder-structure/helper.js +34 -0
  66. package/build/setup-folder-structure/reportEnhancement/addonScript.html +25 -0
  67. package/build/setup-folder-structure/reportEnhancement/reportAlteration.js +25 -0
  68. package/build/setup-folder-structure/samples/git-ignore.sample.js +8 -4
  69. package/build/setup-folder-structure/samples/uat-config-sample.js +3 -2
  70. package/build/setup-folder-structure/setupProject.js +10 -5
  71. package/build/utils/fileUtils.js +15 -4
  72. package/build/utils/logger.js +1 -2
  73. package/build/utils/stepDefinitionsFormatter.js +1 -2
  74. package/changelog.md +57 -0
  75. package/npm-shrinkwrap.json +1426 -2172
  76. package/package.json +5 -4
  77. package/build/bdd-framework/cucumber/gherkin.d.ts +0 -45
  78. package/build/bdd-framework/gen/poms.js +0 -46
  79. package/build/bdd-framework/stepDefinitions/createDecorators.js +0 -109
  80. package/build/bdd-poc/main.js +0 -10
  81. /package/build/bdd-poc/{runner.js → core-runner/runner.js} +0 -0
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isParentChildTest = isParentChildTest;
6
+ exports.isTestContainsSubtest = isTestContainsSubtest;
7
7
  exports.runStepWithCustomLocation = runStepWithCustomLocation;
8
8
  var _test = require("@playwright/test");
9
9
  var _utils = require("../utils");
@@ -39,13 +39,17 @@ async function runStepWithCustomLocation(test, stepText, location, body) {
39
39
  });
40
40
  }
41
41
  /**
42
- * Returns true if all fixtures of parent test found in child test.
42
+ * Returns true if test contains all fixtures of subtest.
43
+ * - test was extended from subtest
44
+ * - test is a result of mergeTests(subtest, ...)
43
45
  */
44
- function isParentChildTest(parent, child) {
45
- if (parent === child) return false;
46
- const childLocationsSet = new Set(getTestFixtures(child).map(f => locationToString(f.location)));
47
- return getTestFixtures(parent).every(f => {
48
- return childLocationsSet.has(locationToString(f.location));
46
+ function isTestContainsSubtest(test, subtest) {
47
+ if (test === subtest) {
48
+ return true;
49
+ }
50
+ const testFixtures = new Set(getTestFixtures(test).map(f => locationToString(f.location)));
51
+ return getTestFixtures(subtest).every(f => {
52
+ return testFixtures.has(locationToString(f.location));
49
53
  });
50
54
  }
51
55
  function locationToString({
@@ -30,13 +30,17 @@ function installTransform() {
30
30
  function resolveFilename(specifier, parent, ...rest) {
31
31
  if (!reverted && parent) {
32
32
  const resolved = resolveHook(parent.filename, specifier);
33
- if (resolved !== undefined) specifier = resolved;
33
+ if (resolved !== undefined) {
34
+ specifier = resolved;
35
+ }
34
36
  }
35
37
  return originalResolveFilename.call(this, specifier, parent, ...rest);
36
38
  }
37
39
  _module.default._resolveFilename = resolveFilename;
38
40
  const revertPirates = pirates.addHook((code, filename) => {
39
- if (!shouldTransform(filename)) return code;
41
+ if (!shouldTransform(filename)) {
42
+ return code;
43
+ }
40
44
  return transformHook(code, filename);
41
45
  }, {
42
46
  exts: ['.ts', '.tsx', '.js', '.jsx', '.mjs']
@@ -28,10 +28,7 @@ function getPlaywrightRoot() {
28
28
  // See: https://github.com/microsoft/playwright/pull/26946
29
29
  const playwrightTestRoot = (0, _utils.resolvePackageRoot)('@playwright/test');
30
30
  const libDir = _path.default.join(playwrightTestRoot, 'lib');
31
-
32
- // Recently added functionality in playwright
33
- const playwrightDir = _path.default.join(playwrightTestRoot, 'node_modules', 'playwright');
34
- playwrightRoot = _fs.default.existsSync(libDir) ? playwrightTestRoot : playwrightDir;
31
+ playwrightRoot = _fs.default.existsSync(libDir) ? playwrightTestRoot : (0, _utils.resolvePackageRoot)('playwright');
35
32
  }
36
33
  return playwrightRoot;
37
34
  }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StepInvoker = void 0;
7
+ var _loadSteps = require("../cucumber/loadSteps");
8
+ var _getLocationInFile = require("../playwright/getLocationInFile");
9
+ var _testTypeImpl = require("../playwright/testTypeImpl");
10
+ var _defineStep = require("../stepDefinitions/defineStep");
11
+ var _lang = require("../config/lang");
12
+ /**
13
+ * Class to invoke steps in generated files.
14
+ */
15
+
16
+ class StepInvoker {
17
+ world;
18
+ keyword;
19
+ text = '';
20
+ argument;
21
+ constructor(world, keyword) {
22
+ this.world = world;
23
+ this.keyword = keyword;
24
+ this.invoke = this.invoke.bind(this);
25
+ }
26
+ async invoke(text, argument, stepFixtures) {
27
+ this.text = text;
28
+ this.argument = argument;
29
+ const {
30
+ world
31
+ } = this;
32
+ world.stepFixtures = stepFixtures || {};
33
+ const stepDefinition = this.getStepDefinition();
34
+ // Get location of step call in generated test file.
35
+ // This call must be exactly here to have correct call stack (before async calls)
36
+ const location = (0, _getLocationInFile.getLocationInFile)(world.test.info().file);
37
+ const stepTitle = this.getStepTitle();
38
+ const code = (0, _defineStep.getStepCode)(stepDefinition);
39
+ const parameters = await this.getStepParameters(stepDefinition);
40
+ return (0, _testTypeImpl.runStepWithCustomLocation)(world.test, stepTitle, location, () => code.apply(world, parameters));
41
+ }
42
+ getStepDefinition() {
43
+ const stepDefinition = (0, _loadSteps.findStepDefinition)(this.world.options.supportCodeLibrary, this.text, this.world.testInfo.file);
44
+ if (!stepDefinition) {
45
+ throw new Error(`Undefined step: "${this.text}"`);
46
+ }
47
+ return stepDefinition;
48
+ }
49
+ async getStepParameters(stepDefinition) {
50
+ const {
51
+ text,
52
+ argument,
53
+ world
54
+ } = this;
55
+ const {
56
+ parameters
57
+ } = await stepDefinition.getInvocationParameters({
58
+ hookParameter: {},
59
+ step: {
60
+ text,
61
+ argument
62
+ },
63
+ world
64
+ });
65
+ return parameters;
66
+ }
67
+ getStepTitle() {
68
+ // Currently prepend keyword only for English.
69
+ // For other langs it's more complex as we need to pass original keyword from step.
70
+ return (0, _lang.isEnglish)(this.world.options.lang) ? `${this.keyword} ${this.text}` : this.text;
71
+ }
72
+ }
73
+ exports.StepInvoker = StepInvoker;
@@ -13,12 +13,15 @@ var _config = require("../config");
13
13
  var _env = require("../config/env");
14
14
  var _steps = require("../stepDefinitions/decorators/steps");
15
15
  var _dir = require("../config/dir");
16
- const test = _test.test.extend({
17
- $bddWorldBase: async ({
18
- $tags,
19
- $test
20
- }, use, testInfo) => {
21
- const config = (0, _env.getConfigFromEnv)(testInfo.project.testDir);
16
+ var _scenario = require("../hooks/scenario");
17
+ var _worker = require("../hooks/worker");
18
+ var _StepInvoker = require("./StepInvoker");
19
+ const test = exports.test = _test.test.extend({
20
+ // load cucumber once per worker (auto-fixture)
21
+ // todo: maybe remove caching in cucumber/loadConfig.ts and cucumber/loadSteps.ts
22
+ // as we call it once per worker. Check generation phase.
23
+ $cucumber: [async ({}, use, workerInfo) => {
24
+ const config = (0, _env.getConfigFromEnv)(workerInfo.project.testDir);
22
25
  const environment = {
23
26
  cwd: (0, _dir.getPlaywrightConfigDir)()
24
27
  };
@@ -30,11 +33,37 @@ const test = _test.test.extend({
30
33
  const supportCodeLibrary = await (0, _loadSteps.loadSteps)(runConfiguration, environment);
31
34
  (0, _steps.appendDecoratorSteps)(supportCodeLibrary);
32
35
  const World = (0, _bddWorld.getWorldConstructor)(supportCodeLibrary);
36
+ await use({
37
+ runConfiguration,
38
+ supportCodeLibrary,
39
+ World
40
+ });
41
+ }, {
42
+ auto: true,
43
+ scope: 'worker'
44
+ }],
45
+ $lang: ({}, use) => use(''),
46
+ // init $bddWorldFixtures with empty object, will be owerwritten in test file for cucumber-style
47
+ $bddWorldFixtures: ({}, use) => use({}),
48
+ $bddWorld: async ({
49
+ $tags,
50
+ $test,
51
+ $bddWorldFixtures,
52
+ $cucumber,
53
+ $lang
54
+ }, use, testInfo) => {
55
+ const {
56
+ runConfiguration,
57
+ supportCodeLibrary,
58
+ World
59
+ } = $cucumber;
33
60
  const world = new World({
34
61
  testInfo,
35
62
  supportCodeLibrary,
36
63
  $tags,
37
64
  $test,
65
+ $bddWorldFixtures,
66
+ lang: $lang,
38
67
  parameters: runConfiguration.runtime.worldParameters || {},
39
68
  log: () => {},
40
69
  attach: async () => {}
@@ -43,65 +72,98 @@ const test = _test.test.extend({
43
72
  await use(world);
44
73
  await world.destroy();
45
74
  },
46
- $bddWorld: async ({
47
- $bddWorldBase,
48
- page,
49
- context,
50
- browser,
51
- browserName,
52
- request
53
- }, use) => {
54
- $bddWorldBase.builtinFixtures = {
55
- page,
56
- context,
57
- browser,
58
- browserName,
59
- request
60
- };
61
- await use($bddWorldBase);
62
- },
63
- // below fixtures are used in playwright-style
64
- // and does not automatically init Playwright builtin fixtures
65
75
  Given: ({
66
- $bddWorldBase
67
- }, use) => use($bddWorldBase.invokeStep),
68
- When: ({
69
- $bddWorldBase
70
- }, use) => use($bddWorldBase.invokeStep),
71
- Then: ({
72
- $bddWorldBase
73
- }, use) => use($bddWorldBase.invokeStep),
74
- And: ({
75
- $bddWorldBase
76
- }, use) => use($bddWorldBase.invokeStep),
77
- But: ({
78
- $bddWorldBase
79
- }, use) => use($bddWorldBase.invokeStep),
80
- // below fixtures are used in cucumber-style
81
- // and automatically init Playwright builtin fixtures
82
- Given_: ({
83
76
  $bddWorld
84
- }, use) => use($bddWorld.invokeStep),
85
- When_: ({
77
+ }, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'Given').invoke),
78
+ When: ({
86
79
  $bddWorld
87
- }, use) => use($bddWorld.invokeStep),
88
- Then_: ({
80
+ }, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'When').invoke),
81
+ Then: ({
89
82
  $bddWorld
90
- }, use) => use($bddWorld.invokeStep),
91
- And_: ({
83
+ }, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'Then').invoke),
84
+ And: ({
92
85
  $bddWorld
93
- }, use) => use($bddWorld.invokeStep),
94
- But_: ({
86
+ }, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'And').invoke),
87
+ But: ({
95
88
  $bddWorld
96
- }, use) => use($bddWorld.invokeStep),
97
- // Init $tags fixture with empty array. Can be owerwritten in test file
98
- // eslint-disable-next-line
89
+ }, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'But').invoke),
90
+ // init $tags with empty array, can be owerwritten in test file
99
91
  $tags: ({}, use) => use([]),
100
- // Init $test fixture with base test, but it will be always overwritten in test file
101
- // eslint-disable-next-line
102
- $test: ({}, use) => use(_test.test)
92
+ // init $test with base test, but it will be always overwritten in test file
93
+ $test: ({}, use) => use(_test.test),
94
+ // can be owerwritten in test file if there are scenario hooks
95
+ $scenarioHookFixtures: ({}, use) => use({}),
96
+ $before: [
97
+ // Unused dependencies are important:
98
+ // 1. $beforeAll / $afterAll: in pw < 1.39 worker-scoped auto-fixtures were called after test-scoped
99
+ // 2. $after: to call after hooks in case of errors in before hooks
100
+ async ({
101
+ $scenarioHookFixtures,
102
+ $bddWorld,
103
+ $tags,
104
+ $beforeAll,
105
+ $afterAll,
106
+ $after
107
+ }, use, $testInfo) => {
108
+ await (0, _scenario.runScenarioHooks)('before', {
109
+ $bddWorld,
110
+ $tags,
111
+ $testInfo,
112
+ ...$scenarioHookFixtures
113
+ });
114
+ await use();
115
+ }, {
116
+ auto: true
117
+ }],
118
+ $after: [async ({
119
+ $scenarioHookFixtures,
120
+ $bddWorld,
121
+ $tags
122
+ }, use, $testInfo) => {
123
+ await use();
124
+ await (0, _scenario.runScenarioHooks)('after', {
125
+ $bddWorld,
126
+ $tags,
127
+ $testInfo,
128
+ ...$scenarioHookFixtures
129
+ });
130
+ }, {
131
+ auto: true
132
+ }],
133
+ // can be owerwritten in test file if there are worker hooks
134
+ $workerHookFixtures: [({}, use) => use({}), {
135
+ scope: 'worker'
136
+ }],
137
+ $beforeAll: [
138
+ // Important unused dependencies:
139
+ // 1. $afterAll: in pw < 1.39 worker-scoped auto-fixtures are called in incorrect order
140
+ // 2. $cucumber: to load hooks before this fixtures
141
+ async ({
142
+ $workerHookFixtures,
143
+ $cucumber
144
+ }, use, $workerInfo) => {
145
+ await (0, _worker.runWorkerHooks)('beforeAll', {
146
+ $workerInfo,
147
+ ...$workerHookFixtures
148
+ });
149
+ await use();
150
+ }, {
151
+ auto: true,
152
+ scope: 'worker'
153
+ }],
154
+ $afterAll: [async ({
155
+ $workerHookFixtures
156
+ }, use, $workerInfo) => {
157
+ await use();
158
+ await (0, _worker.runWorkerHooks)('afterAll', {
159
+ $workerInfo,
160
+ ...$workerHookFixtures
161
+ });
162
+ }, {
163
+ auto: true,
164
+ scope: 'worker'
165
+ }]
103
166
  });
104
- exports.test = test;
105
167
  const BDD_AUTO_INJECT_FIXTURES = ['$testInfo', '$test', '$tags'];
106
168
  function isBddAutoInjectFixture(name) {
107
169
  return BDD_AUTO_INJECT_FIXTURES.includes(name);
@@ -6,58 +6,46 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.BddWorld = void 0;
7
7
  exports.getWorldConstructor = getWorldConstructor;
8
8
  var _cucumber = require("@cucumber/cucumber");
9
- var _loadSteps = require("../cucumber/loadSteps");
10
- var _getLocationInFile = require("../playwright/getLocationInFile");
11
- var _testTypeImpl = require("../playwright/testTypeImpl");
12
- var _defineStep = require("../stepDefinitions/defineStep");
13
9
  class BddWorld extends _cucumber.World {
14
10
  options;
15
- builtinFixtures;
16
- customFixtures;
11
+ stepFixtures = {};
17
12
  constructor(options) {
18
13
  super(options);
19
14
  this.options = options;
20
- this.invokeStep = this.invokeStep.bind(this);
21
15
  }
22
- async invokeStep(text, argument, customFixtures) {
23
- const stepDefinition = (0, _loadSteps.findStepDefinition)(this.options.supportCodeLibrary, text, this.testInfo.file);
24
- if (!stepDefinition) {
25
- throw new Error(`Undefined step: "${text}"`);
26
- }
27
- // attach custom fixtures to world - the only way to pass them to cucumber step fn
28
- this.customFixtures = customFixtures;
29
- const code = (0, _defineStep.getStepCode)(stepDefinition);
30
- // Get location of step call in generated test file.
31
- // This call must be exactly here to have correct call stack.
32
- const location = (0, _getLocationInFile.getLocationInFile)(this.test.info().file);
33
- const {
34
- parameters
35
- } = await stepDefinition.getInvocationParameters({
36
- hookParameter: {},
37
- step: {
38
- text,
39
- argument
40
- },
41
- world: this
42
- });
43
- const res = await (0, _testTypeImpl.runStepWithCustomLocation)(this.test, text, location, () => code.apply(this, parameters));
44
- delete this.customFixtures;
45
- return res;
16
+ /**
17
+ * Use particular fixture in cucumber-style steps.
18
+ *
19
+ * Note: TS does not support partial generic inference,
20
+ * that's why we can't use this.useFixture<typeof test>('xxx');
21
+ * The solution is to pass TestType as a generic to BddWorld
22
+ * and call useFixture without explicit generic params.
23
+ * Finally, it looks even better as there is no need to pass `typeof test`
24
+ * in every `this.useFixture` call.
25
+ *
26
+ * The downside - it's impossible to pass fixtures type directly to `this.useFixture`
27
+ * like it's done in @Fixture decorator.
28
+ *
29
+ * See: https://stackoverflow.com/questions/45509621/specify-only-first-type-argument
30
+ * See: https://github.com/Microsoft/TypeScript/pull/26349
31
+ */
32
+ useFixture(fixtureName) {
33
+ return this.stepFixtures[fixtureName];
46
34
  }
47
35
  get page() {
48
- return this.builtinFixtures.page;
36
+ return this.options.$bddWorldFixtures.page;
49
37
  }
50
38
  get context() {
51
- return this.builtinFixtures.context;
39
+ return this.options.$bddWorldFixtures.context;
52
40
  }
53
41
  get browser() {
54
- return this.builtinFixtures.browser;
42
+ return this.options.$bddWorldFixtures.browser;
55
43
  }
56
44
  get browserName() {
57
- return this.builtinFixtures.browserName;
45
+ return this.options.$bddWorldFixtures.browserName;
58
46
  }
59
47
  get request() {
60
- return this.builtinFixtures.request;
48
+ return this.options.$bddWorldFixtures.request;
61
49
  }
62
50
  get testInfo() {
63
51
  return this.options.testInfo;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Snippets = void 0;
7
+ var _url = require("url");
7
8
  var _loadSnippetBuilder = require("../cucumber/loadSnippetBuilder");
8
9
  var _logger = require("../utils/logger");
9
10
  var _stepConfig = require("../stepDefinitions/stepConfig");
@@ -30,7 +31,6 @@ class Snippets {
30
31
  this.printFooter(snippets);
31
32
  // exit();
32
33
  }
33
-
34
34
  async createSnippetBuilder() {
35
35
  const {
36
36
  snippetInterface
@@ -44,7 +44,8 @@ class Snippets {
44
44
  } = this.runConfiguration.formats.options;
45
45
  if (!snippetSyntax && this.isPlaywrightStyle()) {
46
46
  this.bddBuiltInSyntax = true;
47
- return this.isDecorators() ? require.resolve('./snippetSyntaxDecorators.js') : this.isTypeScript() ? require.resolve('./snippetSyntaxTs.js') : require.resolve('./snippetSyntax.js');
47
+ const filePath = this.isDecorators() ? require.resolve('./snippetSyntaxDecorators.js') : this.isTypeScript() ? require.resolve('./snippetSyntaxTs.js') : require.resolve('./snippetSyntax.js');
48
+ return (0, _url.pathToFileURL)(filePath).toString();
48
49
  } else {
49
50
  return snippetSyntax;
50
51
  }
@@ -27,7 +27,9 @@ class _default {
27
27
  });
28
28
  const allParameterNames = ['{}', ...expressionParameters, ...stepParameters];
29
29
  const functionSignature = `${functionName}('${this.escapeSpecialCharacters(generatedExpression)}', async (${allParameterNames.join(', ')}) => {`;
30
- return [functionSignature, ` // ...`, '});'].join('\n');
30
+ return [functionSignature,
31
+ // prettier-ignore
32
+ ` // ...`, '});'].join('\n');
31
33
  }
32
34
  escapeSpecialCharacters(generatedExpression) {
33
35
  let source = generatedExpression.source;
@@ -4,27 +4,42 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createBdd = createBdd;
7
- exports.extractFixtureNames = extractFixtureNames;
8
- var _fixtureParameterNames = require("../playwright/fixtureParameterNames");
7
+ exports.hasCustomTest = void 0;
9
8
  var _bddFixtures = require("../run/bddFixtures");
10
9
  var _testTypeImpl = require("../playwright/testTypeImpl");
11
10
  var _defineStep = require("./defineStep");
12
11
  var _exit = require("../utils/exit");
12
+ var _scenario = require("../hooks/scenario");
13
+ var _worker = require("../hooks/worker");
13
14
  /**
14
15
  * Stuff related to writing steps in Playwright-style.
15
16
  */
16
17
 
18
+ // Global flag showing that custom test was passed.
19
+ // Used when checking 'importTestFrom' config option.
20
+ // todo: https://github.com/vitalets/playwright-bdd/issues/46
21
+ let hasCustomTest = exports.hasCustomTest = false;
17
22
  function createBdd(customTest) {
18
- const hasCustomTest = isCustomTest(customTest);
23
+ if (!hasCustomTest) {
24
+ exports.hasCustomTest = hasCustomTest = isCustomTest(customTest);
25
+ }
19
26
  const Given = defineStepCtor('Given', hasCustomTest);
20
27
  const When = defineStepCtor('When', hasCustomTest);
21
28
  const Then = defineStepCtor('Then', hasCustomTest);
22
29
  const Step = defineStepCtor('Unknown', hasCustomTest);
30
+ const Before = (0, _scenario.scenarioHookFactory)('before');
31
+ const After = (0, _scenario.scenarioHookFactory)('after');
32
+ const BeforeAll = (0, _worker.workerHookFactory)('beforeAll');
33
+ const AfterAll = (0, _worker.workerHookFactory)('afterAll');
23
34
  return {
24
35
  Given,
25
36
  When,
26
37
  Then,
27
- Step
38
+ Step,
39
+ Before,
40
+ After,
41
+ BeforeAll,
42
+ AfterAll
28
43
  };
29
44
  }
30
45
  function defineStepCtor(keyword, hasCustomTest) {
@@ -37,13 +52,15 @@ function defineStepCtor(keyword, hasCustomTest) {
37
52
  });
38
53
  };
39
54
  }
40
- function extractFixtureNames(fn) {
41
- return (0, _fixtureParameterNames.fixtureParameterNames)(fn).filter(name => !(0, _bddFixtures.isBddAutoInjectFixture)(name));
42
- }
43
55
  function isCustomTest(customTest) {
44
- const isCustomTest = Boolean(customTest && customTest !== _bddFixtures.test);
45
- if (isCustomTest && customTest && !(0, _testTypeImpl.isParentChildTest)(_bddFixtures.test, customTest)) {
46
- (0, _exit.exit)(`createBdd() should use test extended from "@zohodesk/testinglibrary"`);
56
+ if (!customTest || customTest === _bddFixtures.test) {
57
+ return false;
58
+ }
59
+ assertTestHasBddFixtures(customTest);
60
+ return true;
61
+ }
62
+ function assertTestHasBddFixtures(customTest) {
63
+ if (!(0, _testTypeImpl.isTestContainsSubtest)(customTest, _bddFixtures.test)) {
64
+ (0, _exit.exit)(`createBdd() should use 'test' extended from "playwright-bdd"`);
47
65
  }
48
- return isCustomTest;
49
66
  }
@@ -8,7 +8,7 @@ exports.getPomNodeByFixtureName = getPomNodeByFixtureName;
8
8
  var _steps = require("./steps");
9
9
  var _exit = require("../../utils/exit");
10
10
  /**
11
- * POM classes marked with @Fixture
11
+ * Class level @Fixture decorator.
12
12
  */
13
13
 
14
14
  /**
@@ -51,7 +51,9 @@ function ensureUniqueFixtureName({
51
51
  }
52
52
  function linkParentWithPomNode(Ctor, pomNode) {
53
53
  const parentCtor = Object.getPrototypeOf(Ctor);
54
- if (!parentCtor) return;
54
+ if (!parentCtor) {
55
+ return;
56
+ }
55
57
  // if parentCtor is not in pomGraph, add it.
56
58
  // Case: parent class is not marked with @Fixture, but has decorator steps (base class)
57
59
  const parentPomNode = pomGraph.get(parentCtor) || createPomNode(parentCtor, '');
@@ -59,6 +61,8 @@ function linkParentWithPomNode(Ctor, pomNode) {
59
61
  }
60
62
  function getPomNodeByFixtureName(fixtureName) {
61
63
  for (const pomNode of pomGraph.values()) {
62
- if (pomNode.fixtureName === fixtureName) return pomNode;
64
+ if (pomNode.fixtureName === fixtureName) {
65
+ return pomNode;
66
+ }
63
67
  }
64
68
  }
@@ -36,11 +36,15 @@ function createStepDecorator(keyword) {
36
36
  };
37
37
  }
38
38
  function linkStepsWithPomNode(Ctor, pomNode) {
39
- if (!(Ctor !== null && Ctor !== void 0 && Ctor.prototype)) return;
39
+ if (!(Ctor !== null && Ctor !== void 0 && Ctor.prototype)) {
40
+ return;
41
+ }
40
42
  const propertyDescriptors = Object.getOwnPropertyDescriptors(Ctor.prototype);
41
43
  return Object.values(propertyDescriptors).forEach(descriptor => {
42
44
  const stepConfig = getStepConfigFromMethod(descriptor);
43
- if (!stepConfig) return;
45
+ if (!stepConfig) {
46
+ return;
47
+ }
44
48
  stepConfig.pomNode = pomNode;
45
49
  decoratedSteps.add(stepConfig);
46
50
  });
@@ -65,7 +69,9 @@ function appendDecoratorSteps(supportCodeLibrary) {
65
69
  pattern,
66
70
  code,
67
71
  line: 0,
72
+ // not used in playwright-bdd
68
73
  options: {},
74
+ // not used in playwright-bdd
69
75
  uri: '' // not used in playwright-bdd
70
76
  }, supportCodeLibrary);
71
77
  supportCodeLibrary.stepDefinitions.push(stepDefinition);
@@ -73,7 +79,6 @@ function appendDecoratorSteps(supportCodeLibrary) {
73
79
  decoratedSteps.clear();
74
80
  // todo: fill supportCodeLibrary.originalCoordinates as it is used in snippets?
75
81
  }
76
-
77
82
  function getFirstNonAutoInjectFixture(fixturesArg, stepConfig) {
78
83
  // there should be exatcly one suitable fixture in fixturesArg
79
84
  const fixtureNames = Object.keys(fixturesArg).filter(fixtureName => !(0, _bddFixtures.isBddAutoInjectFixture)(fixtureName));
@@ -34,7 +34,8 @@ function defineStep(stepConfig) {
34
34
  }
35
35
  function buildCucumberStepCode(stepConfig) {
36
36
  const code = function (...args) {
37
- const fixturesArg = Object.assign({}, this.customFixtures, {
37
+ // build the first argument (fixtures) for step fn
38
+ const fixturesArg = Object.assign({}, this.stepFixtures, {
38
39
  $testInfo: this.testInfo,
39
40
  $test: this.test,
40
41
  $tags: this.tags
@@ -5,17 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.exit = exit;
7
7
  exports.withExitHandler = withExitHandler;
8
- var _logger = require("./logger");
9
8
  var _worker_threads = require("worker_threads");
10
9
  /**
11
10
  * Exit utils.
12
11
  *
13
- * When calling process.exit() in worker thread used for file generation,
12
+ * When calling process.exit() in worker thread used for test-file generation,
14
13
  * logs are not flushed (https://github.com/vitalets/playwright-bdd/issues/59).
15
14
  * That's why instead of process.exit we throw ExitError
16
15
  * that just sets process.exitCode = 1 and allow program to exit normally.
16
+ * This esnured by wrapping code with withExitHandler().
17
17
  *
18
- * On the other hand, when running in main thread, especially inside Playwright,
18
+ * On the other hand, when running in the main thread, especially inside Playwright,
19
19
  * thrown error is captured by Playwright and show with additional messages (e.g. no tests found).
20
20
  * That's why in main thread we to call process.exit() to show only needed error.
21
21
  *
@@ -35,6 +35,10 @@ async function withExitHandler(fn) {
35
35
  return await fn();
36
36
  } catch (e) {
37
37
  if (e instanceof ExitError) {
38
+ if (e.message) {
39
+ // eslint-disable-next-line no-console
40
+ console.error(e.message);
41
+ }
38
42
  process.exitCode = 1;
39
43
  } else {
40
44
  throw e;
@@ -45,7 +49,7 @@ function exit(...messages) {
45
49
  messages = messages.filter(Boolean);
46
50
  if (_worker_threads.isMainThread) {
47
51
  if (messages.length) {
48
- _logger.logger.error('Error:', ...messages);
52
+ logger.error('Error:', ...messages);
49
53
  }
50
54
  process.exit(1);
51
55
  } else {