@zohodesk/testinglibrary 0.1.8-stb-bdd-v26 → 0.1.9-exp-actors

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 (170) hide show
  1. package/.babelrc +21 -18
  2. package/.eslintrc.js +31 -31
  3. package/.prettierrc +5 -5
  4. package/README.md +17 -17
  5. package/bin/cli.js +2 -2
  6. package/build/bdd-framework/cli/commands/env.js +42 -0
  7. package/build/bdd-framework/cli/commands/export.js +47 -0
  8. package/build/bdd-framework/cli/commands/test.js +64 -0
  9. package/build/bdd-framework/cli/index.js +11 -0
  10. package/build/bdd-framework/cli/options.js +19 -0
  11. package/build/bdd-framework/cli/worker.js +13 -0
  12. package/build/bdd-framework/config/configDir.js +35 -0
  13. package/build/bdd-framework/config/enrichReporterData.js +23 -0
  14. package/build/bdd-framework/config/env.js +50 -0
  15. package/build/bdd-framework/config/index.js +94 -0
  16. package/build/bdd-framework/config/lang.js +14 -0
  17. package/build/bdd-framework/cucumber/buildStepDefinition.js +43 -0
  18. package/build/bdd-framework/cucumber/createTestStep.js +43 -0
  19. package/build/bdd-framework/cucumber/formatter/EventDataCollector.js +126 -0
  20. package/build/bdd-framework/cucumber/formatter/GherkinDocumentParser.js +72 -0
  21. package/build/bdd-framework/cucumber/formatter/PickleParser.js +25 -0
  22. package/build/bdd-framework/cucumber/formatter/durationHelpers.js +13 -0
  23. package/build/bdd-framework/cucumber/formatter/getColorFns.js +57 -0
  24. package/build/bdd-framework/cucumber/formatter/index.js +16 -0
  25. package/build/bdd-framework/cucumber/formatter/locationHelpers.js +16 -0
  26. package/build/bdd-framework/cucumber/loadConfig.js +17 -0
  27. package/build/bdd-framework/cucumber/loadFeatures.js +70 -0
  28. package/build/bdd-framework/cucumber/loadSnippetBuilder.js +20 -0
  29. package/build/bdd-framework/cucumber/loadSteps.js +47 -0
  30. package/build/bdd-framework/cucumber/resolveFeaturePaths.js +62 -0
  31. package/build/bdd-framework/cucumber/stepArguments.js +21 -0
  32. package/build/bdd-framework/cucumber/types.js +5 -0
  33. package/build/bdd-framework/cucumber/valueChecker.js +23 -0
  34. package/build/bdd-framework/decorators.js +18 -0
  35. package/build/bdd-framework/gen/fixtures.js +48 -0
  36. package/build/bdd-framework/gen/formatter.js +123 -0
  37. package/build/bdd-framework/gen/i18n.js +39 -0
  38. package/build/bdd-framework/gen/index.js +185 -0
  39. package/build/bdd-framework/gen/testFile.js +465 -0
  40. package/build/bdd-framework/gen/testMeta.js +60 -0
  41. package/build/bdd-framework/gen/testNode.js +60 -0
  42. package/build/bdd-framework/gen/testPoms.js +133 -0
  43. package/build/bdd-framework/hooks/scenario.js +130 -0
  44. package/build/bdd-framework/hooks/worker.js +89 -0
  45. package/build/bdd-framework/index.js +52 -0
  46. package/build/bdd-framework/playwright/fixtureParameterNames.js +93 -0
  47. package/build/bdd-framework/playwright/getLocationInFile.js +79 -0
  48. package/build/bdd-framework/playwright/loadConfig.js +42 -0
  49. package/build/bdd-framework/playwright/loadUtils.js +33 -0
  50. package/build/bdd-framework/playwright/testTypeImpl.js +61 -0
  51. package/build/bdd-framework/playwright/transform.js +88 -0
  52. package/build/bdd-framework/playwright/types.js +5 -0
  53. package/build/bdd-framework/playwright/utils.js +34 -0
  54. package/build/bdd-framework/reporter/cucumber/base.js +57 -0
  55. package/build/bdd-framework/reporter/cucumber/custom.js +73 -0
  56. package/build/bdd-framework/reporter/cucumber/helper.js +12 -0
  57. package/build/bdd-framework/reporter/cucumber/html.js +35 -0
  58. package/build/bdd-framework/reporter/cucumber/index.js +74 -0
  59. package/build/bdd-framework/reporter/cucumber/json.js +312 -0
  60. package/build/bdd-framework/reporter/cucumber/junit.js +205 -0
  61. package/build/bdd-framework/reporter/cucumber/message.js +20 -0
  62. package/build/bdd-framework/reporter/cucumber/messagesBuilder/AttachmentMapper.js +64 -0
  63. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Builder.js +196 -0
  64. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocument.js +43 -0
  65. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocumentClone.js +52 -0
  66. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocuments.js +105 -0
  67. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Hook.js +70 -0
  68. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Meta.js +45 -0
  69. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Pickles.js +27 -0
  70. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Projects.js +38 -0
  71. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCase.js +128 -0
  72. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRun.js +126 -0
  73. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRunHooks.js +102 -0
  74. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepAttachments.js +50 -0
  75. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepRun.js +88 -0
  76. package/build/bdd-framework/reporter/cucumber/messagesBuilder/index.js +30 -0
  77. package/build/bdd-framework/reporter/cucumber/messagesBuilder/pwUtils.js +51 -0
  78. package/build/bdd-framework/reporter/cucumber/messagesBuilder/timing.js +35 -0
  79. package/build/bdd-framework/reporter/cucumber/messagesBuilder/types.js +5 -0
  80. package/build/bdd-framework/run/StepInvoker.js +68 -0
  81. package/build/bdd-framework/run/bddDataAttachment.js +46 -0
  82. package/build/bdd-framework/run/bddFixtures.js +191 -0
  83. package/build/bdd-framework/run/bddWorld.js +79 -0
  84. package/build/bdd-framework/run/bddWorldInternal.js +15 -0
  85. package/build/bdd-framework/snippets/index.js +132 -0
  86. package/build/bdd-framework/snippets/snippetSyntax.js +43 -0
  87. package/build/bdd-framework/snippets/snippetSyntaxDecorators.js +26 -0
  88. package/build/bdd-framework/snippets/snippetSyntaxTs.js +18 -0
  89. package/build/bdd-framework/stepDefinitions/createBdd.js +66 -0
  90. package/build/bdd-framework/stepDefinitions/decorators/class.js +68 -0
  91. package/build/bdd-framework/stepDefinitions/decorators/steps.js +99 -0
  92. package/build/bdd-framework/stepDefinitions/defineStep.js +62 -0
  93. package/build/bdd-framework/stepDefinitions/stepConfig.js +24 -0
  94. package/build/bdd-framework/utils/AutofillMap.js +20 -0
  95. package/build/bdd-framework/utils/exit.js +62 -0
  96. package/build/bdd-framework/utils/index.js +93 -0
  97. package/build/bdd-framework/utils/jsStringWrap.js +44 -0
  98. package/build/bdd-framework/utils/logger.js +30 -0
  99. package/build/bdd-framework/utils/stripAnsiEscapes.js +20 -0
  100. package/build/core/playwright/builtInFixtures/addTags.js +1 -1
  101. package/build/core/playwright/builtInFixtures/context.js +18 -1
  102. package/build/core/playwright/builtInFixtures/i18N.js +33 -0
  103. package/build/core/playwright/builtInFixtures/index.js +19 -7
  104. package/build/core/playwright/builtInFixtures/page.js +87 -39
  105. package/build/core/playwright/builtInFixtures/unauthenticatedPage.js +18 -0
  106. package/build/core/playwright/clear-caches.js +19 -8
  107. package/build/core/playwright/codegen.js +4 -4
  108. package/build/core/playwright/constants/browserTypes.js +12 -0
  109. package/build/core/playwright/custom-commands.js +1 -1
  110. package/build/core/playwright/env-initializer.js +10 -6
  111. package/build/core/playwright/helpers/auth/accountLogin.js +18 -0
  112. package/build/core/playwright/helpers/auth/checkAuthCookies.js +50 -0
  113. package/build/core/playwright/helpers/auth/getUrlOrigin.js +13 -0
  114. package/build/core/playwright/helpers/auth/getUsers.js +111 -0
  115. package/build/core/playwright/helpers/auth/index.js +70 -0
  116. package/build/core/playwright/helpers/auth/loginSteps.js +36 -0
  117. package/build/core/playwright/helpers/configFileNameProvider.js +24 -0
  118. package/build/core/playwright/helpers/getUserFixtures.js +23 -0
  119. package/build/core/playwright/helpers/mergeObjects.js +13 -0
  120. package/build/core/playwright/helpers/parseUserArgs.js +11 -0
  121. package/build/core/playwright/index.js +81 -15
  122. package/build/core/playwright/readConfigFile.js +50 -39
  123. package/build/core/playwright/report-generator.js +7 -7
  124. package/build/core/playwright/setup/config-creator.js +15 -16
  125. package/build/core/playwright/setup/config-utils.js +60 -26
  126. package/build/core/playwright/setup/custom-reporter.js +3 -2
  127. package/build/core/playwright/tag-processor.js +12 -23
  128. package/build/core/playwright/test-runner.js +50 -65
  129. package/build/core/playwright/types.js +43 -0
  130. package/build/decorators.d.ts +1 -1
  131. package/build/decorators.js +16 -2
  132. package/build/index.d.ts +97 -12
  133. package/build/index.js +63 -9
  134. package/build/lib/cli.js +12 -3
  135. package/build/lib/post-install.js +18 -10
  136. package/build/parser/sample.feature +34 -34
  137. package/build/parser/sample.spec.js +18 -18
  138. package/build/setup-folder-structure/helper.js +3 -0
  139. package/build/setup-folder-structure/reportEnhancement/addonScript.html +24 -24
  140. package/build/setup-folder-structure/samples/auth-setup-sample.js +71 -72
  141. package/build/setup-folder-structure/samples/authUsers-sample.json +8 -8
  142. package/build/setup-folder-structure/samples/env-config-sample.json +20 -20
  143. package/build/setup-folder-structure/samples/git-ignore.sample.js +36 -36
  144. package/build/setup-folder-structure/samples/uat-config-sample.js +44 -44
  145. package/build/utils/cliArgsToObject.js +30 -26
  146. package/build/utils/fileUtils.js +4 -19
  147. package/build/utils/getFilePath.js +1 -2
  148. package/build/utils/rootPath.js +16 -9
  149. package/changelog.md +144 -131
  150. package/jest.config.js +63 -63
  151. package/npm-shrinkwrap.json +6475 -5994
  152. package/package.json +57 -56
  153. package/playwright.config.js +112 -112
  154. package/build/bdd-poc/config/pathConfig.js +0 -22
  155. package/build/bdd-poc/core-runner/exportMethods.js +0 -22
  156. package/build/bdd-poc/core-runner/main.js +0 -15
  157. package/build/bdd-poc/core-runner/stepDefinitions.js +0 -157
  158. package/build/bdd-poc/core-runner/stepRunner.js +0 -25
  159. package/build/bdd-poc/errors/throwError.js +0 -23
  160. package/build/bdd-poc/index.js +0 -26
  161. package/build/bdd-poc/test/cucumber/featureFileParer.js +0 -84
  162. package/build/bdd-poc/test/cucumber/parserCucumber.js +0 -15
  163. package/build/bdd-poc/test/stepGenerate/extractTestInputs.js +0 -65
  164. package/build/bdd-poc/test/stepGenerate/parserSteps.js +0 -81
  165. package/build/bdd-poc/test/stepGenerate/stepFileGenerate.js +0 -40
  166. package/build/bdd-poc/test/stepGenerate/stepsnippets.js +0 -61
  167. package/build/bdd-poc/test/tagsHandle.js +0 -70
  168. package/build/bdd-poc/test/testData.js +0 -125
  169. package/build/bdd-poc/test/testStructure.js +0 -92
  170. package/build/bdd-poc/utils/stringManipulation.js +0 -26
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TestCase = void 0;
7
+ var _utils = require("../../../utils");
8
+ class TestCase {
9
+ id;
10
+ gherkinDocuments;
11
+ #pickle;
12
+ #projectInfo;
13
+ beforeHooks = new Map();
14
+ afterHooks = new Map();
15
+ mainSteps = [];
16
+ constructor(id, gherkinDocuments) {
17
+ this.id = id;
18
+ this.gherkinDocuments = gherkinDocuments;
19
+ }
20
+ get projectInfo() {
21
+ if (!this.#projectInfo) {
22
+ throw new Error(`Empty projectInfo for testCase: ${this.id}`);
23
+ }
24
+ return this.#projectInfo;
25
+ }
26
+ get pickle() {
27
+ if (!this.#pickle) {
28
+ throw new Error(`Empty pickle for testCase: ${this.id}`);
29
+ }
30
+ return this.#pickle;
31
+ }
32
+ addRun(testCaseRun) {
33
+ if (!this.#projectInfo) {
34
+ this.#projectInfo = testCaseRun.projectInfo;
35
+ }
36
+ this.addHooks(testCaseRun, 'before');
37
+ this.addHooks(testCaseRun, 'after');
38
+ if (!this.#pickle) {
39
+ this.#pickle = this.findPickle(testCaseRun.bddData);
40
+ this.addStepsFromPickle(this.#pickle);
41
+ }
42
+ this.addStepsArgumentsLists(testCaseRun);
43
+ }
44
+ getHooks(hookType) {
45
+ return hookType == 'before' ? this.beforeHooks : this.afterHooks;
46
+ }
47
+ getMainSteps() {
48
+ return this.mainSteps;
49
+ }
50
+ buildMessage() {
51
+ const testSteps = [...Array.from(this.beforeHooks.values()).map(hook => hook.testStep), ...(this.mainSteps || []), ...Array.from(this.afterHooks.values()).map(hook => hook.testStep)];
52
+ const testCase = {
53
+ id: this.id,
54
+ pickleId: this.pickle.id,
55
+ testSteps
56
+ };
57
+ return {
58
+ testCase
59
+ };
60
+ }
61
+ /**
62
+ * We collect hooks from all runs of this test case, avoiding duplicates.
63
+ */
64
+ addHooks(testCaseRun, hookType) {
65
+ const testCaseHooks = hookType === 'before' ? this.beforeHooks : this.afterHooks;
66
+ const testRunHooks = testCaseRun.getExecutedHooks(hookType);
67
+ testRunHooks.forEach(({
68
+ hook
69
+ }) => {
70
+ if (testCaseHooks.has(hook.internalId)) {
71
+ return;
72
+ }
73
+ const testStep = {
74
+ id: `${this.id}-${hookType}-${testCaseHooks.size}`,
75
+ hookId: hook.id
76
+ };
77
+ testCaseHooks.set(hook.internalId, {
78
+ hook,
79
+ testStep
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Initially create steps from pickle steps, with empty stepMatchArgumentsLists.
85
+ */
86
+ addStepsFromPickle(pickle) {
87
+ this.mainSteps = pickle.steps.map((pickleStep, stepIndex) => {
88
+ return {
89
+ id: `${this.id}-step-${stepIndex}`,
90
+ pickleStepId: pickleStep.id,
91
+ stepDefinitionIds: [],
92
+ stepMatchArgumentsLists: []
93
+ };
94
+ });
95
+ }
96
+ /**
97
+ * Fill stepMatchArgumentsLists from all test runs.
98
+ * It allows to fill as many steps as possible.
99
+ * Possibly, we write the same stepMatchArgumentsLists several times,
100
+ * looks like it's not a problem as they should be equal for all runs.
101
+ */
102
+ addStepsArgumentsLists(testCaseRun) {
103
+ testCaseRun.bddData.steps.forEach((bddDataStep, stepIndex) => {
104
+ var _this$mainSteps;
105
+ const testCaseStep = (_this$mainSteps = this.mainSteps) === null || _this$mainSteps === void 0 ? void 0 : _this$mainSteps[stepIndex];
106
+ if (testCaseStep && bddDataStep.stepMatchArgumentsLists) {
107
+ testCaseStep.stepMatchArgumentsLists = bddDataStep.stepMatchArgumentsLists;
108
+ }
109
+ });
110
+ }
111
+ findPickle({
112
+ uri,
113
+ pickleLocation
114
+ }) {
115
+ const doc = this.gherkinDocuments.find(doc => doc.uri === uri);
116
+ if (!doc) {
117
+ throw new Error('GherkinDocument not found');
118
+ }
119
+ const pickle = doc.pickles.find(pickle => {
120
+ return (0, _utils.stringifyLocation)(pickle.location) === pickleLocation;
121
+ });
122
+ if (!pickle) {
123
+ throw new Error('Pickle not found');
124
+ }
125
+ return pickle;
126
+ }
127
+ }
128
+ exports.TestCase = TestCase;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TestCaseRun = void 0;
7
+ var _utils = require("../../../utils");
8
+ var _TestStepRun = require("./TestStepRun");
9
+ var _timing = require("./timing");
10
+ var _pwUtils = require("./pwUtils");
11
+ var _bddDataAttachment = require("../../../run/bddDataAttachment");
12
+ var _AttachmentMapper = require("./AttachmentMapper");
13
+ var _TestCaseRunHooks = require("./TestCaseRunHooks");
14
+ var _Projects = require("./Projects");
15
+ class TestCaseRun {
16
+ test;
17
+ result;
18
+ hooks;
19
+ id;
20
+ bddData;
21
+ testCase;
22
+ attachmentMapper;
23
+ projectInfo;
24
+ executedBeforeHooks;
25
+ executedAfterHooks;
26
+ executedSteps;
27
+ // eslint-disable-next-line max-params
28
+ constructor(test, result, hooks) {
29
+ this.test = test;
30
+ this.result = result;
31
+ this.hooks = hooks;
32
+ this.id = this.generateTestRunId();
33
+ this.bddData = this.getBddData();
34
+ this.projectInfo = (0, _Projects.getProjectInfo)(this.test);
35
+ this.attachmentMapper = new _AttachmentMapper.AttachmentMapper(this.result);
36
+ this.executedSteps = this.fillExecutedSteps();
37
+ this.executedBeforeHooks = this.fillExecutedHooks('before');
38
+ this.executedAfterHooks = this.fillExecutedHooks('after');
39
+ }
40
+ getTestCase() {
41
+ if (!this.testCase) {
42
+ throw new Error(`TestCase is not set.`);
43
+ }
44
+ return this.testCase;
45
+ }
46
+ generateTestRunId() {
47
+ return `${this.test.id}-run-${this.result.retry}`;
48
+ }
49
+ getBddData() {
50
+ const bddData = (0, _bddDataAttachment.getBddDataFromTestResult)(this.result);
51
+ if (!bddData) {
52
+ throw new Error([`BDD data attachment is not found for test: ${this.test.title}`, `Did you set enrichReporterData: true in the Playwright config?`, ''].join('\n'));
53
+ }
54
+ return bddData;
55
+ }
56
+ fillExecutedSteps() {
57
+ const possiblePwSteps = this.getPossiblePlaywrightSteps();
58
+ return this.bddData.steps.map(bddDataStep => {
59
+ const pwStep = this.findPlaywrightStep(possiblePwSteps, bddDataStep);
60
+ return {
61
+ bddDataStep,
62
+ pwStep
63
+ };
64
+ });
65
+ }
66
+ fillExecutedHooks(hookType) {
67
+ return new _TestCaseRunHooks.TestCaseRunHooks(this, hookType).fill(this.executedSteps);
68
+ }
69
+ buildMessages() {
70
+ return [this.buildTestCaseStarted(), ...this.executedBeforeHooks.buildMessages(), ...this.buildStepRuns(), ...this.executedAfterHooks.buildMessages(), this.buildTestCaseFinished()];
71
+ }
72
+ getExecutedHooks(hookType) {
73
+ return hookType === 'before' ? this.executedBeforeHooks.executedHooks : this.executedAfterHooks.executedHooks;
74
+ }
75
+ buildTestCaseStarted() {
76
+ const testCaseStarted = {
77
+ id: this.id,
78
+ attempt: this.result.retry,
79
+ testCaseId: this.getTestCase().id,
80
+ // workerId: 'worker-1'
81
+ timestamp: (0, _timing.toCucumberTimestamp)(this.result.startTime.getTime())
82
+ };
83
+ return {
84
+ testCaseStarted
85
+ };
86
+ }
87
+ buildStepRuns() {
88
+ return this.getTestCase().getMainSteps().reduce((messages, testStep, stepIndex) => {
89
+ const {
90
+ pwStep
91
+ } = this.executedSteps[stepIndex] || {};
92
+ const testStepRun = new _TestStepRun.TestStepRun(this, testStep, pwStep);
93
+ return messages.concat(testStepRun.buildMessages());
94
+ }, []);
95
+ }
96
+ buildTestCaseFinished() {
97
+ const {
98
+ startTime,
99
+ duration
100
+ } = this.result;
101
+ const testCaseFinished = {
102
+ testCaseStartedId: this.id,
103
+ willBeRetried: Boolean(this.result.error && this.result.retry < this.test.retries),
104
+ timestamp: (0, _timing.toCucumberTimestamp)(startTime.getTime() + duration)
105
+ };
106
+ return {
107
+ testCaseFinished
108
+ };
109
+ }
110
+ findPlaywrightStep(possiblePwSteps, bddDataStep) {
111
+ const pwStep = possiblePwSteps.find(pwStep => {
112
+ return pwStep.location && (0, _utils.stringifyLocation)(pwStep.location) === bddDataStep.pwStepLocation;
113
+ });
114
+ if (!pwStep) {
115
+ throw new Error('Playwright step not found for bdd step');
116
+ }
117
+ return pwStep;
118
+ }
119
+ getPossiblePlaywrightSteps() {
120
+ const beforeHooksRoot = (0, _pwUtils.getHooksRootStep)(this.result, 'before');
121
+ const bgSteps = (0, _pwUtils.collectStepsWithCategory)(beforeHooksRoot, 'test.step');
122
+ const topLevelSteps = this.result.steps.filter(step => step.category === 'test.step');
123
+ return [...bgSteps, ...topLevelSteps];
124
+ }
125
+ }
126
+ exports.TestCaseRun = TestCaseRun;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TestCaseRunHooks = void 0;
7
+ var _Hook = require("./Hook");
8
+ var _pwUtils = require("./pwUtils");
9
+ var _TestStepRun = require("./TestStepRun");
10
+ class TestCaseRunHooks {
11
+ testCaseRun;
12
+ hookType;
13
+ rootStep;
14
+ candidateSteps = [];
15
+ hookSteps = new Set();
16
+ executedHooks = new Map();
17
+ constructor(testCaseRun, hookType) {
18
+ this.testCaseRun = testCaseRun;
19
+ this.hookType = hookType;
20
+ }
21
+ fill(mainSteps) {
22
+ this.setRootStep();
23
+ this.setCandidateSteps();
24
+ this.addStepsWithName();
25
+ this.addStepsWithAttachment();
26
+ this.addStepWithError();
27
+ this.excludeBackgroundSteps(mainSteps);
28
+ this.setExecutedHooks();
29
+ return this;
30
+ }
31
+ buildMessages() {
32
+ const messages = [];
33
+ this.testCaseRun.getTestCase().getHooks(this.hookType).forEach(hookInfo => {
34
+ const executedHook = this.executedHooks.get(hookInfo.hook.internalId);
35
+ // todo: if pwStep is not found in this.executedBeforeHooks,
36
+ // it means that this hook comes from another run of this test case.
37
+ // We can stil try to find it in test result, as otherwise it will be marked as skipped,
38
+ // but actually it was executed.
39
+ const testStepRun = new _TestStepRun.TestStepRun(this.testCaseRun, hookInfo.testStep, executedHook === null || executedHook === void 0 ? void 0 : executedHook.pwStep);
40
+ messages.push(...testStepRun.buildMessages());
41
+ });
42
+ return messages;
43
+ }
44
+ setRootStep() {
45
+ this.rootStep = (0, _pwUtils.getHooksRootStep)(this.testCaseRun.result, this.hookType);
46
+ }
47
+ setCandidateSteps() {
48
+ if (this.rootStep) {
49
+ this.candidateSteps.push(this.rootStep);
50
+ }
51
+ this.candidateSteps.push(...(0, _pwUtils.collectStepsDfs)(this.rootStep));
52
+ }
53
+ addStepsWithName() {
54
+ this.candidateSteps.forEach(pwStep => {
55
+ if (pwStep.category === 'test.step' && pwStep.title) {
56
+ this.hookSteps.add(pwStep);
57
+ }
58
+ });
59
+ }
60
+ addStepsWithAttachment() {
61
+ const {
62
+ attachmentMapper
63
+ } = this.testCaseRun;
64
+ this.candidateSteps.forEach(pwStep => {
65
+ if (attachmentMapper.getStepAttachments(pwStep).length > 0) {
66
+ this.hookSteps.add(pwStep);
67
+ }
68
+ });
69
+ }
70
+ addStepWithError() {
71
+ const stepWithError = (0, _pwUtils.findDeepestErrorStep)(this.rootStep);
72
+ if (stepWithError) {
73
+ this.hookSteps.add(stepWithError);
74
+ // in Playwright error is inherited by all parent steps,
75
+ // but we want to show it once (in the deepest step)
76
+ this.hookSteps.forEach(step => {
77
+ if (step !== stepWithError) {
78
+ delete step.error;
79
+ }
80
+ });
81
+ }
82
+ }
83
+ excludeBackgroundSteps(mainSteps) {
84
+ // exclude background steps, b/c they are in pickle, not in hooks.
85
+ // Important to run this fn after this.fillExecutedSteps()
86
+ // as we assume steps are already populated
87
+ if (this.hookType === 'before') {
88
+ mainSteps.forEach(stepInfo => this.hookSteps.delete(stepInfo.pwStep));
89
+ }
90
+ }
91
+ setExecutedHooks() {
92
+ this.hookSteps.forEach(pwStep => {
93
+ const internalId = _Hook.Hook.getInternalId(pwStep);
94
+ const hook = this.testCaseRun.hooks.getOrCreate(internalId, () => new _Hook.Hook(internalId, pwStep));
95
+ this.executedHooks.set(internalId, {
96
+ hook,
97
+ pwStep
98
+ });
99
+ });
100
+ }
101
+ }
102
+ exports.TestCaseRunHooks = TestCaseRunHooks;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.TestStepAttachments = void 0;
8
+ var _fs = _interopRequireDefault(require("fs"));
9
+ var messages = _interopRequireWildcard(require("@cucumber/messages"));
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ /**
13
+ * Class for getting attachment messages for a particular step.
14
+ */
15
+
16
+ class TestStepAttachments {
17
+ testCaseRun;
18
+ testStep;
19
+ pwStep;
20
+ constructor(testCaseRun, testStep, pwStep) {
21
+ this.testCaseRun = testCaseRun;
22
+ this.testStep = testStep;
23
+ this.pwStep = pwStep;
24
+ }
25
+ buildMessages() {
26
+ if (!this.pwStep) {
27
+ return [];
28
+ }
29
+ return this.testCaseRun.attachmentMapper.getStepAttachments(this.pwStep).map(pwAttachment => this.buildAttachmentMessage(pwAttachment));
30
+ }
31
+ buildAttachmentMessage(pwAttachment) {
32
+ const attachment = {
33
+ testCaseStartedId: this.testCaseRun.id,
34
+ testStepId: this.testStep.id,
35
+ // for now always attach as base64
36
+ // todo: for text/plain and application/json use raw to save some bytes
37
+ body: this.getAttachmentBodyBase64(pwAttachment),
38
+ contentEncoding: messages.AttachmentContentEncoding.BASE64,
39
+ mediaType: pwAttachment.contentType,
40
+ fileName: pwAttachment.name
41
+ };
42
+ return {
43
+ attachment
44
+ };
45
+ }
46
+ getAttachmentBodyBase64(pwAttachment) {
47
+ return pwAttachment.path ? _fs.default.readFileSync(pwAttachment.path, 'base64') : pwAttachment.body.toString('base64');
48
+ }
49
+ }
50
+ exports.TestStepAttachments = TestStepAttachments;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TestStepRun = void 0;
7
+ var messages = _interopRequireWildcard(require("@cucumber/messages"));
8
+ var _stripAnsiEscapes = require("../../../utils/stripAnsiEscapes");
9
+ var _timing = require("./timing");
10
+ var _TestStepAttachments = require("./TestStepAttachments");
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ class TestStepRun {
14
+ testCaseRun;
15
+ testStep;
16
+ pwStep;
17
+ constructor(testCaseRun, testStep, pwStep) {
18
+ this.testCaseRun = testCaseRun;
19
+ this.testStep = testStep;
20
+ this.pwStep = pwStep;
21
+ }
22
+ buildMessages() {
23
+ const stepAttachments = new _TestStepAttachments.TestStepAttachments(this.testCaseRun, this.testStep, this.pwStep);
24
+ return [this.buildTestStepStarted(),
25
+ // prettier-ignore
26
+ ...stepAttachments.buildMessages(), this.buildTestStepFinished()];
27
+ }
28
+ wasExecuted() {
29
+ return Boolean(this.pwStep);
30
+ }
31
+ get startTime() {
32
+ return this.wasExecuted() ? this.pwStep.startTime : this.testCaseRun.result.startTime;
33
+ }
34
+ get duration() {
35
+ return this.wasExecuted() ? this.pwStep.duration : 0;
36
+ }
37
+ buildTestStepStarted() {
38
+ const testStepStarted = {
39
+ testCaseStartedId: this.testCaseRun.id,
40
+ testStepId: this.testStep.id,
41
+ timestamp: (0, _timing.toCucumberTimestamp)(this.startTime.getTime())
42
+ };
43
+ return {
44
+ testStepStarted
45
+ };
46
+ }
47
+ buildTestStepFinished() {
48
+ var _this$pwStep;
49
+ const error = (_this$pwStep = this.pwStep) === null || _this$pwStep === void 0 ? void 0 : _this$pwStep.error;
50
+ const testStepFinished = {
51
+ testCaseStartedId: this.testCaseRun.id,
52
+ testStepId: this.testStep.id,
53
+ testStepResult: {
54
+ duration: messages.TimeConversion.millisecondsToDuration(this.duration),
55
+ status: this.getStatus(error),
56
+ message: error ? formatError(error) : undefined,
57
+ exception: error ? this.buildException(error) : undefined
58
+ },
59
+ timestamp: (0, _timing.toCucumberTimestamp)(this.startTime.getTime() + this.duration)
60
+ };
61
+ return {
62
+ testStepFinished
63
+ };
64
+ }
65
+ buildException(error) {
66
+ return {
67
+ type: 'Error',
68
+ message: error.message ? (0, _stripAnsiEscapes.stripAnsiEscapes)(error.message) : undefined,
69
+ stackTrace: error.stack ? (0, _stripAnsiEscapes.stripAnsiEscapes)(error.stack) : undefined
70
+ // Use type casting b/c older versions of @cucumber/messages don't have 'stackTrace' field
71
+ // todo: add direct dependency on @cucumber/messages
72
+ };
73
+ }
74
+ getStatus(error) {
75
+ switch (true) {
76
+ case !this.wasExecuted():
77
+ return messages.TestStepResultStatus.SKIPPED;
78
+ case Boolean(error):
79
+ return messages.TestStepResultStatus.FAILED;
80
+ default:
81
+ return messages.TestStepResultStatus.PASSED;
82
+ }
83
+ }
84
+ }
85
+ exports.TestStepRun = TestStepRun;
86
+ function formatError(error) {
87
+ return (0, _stripAnsiEscapes.stripAnsiEscapes)([error.message, error.snippet].filter(Boolean).join('\n'));
88
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getMessagesBuilderRef = getMessagesBuilderRef;
7
+ var _Builder = require("./Builder");
8
+ /**
9
+ * Returns reference to a messagesBuilder singleton.
10
+ * We pass onTestEnd and onEnd calls only for the first reference (reporter),
11
+ * otherwise all events will be duplicated.
12
+ */
13
+
14
+ let instance;
15
+ let referenceCount = 0;
16
+ function getMessagesBuilderRef() {
17
+ if (!instance) {
18
+ instance = new _Builder.MessagesBuilder();
19
+ }
20
+ const isFirstRef = ++referenceCount === 1;
21
+ return {
22
+ builder: instance,
23
+ onTestEnd(test, result) {
24
+ isFirstRef && this.builder.onTestEnd(test, result);
25
+ },
26
+ onEnd(fullResult) {
27
+ isFirstRef && this.builder.onEnd(fullResult);
28
+ }
29
+ };
30
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.collectStepsDfs = collectStepsDfs;
7
+ exports.collectStepsWithCategory = collectStepsWithCategory;
8
+ exports.findDeepestErrorStep = findDeepestErrorStep;
9
+ exports.getHooksRootStep = getHooksRootStep;
10
+ /**
11
+ * Utility functions for filtering Playwright steps.
12
+ */
13
+ // Playwright step categoires, that can be mapped to testStep / hook in Cucumber report
14
+ const MEANINGFUL_STEP_CATEGORIES = ['hook', 'fixture', 'test.step'];
15
+ function collectStepsWithCategory(parent, category) {
16
+ const categories = Array.isArray(category) ? category : [category];
17
+ const steps = collectStepsDfs(parent);
18
+ return steps.filter(step => categories.includes(step.category));
19
+ }
20
+ function getHooksRootStep(result, type) {
21
+ const rootStepTitle = type === 'before' ? 'Before Hooks' : 'After Hooks';
22
+ return result.steps.find(step => step.category === 'hook' && step.title === rootStepTitle);
23
+ }
24
+ /**
25
+ * Drills down to the deepest error step.
26
+ */
27
+ function findDeepestErrorStep(root) {
28
+ let errorStep = root !== null && root !== void 0 && root.error ? root : null;
29
+ while (errorStep) {
30
+ const nextErrorStep = errorStep.steps.find(step => {
31
+ return step.error && MEANINGFUL_STEP_CATEGORIES.includes(step.category);
32
+ });
33
+ if (!nextErrorStep) {
34
+ break;
35
+ }
36
+ errorStep = nextErrorStep;
37
+ }
38
+ return errorStep;
39
+ }
40
+ /**
41
+ * Returns all steps in DFS order.
42
+ * See: https://en.wikipedia.org/wiki/Depth-first_search
43
+ */
44
+ function collectStepsDfs(parent) {
45
+ var _parent$steps;
46
+ return (parent === null || parent === void 0 || (_parent$steps = parent.steps) === null || _parent$steps === void 0 ? void 0 : _parent$steps.reduce((res, step) => {
47
+ res.push(step);
48
+ res.push(...collectStepsDfs(step));
49
+ return res;
50
+ }, [])) || [];
51
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.calcMinMaxByArray = calcMinMaxByArray;
7
+ exports.toCucumberTimestamp = toCucumberTimestamp;
8
+ var _messages = require("@cucumber/messages");
9
+ /**
10
+ * Timing utils.
11
+ */
12
+
13
+ function toCucumberTimestamp(time) {
14
+ return _messages.TimeConversion.millisecondsSinceEpochToTimestamp(time);
15
+ }
16
+ function calcMinMaxByArray(items) {
17
+ let startTime = items.length > 0 ? items[0].startTime : new Date();
18
+ let endTime = items.length > 0 ? getEndTime(items[0]) : new Date();
19
+ items.forEach(item => {
20
+ const resultEndTime = getEndTime(item);
21
+ if (item.startTime < startTime) {
22
+ startTime = item.startTime;
23
+ }
24
+ if (resultEndTime > endTime) {
25
+ endTime = resultEndTime;
26
+ }
27
+ });
28
+ return {
29
+ startTime,
30
+ duration: endTime.getTime() - startTime.getTime()
31
+ };
32
+ }
33
+ function getEndTime(entity) {
34
+ return new Date(entity.startTime.getTime() + entity.duration);
35
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,68 @@
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 step in playwright runner.
14
+ */
15
+
16
+ class StepInvoker {
17
+ world;
18
+ keyword;
19
+ constructor(world, keyword) {
20
+ this.world = world;
21
+ this.keyword = keyword;
22
+ this.invoke = this.invoke.bind(this);
23
+ }
24
+ /**
25
+ * Invokes particular step.
26
+ * See: https://github.com/cucumber/cucumber-js/blob/main/src/runtime/test_case_runner.ts#L299
27
+ */
28
+ async invoke(text, argument, stepFixtures) {
29
+ this.world.$internal.currentStepFixtures = stepFixtures || {};
30
+ const stepDefinition = this.getStepDefinition(text);
31
+ // Get location of step call in generated test file.
32
+ // This call must be exactly here to have correct call stack (before async calls)
33
+ const location = (0, _getLocationInFile.getLocationInFile)(this.world.testInfo.file);
34
+ const stepTitle = this.getStepTitle(text);
35
+ const code = (0, _defineStep.getStepCode)(stepDefinition);
36
+ const parameters = await this.getStepParameters(stepDefinition, text, argument || undefined);
37
+ this.world.$internal.bddData.registerStep(stepDefinition, text, location);
38
+ return (0, _testTypeImpl.runStepWithCustomLocation)(this.world.test, stepTitle, location, () => code.apply(this.world, parameters));
39
+ }
40
+ getStepDefinition(text) {
41
+ const stepDefinition = (0, _loadSteps.findStepDefinition)(this.world.options.supportCodeLibrary, text, this.world.testInfo.file);
42
+ if (!stepDefinition) {
43
+ throw new Error(`Undefined step: "${text}"`);
44
+ }
45
+ return stepDefinition;
46
+ }
47
+ async getStepParameters(stepDefinition, text, argument) {
48
+ // see: https://github.com/cucumber/cucumber-js/blob/main/src/models/step_definition.ts#L25
49
+ const {
50
+ parameters
51
+ } = await stepDefinition.getInvocationParameters({
52
+ hookParameter: {},
53
+ // only text and argument are needed
54
+ step: {
55
+ text,
56
+ argument
57
+ },
58
+ world: this.world
59
+ });
60
+ return parameters;
61
+ }
62
+ getStepTitle(text) {
63
+ // Currently prepend keyword only for English.
64
+ // For other langs it's more complex as we need to pass original keyword from step.
65
+ return (0, _lang.isEnglish)(this.world.options.lang) ? `${this.keyword} ${text}` : text;
66
+ }
67
+ }
68
+ exports.StepInvoker = StepInvoker;