cucumber-dressing 0.1.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.
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Statistics Calculator - Generates report statistics
3
+ */
4
+ import { calculateFeatureStatus, calculatePassRate, calculateScenarioDuration, calculateScenarioStatus, } from './utils.js';
5
+ export class StatisticsCalculator {
6
+ /**
7
+ * Calculate comprehensive statistics from features
8
+ * @param features - Array of Gherkin features to analyze
9
+ * @returns Comprehensive statistics including counts, duration, and pass rate
10
+ */
11
+ static calculateStatistics(features) {
12
+ const stats = {
13
+ features: features.length,
14
+ scenarios: 0,
15
+ steps: 0,
16
+ passed: 0,
17
+ failed: 0,
18
+ skipped: 0,
19
+ pending: 0,
20
+ undefined: 0,
21
+ ambiguous: 0,
22
+ duration: 0,
23
+ passRate: 0,
24
+ };
25
+ features.forEach(feature => {
26
+ feature.elements.forEach(scenario => {
27
+ if (scenario.type === 'background') {
28
+ return;
29
+ }
30
+ stats.scenarios++;
31
+ scenario.steps.forEach(step => {
32
+ stats.steps++;
33
+ stats.duration += step.result.duration ?? 0;
34
+ switch (step.result.status) {
35
+ case 'passed':
36
+ stats.passed++;
37
+ break;
38
+ case 'failed':
39
+ stats.failed++;
40
+ break;
41
+ case 'skipped':
42
+ stats.skipped++;
43
+ break;
44
+ case 'pending':
45
+ stats.pending++;
46
+ break;
47
+ case 'undefined':
48
+ stats.undefined++;
49
+ break;
50
+ case 'ambiguous':
51
+ stats.ambiguous++;
52
+ break;
53
+ }
54
+ });
55
+ });
56
+ });
57
+ stats.passRate = calculatePassRate(stats.passed, stats.steps);
58
+ return stats;
59
+ }
60
+ /**
61
+ * Calculate statistics for a single feature
62
+ * @param feature - Gherkin feature to analyze
63
+ * @returns Object containing total scenarios, status counts, and duration in nanoseconds
64
+ */
65
+ static calculateFeatureStatistics(feature) {
66
+ const scenarios = feature.elements.filter(el => el.type === 'scenario');
67
+ const stats = {
68
+ total: scenarios.length,
69
+ passed: 0,
70
+ failed: 0,
71
+ skipped: 0,
72
+ pending: 0,
73
+ undefined: 0,
74
+ duration: 0,
75
+ };
76
+ scenarios.forEach(scenario => {
77
+ const status = calculateScenarioStatus(scenario.steps);
78
+ const duration = calculateScenarioDuration(scenario);
79
+ stats.duration += duration;
80
+ switch (status) {
81
+ case 'passed':
82
+ stats.passed++;
83
+ break;
84
+ case 'failed':
85
+ case 'undefined':
86
+ stats.failed++;
87
+ break;
88
+ case 'skipped':
89
+ stats.skipped++;
90
+ break;
91
+ case 'pending':
92
+ stats.pending++;
93
+ break;
94
+ }
95
+ });
96
+ return stats;
97
+ }
98
+ /**
99
+ * Calculate status breakdown across features, scenarios, and steps
100
+ * @param features - Array of Gherkin features to analyze
101
+ * @returns Nested object with status counts for features, scenarios, and steps
102
+ */
103
+ static calculateStatusBreakdown(features) {
104
+ const breakdown = {
105
+ features: {
106
+ passed: 0,
107
+ failed: 0,
108
+ skipped: 0,
109
+ pending: 0,
110
+ },
111
+ scenarios: {
112
+ passed: 0,
113
+ failed: 0,
114
+ skipped: 0,
115
+ pending: 0,
116
+ undefined: 0,
117
+ },
118
+ steps: {
119
+ passed: 0,
120
+ failed: 0,
121
+ skipped: 0,
122
+ pending: 0,
123
+ undefined: 0,
124
+ ambiguous: 0,
125
+ },
126
+ };
127
+ features.forEach(feature => {
128
+ const featureStatus = calculateFeatureStatus(feature.elements);
129
+ breakdown.features[featureStatus]++;
130
+ feature.elements.forEach(scenario => {
131
+ if (scenario.type === 'background') {
132
+ return;
133
+ }
134
+ const scenarioStatus = calculateScenarioStatus(scenario.steps);
135
+ breakdown.scenarios[scenarioStatus]++;
136
+ scenario.steps.forEach(step => {
137
+ breakdown.steps[step.result.status]++;
138
+ });
139
+ });
140
+ });
141
+ return breakdown;
142
+ }
143
+ /**
144
+ * Process features with calculated status and duration for each feature and scenario
145
+ * @param features - Array of Gherkin features to process
146
+ * @returns Array of processed features with computed status, duration, and enriched scenarios
147
+ */
148
+ static processFeatures(features) {
149
+ return features.map(feature => {
150
+ const scenarios = feature.elements
151
+ .filter(el => el.type === 'scenario')
152
+ .map(scenario => ({
153
+ ...scenario,
154
+ status: calculateScenarioStatus(scenario.steps),
155
+ duration: calculateScenarioDuration(scenario),
156
+ featureName: feature.name,
157
+ featureId: feature.id,
158
+ }));
159
+ const status = calculateFeatureStatus(feature.elements);
160
+ const duration = scenarios.reduce((sum, s) => sum + s.duration, 0);
161
+ return {
162
+ ...feature,
163
+ status,
164
+ duration,
165
+ scenarios,
166
+ };
167
+ });
168
+ }
169
+ /**
170
+ * Extract all failed scenarios with error details
171
+ * @param features - Array of Gherkin features to search
172
+ * @returns Array of failed scenario objects with feature name, scenario name, failing step, error message, and tags
173
+ */
174
+ static getFailedScenarios(features) {
175
+ const failed = [];
176
+ features.forEach(feature => {
177
+ feature.elements.forEach(scenario => {
178
+ if (scenario.type === 'background') {
179
+ return;
180
+ }
181
+ const failedStep = scenario.steps.find(step => step.result.status === 'failed' ||
182
+ step.result.status === 'undefined' ||
183
+ step.result.status === 'ambiguous');
184
+ if (failedStep) {
185
+ failed.push({
186
+ feature: feature.name,
187
+ scenario: scenario.name,
188
+ step: `${failedStep.keyword}${failedStep.name}`,
189
+ error: failedStep.result.error_message ?? 'No error message',
190
+ tags: [
191
+ ...(feature.tags ?? []).map(t => t.name),
192
+ ...(scenario.tags ?? []).map(t => t.name),
193
+ ],
194
+ });
195
+ }
196
+ });
197
+ });
198
+ return failed;
199
+ }
200
+ /**
201
+ * Get the slowest scenarios sorted by duration
202
+ * @param features - Array of Gherkin features to analyze
203
+ * @param count - Maximum number of scenarios to return (default: 10)
204
+ * @returns Array of scenario objects with feature name, scenario name, and duration in nanoseconds, sorted by duration descending
205
+ */
206
+ static getTopSlowestScenarios(features, count = 10) {
207
+ const scenarios = [];
208
+ features.forEach(feature => {
209
+ feature.elements.forEach(scenario => {
210
+ if (scenario.type === 'background') {
211
+ return;
212
+ }
213
+ scenarios.push({
214
+ feature: feature.name,
215
+ scenario: scenario.name,
216
+ duration: calculateScenarioDuration(scenario),
217
+ });
218
+ });
219
+ });
220
+ return scenarios.sort((a, b) => b.duration - a.duration).slice(0, count);
221
+ }
222
+ /**
223
+ * Calculate time-based statistics across all scenarios
224
+ * @param features - Array of Gherkin features to analyze
225
+ * @returns Object with min, max, average, median, and total duration in nanoseconds
226
+ */
227
+ static calculateTimeStatistics(features) {
228
+ const durations = [];
229
+ features.forEach(feature => {
230
+ feature.elements.forEach(scenario => {
231
+ if (scenario.type === 'background') {
232
+ return;
233
+ }
234
+ durations.push(calculateScenarioDuration(scenario));
235
+ });
236
+ });
237
+ if (durations.length === 0) {
238
+ return {
239
+ min: 0,
240
+ max: 0,
241
+ average: 0,
242
+ median: 0,
243
+ total: 0,
244
+ };
245
+ }
246
+ durations.sort((a, b) => a - b);
247
+ return {
248
+ min: durations[0],
249
+ max: durations[durations.length - 1],
250
+ average: durations.reduce((a, b) => a + b, 0) / durations.length,
251
+ median: durations[Math.floor(durations.length / 2)],
252
+ total: durations.reduce((a, b) => a + b, 0),
253
+ };
254
+ }
255
+ }
256
+ //# sourceMappingURL=statistics.js.map
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Template Generator - Creates HTML report from data
3
+ */
4
+ import { ChartData, ProcessedFeature, ReportOptions, ReportStatistics } from './types.js';
5
+ export declare class TemplateGenerator {
6
+ private options;
7
+ constructor(options: ReportOptions);
8
+ /**
9
+ * Register Handlebars helpers for formatting, status handling, and data manipulation in templates
10
+ */
11
+ private registerHelpers;
12
+ /**
13
+ * Generate complete HTML report from processed data
14
+ * @param features - Processed features with calculated status and duration
15
+ * @param statistics - Report statistics including counts and pass rate
16
+ * @param chartData - Chart.js data for visualization
17
+ * @returns Complete HTML report as a string
18
+ */
19
+ generateReport(features: ProcessedFeature[], statistics: ReportStatistics, chartData: ChartData): string;
20
+ /**
21
+ * Get main HTML template structure with embedded styles and scripts
22
+ * @returns HTML template string with placeholders for Handlebars compilation
23
+ */
24
+ private getMainTemplate;
25
+ /**
26
+ * Get header template with branding and report info
27
+ * @returns HTML template string for the report header section
28
+ */
29
+ private getHeaderTemplate;
30
+ /**
31
+ * Get statistics overview template with test execution summary cards
32
+ * @returns HTML template string for statistics display
33
+ */
34
+ private getStatisticsTemplate;
35
+ /**
36
+ * Get charts section template for status distribution and pass rate visualization
37
+ * @returns HTML template string with canvas elements for Chart.js
38
+ */
39
+ private getChartsTemplate;
40
+ /**
41
+ * Get metadata section template for browser, platform, and custom data display
42
+ * @returns HTML template string for optional metadata sections
43
+ */
44
+ private getMetadataTemplate;
45
+ /**
46
+ * Get features list template with search filter and feature cards
47
+ * @returns HTML template string for features section
48
+ */
49
+ private getFeaturesListTemplate;
50
+ /**
51
+ * Get filter controls template for searching and status filtering
52
+ * @returns HTML template string with search input and filter buttons
53
+ */
54
+ private getFilterTemplate;
55
+ /**
56
+ * Get feature card template with collapsible scenarios
57
+ * @returns HTML template string for individual feature display
58
+ */
59
+ private getFeatureCardTemplate;
60
+ /**
61
+ * Get feature header template with title, tags, and toggle controls
62
+ * @returns HTML template string for feature header with collapsible functionality
63
+ */
64
+ private getFeatureHeaderTemplate;
65
+ /**
66
+ * Get scenario card template with collapsible steps
67
+ * @returns HTML template string for individual scenario display
68
+ */
69
+ private getScenarioCardTemplate;
70
+ /**
71
+ * Get scenario header template with title, tags, and toggle controls
72
+ * @returns HTML template string for scenario header with collapsible functionality
73
+ */
74
+ private getScenarioHeaderTemplate;
75
+ /**
76
+ * Get steps list template with errors, data tables, and screenshots
77
+ * @returns HTML template string for scenario steps display
78
+ */
79
+ private getStepsListTemplate;
80
+ /**
81
+ * Get footer template with branding and version info
82
+ * @returns HTML template string for report footer
83
+ */
84
+ private getFooterTemplate;
85
+ /**
86
+ * Get CSS styles from template file
87
+ * @returns CSS stylesheet string for report styling
88
+ */
89
+ private getStyles;
90
+ /**
91
+ * Generate custom CSS color variables if colors option is provided
92
+ * @returns CSS custom properties string with color overrides, or empty string if no colors specified
93
+ */
94
+ private getCustomColorStyles;
95
+ /**
96
+ * Get JavaScript code from template file for report interactivity
97
+ * @returns JavaScript code string for charts, filtering, and collapsible sections
98
+ */
99
+ private getScripts;
100
+ }
101
+ //# sourceMappingURL=template-generator.d.ts.map