@cucumber/cucumber 7.2.1 → 8.0.0-rc.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 (177) hide show
  1. package/README.md +11 -4
  2. package/lib/cli/argv_parser.d.ts +1 -2
  3. package/lib/cli/argv_parser.js +8 -12
  4. package/lib/cli/argv_parser.js.map +1 -1
  5. package/lib/cli/configuration_builder.d.ts +0 -1
  6. package/lib/cli/configuration_builder.js +20 -21
  7. package/lib/cli/configuration_builder.js.map +1 -1
  8. package/lib/cli/helpers.d.ts +1 -0
  9. package/lib/cli/helpers.js +49 -22
  10. package/lib/cli/helpers.js.map +1 -1
  11. package/lib/cli/i18n.js +6 -6
  12. package/lib/cli/i18n.js.map +1 -1
  13. package/lib/cli/index.d.ts +1 -1
  14. package/lib/cli/index.js +35 -29
  15. package/lib/cli/index.js.map +1 -1
  16. package/lib/cli/profile_loader.d.ts +3 -3
  17. package/lib/cli/profile_loader.js +17 -10
  18. package/lib/cli/profile_loader.js.map +1 -1
  19. package/lib/cli/publish_banner.js +1 -1
  20. package/lib/cli/publish_banner.js.map +1 -1
  21. package/lib/formatter/builder.d.ts +5 -4
  22. package/lib/formatter/builder.js +38 -52
  23. package/lib/formatter/builder.js.map +1 -1
  24. package/lib/formatter/get_color_fns.d.ts +6 -2
  25. package/lib/formatter/get_color_fns.js +18 -12
  26. package/lib/formatter/get_color_fns.js.map +1 -1
  27. package/lib/formatter/helpers/event_data_collector.d.ts +15 -17
  28. package/lib/formatter/helpers/event_data_collector.js +19 -12
  29. package/lib/formatter/helpers/event_data_collector.js.map +1 -1
  30. package/lib/formatter/helpers/formatters.d.ts +6 -0
  31. package/lib/formatter/helpers/formatters.js +41 -0
  32. package/lib/formatter/helpers/formatters.js.map +1 -0
  33. package/lib/formatter/helpers/gherkin_document_parser.d.ts +5 -6
  34. package/lib/formatter/helpers/gherkin_document_parser.js +24 -40
  35. package/lib/formatter/helpers/gherkin_document_parser.js.map +1 -1
  36. package/lib/formatter/helpers/issue_helpers.d.ts +6 -6
  37. package/lib/formatter/helpers/issue_helpers.js +6 -8
  38. package/lib/formatter/helpers/issue_helpers.js.map +1 -1
  39. package/lib/formatter/helpers/keyword_type.js +1 -5
  40. package/lib/formatter/helpers/keyword_type.js.map +1 -1
  41. package/lib/formatter/helpers/pickle_parser.d.ts +9 -10
  42. package/lib/formatter/helpers/pickle_parser.js +8 -17
  43. package/lib/formatter/helpers/pickle_parser.js.map +1 -1
  44. package/lib/formatter/helpers/step_argument_formatter.d.ts +2 -2
  45. package/lib/formatter/helpers/step_argument_formatter.js.map +1 -1
  46. package/lib/formatter/helpers/summary_helpers.d.ts +2 -2
  47. package/lib/formatter/helpers/summary_helpers.js +39 -20
  48. package/lib/formatter/helpers/summary_helpers.js.map +1 -1
  49. package/lib/formatter/helpers/test_case_attempt_formatter.js +34 -15
  50. package/lib/formatter/helpers/test_case_attempt_formatter.js.map +1 -1
  51. package/lib/formatter/helpers/test_case_attempt_parser.d.ts +5 -5
  52. package/lib/formatter/helpers/test_case_attempt_parser.js +30 -15
  53. package/lib/formatter/helpers/test_case_attempt_parser.js.map +1 -1
  54. package/lib/formatter/helpers/usage_helpers/index.d.ts +3 -3
  55. package/lib/formatter/helpers/usage_helpers/index.js +48 -45
  56. package/lib/formatter/helpers/usage_helpers/index.js.map +1 -1
  57. package/lib/formatter/html_formatter.d.ts +1 -0
  58. package/lib/formatter/html_formatter.js +2 -1
  59. package/lib/formatter/html_formatter.js.map +1 -1
  60. package/lib/formatter/http_stream.js +1 -1
  61. package/lib/formatter/http_stream.js.map +1 -1
  62. package/lib/formatter/index.d.ts +1 -0
  63. package/lib/formatter/index.js.map +1 -1
  64. package/lib/formatter/json_formatter.d.ts +22 -27
  65. package/lib/formatter/json_formatter.js +62 -30
  66. package/lib/formatter/json_formatter.js.map +1 -1
  67. package/lib/formatter/message_formatter.d.ts +1 -0
  68. package/lib/formatter/message_formatter.js +2 -1
  69. package/lib/formatter/message_formatter.js.map +1 -1
  70. package/lib/formatter/progress_bar_formatter.d.ts +7 -6
  71. package/lib/formatter/progress_bar_formatter.js +5 -4
  72. package/lib/formatter/progress_bar_formatter.js.map +1 -1
  73. package/lib/formatter/progress_formatter.d.ts +3 -2
  74. package/lib/formatter/progress_formatter.js +30 -10
  75. package/lib/formatter/progress_formatter.js.map +1 -1
  76. package/lib/formatter/rerun_formatter.d.ts +1 -0
  77. package/lib/formatter/rerun_formatter.js +33 -11
  78. package/lib/formatter/rerun_formatter.js.map +1 -1
  79. package/lib/formatter/snippets_formatter.d.ts +1 -0
  80. package/lib/formatter/snippets_formatter.js +22 -2
  81. package/lib/formatter/snippets_formatter.js.map +1 -1
  82. package/lib/formatter/step_definition_snippet_builder/index.d.ts +3 -3
  83. package/lib/formatter/step_definition_snippet_builder/index.js.map +1 -1
  84. package/lib/formatter/step_definition_snippet_builder/javascript_snippet_syntax.js +3 -0
  85. package/lib/formatter/step_definition_snippet_builder/javascript_snippet_syntax.js.map +1 -1
  86. package/lib/formatter/step_definition_snippet_builder/snippet_syntax.d.ts +1 -1
  87. package/lib/formatter/step_definition_snippet_builder/snippet_syntax.js.map +1 -1
  88. package/lib/formatter/summary_formatter.d.ts +3 -2
  89. package/lib/formatter/summary_formatter.js +4 -4
  90. package/lib/formatter/summary_formatter.js.map +1 -1
  91. package/lib/formatter/usage_formatter.d.ts +1 -0
  92. package/lib/formatter/usage_formatter.js +24 -5
  93. package/lib/formatter/usage_formatter.js.map +1 -1
  94. package/lib/formatter/usage_json_formatter.d.ts +1 -0
  95. package/lib/formatter/usage_json_formatter.js +1 -0
  96. package/lib/formatter/usage_json_formatter.js.map +1 -1
  97. package/lib/importer.js +13 -0
  98. package/lib/index.d.ts +15 -12
  99. package/lib/index.js +6 -3
  100. package/lib/index.js.map +1 -1
  101. package/lib/models/data_table.d.ts +3 -4
  102. package/lib/models/data_table.js +9 -7
  103. package/lib/models/data_table.js.map +1 -1
  104. package/lib/models/definition.d.ts +2 -2
  105. package/lib/models/definition.js.map +1 -1
  106. package/lib/models/step_definition.js +1 -2
  107. package/lib/models/step_definition.js.map +1 -1
  108. package/lib/models/test_case_hook_definition.d.ts +2 -2
  109. package/lib/models/test_case_hook_definition.js.map +1 -1
  110. package/lib/models/test_step_hook_definition.d.ts +2 -2
  111. package/lib/models/test_step_hook_definition.js.map +1 -1
  112. package/lib/pickle_filter.d.ts +9 -11
  113. package/lib/pickle_filter.js +9 -9
  114. package/lib/pickle_filter.js.map +1 -1
  115. package/lib/runtime/assemble_test_cases.d.ts +13 -0
  116. package/lib/runtime/assemble_test_cases.js +88 -0
  117. package/lib/runtime/assemble_test_cases.js.map +1 -0
  118. package/lib/runtime/attachment_manager/index.d.ts +2 -2
  119. package/lib/runtime/attachment_manager/index.js +23 -4
  120. package/lib/runtime/attachment_manager/index.js.map +1 -1
  121. package/lib/runtime/helpers.d.ts +3 -2
  122. package/lib/runtime/helpers.js +36 -1
  123. package/lib/runtime/helpers.js.map +1 -1
  124. package/lib/runtime/index.d.ts +3 -4
  125. package/lib/runtime/index.js +27 -43
  126. package/lib/runtime/index.js.map +1 -1
  127. package/lib/runtime/parallel/command_types.d.ts +10 -9
  128. package/lib/runtime/parallel/command_types.js.map +1 -1
  129. package/lib/runtime/parallel/coordinator.d.ts +9 -9
  130. package/lib/runtime/parallel/coordinator.js +62 -55
  131. package/lib/runtime/parallel/coordinator.js.map +1 -1
  132. package/lib/runtime/parallel/worker.d.ts +2 -2
  133. package/lib/runtime/parallel/worker.js +23 -21
  134. package/lib/runtime/parallel/worker.js.map +1 -1
  135. package/lib/runtime/step_runner.d.ts +3 -3
  136. package/lib/runtime/step_runner.js +16 -14
  137. package/lib/runtime/step_runner.js.map +1 -1
  138. package/lib/runtime/stopwatch.d.ts +4 -4
  139. package/lib/runtime/stopwatch.js +21 -2
  140. package/lib/runtime/stopwatch.js.map +1 -1
  141. package/lib/runtime/test_case_runner.d.ts +51 -0
  142. package/lib/runtime/test_case_runner.js +253 -0
  143. package/lib/runtime/test_case_runner.js.map +1 -0
  144. package/lib/stack_trace_filter.js +4 -5
  145. package/lib/stack_trace_filter.js.map +1 -1
  146. package/lib/step_arguments.d.ts +4 -4
  147. package/lib/step_arguments.js.map +1 -1
  148. package/lib/support_code_library_builder/build_helpers.js +14 -10
  149. package/lib/support_code_library_builder/build_helpers.js.map +1 -1
  150. package/lib/support_code_library_builder/index.d.ts +9 -7
  151. package/lib/support_code_library_builder/index.js +10 -24
  152. package/lib/support_code_library_builder/index.js.map +1 -1
  153. package/lib/support_code_library_builder/types.d.ts +22 -23
  154. package/lib/support_code_library_builder/types.js.map +1 -1
  155. package/lib/support_code_library_builder/validate_arguments.js +14 -19
  156. package/lib/support_code_library_builder/validate_arguments.js.map +1 -1
  157. package/lib/support_code_library_builder/world.d.ts +7 -1
  158. package/lib/support_code_library_builder/world.js.map +1 -1
  159. package/lib/time.d.ts +3 -10
  160. package/lib/time.js +39 -48
  161. package/lib/time.js.map +1 -1
  162. package/lib/user_code_runner.js +7 -14
  163. package/lib/user_code_runner.js.map +1 -1
  164. package/lib/value_checker.d.ts +2 -2
  165. package/lib/value_checker.js.map +1 -1
  166. package/lib/wrapper.mjs +38 -0
  167. package/package.json +73 -64
  168. package/CHANGELOG.md +0 -1881
  169. package/lib/runtime/pickle_runner.d.ts +0 -67
  170. package/lib/runtime/pickle_runner.js +0 -305
  171. package/lib/runtime/pickle_runner.js.map +0 -1
  172. package/lib/status.d.ts +0 -3
  173. package/lib/status.js +0 -5
  174. package/lib/status.js.map +0 -1
  175. package/lib/support_code_library_builder/finalize_helpers.d.ts +0 -10
  176. package/lib/support_code_library_builder/finalize_helpers.js +0 -26
  177. package/lib/support_code_library_builder/finalize_helpers.js.map +0 -1
@@ -1,26 +1,28 @@
1
1
  "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
15
20
  };
16
21
  Object.defineProperty(exports, "__esModule", { value: true });
17
22
  exports.getUsage = void 0;
18
- const lodash_1 = __importDefault(require("lodash"));
19
23
  const pickle_parser_1 = require("../pickle_parser");
20
- const path_1 = __importDefault(require("path"));
21
24
  const gherkin_document_parser_1 = require("../gherkin_document_parser");
22
- const time_1 = require("../../../time");
23
- const messages_1 = require("@cucumber/messages");
25
+ const messages = __importStar(require("@cucumber/messages"));
24
26
  const value_checker_1 = require("../../../value_checker");
25
27
  function buildEmptyMapping(stepDefinitions) {
26
28
  const mapping = {};
@@ -36,13 +38,18 @@ function buildEmptyMapping(stepDefinitions) {
36
38
  });
37
39
  return mapping;
38
40
  }
41
+ const unexecutedStatuses = [
42
+ messages.TestStepResultStatus.AMBIGUOUS,
43
+ messages.TestStepResultStatus.SKIPPED,
44
+ messages.TestStepResultStatus.UNDEFINED,
45
+ ];
39
46
  function buildMapping({ cwd, stepDefinitions, eventDataCollector, }) {
40
47
  const mapping = buildEmptyMapping(stepDefinitions);
41
- lodash_1.default.each(eventDataCollector.getTestCaseAttempts(), (testCaseAttempt) => {
48
+ eventDataCollector.getTestCaseAttempts().forEach((testCaseAttempt) => {
42
49
  const pickleStepMap = pickle_parser_1.getPickleStepMap(testCaseAttempt.pickle);
43
50
  const gherkinStepMap = gherkin_document_parser_1.getGherkinStepMap(testCaseAttempt.gherkinDocument);
44
51
  testCaseAttempt.testCase.testSteps.forEach((testStep) => {
45
- if (testStep.pickleStepId !== '' &&
52
+ if (value_checker_1.doesHaveValue(testStep.pickleStepId) &&
46
53
  testStep.stepDefinitionIds.length === 1) {
47
54
  const stepDefinitionId = testStep.stepDefinitionIds[0];
48
55
  const pickleStep = pickleStepMap[testStep.pickleStepId];
@@ -50,15 +57,10 @@ function buildMapping({ cwd, stepDefinitions, eventDataCollector, }) {
50
57
  const match = {
51
58
  line: gherkinStep.location.line,
52
59
  text: pickleStep.text,
53
- uri: path_1.default.relative(cwd, testCaseAttempt.pickle.uri),
60
+ uri: testCaseAttempt.pickle.uri,
54
61
  };
55
62
  const { duration, status } = testCaseAttempt.stepResults[testStep.id];
56
- if (![
57
- messages_1.messages.TestStepFinished.TestStepResult.Status.AMBIGUOUS,
58
- messages_1.messages.TestStepFinished.TestStepResult.Status.SKIPPED,
59
- messages_1.messages.TestStepFinished.TestStepResult.Status.UNDEFINED,
60
- ].includes(status) &&
61
- value_checker_1.doesHaveValue(duration)) {
63
+ if (!unexecutedStatuses.includes(status) && value_checker_1.doesHaveValue(duration)) {
62
64
  match.duration = duration;
63
65
  }
64
66
  if (value_checker_1.doesHaveValue(mapping[stepDefinitionId])) {
@@ -69,32 +71,33 @@ function buildMapping({ cwd, stepDefinitions, eventDataCollector, }) {
69
71
  });
70
72
  return mapping;
71
73
  }
72
- function invertDuration(duration) {
73
- if (value_checker_1.doesHaveValue(duration)) {
74
- return -1 * time_1.durationToMilliseconds(duration);
74
+ function normalizeDuration(duration) {
75
+ if (duration == null) {
76
+ return Number.MIN_SAFE_INTEGER;
75
77
  }
76
- return 1;
78
+ return messages.TimeConversion.durationToMilliseconds(duration);
77
79
  }
78
80
  function buildResult(mapping) {
79
- return lodash_1.default.chain(mapping)
80
- .map((_a) => {
81
- var { matches } = _a, rest = __rest(_a, ["matches"]);
82
- const sortedMatches = lodash_1.default.sortBy(matches, [
83
- (match) => invertDuration(match.duration),
84
- 'text',
85
- ]);
86
- const result = Object.assign({ matches: sortedMatches }, rest);
87
- const durations = lodash_1.default.chain(matches)
88
- .map((m) => m.duration)
89
- .compact()
90
- .value();
81
+ return Object.keys(mapping)
82
+ .map((stepDefinitionId) => {
83
+ const { matches, ...rest } = mapping[stepDefinitionId];
84
+ const sortedMatches = matches.sort((a, b) => {
85
+ if (a.duration === b.duration) {
86
+ return a.text < b.text ? -1 : 1;
87
+ }
88
+ return normalizeDuration(b.duration) - normalizeDuration(a.duration);
89
+ });
90
+ const result = { matches: sortedMatches, ...rest };
91
+ const durations = matches
92
+ .filter((m) => m.duration != null)
93
+ .map((m) => m.duration);
91
94
  if (durations.length > 0) {
92
- result.meanDuration = time_1.millisecondsToDuration(lodash_1.default.meanBy(durations, (d) => time_1.durationToMilliseconds(d)));
95
+ const totalMilliseconds = durations.reduce((acc, x) => acc + messages.TimeConversion.durationToMilliseconds(x), 0);
96
+ result.meanDuration = messages.TimeConversion.millisecondsToDuration(totalMilliseconds / durations.length);
93
97
  }
94
98
  return result;
95
99
  })
96
- .sortBy((usage) => invertDuration(usage.meanDuration))
97
- .value();
100
+ .sort((a, b) => normalizeDuration(b.meanDuration) - normalizeDuration(a.meanDuration));
98
101
  }
99
102
  function getUsage({ cwd, stepDefinitions, eventDataCollector, }) {
100
103
  const mapping = buildMapping({ cwd, stepDefinitions, eventDataCollector });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/formatter/helpers/usage_helpers/index.ts"],"names":[],"mappings":"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","sourcesContent":["import _, { Dictionary } from 'lodash'\nimport { getPickleStepMap } from '../pickle_parser'\nimport path from 'path'\nimport { getGherkinStepMap } from '../gherkin_document_parser'\nimport { durationToMilliseconds, millisecondsToDuration } from '../../../time'\nimport { messages } from '@cucumber/messages'\nimport StepDefinition from '../../../models/step_definition'\nimport { doesHaveValue } from '../../../value_checker'\nimport EventDataCollector from '../event_data_collector'\n\nexport interface IUsageMatch {\n duration?: messages.IDuration\n line: number\n text: string\n uri: string\n}\n\nexport interface IUsage {\n code: string\n line: number\n matches: IUsageMatch[]\n meanDuration?: messages.IDuration\n pattern: string\n patternType: string\n uri: string\n}\n\nexport interface IGetUsageRequest {\n cwd: string\n eventDataCollector: EventDataCollector\n stepDefinitions: StepDefinition[]\n}\n\nfunction buildEmptyMapping(\n stepDefinitions: StepDefinition[]\n): Dictionary<IUsage> {\n const mapping: Dictionary<IUsage> = {}\n stepDefinitions.forEach((stepDefinition) => {\n mapping[stepDefinition.id] = {\n code: stepDefinition.unwrappedCode.toString(),\n line: stepDefinition.line,\n pattern: stepDefinition.expression.source,\n patternType: stepDefinition.expression.constructor.name,\n matches: [],\n uri: stepDefinition.uri,\n }\n })\n return mapping\n}\n\nfunction buildMapping({\n cwd,\n stepDefinitions,\n eventDataCollector,\n}: IGetUsageRequest): Dictionary<IUsage> {\n const mapping = buildEmptyMapping(stepDefinitions)\n _.each(eventDataCollector.getTestCaseAttempts(), (testCaseAttempt) => {\n const pickleStepMap = getPickleStepMap(testCaseAttempt.pickle)\n const gherkinStepMap = getGherkinStepMap(testCaseAttempt.gherkinDocument)\n testCaseAttempt.testCase.testSteps.forEach((testStep) => {\n if (\n testStep.pickleStepId !== '' &&\n testStep.stepDefinitionIds.length === 1\n ) {\n const stepDefinitionId = testStep.stepDefinitionIds[0]\n const pickleStep = pickleStepMap[testStep.pickleStepId]\n const gherkinStep = gherkinStepMap[pickleStep.astNodeIds[0]]\n const match: IUsageMatch = {\n line: gherkinStep.location.line,\n text: pickleStep.text,\n uri: path.relative(cwd, testCaseAttempt.pickle.uri),\n }\n const { duration, status } = testCaseAttempt.stepResults[testStep.id]\n if (\n ![\n messages.TestStepFinished.TestStepResult.Status.AMBIGUOUS,\n messages.TestStepFinished.TestStepResult.Status.SKIPPED,\n messages.TestStepFinished.TestStepResult.Status.UNDEFINED,\n ].includes(status) &&\n doesHaveValue(duration)\n ) {\n match.duration = duration\n }\n if (doesHaveValue(mapping[stepDefinitionId])) {\n mapping[stepDefinitionId].matches.push(match)\n }\n }\n })\n })\n return mapping\n}\n\nfunction invertDuration(duration: messages.IDuration): number {\n if (doesHaveValue(duration)) {\n return -1 * durationToMilliseconds(duration)\n }\n return 1\n}\n\nfunction buildResult(mapping: Dictionary<IUsage>): IUsage[] {\n return _.chain(mapping)\n .map(({ matches, ...rest }: IUsage) => {\n const sortedMatches = _.sortBy(matches, [\n (match: IUsageMatch) => invertDuration(match.duration),\n 'text',\n ])\n const result = { matches: sortedMatches, ...rest }\n const durations: messages.IDuration[] = _.chain(matches)\n .map((m: IUsageMatch) => m.duration)\n .compact()\n .value()\n if (durations.length > 0) {\n result.meanDuration = millisecondsToDuration(\n _.meanBy(durations, (d: messages.IDuration) =>\n durationToMilliseconds(d)\n )\n )\n }\n return result\n })\n .sortBy((usage: IUsage) => invertDuration(usage.meanDuration))\n .value()\n}\n\nexport function getUsage({\n cwd,\n stepDefinitions,\n eventDataCollector,\n}: IGetUsageRequest): IUsage[] {\n const mapping = buildMapping({ cwd, stepDefinitions, eventDataCollector })\n return buildResult(mapping)\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/formatter/helpers/usage_helpers/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPickleStepMap } from '../pickle_parser'\nimport { getGherkinStepMap } from '../gherkin_document_parser'\nimport * as messages from '@cucumber/messages'\nimport StepDefinition from '../../../models/step_definition'\nimport { doesHaveValue } from '../../../value_checker'\nimport EventDataCollector from '../event_data_collector'\n\nexport interface IUsageMatch {\n duration?: messages.Duration\n line: number\n text: string\n uri: string\n}\n\nexport interface IUsage {\n code: string\n line: number\n matches: IUsageMatch[]\n meanDuration?: messages.Duration\n pattern: string\n patternType: string\n uri: string\n}\n\nexport interface IGetUsageRequest {\n cwd: string\n eventDataCollector: EventDataCollector\n stepDefinitions: StepDefinition[]\n}\n\nfunction buildEmptyMapping(\n stepDefinitions: StepDefinition[]\n): Record<string, IUsage> {\n const mapping: Record<string, IUsage> = {}\n stepDefinitions.forEach((stepDefinition) => {\n mapping[stepDefinition.id] = {\n code: stepDefinition.unwrappedCode.toString(),\n line: stepDefinition.line,\n pattern: stepDefinition.expression.source,\n patternType: stepDefinition.expression.constructor.name,\n matches: [],\n uri: stepDefinition.uri,\n }\n })\n return mapping\n}\n\nconst unexecutedStatuses: readonly messages.TestStepResultStatus[] = [\n messages.TestStepResultStatus.AMBIGUOUS,\n messages.TestStepResultStatus.SKIPPED,\n messages.TestStepResultStatus.UNDEFINED,\n]\n\nfunction buildMapping({\n cwd,\n stepDefinitions,\n eventDataCollector,\n}: IGetUsageRequest): Record<string, IUsage> {\n const mapping = buildEmptyMapping(stepDefinitions)\n eventDataCollector.getTestCaseAttempts().forEach((testCaseAttempt) => {\n const pickleStepMap = getPickleStepMap(testCaseAttempt.pickle)\n const gherkinStepMap = getGherkinStepMap(testCaseAttempt.gherkinDocument)\n testCaseAttempt.testCase.testSteps.forEach((testStep) => {\n if (\n doesHaveValue(testStep.pickleStepId) &&\n testStep.stepDefinitionIds.length === 1\n ) {\n const stepDefinitionId = testStep.stepDefinitionIds[0]\n const pickleStep = pickleStepMap[testStep.pickleStepId]\n const gherkinStep = gherkinStepMap[pickleStep.astNodeIds[0]]\n const match: IUsageMatch = {\n line: gherkinStep.location.line,\n text: pickleStep.text,\n uri: testCaseAttempt.pickle.uri,\n }\n const { duration, status } = testCaseAttempt.stepResults[testStep.id]\n if (!unexecutedStatuses.includes(status) && doesHaveValue(duration)) {\n match.duration = duration\n }\n if (doesHaveValue(mapping[stepDefinitionId])) {\n mapping[stepDefinitionId].matches.push(match)\n }\n }\n })\n })\n return mapping\n}\n\nfunction normalizeDuration(duration?: messages.Duration): number {\n if (duration == null) {\n return Number.MIN_SAFE_INTEGER\n }\n return messages.TimeConversion.durationToMilliseconds(duration)\n}\n\nfunction buildResult(mapping: Record<string, IUsage>): IUsage[] {\n return Object.keys(mapping)\n .map((stepDefinitionId) => {\n const { matches, ...rest } = mapping[stepDefinitionId]\n const sortedMatches = matches.sort((a: IUsageMatch, b: IUsageMatch) => {\n if (a.duration === b.duration) {\n return a.text < b.text ? -1 : 1\n }\n return normalizeDuration(b.duration) - normalizeDuration(a.duration)\n })\n const result = { matches: sortedMatches, ...rest }\n const durations: messages.Duration[] = matches\n .filter((m) => m.duration != null)\n .map((m) => m.duration)\n if (durations.length > 0) {\n const totalMilliseconds = durations.reduce(\n (acc, x) => acc + messages.TimeConversion.durationToMilliseconds(x),\n 0\n )\n result.meanDuration = messages.TimeConversion.millisecondsToDuration(\n totalMilliseconds / durations.length\n )\n }\n return result\n })\n .sort(\n (a: IUsage, b: IUsage) =>\n normalizeDuration(b.meanDuration) - normalizeDuration(a.meanDuration)\n )\n}\n\nexport function getUsage({\n cwd,\n stepDefinitions,\n eventDataCollector,\n}: IGetUsageRequest): IUsage[] {\n const mapping = buildMapping({ cwd, stepDefinitions, eventDataCollector })\n return buildResult(mapping)\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import Formatter, { IFormatterOptions } from '.';
2
2
  export default class HtmlFormatter extends Formatter {
3
3
  private readonly _finished;
4
+ static readonly documentation: string;
4
5
  constructor(options: IFormatterOptions);
5
6
  finished(): Promise<void>;
6
7
  }
@@ -13,7 +13,7 @@ class HtmlFormatter extends _1.default {
13
13
  constructor(options) {
14
14
  super(options);
15
15
  const cucumberHtmlStream = new html_formatter_1.default(resolve_pkg_1.default('@cucumber/html-formatter', { cwd: __dirname }) +
16
- '/dist/cucumber-react.css', resolve_pkg_1.default('@cucumber/html-formatter', { cwd: __dirname }) +
16
+ '/dist/main.css', resolve_pkg_1.default('@cucumber/html-formatter', { cwd: __dirname }) +
17
17
  '/dist/main.js');
18
18
  options.eventBroadcaster.on('envelope', (envelope) => {
19
19
  cucumberHtmlStream.write(envelope);
@@ -30,4 +30,5 @@ class HtmlFormatter extends _1.default {
30
30
  }
31
31
  }
32
32
  exports.default = HtmlFormatter;
33
+ HtmlFormatter.documentation = 'Outputs HTML report';
33
34
  //# sourceMappingURL=html_formatter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html_formatter.js","sourceRoot":"","sources":["../../src/formatter/html_formatter.ts"],"names":[],"mappings":";;;;;AAAA,yCAAgD;AAEhD,8DAAoC;AACpC,8EAAyD;AACzD,oDAAgD;AAChD,mCAAiC;AACjC,+BAAgC;AAEhC,MAAqB,aAAc,SAAQ,UAAS;IAGlD,YAAY,OAA0B;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,MAAM,kBAAkB,GAAG,IAAI,wBAAkB,CAC/C,qBAAU,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACxD,0BAA0B,EAC5B,qBAAU,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACxD,eAAe,CAClB,CAAA;QACD,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,QAA2B,EAAE,EAAE;YACtE,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,6BAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;gBAC3C,kBAAkB,CAAC,GAAG,EAAE,CAAA;aACzB;QACH,CAAC,CAAC,CAAA;QACF,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QACzD,IAAI,CAAC,SAAS,GAAG,gBAAS,CAAC,iBAAQ,CAAC,CAAC,kBAAkB,CAAC,CAAA;IAC1D,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,SAAS,CAAA;QACpB,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAA;IACxB,CAAC;CACF;AAzBD,gCAyBC","sourcesContent":["import Formatter, { IFormatterOptions } from '.'\nimport { messages } from '@cucumber/messages'\nimport resolvePkg from 'resolve-pkg'\nimport CucumberHtmlStream from '@cucumber/html-formatter'\nimport { doesHaveValue } from '../value_checker'\nimport { finished } from 'stream'\nimport { promisify } from 'util'\n\nexport default class HtmlFormatter extends Formatter {\n private readonly _finished: Promise<void>\n\n constructor(options: IFormatterOptions) {\n super(options)\n const cucumberHtmlStream = new CucumberHtmlStream(\n resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) +\n '/dist/cucumber-react.css',\n resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) +\n '/dist/main.js'\n )\n options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => {\n cucumberHtmlStream.write(envelope)\n if (doesHaveValue(envelope.testRunFinished)) {\n cucumberHtmlStream.end()\n }\n })\n cucumberHtmlStream.on('data', (chunk) => this.log(chunk))\n this._finished = promisify(finished)(cucumberHtmlStream)\n }\n\n async finished(): Promise<void> {\n await this._finished\n await super.finished()\n }\n}\n"]}
1
+ {"version":3,"file":"html_formatter.js","sourceRoot":"","sources":["../../src/formatter/html_formatter.ts"],"names":[],"mappings":";;;;;AAAA,yCAAgD;AAEhD,8DAAoC;AACpC,8EAAyD;AACzD,oDAAgD;AAChD,mCAAiC;AACjC,+BAAgC;AAEhC,MAAqB,aAAc,SAAQ,UAAS;IAIlD,YAAY,OAA0B;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,MAAM,kBAAkB,GAAG,IAAI,wBAAkB,CAC/C,qBAAU,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACxD,gBAAgB,EAClB,qBAAU,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACxD,eAAe,CAClB,CAAA;QACD,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,QAA2B,EAAE,EAAE;YACtE,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,6BAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;gBAC3C,kBAAkB,CAAC,GAAG,EAAE,CAAA;aACzB;QACH,CAAC,CAAC,CAAA;QACF,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QACzD,IAAI,CAAC,SAAS,GAAG,gBAAS,CAAC,iBAAQ,CAAC,CAAC,kBAAkB,CAAC,CAAA;IAC1D,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,SAAS,CAAA;QACpB,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAA;IACxB,CAAC;;AAzBH,gCA0BC;AAxBwB,2BAAa,GAAW,qBAAqB,CAAA","sourcesContent":["import Formatter, { IFormatterOptions } from '.'\nimport * as messages from '@cucumber/messages'\nimport resolvePkg from 'resolve-pkg'\nimport CucumberHtmlStream from '@cucumber/html-formatter'\nimport { doesHaveValue } from '../value_checker'\nimport { finished } from 'stream'\nimport { promisify } from 'util'\n\nexport default class HtmlFormatter extends Formatter {\n private readonly _finished: Promise<void>\n public static readonly documentation: string = 'Outputs HTML report'\n\n constructor(options: IFormatterOptions) {\n super(options)\n const cucumberHtmlStream = new CucumberHtmlStream(\n resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) +\n '/dist/main.css',\n resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) +\n '/dist/main.js'\n )\n options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => {\n cucumberHtmlStream.write(envelope)\n if (doesHaveValue(envelope.testRunFinished)) {\n cucumberHtmlStream.end()\n }\n })\n cucumberHtmlStream.on('data', (chunk) => this.log(chunk))\n this._finished = promisify(finished)(cucumberHtmlStream)\n }\n\n async finished(): Promise<void> {\n await this._finished\n await super.finished()\n }\n}\n"]}
@@ -86,7 +86,7 @@ class HttpStream extends stream_1.Transform {
86
86
  if (upload) {
87
87
  additionalHttpHeaders['Content-Length'] = fs_1.default.statSync(this.tempFilePath).size;
88
88
  }
89
- const allHeaders = Object.assign(Object.assign({}, headers), additionalHttpHeaders);
89
+ const allHeaders = { ...headers, ...additionalHttpHeaders };
90
90
  const req = httpx.request(url, {
91
91
  method,
92
92
  headers: allHeaders,
@@ -1 +1 @@
1
- {"version":3,"file":"http_stream.js","sourceRoot":"","sources":["../../src/formatter/http_stream.ts"],"names":[],"mappings":"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","sourcesContent":["import { pipeline, Transform, Writable } from 'stream'\nimport tmp from 'tmp'\nimport fs from 'fs'\nimport http from 'http'\nimport https from 'https'\nimport { doesHaveValue } from '../value_checker'\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT'\n\n/**\n * This Writable writes data to a HTTP/HTTPS URL.\n *\n * It has special handling for https://reports.cucumber.io/\n * which uses an API where the first request is a `GET`,\n * and if the response is 202 with a Location header, issues\n * a PUT request to that URL.\n *\n * 3xx redirects are not currently followed.\n */\nexport default class HttpStream extends Transform {\n private tempFilePath: string\n private tempFile: Writable\n\n constructor(\n private readonly url: string,\n private readonly method: HttpMethod,\n private readonly headers: http.OutgoingHttpHeaders\n ) {\n super({\n readableObjectMode: true,\n })\n }\n\n _write(\n chunk: any,\n encoding: BufferEncoding,\n callback: (err?: Error | null) => void\n ): void {\n if (this.tempFile === undefined) {\n tmp.file((err, name, fd) => {\n if (doesHaveValue(err)) return callback(err)\n this.tempFilePath = name\n this.tempFile = fs.createWriteStream(name, { fd })\n this.tempFile.write(chunk, encoding, callback)\n })\n } else {\n this.tempFile.write(chunk, encoding, callback)\n }\n }\n\n _final(callback: (error?: Error | null) => void): void {\n this.tempFile.end(() => {\n this.sendHttpRequest(\n this.url,\n this.method,\n this.headers,\n (err1, res1) => {\n if (doesHaveValue(err1)) return callback(err1)\n this.pushResponseBody(res1, () => {\n this.emitErrorUnlessHttp2xx(res1, this.url, this.method)\n if (\n res1.statusCode === 202 &&\n res1.headers.location !== undefined\n ) {\n this.sendHttpRequest(\n res1.headers.location,\n 'PUT',\n {},\n (err2, res2) => {\n if (doesHaveValue(err2)) return callback(err2)\n this.emitErrorUnlessHttp2xx(res2, this.url, this.method)\n callback()\n }\n )\n } else {\n callback()\n }\n })\n }\n )\n })\n }\n\n private pushResponseBody(res: http.IncomingMessage, done: () => void): void {\n let body = Buffer.alloc(0)\n res.on('data', (chunk) => {\n body = Buffer.concat([body, chunk])\n })\n res.on('end', () => {\n this.push(body.toString('utf-8'))\n done()\n })\n }\n\n private emitErrorUnlessHttp2xx(\n res: http.IncomingMessage,\n url: string,\n method: string\n ): void {\n if (res.statusCode >= 300)\n this.emit(\n 'error',\n new Error(\n `Unexpected http status ${res.statusCode} from ${method} ${url}`\n )\n )\n }\n\n private sendHttpRequest(\n url: string,\n method: HttpMethod,\n headers: http.OutgoingHttpHeaders,\n callback: (err?: Error | null, res?: http.IncomingMessage) => void\n ): void {\n const httpx = doesHaveValue(url.match(/^https:/)) ? https : http\n const additionalHttpHeaders: http.OutgoingHttpHeaders = {}\n\n const upload = method === 'PUT' || method === 'POST'\n if (upload) {\n additionalHttpHeaders['Content-Length'] = fs.statSync(\n this.tempFilePath\n ).size\n }\n\n const allHeaders = { ...headers, ...additionalHttpHeaders }\n const req = httpx.request(url, {\n method,\n headers: allHeaders,\n })\n req.on('error', (err) => this.emit('error', err))\n req.on('response', (res) => {\n res.on('error', (err) => this.emit('error', err))\n callback(null, res)\n })\n\n if (upload) {\n pipeline(fs.createReadStream(this.tempFilePath), req, (err) => {\n if (doesHaveValue(err)) {\n this.emit('error', err)\n }\n })\n } else {\n req.end()\n }\n }\n}\n"]}
1
+ {"version":3,"file":"http_stream.js","sourceRoot":"","sources":["../../src/formatter/http_stream.ts"],"names":[],"mappings":"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","sourcesContent":["import { pipeline, Transform, Writable } from 'stream'\nimport tmp from 'tmp'\nimport fs from 'fs'\nimport http from 'http'\nimport https from 'https'\nimport { doesHaveValue } from '../value_checker'\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT'\n\n/**\n * This Writable writes data to a HTTP/HTTPS URL.\n *\n * It has special handling for https://reports.cucumber.io/\n * which uses an API where the first request is a `GET`,\n * and if the response is 202 with a Location header, issues\n * a PUT request to that URL.\n *\n * 3xx redirects are not currently followed.\n */\nexport default class HttpStream extends Transform {\n private tempFilePath: string\n private tempFile: Writable\n\n constructor(\n private readonly url: string,\n private readonly method: HttpMethod,\n private readonly headers: http.OutgoingHttpHeaders\n ) {\n super({\n readableObjectMode: true,\n })\n }\n\n _write(\n chunk: any,\n encoding: BufferEncoding,\n callback: (err?: Error | null) => void\n ): void {\n if (this.tempFile === undefined) {\n tmp.file((err, name, fd) => {\n if (doesHaveValue(err)) return callback(err)\n this.tempFilePath = name\n this.tempFile = fs.createWriteStream(name, { fd })\n this.tempFile.write(chunk, encoding, callback)\n })\n } else {\n this.tempFile.write(chunk, encoding, callback)\n }\n }\n\n _final(callback: (error?: Error | null) => void): void {\n this.tempFile.end(() => {\n this.sendHttpRequest(\n this.url,\n this.method,\n this.headers,\n (err1, res1) => {\n if (doesHaveValue(err1)) return callback(err1)\n this.pushResponseBody(res1, () => {\n this.emitErrorUnlessHttp2xx(res1, this.url, this.method)\n if (\n res1.statusCode === 202 &&\n res1.headers.location !== undefined\n ) {\n this.sendHttpRequest(\n res1.headers.location,\n 'PUT',\n {},\n (err2, res2) => {\n if (doesHaveValue(err2)) return callback(err2)\n this.emitErrorUnlessHttp2xx(res2, this.url, this.method)\n callback()\n }\n )\n } else {\n callback()\n }\n })\n }\n )\n })\n }\n\n private pushResponseBody(res: http.IncomingMessage, done: () => void): void {\n let body = Buffer.alloc(0)\n res.on('data', (chunk) => {\n body = Buffer.concat([body, chunk])\n })\n res.on('end', () => {\n this.push(body.toString('utf-8'))\n done()\n })\n }\n\n private emitErrorUnlessHttp2xx(\n res: http.IncomingMessage,\n url: string,\n method: string\n ): void {\n if (res.statusCode >= 300)\n this.emit(\n 'error',\n new Error(\n `Unexpected http status ${res.statusCode} from ${method} ${url}`\n )\n )\n }\n\n private sendHttpRequest(\n url: string,\n method: HttpMethod,\n headers: http.OutgoingHttpHeaders,\n callback: (err?: Error | null, res?: http.IncomingMessage) => void\n ): void {\n const httpx = doesHaveValue(url.match(/^https:/)) ? https : http\n const additionalHttpHeaders: http.OutgoingHttpHeaders = {}\n\n const upload = method === 'PUT' || method === 'POST'\n if (upload) {\n additionalHttpHeaders['Content-Length'] = fs.statSync(\n this.tempFilePath\n ).size\n }\n\n const allHeaders = { ...headers, ...additionalHttpHeaders }\n const req = httpx.request(url, {\n method,\n headers: allHeaders,\n })\n req.on('error', (err) => this.emit('error', err))\n req.on('response', (res) => {\n res.on('error', (err) => this.emit('error', err))\n callback(null, res)\n })\n\n if (upload) {\n pipeline(fs.createReadStream(this.tempFilePath), req, (err) => {\n if (doesHaveValue(err)) {\n this.emit('error', err)\n }\n })\n } else {\n req.end()\n }\n }\n}\n"]}
@@ -33,6 +33,7 @@ export default class Formatter {
33
33
  protected stream: WritableStream;
34
34
  protected supportCodeLibrary: ISupportCodeLibrary;
35
35
  private readonly cleanup;
36
+ static readonly documentation: string;
36
37
  constructor(options: IFormatterOptions);
37
38
  finished(): Promise<void>;
38
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatter/index.ts"],"names":[],"mappings":";;AAgCA,MAAqB,SAAS;IAU5B,YAAY,OAA0B;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF;AAxBD,4BAwBC","sourcesContent":["import { IColorFns } from './get_color_fns'\nimport { EventDataCollector } from './helpers'\nimport StepDefinitionSnippetBuilder from './step_definition_snippet_builder'\nimport { PassThrough, Writable as WritableStream } from 'stream'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { WriteStream as FsWriteStream } from 'fs'\nimport { WriteStream as TtyWriteStream } from 'tty'\nimport { EventEmitter } from 'events'\nimport { IParsedArgvFormatOptions } from '../cli/argv_parser'\nimport HttpStream from './http_stream'\n\nexport type IFormatterStream =\n | FsWriteStream\n | TtyWriteStream\n | PassThrough\n | HttpStream\nexport type IFormatterLogFn = (buffer: string | Uint8Array) => void\nexport type IFormatterCleanupFn = () => Promise<any>\n\nexport interface IFormatterOptions {\n colorFns: IColorFns\n cwd: string\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n log: IFormatterLogFn\n parsedArgvOptions: IParsedArgvFormatOptions\n snippetBuilder: StepDefinitionSnippetBuilder\n stream: WritableStream\n cleanup: IFormatterCleanupFn\n supportCodeLibrary: ISupportCodeLibrary\n}\n\nexport default class Formatter {\n protected colorFns: IColorFns\n protected cwd: string\n protected eventDataCollector: EventDataCollector\n protected log: IFormatterLogFn\n protected snippetBuilder: StepDefinitionSnippetBuilder\n protected stream: WritableStream\n protected supportCodeLibrary: ISupportCodeLibrary\n private readonly cleanup: IFormatterCleanupFn\n\n constructor(options: IFormatterOptions) {\n this.colorFns = options.colorFns\n this.cwd = options.cwd\n this.eventDataCollector = options.eventDataCollector\n this.log = options.log\n this.snippetBuilder = options.snippetBuilder\n this.stream = options.stream\n this.supportCodeLibrary = options.supportCodeLibrary\n this.cleanup = options.cleanup\n }\n\n async finished(): Promise<void> {\n await this.cleanup()\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatter/index.ts"],"names":[],"mappings":";;AAgCA,MAAqB,SAAS;IAW5B,YAAY,OAA0B;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF;AAzBD,4BAyBC","sourcesContent":["import { IColorFns } from './get_color_fns'\nimport { EventDataCollector } from './helpers'\nimport StepDefinitionSnippetBuilder from './step_definition_snippet_builder'\nimport { PassThrough, Writable as WritableStream } from 'stream'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { WriteStream as FsWriteStream } from 'fs'\nimport { WriteStream as TtyWriteStream } from 'tty'\nimport { EventEmitter } from 'events'\nimport { IParsedArgvFormatOptions } from '../cli/argv_parser'\nimport HttpStream from './http_stream'\n\nexport type IFormatterStream =\n | FsWriteStream\n | TtyWriteStream\n | PassThrough\n | HttpStream\nexport type IFormatterLogFn = (buffer: string | Uint8Array) => void\nexport type IFormatterCleanupFn = () => Promise<any>\n\nexport interface IFormatterOptions {\n colorFns: IColorFns\n cwd: string\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n log: IFormatterLogFn\n parsedArgvOptions: IParsedArgvFormatOptions\n snippetBuilder: StepDefinitionSnippetBuilder\n stream: WritableStream\n cleanup: IFormatterCleanupFn\n supportCodeLibrary: ISupportCodeLibrary\n}\n\nexport default class Formatter {\n protected colorFns: IColorFns\n protected cwd: string\n protected eventDataCollector: EventDataCollector\n protected log: IFormatterLogFn\n protected snippetBuilder: StepDefinitionSnippetBuilder\n protected stream: WritableStream\n protected supportCodeLibrary: ISupportCodeLibrary\n private readonly cleanup: IFormatterCleanupFn\n static readonly documentation: string\n\n constructor(options: IFormatterOptions) {\n this.colorFns = options.colorFns\n this.cwd = options.cwd\n this.eventDataCollector = options.eventDataCollector\n this.log = options.log\n this.snippetBuilder = options.snippetBuilder\n this.stream = options.stream\n this.supportCodeLibrary = options.supportCodeLibrary\n this.cleanup = options.cleanup\n }\n\n async finished(): Promise<void> {\n await this.cleanup()\n }\n}\n"]}
@@ -1,10 +1,5 @@
1
- import { Dictionary } from 'lodash';
2
1
  import Formatter, { IFormatterOptions } from './';
3
- import { messages } from '@cucumber/messages';
4
- import IFeature = messages.GherkinDocument.IFeature;
5
- import IPickle = messages.IPickle;
6
- import IScenario = messages.GherkinDocument.Feature.IScenario;
7
- import IRule = messages.GherkinDocument.Feature.FeatureChild.IRule;
2
+ import * as messages from '@cucumber/messages';
8
3
  export interface IJsonFeature {
9
4
  description: string;
10
5
  elements: IJsonScenario[];
@@ -40,44 +35,44 @@ export interface IJsonTag {
40
35
  line: number;
41
36
  }
42
37
  interface IBuildJsonFeatureOptions {
43
- feature: messages.GherkinDocument.IFeature;
38
+ feature: messages.Feature;
44
39
  elements: IJsonScenario[];
45
40
  uri: string;
46
41
  }
47
42
  interface IBuildJsonScenarioOptions {
48
- feature: messages.GherkinDocument.IFeature;
49
- gherkinScenarioMap: Dictionary<IScenario>;
50
- gherkinExampleRuleMap: Dictionary<IRule>;
51
- gherkinScenarioLocationMap: Dictionary<messages.ILocation>;
52
- pickle: messages.IPickle;
43
+ feature: messages.Feature;
44
+ gherkinScenarioMap: Record<string, messages.Scenario>;
45
+ gherkinExampleRuleMap: Record<string, messages.Rule>;
46
+ gherkinScenarioLocationMap: Record<string, messages.Location>;
47
+ pickle: messages.Pickle;
53
48
  steps: IJsonStep[];
54
49
  }
55
50
  interface IBuildJsonStepOptions {
56
51
  isBeforeHook: boolean;
57
- gherkinStepMap: Dictionary<messages.GherkinDocument.Feature.IStep>;
58
- pickleStepMap: Dictionary<messages.Pickle.IPickleStep>;
59
- testStep: messages.TestCase.ITestStep;
60
- testStepAttachments: messages.IAttachment[];
61
- testStepResult: messages.TestStepFinished.ITestStepResult;
52
+ gherkinStepMap: Record<string, messages.Step>;
53
+ pickleStepMap: Record<string, messages.PickleStep>;
54
+ testStep: messages.TestStep;
55
+ testStepAttachments: messages.Attachment[];
56
+ testStepResult: messages.TestStepResult;
62
57
  }
63
58
  export default class JsonFormatter extends Formatter {
59
+ static readonly documentation: string;
64
60
  constructor(options: IFormatterOptions);
65
- convertNameToId(obj: IFeature | IPickle): string;
66
- formatDataTable(dataTable: messages.PickleStepArgument.IPickleTable): any;
67
- formatDocString(docString: messages.PickleStepArgument.IPickleDocString, gherkinStep: messages.GherkinDocument.Feature.IStep): any;
68
- formatStepArgument(stepArgument: messages.IPickleStepArgument, gherkinStep: messages.GherkinDocument.Feature.IStep): any;
61
+ convertNameToId(obj: messages.Feature | messages.Pickle): string;
62
+ formatDataTable(dataTable: messages.PickleTable): any;
63
+ formatDocString(docString: messages.PickleDocString, gherkinStep: messages.Step): any;
64
+ formatStepArgument(stepArgument: messages.PickleStepArgument, gherkinStep: messages.Step): any;
69
65
  onTestRunFinished(): void;
70
66
  getFeatureData({ feature, elements, uri, }: IBuildJsonFeatureOptions): IJsonFeature;
71
67
  getScenarioData({ feature, gherkinScenarioLocationMap, gherkinExampleRuleMap, gherkinScenarioMap, pickle, steps, }: IBuildJsonScenarioOptions): IJsonScenario;
72
68
  private formatScenarioId;
73
69
  getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments, testStepResult, }: IBuildJsonStepOptions): IJsonStep;
74
- getFeatureTags(feature: IFeature): IJsonTag[];
70
+ getFeatureTags(feature: messages.Feature): IJsonTag[];
75
71
  getScenarioTags({ feature, pickle, gherkinScenarioMap, }: {
76
- feature: IFeature;
77
- pickle: IPickle;
78
- gherkinScenarioMap: {
79
- [id: string]: IScenario;
80
- };
72
+ feature: messages.Feature;
73
+ pickle: messages.Pickle;
74
+ gherkinScenarioMap: Record<string, messages.Scenario>;
81
75
  }): IJsonTag[];
76
+ private getScenarioTag;
82
77
  }
83
78
  export {};
@@ -1,23 +1,38 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
23
  };
5
24
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const lodash_1 = __importDefault(require("lodash"));
7
25
  const _1 = __importDefault(require("./"));
8
- const status_1 = __importDefault(require("../status"));
9
26
  const helpers_1 = require("./helpers");
10
- const time_1 = require("../time");
11
- const path_1 = __importDefault(require("path"));
27
+ const messages = __importStar(require("@cucumber/messages"));
12
28
  const gherkin_document_parser_1 = require("./helpers/gherkin_document_parser");
13
29
  const value_checker_1 = require("../value_checker");
14
30
  const step_arguments_1 = require("../step_arguments");
15
31
  const { getGherkinStepMap, getGherkinScenarioMap } = helpers_1.GherkinDocumentParser;
16
- const { getScenarioDescription, getPickleStepMap, getStepKeyword, } = helpers_1.PickleParser;
32
+ const { getScenarioDescription, getPickleStepMap, getStepKeyword } = helpers_1.PickleParser;
17
33
  class JsonFormatter extends _1.default {
18
34
  constructor(options) {
19
35
  super(options);
20
- console.warn("The built-in JSON formatter is deprecated and will be removed in the next major release. Where you need a structured data representation of your test run, it's best to use the `message` formatter. For legacy tools that depend on the deprecated JSON format, a standalone formatter is available (see https://github.com/cucumber/cucumber/tree/master/json-formatter).");
21
36
  options.eventBroadcaster.on('envelope', (envelope) => {
22
37
  if (value_checker_1.doesHaveValue(envelope.testRunFinished)) {
23
38
  this.onTestRunFinished();
@@ -29,7 +44,9 @@ class JsonFormatter extends _1.default {
29
44
  }
30
45
  formatDataTable(dataTable) {
31
46
  return {
32
- rows: dataTable.rows.map((row) => ({ cells: lodash_1.default.map(row.cells, 'value') })),
47
+ rows: dataTable.rows.map((row) => ({
48
+ cells: row.cells.map((x) => x.value),
49
+ })),
33
50
  };
34
51
  }
35
52
  formatDocString(docString, gherkinStep) {
@@ -51,16 +68,19 @@ class JsonFormatter extends _1.default {
51
68
  }
52
69
  onTestRunFinished() {
53
70
  const groupedTestCaseAttempts = {};
54
- lodash_1.default.each(this.eventDataCollector.getTestCaseAttempts(), (testCaseAttempt) => {
55
- if (!testCaseAttempt.worstTestStepResult.willBeRetried) {
56
- const uri = path_1.default.relative(this.cwd, testCaseAttempt.pickle.uri);
71
+ this.eventDataCollector
72
+ .getTestCaseAttempts()
73
+ .forEach((testCaseAttempt) => {
74
+ if (!testCaseAttempt.willBeRetried) {
75
+ const uri = testCaseAttempt.pickle.uri;
57
76
  if (value_checker_1.doesNotHaveValue(groupedTestCaseAttempts[uri])) {
58
77
  groupedTestCaseAttempts[uri] = [];
59
78
  }
60
79
  groupedTestCaseAttempts[uri].push(testCaseAttempt);
61
80
  }
62
81
  });
63
- const features = lodash_1.default.map(groupedTestCaseAttempts, (group, uri) => {
82
+ const features = Object.keys(groupedTestCaseAttempts).map((uri) => {
83
+ const group = groupedTestCaseAttempts[uri];
64
84
  const { gherkinDocument } = group[0];
65
85
  const gherkinStepMap = getGherkinStepMap(gherkinDocument);
66
86
  const gherkinScenarioMap = getGherkinScenarioMap(gherkinDocument);
@@ -71,7 +91,7 @@ class JsonFormatter extends _1.default {
71
91
  const pickleStepMap = getPickleStepMap(pickle);
72
92
  let isBeforeHook = true;
73
93
  const steps = testCaseAttempt.testCase.testSteps.map((testStep) => {
74
- isBeforeHook = isBeforeHook && testStep.pickleStepId === '';
94
+ isBeforeHook = isBeforeHook && !value_checker_1.doesHaveValue(testStep.pickleStepId);
75
95
  return this.getStepData({
76
96
  isBeforeHook,
77
97
  gherkinStepMap,
@@ -139,7 +159,7 @@ class JsonFormatter extends _1.default {
139
159
  }
140
160
  getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments, testStepResult, }) {
141
161
  const data = {};
142
- if (testStep.pickleStepId !== '') {
162
+ if (value_checker_1.doesHaveValue(testStep.pickleStepId)) {
143
163
  const pickleStep = pickleStepMap[testStep.pickleStepId];
144
164
  data.arguments = this.formatStepArgument(pickleStep.argument, gherkinStepMap[pickleStep.astNodeIds[0]]);
145
165
  data.keyword = getStepKeyword({ pickleStep, gherkinStepMap });
@@ -150,19 +170,24 @@ class JsonFormatter extends _1.default {
150
170
  data.keyword = isBeforeHook ? 'Before' : 'After';
151
171
  data.hidden = true;
152
172
  }
153
- if (testStep.stepDefinitionIds.length === 1) {
173
+ if (value_checker_1.doesHaveValue(testStep.stepDefinitionIds) &&
174
+ testStep.stepDefinitionIds.length === 1) {
154
175
  const stepDefinition = this.supportCodeLibrary.stepDefinitions.find((s) => s.id === testStep.stepDefinitionIds[0]);
155
176
  data.match = { location: helpers_1.formatLocation(stepDefinition) };
156
177
  }
157
178
  const { message, status } = testStepResult;
158
- data.result = { status: status_1.default[status].toLowerCase() };
179
+ data.result = {
180
+ status: messages.TestStepResultStatus[status].toLowerCase(),
181
+ };
159
182
  if (value_checker_1.doesHaveValue(testStepResult.duration)) {
160
- data.result.duration = time_1.durationToNanoseconds(testStepResult.duration);
183
+ data.result.duration =
184
+ messages.TimeConversion.durationToMilliseconds(testStepResult.duration) * 1000000;
161
185
  }
162
- if (status === status_1.default.FAILED && value_checker_1.doesHaveValue(message)) {
186
+ if (status === messages.TestStepResultStatus.FAILED &&
187
+ value_checker_1.doesHaveValue(message)) {
163
188
  data.result.error_message = message;
164
189
  }
165
- if (lodash_1.default.size(testStepAttachments) > 0) {
190
+ if ((testStepAttachments === null || testStepAttachments === void 0 ? void 0 : testStepAttachments.length) > 0) {
166
191
  data.embeddings = testStepAttachments.map((attachment) => ({
167
192
  data: attachment.body,
168
193
  mime_type: attachment.mediaType,
@@ -171,24 +196,31 @@ class JsonFormatter extends _1.default {
171
196
  return data;
172
197
  }
173
198
  getFeatureTags(feature) {
174
- return lodash_1.default.map(feature.tags, (tagData) => ({
199
+ return feature.tags.map((tagData) => ({
175
200
  name: tagData.name,
176
201
  line: tagData.location.line,
177
202
  }));
178
203
  }
179
204
  getScenarioTags({ feature, pickle, gherkinScenarioMap, }) {
180
- return lodash_1.default.map(pickle.tags, (tagData) => {
181
- const featureSource = feature.tags.find((t) => t.id === tagData.astNodeId);
182
- const scenarioSource = gherkinScenarioMap[pickle.astNodeIds[0]].tags.find((t) => t.id === tagData.astNodeId);
183
- const line = value_checker_1.doesHaveValue(featureSource)
184
- ? featureSource.location.line
185
- : scenarioSource.location.line;
186
- return {
187
- name: tagData.name,
188
- line,
189
- };
190
- });
205
+ const scenario = gherkinScenarioMap[pickle.astNodeIds[0]];
206
+ return pickle.tags.map((tagData) => this.getScenarioTag(tagData, feature, scenario));
207
+ }
208
+ getScenarioTag(tagData, feature, scenario) {
209
+ var _a;
210
+ const byAstNodeId = (tag) => tag.id === tagData.astNodeId;
211
+ const flatten = (acc, val) => acc.concat(val);
212
+ const tag = feature.tags.find(byAstNodeId) ||
213
+ scenario.tags.find(byAstNodeId) ||
214
+ scenario.examples
215
+ .map((e) => e.tags)
216
+ .reduce(flatten, [])
217
+ .find(byAstNodeId);
218
+ return {
219
+ name: tagData.name,
220
+ line: (_a = tag === null || tag === void 0 ? void 0 : tag.location) === null || _a === void 0 ? void 0 : _a.line,
221
+ };
191
222
  }
192
223
  }
193
224
  exports.default = JsonFormatter;
225
+ JsonFormatter.documentation = 'Prints the feature as JSON. The JSON format is in maintenance mode. Please consider using the message formatter with the standalone json-formatter (https://github.com/cucumber/cucumber/tree/master/json-formatter).';
194
226
  //# sourceMappingURL=json_formatter.js.map