@serenity-js/console-reporter 3.41.1 → 3.42.0

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 (131) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/esm/index.d.ts +6 -0
  3. package/esm/index.d.ts.map +1 -0
  4. package/esm/index.js +6 -0
  5. package/esm/index.js.map +1 -0
  6. package/esm/stage/crew/console-reporter/ConsoleReporter.d.ts +187 -0
  7. package/esm/stage/crew/console-reporter/ConsoleReporter.d.ts.map +1 -0
  8. package/esm/stage/crew/console-reporter/ConsoleReporter.js +423 -0
  9. package/esm/stage/crew/console-reporter/ConsoleReporter.js.map +1 -0
  10. package/esm/stage/crew/console-reporter/ConsoleReporterConfig.d.ts +13 -0
  11. package/esm/stage/crew/console-reporter/ConsoleReporterConfig.d.ts.map +1 -0
  12. package/esm/stage/crew/console-reporter/ConsoleReporterConfig.js +2 -0
  13. package/esm/stage/crew/console-reporter/ConsoleReporterConfig.js.map +1 -0
  14. package/esm/stage/crew/console-reporter/Printer.d.ts +32 -0
  15. package/esm/stage/crew/console-reporter/Printer.d.ts.map +1 -0
  16. package/esm/stage/crew/console-reporter/Printer.js +67 -0
  17. package/esm/stage/crew/console-reporter/Printer.js.map +1 -0
  18. package/esm/stage/crew/console-reporter/Summary.d.ts +39 -0
  19. package/esm/stage/crew/console-reporter/Summary.d.ts.map +1 -0
  20. package/esm/stage/crew/console-reporter/Summary.js +49 -0
  21. package/esm/stage/crew/console-reporter/Summary.js.map +1 -0
  22. package/esm/stage/crew/console-reporter/SummaryFormatter.d.ts +14 -0
  23. package/esm/stage/crew/console-reporter/SummaryFormatter.d.ts.map +1 -0
  24. package/esm/stage/crew/console-reporter/SummaryFormatter.js +57 -0
  25. package/esm/stage/crew/console-reporter/SummaryFormatter.js.map +1 -0
  26. package/esm/stage/crew/console-reporter/index.d.ts +3 -0
  27. package/esm/stage/crew/console-reporter/index.d.ts.map +1 -0
  28. package/esm/stage/crew/console-reporter/index.js +3 -0
  29. package/esm/stage/crew/console-reporter/index.js.map +1 -0
  30. package/esm/stage/crew/console-reporter/themes/TerminalTheme.d.ts +21 -0
  31. package/esm/stage/crew/console-reporter/themes/TerminalTheme.d.ts.map +1 -0
  32. package/esm/stage/crew/console-reporter/themes/TerminalTheme.js +24 -0
  33. package/esm/stage/crew/console-reporter/themes/TerminalTheme.js.map +1 -0
  34. package/esm/stage/crew/console-reporter/themes/ThemeForColourTerminals.d.ts +29 -0
  35. package/esm/stage/crew/console-reporter/themes/ThemeForColourTerminals.d.ts.map +1 -0
  36. package/esm/stage/crew/console-reporter/themes/ThemeForColourTerminals.js +50 -0
  37. package/esm/stage/crew/console-reporter/themes/ThemeForColourTerminals.js.map +1 -0
  38. package/esm/stage/crew/console-reporter/themes/ThemeForDarkTerminals.d.ts +32 -0
  39. package/esm/stage/crew/console-reporter/themes/ThemeForDarkTerminals.d.ts.map +1 -0
  40. package/esm/stage/crew/console-reporter/themes/ThemeForDarkTerminals.js +39 -0
  41. package/esm/stage/crew/console-reporter/themes/ThemeForDarkTerminals.js.map +1 -0
  42. package/esm/stage/crew/console-reporter/themes/ThemeForLightTerminals.d.ts +32 -0
  43. package/esm/stage/crew/console-reporter/themes/ThemeForLightTerminals.d.ts.map +1 -0
  44. package/esm/stage/crew/console-reporter/themes/ThemeForLightTerminals.js +39 -0
  45. package/esm/stage/crew/console-reporter/themes/ThemeForLightTerminals.js.map +1 -0
  46. package/esm/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.d.ts +41 -0
  47. package/esm/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.d.ts.map +1 -0
  48. package/esm/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.js +48 -0
  49. package/esm/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.js.map +1 -0
  50. package/esm/stage/crew/console-reporter/themes/index.d.ts +5 -0
  51. package/esm/stage/crew/console-reporter/themes/index.d.ts.map +1 -0
  52. package/esm/stage/crew/console-reporter/themes/index.js +5 -0
  53. package/esm/stage/crew/console-reporter/themes/index.js.map +1 -0
  54. package/esm/stage/crew/index.d.ts +2 -0
  55. package/esm/stage/crew/index.d.ts.map +1 -0
  56. package/esm/stage/crew/index.js +2 -0
  57. package/esm/stage/crew/index.js.map +1 -0
  58. package/esm/stage/index.d.ts +2 -0
  59. package/esm/stage/index.d.ts.map +1 -0
  60. package/esm/stage/index.js +2 -0
  61. package/esm/stage/index.js.map +1 -0
  62. package/lib/index.d.ts +3 -3
  63. package/lib/index.d.ts.map +1 -1
  64. package/lib/index.js +3 -3
  65. package/lib/index.js.map +1 -1
  66. package/lib/package.json +1 -0
  67. package/lib/stage/crew/console-reporter/ConsoleReporter.d.ts +4 -4
  68. package/lib/stage/crew/console-reporter/ConsoleReporter.d.ts.map +1 -1
  69. package/lib/stage/crew/console-reporter/ConsoleReporter.js +36 -29
  70. package/lib/stage/crew/console-reporter/ConsoleReporter.js.map +1 -1
  71. package/lib/stage/crew/console-reporter/Printer.d.ts +1 -1
  72. package/lib/stage/crew/console-reporter/Printer.d.ts.map +1 -1
  73. package/lib/stage/crew/console-reporter/Summary.d.ts +1 -1
  74. package/lib/stage/crew/console-reporter/Summary.d.ts.map +1 -1
  75. package/lib/stage/crew/console-reporter/Summary.js +1 -1
  76. package/lib/stage/crew/console-reporter/Summary.js.map +1 -1
  77. package/lib/stage/crew/console-reporter/SummaryFormatter.d.ts +2 -2
  78. package/lib/stage/crew/console-reporter/SummaryFormatter.d.ts.map +1 -1
  79. package/lib/stage/crew/console-reporter/SummaryFormatter.js +1 -1
  80. package/lib/stage/crew/console-reporter/SummaryFormatter.js.map +1 -1
  81. package/lib/stage/crew/console-reporter/index.d.ts +2 -2
  82. package/lib/stage/crew/console-reporter/index.d.ts.map +1 -1
  83. package/lib/stage/crew/console-reporter/index.js +2 -2
  84. package/lib/stage/crew/console-reporter/index.js.map +1 -1
  85. package/lib/stage/crew/console-reporter/themes/TerminalTheme.d.ts +1 -1
  86. package/lib/stage/crew/console-reporter/themes/TerminalTheme.d.ts.map +1 -1
  87. package/lib/stage/crew/console-reporter/themes/ThemeForColourTerminals.d.ts +2 -2
  88. package/lib/stage/crew/console-reporter/themes/ThemeForColourTerminals.d.ts.map +1 -1
  89. package/lib/stage/crew/console-reporter/themes/ThemeForColourTerminals.js +3 -3
  90. package/lib/stage/crew/console-reporter/themes/ThemeForColourTerminals.js.map +1 -1
  91. package/lib/stage/crew/console-reporter/themes/ThemeForDarkTerminals.d.ts +1 -1
  92. package/lib/stage/crew/console-reporter/themes/ThemeForDarkTerminals.d.ts.map +1 -1
  93. package/lib/stage/crew/console-reporter/themes/ThemeForDarkTerminals.js +2 -2
  94. package/lib/stage/crew/console-reporter/themes/ThemeForDarkTerminals.js.map +1 -1
  95. package/lib/stage/crew/console-reporter/themes/ThemeForLightTerminals.d.ts +1 -1
  96. package/lib/stage/crew/console-reporter/themes/ThemeForLightTerminals.d.ts.map +1 -1
  97. package/lib/stage/crew/console-reporter/themes/ThemeForLightTerminals.js +2 -2
  98. package/lib/stage/crew/console-reporter/themes/ThemeForLightTerminals.js.map +1 -1
  99. package/lib/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.d.ts +2 -2
  100. package/lib/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.d.ts.map +1 -1
  101. package/lib/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.js +2 -2
  102. package/lib/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.js.map +1 -1
  103. package/lib/stage/crew/console-reporter/themes/index.d.ts +4 -4
  104. package/lib/stage/crew/console-reporter/themes/index.d.ts.map +1 -1
  105. package/lib/stage/crew/console-reporter/themes/index.js +4 -4
  106. package/lib/stage/crew/console-reporter/themes/index.js.map +1 -1
  107. package/lib/stage/crew/index.d.ts +1 -1
  108. package/lib/stage/crew/index.d.ts.map +1 -1
  109. package/lib/stage/crew/index.js +1 -1
  110. package/lib/stage/crew/index.js.map +1 -1
  111. package/lib/stage/index.d.ts +1 -1
  112. package/lib/stage/index.d.ts.map +1 -1
  113. package/lib/stage/index.js +1 -1
  114. package/lib/stage/index.js.map +1 -1
  115. package/package.json +29 -8
  116. package/src/index.ts +3 -3
  117. package/src/stage/crew/console-reporter/ConsoleReporter.ts +32 -27
  118. package/src/stage/crew/console-reporter/Printer.ts +1 -1
  119. package/src/stage/crew/console-reporter/Summary.ts +2 -2
  120. package/src/stage/crew/console-reporter/SummaryFormatter.ts +3 -3
  121. package/src/stage/crew/console-reporter/index.ts +2 -2
  122. package/src/stage/crew/console-reporter/themes/TerminalTheme.ts +1 -1
  123. package/src/stage/crew/console-reporter/themes/ThemeForColourTerminals.ts +2 -2
  124. package/src/stage/crew/console-reporter/themes/ThemeForDarkTerminals.ts +1 -1
  125. package/src/stage/crew/console-reporter/themes/ThemeForLightTerminals.ts +1 -1
  126. package/src/stage/crew/console-reporter/themes/ThemeForMonochromaticTerminals.ts +2 -2
  127. package/src/stage/crew/console-reporter/themes/index.ts +4 -4
  128. package/src/stage/crew/index.ts +1 -1
  129. package/src/stage/index.ts +1 -1
  130. package/tsconfig-cjs.build.json +18 -0
  131. package/tsconfig-esm.build.json +18 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.42.0](https://github.com/serenity-js/serenity-js/compare/v3.41.2...v3.42.0) (2026-03-19)
7
+
8
+
9
+ ### Features
10
+
11
+ * **core:** add dual ESM/CJS build support for Wave 2 packages ([0e2631c](https://github.com/serenity-js/serenity-js/commit/0e2631ca7cdbe68da7feec343eaf4f7fe9bb64d6))
12
+ * **core:** add ESM/CJS dual build support for web packages ([94c5a64](https://github.com/serenity-js/serenity-js/commit/94c5a6423dc369477bbabbacee5a54f8fca20209))
13
+
14
+
15
+
16
+
17
+
18
+ ## [3.41.2](https://github.com/serenity-js/serenity-js/compare/v3.41.1...v3.41.2) (2026-03-05)
19
+
20
+ **Note:** Version bump only for package @serenity-js/console-reporter
21
+
22
+
23
+
24
+
25
+
6
26
  ## [3.41.1](https://github.com/serenity-js/serenity-js/compare/v3.41.0...v3.41.1) (2026-02-27)
7
27
 
8
28
  **Note:** Version bump only for package @serenity-js/console-reporter
package/esm/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { StageCrewMemberBuilder } from '@serenity-js/core';
2
+ import type { ConsoleReporterConfig } from './stage/index.js';
3
+ import { ConsoleReporter } from './stage/index.js';
4
+ export * from './stage/index.js';
5
+ export default function create(config?: ConsoleReporterConfig): StageCrewMemberBuilder<ConsoleReporter>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,cAAc,kBAAkB,CAAC;AAEjC,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,MAAM,GAAE,qBAAiC,GAAG,sBAAsB,CAAC,eAAe,CAAC,CAEjH"}
package/esm/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { ConsoleReporter } from './stage/index.js';
2
+ export * from './stage/index.js';
3
+ export default function create(config = undefined) {
4
+ return ConsoleReporter.fromJSON(config || { theme: 'auto' });
5
+ }
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,cAAc,kBAAkB,CAAC;AAEjC,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,SAAgC,SAAS;IACpE,OAAO,eAAe,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,187 @@
1
+ import type { ListensToDomainEvents, Stage, StageCrewMemberBuilder } from '@serenity-js/core';
2
+ import type { DomainEvent } from '@serenity-js/core/events';
3
+ import type { ConsoleReporterConfig } from './ConsoleReporterConfig.js';
4
+ import { Printer } from './Printer.js';
5
+ import type { TerminalTheme } from './themes/index.js';
6
+ /**
7
+ * A [`StageCrewMember`](https://serenity-js.org/api/core/interface/StageCrewMember/) that uses [standard output](https://en.wikipedia.org/wiki/Standard_streams)
8
+ * to report on progress of your Serenity/JS acceptance tests.
9
+ *
10
+ * `ConsoleReporter` ships with colour themes for both dark and light terminals,
11
+ * as well as a monochromatic theme for those moments when you're in a noir mood
12
+ * (or have a terminal that doesn't support colours, like the good old `cmd.exe` on Windows).
13
+ *
14
+ * ## Registering Console Reporter programmatically
15
+ *
16
+ * ```ts
17
+ * import { configure } from '@serenity-js/core';
18
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
19
+ *
20
+ * configure({
21
+ * crew: [
22
+ * ConsoleReporter.withDefaultColourSupport()
23
+ * ],
24
+ * });
25
+ * ```
26
+ *
27
+ * ## Redirecting output to a file
28
+ *
29
+ * ```ts
30
+ * import { configure } from '@serenity-js/core';
31
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
32
+ * import { createWriteStream } from 'node:fs';
33
+ *
34
+ * configure({
35
+ * outputStream: createWriteStream('./output.log'),
36
+ * crew: [ ConsoleReporter.withDefaultColourSupport() ],
37
+ * });
38
+ * ```
39
+ *
40
+ * ## Registering Console Reporter with Playwright Test
41
+ *
42
+ * ```ts
43
+ * // playwright.config.ts
44
+ * import { devices } from '@playwright/test';
45
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test';
46
+ *
47
+ * const config: PlaywrightTestConfig = {
48
+ *
49
+ * reporter: [
50
+ * [ 'line' ],
51
+ * [ 'html', { open: 'never' } ],
52
+ * [ '@serenity-js/playwright-test', {
53
+ * crew: [
54
+ * '@serenity-js/console-reporter',
55
+ * ]
56
+ * }]
57
+ * ],
58
+ * }
59
+ * ```
60
+ *
61
+ * ## Registering Console Reporter with WebdriverIO
62
+ *
63
+ * ```ts
64
+ * // wdio.conf.ts
65
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
66
+ * import { WebdriverIOConfig } from '@serenity-js/webdriverio';
67
+ *
68
+ * export const config: WebdriverIOConfig = {
69
+ *
70
+ * framework: '@serenity-js/webdriverio',
71
+ *
72
+ * serenity: {
73
+ * crew: [
74
+ * '@serenity-js/console-reporter',
75
+ * ]
76
+ * // other Serenity/JS config
77
+ * },
78
+ *
79
+ * // other WebdriverIO config
80
+ * }
81
+ * ```
82
+ *
83
+ * ## Registering Console Reporter with Protractor
84
+ *
85
+ * ```js
86
+ * // protractor.conf.js
87
+ * const { ConsoleReporter } = require('@serenity-js/console-reporter');
88
+ *
89
+ * exports.config = {
90
+ * framework: 'custom',
91
+ * frameworkPath: require.resolve('@serenity-js/protractor/adapter'),
92
+ *
93
+ * serenity: {
94
+ * crew: [
95
+ * '@serenity-js/console-reporter',
96
+ * ],
97
+ * // other Serenity/JS config
98
+ * },
99
+ *
100
+ * // other Protractor config
101
+ * }
102
+ * ```
103
+ *
104
+ * ## Changing the default colour theme
105
+ *
106
+ * ```js
107
+ * // ...
108
+ * serenity: {
109
+ * crew: [
110
+ * [ '@serenity-js/console-reporter', {
111
+ * theme: 'light',
112
+ * // theme: 'dark',
113
+ * // theme: 'mono',
114
+ * // theme: 'auto',
115
+ * } ]
116
+ * ],
117
+ * },
118
+ * //...
119
+ * ```
120
+ *
121
+ * @public
122
+ *
123
+ * @group Stage
124
+ */
125
+ export declare class ConsoleReporter implements ListensToDomainEvents {
126
+ private readonly printer;
127
+ private readonly theme;
128
+ private readonly stage?;
129
+ private startTimes;
130
+ private artifacts;
131
+ private summary;
132
+ private readonly firstErrors;
133
+ private readonly summaryFormatter;
134
+ private readonly eventQueues;
135
+ static fromJSON(config: ConsoleReporterConfig): StageCrewMemberBuilder<ConsoleReporter>;
136
+ /**
137
+ * Instantiates a `ConsoleReporter` that auto-detects
138
+ * your terminal's support for colours and uses a colour theme
139
+ * for dark terminals if successful.
140
+ *
141
+ * Please note that spawning your test process from another process
142
+ * (by using [npm-failsafe](https://www.npmjs.com/package/npm-failsafe), for example)
143
+ * causes the `ConsoleReporter` to use the monochromatic colour scheme,
144
+ * as colour support can't be detected in child processes.
145
+ */
146
+ static withDefaultColourSupport(): StageCrewMemberBuilder<ConsoleReporter>;
147
+ /**
148
+ * Instantiates a `ConsoleReporter` with a monochromatic colour theme.
149
+ * Good for terminals with no colour support (like the `cmd.exe` on Windows),
150
+ * or for times when you need to pipe the output to a text file and want
151
+ * to avoid printing control characters.
152
+ */
153
+ static forMonochromaticTerminals(): StageCrewMemberBuilder<ConsoleReporter>;
154
+ /**
155
+ * Instantiates a `ConsoleReporter` with a colour theme optimised for terminals with dark backgrounds.
156
+ */
157
+ static forDarkTerminals(): StageCrewMemberBuilder<ConsoleReporter>;
158
+ /**
159
+ * Instantiates a `ConsoleReporter` with a colour theme optimised for terminals with light backgrounds.
160
+ */
161
+ static forLightTerminals(): StageCrewMemberBuilder<ConsoleReporter>;
162
+ private static theme;
163
+ /**
164
+ * @param {Printer} printer
165
+ * @param {TerminalTheme} theme
166
+ * @param {Stage} [stage=undefined]
167
+ */
168
+ constructor(printer: Printer, theme: TerminalTheme, stage?: Stage);
169
+ /**
170
+ * Handles [`DomainEvent`](https://serenity-js.org/api/core-events/class/DomainEvent/) objects emitted by the [`Stage`](https://serenity-js.org/api/core/class/Stage/).
171
+ *
172
+ * @see [`StageCrewMember`](https://serenity-js.org/api/core/interface/StageCrewMember/)
173
+ *
174
+ * @listens {DomainEvent}
175
+ *
176
+ * @param {DomainEvent} event
177
+ */
178
+ notifyOf(event: DomainEvent): void;
179
+ private printTestRunErrorOutcome;
180
+ private printScene;
181
+ private printSummary;
182
+ private isSceneSpecific;
183
+ private formattedOutcome;
184
+ private deCamelCased;
185
+ private iconFrom;
186
+ }
187
+ //# sourceMappingURL=ConsoleReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleReporter.d.ts","sourceRoot":"","sources":["../../../../src/stage/crew/console-reporter/ConsoleReporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,qBAAqB,EAAE,KAAK,EAAE,sBAAsB,EAAa,MAAM,mBAAmB,CAAC;AAGnH,OAAO,KAAK,EACR,WAAW,EAAC,MAAM,0BAA0B,CAAC;AA8BjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAKtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsHG;AACH,qBAAa,eAAgB,YAAW,qBAAqB;IAsErD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAtE3B,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IAEvD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,GAAG,sBAAsB,CAAC,eAAe,CAAC;IAIvF;;;;;;;;;OASG;IACH,MAAM,CAAC,wBAAwB,IAAI,sBAAsB,CAAC,eAAe,CAAC;IAI1E;;;;;OAKG;IACH,MAAM,CAAC,yBAAyB,IAAI,sBAAsB,CAAC,eAAe,CAAC;IAI3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,IAAI,sBAAsB,CAAC,eAAe,CAAC;IAIlE;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,sBAAsB,CAAC,eAAe,CAAC;IAInE,OAAO,CAAC,MAAM,CAAC,KAAK;IAapB;;;;OAIG;gBAEkB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,KAAK;IAQlC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IA+BlC,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,UAAU;IAmIlB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,QAAQ;CAqBnB"}
@@ -0,0 +1,423 @@
1
+ import { AssertionError, d, DomainEventQueues, LogicError } from '@serenity-js/core';
2
+ import { ActivityRelatedArtifactGenerated, InteractionFinished, InteractionStarts, SceneFinished, SceneStarts, TaskFinished, TaskStarts, TestRunFinished, TestRunStarts, } from '@serenity-js/core/events';
3
+ import { ExecutionCompromised, ExecutionFailedWithAssertionError, ExecutionFailedWithError, ExecutionIgnored, ExecutionSkipped, ExecutionSuccessful, ImplementationPending, LogEntry, ProblemIndication, } from '@serenity-js/core/model';
4
+ import chalk from 'chalk';
5
+ import { ensure, isDefined, match } from 'tiny-types';
6
+ import { Printer } from './Printer.js';
7
+ import { Summary } from './Summary.js';
8
+ import { SummaryFormatter } from './SummaryFormatter.js';
9
+ import { ThemeForDarkTerminals, ThemeForLightTerminals, ThemeForMonochromaticTerminals } from './themes/index.js';
10
+ const ChalkInstance = chalk.Instance;
11
+ /**
12
+ * A [`StageCrewMember`](https://serenity-js.org/api/core/interface/StageCrewMember/) that uses [standard output](https://en.wikipedia.org/wiki/Standard_streams)
13
+ * to report on progress of your Serenity/JS acceptance tests.
14
+ *
15
+ * `ConsoleReporter` ships with colour themes for both dark and light terminals,
16
+ * as well as a monochromatic theme for those moments when you're in a noir mood
17
+ * (or have a terminal that doesn't support colours, like the good old `cmd.exe` on Windows).
18
+ *
19
+ * ## Registering Console Reporter programmatically
20
+ *
21
+ * ```ts
22
+ * import { configure } from '@serenity-js/core';
23
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
24
+ *
25
+ * configure({
26
+ * crew: [
27
+ * ConsoleReporter.withDefaultColourSupport()
28
+ * ],
29
+ * });
30
+ * ```
31
+ *
32
+ * ## Redirecting output to a file
33
+ *
34
+ * ```ts
35
+ * import { configure } from '@serenity-js/core';
36
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
37
+ * import { createWriteStream } from 'node:fs';
38
+ *
39
+ * configure({
40
+ * outputStream: createWriteStream('./output.log'),
41
+ * crew: [ ConsoleReporter.withDefaultColourSupport() ],
42
+ * });
43
+ * ```
44
+ *
45
+ * ## Registering Console Reporter with Playwright Test
46
+ *
47
+ * ```ts
48
+ * // playwright.config.ts
49
+ * import { devices } from '@playwright/test';
50
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test';
51
+ *
52
+ * const config: PlaywrightTestConfig = {
53
+ *
54
+ * reporter: [
55
+ * [ 'line' ],
56
+ * [ 'html', { open: 'never' } ],
57
+ * [ '@serenity-js/playwright-test', {
58
+ * crew: [
59
+ * '@serenity-js/console-reporter',
60
+ * ]
61
+ * }]
62
+ * ],
63
+ * }
64
+ * ```
65
+ *
66
+ * ## Registering Console Reporter with WebdriverIO
67
+ *
68
+ * ```ts
69
+ * // wdio.conf.ts
70
+ * import { ConsoleReporter } from '@serenity-js/console-reporter';
71
+ * import { WebdriverIOConfig } from '@serenity-js/webdriverio';
72
+ *
73
+ * export const config: WebdriverIOConfig = {
74
+ *
75
+ * framework: '@serenity-js/webdriverio',
76
+ *
77
+ * serenity: {
78
+ * crew: [
79
+ * '@serenity-js/console-reporter',
80
+ * ]
81
+ * // other Serenity/JS config
82
+ * },
83
+ *
84
+ * // other WebdriverIO config
85
+ * }
86
+ * ```
87
+ *
88
+ * ## Registering Console Reporter with Protractor
89
+ *
90
+ * ```js
91
+ * // protractor.conf.js
92
+ * const { ConsoleReporter } = require('@serenity-js/console-reporter');
93
+ *
94
+ * exports.config = {
95
+ * framework: 'custom',
96
+ * frameworkPath: require.resolve('@serenity-js/protractor/adapter'),
97
+ *
98
+ * serenity: {
99
+ * crew: [
100
+ * '@serenity-js/console-reporter',
101
+ * ],
102
+ * // other Serenity/JS config
103
+ * },
104
+ *
105
+ * // other Protractor config
106
+ * }
107
+ * ```
108
+ *
109
+ * ## Changing the default colour theme
110
+ *
111
+ * ```js
112
+ * // ...
113
+ * serenity: {
114
+ * crew: [
115
+ * [ '@serenity-js/console-reporter', {
116
+ * theme: 'light',
117
+ * // theme: 'dark',
118
+ * // theme: 'mono',
119
+ * // theme: 'auto',
120
+ * } ]
121
+ * ],
122
+ * },
123
+ * //...
124
+ * ```
125
+ *
126
+ * @public
127
+ *
128
+ * @group Stage
129
+ */
130
+ export class ConsoleReporter {
131
+ printer;
132
+ theme;
133
+ stage;
134
+ startTimes = new StartTimes();
135
+ artifacts = new ActivityRelatedArtifacts();
136
+ summary = new Summary();
137
+ firstErrors = new Map();
138
+ summaryFormatter;
139
+ eventQueues = new DomainEventQueues();
140
+ static fromJSON(config) {
141
+ return new ConsoleReporterBuilder(ConsoleReporter.theme(config.theme));
142
+ }
143
+ /**
144
+ * Instantiates a `ConsoleReporter` that auto-detects
145
+ * your terminal's support for colours and uses a colour theme
146
+ * for dark terminals if successful.
147
+ *
148
+ * Please note that spawning your test process from another process
149
+ * (by using [npm-failsafe](https://www.npmjs.com/package/npm-failsafe), for example)
150
+ * causes the `ConsoleReporter` to use the monochromatic colour scheme,
151
+ * as colour support can't be detected in child processes.
152
+ */
153
+ static withDefaultColourSupport() {
154
+ return new ConsoleReporterBuilder(ConsoleReporter.theme('auto'));
155
+ }
156
+ /**
157
+ * Instantiates a `ConsoleReporter` with a monochromatic colour theme.
158
+ * Good for terminals with no colour support (like the `cmd.exe` on Windows),
159
+ * or for times when you need to pipe the output to a text file and want
160
+ * to avoid printing control characters.
161
+ */
162
+ static forMonochromaticTerminals() {
163
+ return new ConsoleReporterBuilder(ConsoleReporter.theme('mono'));
164
+ }
165
+ /**
166
+ * Instantiates a `ConsoleReporter` with a colour theme optimised for terminals with dark backgrounds.
167
+ */
168
+ static forDarkTerminals() {
169
+ return new ConsoleReporterBuilder(ConsoleReporter.theme('dark'));
170
+ }
171
+ /**
172
+ * Instantiates a `ConsoleReporter` with a colour theme optimised for terminals with light backgrounds.
173
+ */
174
+ static forLightTerminals() {
175
+ return new ConsoleReporterBuilder(ConsoleReporter.theme('light'));
176
+ }
177
+ static theme(theme) {
178
+ switch (theme) {
179
+ case 'dark':
180
+ return new ThemeForDarkTerminals(new ChalkInstance({ level: 2 }));
181
+ case 'light':
182
+ return new ThemeForLightTerminals(new ChalkInstance({ level: 2 }));
183
+ case 'mono':
184
+ return new ThemeForMonochromaticTerminals();
185
+ default:
186
+ return new ThemeForDarkTerminals(new ChalkInstance( /* auto-detect */));
187
+ }
188
+ }
189
+ /**
190
+ * @param {Printer} printer
191
+ * @param {TerminalTheme} theme
192
+ * @param {Stage} [stage=undefined]
193
+ */
194
+ constructor(printer, theme, stage) {
195
+ this.printer = printer;
196
+ this.theme = theme;
197
+ this.stage = stage;
198
+ ensure('printer', printer, isDefined());
199
+ ensure('theme', theme, isDefined());
200
+ this.summaryFormatter = new SummaryFormatter(this.theme);
201
+ }
202
+ /**
203
+ * Handles [`DomainEvent`](https://serenity-js.org/api/core-events/class/DomainEvent/) objects emitted by the [`Stage`](https://serenity-js.org/api/core/class/Stage/).
204
+ *
205
+ * @see [`StageCrewMember`](https://serenity-js.org/api/core/interface/StageCrewMember/)
206
+ *
207
+ * @listens {DomainEvent}
208
+ *
209
+ * @param {DomainEvent} event
210
+ */
211
+ notifyOf(event) {
212
+ if (event instanceof TestRunStarts) {
213
+ this.summary.recordTestRunStartedAt(event.timestamp);
214
+ }
215
+ if (this.isSceneSpecific(event)) {
216
+ this.eventQueues.enqueue(event);
217
+ }
218
+ if (event instanceof SceneStarts) {
219
+ this.firstErrors.set(event.sceneId.value, new FirstError());
220
+ this.startTimes.recordStartOf(event);
221
+ }
222
+ if (event instanceof SceneFinished) {
223
+ this.printScene(event.sceneId);
224
+ }
225
+ if (event instanceof TestRunFinished) {
226
+ this.summary.recordTestRunFinishedAt(event.timestamp);
227
+ this.printSummary(this.summary);
228
+ if (event.outcome instanceof ProblemIndication) {
229
+ this.printTestRunErrorOutcome(event.outcome);
230
+ }
231
+ }
232
+ }
233
+ printTestRunErrorOutcome(outcome) {
234
+ this.printer.println(this.theme.outcome(outcome, outcome.error.stack));
235
+ }
236
+ printScene(sceneId) {
237
+ const events = this.eventQueues.drainQueueFor(sceneId);
238
+ for (const event of events) {
239
+ match(event)
240
+ .when(SceneStarts, (e) => {
241
+ const category = e.details.name.value ? `${e.details.category.value}: ` : '';
242
+ // Print scenario header
243
+ this.printer.println(this.theme.separator('-'));
244
+ this.printer.println(e.details.location.path.value, e.details.location.line ? `:${e.details.location.line}` : '');
245
+ this.printer.println();
246
+ this.printer.println(this.theme.heading(category, e.details.name.value));
247
+ this.printer.println();
248
+ })
249
+ .when(TaskStarts, (e) => {
250
+ this.printer.indent();
251
+ if (!this.firstErrors.get(e.sceneId.value)?.alreadyRecorded()) {
252
+ this.printer.println(e.details.name.value);
253
+ }
254
+ })
255
+ .when(InteractionStarts, (e) => {
256
+ this.startTimes.recordStartOf(e);
257
+ })
258
+ .when(InteractionFinished, (e) => {
259
+ this.printer.indent();
260
+ this.printer.println(this.formattedOutcome(e));
261
+ this.printer.indent();
262
+ if (e.outcome instanceof ProblemIndication) {
263
+ this.firstErrors.get(e.sceneId.value)?.recordIfNeeded(e.outcome.error);
264
+ if (!(e.outcome.error instanceof AssertionError)) {
265
+ this.printer.println(this.theme.outcome(e.outcome, `${e.outcome.error}`));
266
+ }
267
+ }
268
+ const artifactGeneratedEvents = this.artifacts.recordedFor(e.activityId);
269
+ if (artifactGeneratedEvents.some(a => a instanceof LogEntry)) {
270
+ this.printer.println();
271
+ }
272
+ artifactGeneratedEvents.forEach(artifactGenerated => {
273
+ if (artifactGenerated.artifact instanceof LogEntry) {
274
+ const details = artifactGenerated.artifact.map((artifactContents) => artifactContents.data);
275
+ if (artifactGenerated.name.value !== details) {
276
+ this.printer.println(this.theme.log(artifactGenerated.name.value, ':'));
277
+ }
278
+ this.printer.println(details);
279
+ this.printer.println();
280
+ }
281
+ });
282
+ this.printer.outdent();
283
+ this.printer.outdent();
284
+ })
285
+ .when(ActivityRelatedArtifactGenerated, (e) => {
286
+ this.artifacts.record(e);
287
+ })
288
+ .when(TaskFinished, (e) => {
289
+ this.printer.outdent();
290
+ if (e.outcome instanceof ProblemIndication) {
291
+ this.printer.indent();
292
+ this.printer.indent();
293
+ if (!this.firstErrors.get(e.sceneId.value).alreadyRecorded()) {
294
+ this.printer.println(this.theme.outcome(e.outcome, this.iconFrom(e.outcome), `${e.outcome.error}`));
295
+ }
296
+ this.printer.outdent();
297
+ this.printer.outdent();
298
+ this.firstErrors.get(e.sceneId.value).recordIfNeeded(e.outcome.error);
299
+ }
300
+ else if (!(e.outcome instanceof ExecutionSuccessful)) {
301
+ this.printer.indent();
302
+ this.printer.println(this.iconFrom(e.outcome), e.details.name.value);
303
+ this.printer.outdent();
304
+ }
305
+ })
306
+ .when(SceneFinished, (e) => {
307
+ this.summary.record(e.details, e.outcome, this.startTimes.eventDurationOf(e));
308
+ this.printer.println();
309
+ this.printer.println(this.theme.outcome(e.outcome, this.formattedOutcome(e, this.deCamelCased(e.outcome.constructor.name))));
310
+ if (e.outcome instanceof ProblemIndication) {
311
+ this.printer.println();
312
+ this.printer.indent();
313
+ if (e.outcome instanceof ImplementationPending) {
314
+ this.printer.println(`${e.outcome.error.name}: ${e.outcome.error.message}`);
315
+ }
316
+ else if (e.outcome.error?.stack) {
317
+ this.printer.println(e.outcome.error.stack);
318
+ }
319
+ this.printer.outdent();
320
+ }
321
+ this.artifacts.clear();
322
+ })
323
+ .else((_) => {
324
+ return void 0;
325
+ });
326
+ }
327
+ }
328
+ printSummary(summary) {
329
+ this.printer.println(this.theme.separator('='));
330
+ this.printer.print(this.summaryFormatter.format(summary.aggregated()));
331
+ this.printer.println(this.theme.separator('='));
332
+ }
333
+ isSceneSpecific(event) {
334
+ return Object.prototype.hasOwnProperty.call(event, 'sceneId');
335
+ }
336
+ formattedOutcome(event, description = event.details.name.value) {
337
+ const duration = this.startTimes.eventDurationOf(event);
338
+ const icon = this.iconFrom(event.outcome);
339
+ const message = description.split('\n').map((line, index) => index === 0
340
+ ? `${line} (${duration})`
341
+ : `${' '.repeat(icon.length)}${line}`).join('\n');
342
+ return (event.outcome instanceof ProblemIndication)
343
+ ? this.theme.outcome(event.outcome, `${icon}${message}`)
344
+ : `${this.theme.outcome(event.outcome, icon)}${message}`;
345
+ }
346
+ deCamelCased(name) {
347
+ const deCamelCased = name.replaceAll(/([^A-Z])([A-Z])/g, '$1 $2');
348
+ return deCamelCased.charAt(0).toUpperCase() + deCamelCased.slice(1).toLocaleLowerCase();
349
+ }
350
+ iconFrom(outcome) {
351
+ // Use instanceof instead of constructor comparison to work across ESM/CJS boundaries
352
+ if (outcome instanceof ExecutionCompromised ||
353
+ outcome instanceof ExecutionFailedWithError ||
354
+ outcome instanceof ExecutionFailedWithAssertionError) {
355
+ return '✗ ';
356
+ }
357
+ if (outcome instanceof ImplementationPending) {
358
+ return '☕';
359
+ }
360
+ if (outcome instanceof ExecutionSkipped) {
361
+ return '⇢ ';
362
+ }
363
+ if (outcome instanceof ExecutionIgnored) {
364
+ return '? ';
365
+ }
366
+ if (outcome instanceof ExecutionSuccessful) {
367
+ return '✓ ';
368
+ }
369
+ return '';
370
+ }
371
+ }
372
+ class ConsoleReporterBuilder {
373
+ theme;
374
+ constructor(theme) {
375
+ this.theme = theme;
376
+ }
377
+ build({ stage, outputStream }) {
378
+ return new ConsoleReporter(new Printer(outputStream), this.theme, stage);
379
+ }
380
+ }
381
+ class StartTimes {
382
+ times = {};
383
+ recordStartOf(event) {
384
+ this.times[this.keyFor(event)] = event.timestamp;
385
+ }
386
+ eventDurationOf(event) {
387
+ if (!this.times[this.keyFor(event)]) {
388
+ throw new LogicError(d `StartTime missing for event ${event}`);
389
+ }
390
+ return event.timestamp.diff(this.times[this.keyFor(event)]);
391
+ }
392
+ keyFor(event) {
393
+ return `${event.sceneId.toString()}:${event.activityId?.toString()}`;
394
+ }
395
+ }
396
+ class FirstError {
397
+ error;
398
+ recordIfNeeded(error) {
399
+ if (!this.error) {
400
+ this.error = error;
401
+ }
402
+ }
403
+ alreadyRecorded() {
404
+ return !!this.error;
405
+ }
406
+ get() {
407
+ return this.error;
408
+ }
409
+ }
410
+ class ActivityRelatedArtifacts {
411
+ events = [];
412
+ record(event) {
413
+ this.events.push(event);
414
+ }
415
+ recordedFor(activityId) {
416
+ return this.events
417
+ .filter(event => event.activityId.equals(activityId));
418
+ }
419
+ clear() {
420
+ this.events = [];
421
+ }
422
+ }
423
+ //# sourceMappingURL=ConsoleReporter.js.map