/
report.js
106 lines (96 loc) · 2.97 KB
/
report.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import reportBuilder from 'junit-report-builder';
import path from 'path';
import { createTask, transitionTo } from '../lib/tasks';
import { baseStorybookUrl } from '../lib/utils';
import wroteReport from '../ui/messages/info/wroteReport';
import { initial, pending, success } from '../ui/tasks/report';
const ReportQuery = `
query ReportQuery($buildNumber: Int!) {
app {
build(number: $buildNumber) {
number
status
webUrl
cachedUrl
createdAt
completedAt
tests {
status
result
spec {
name
component {
name
displayName
}
}
parameters {
viewport
viewportIsDefault
}
}
}
}
}
`;
export const generateReport = async (ctx) => {
const { client, log } = ctx;
const { junitReport } = ctx.options;
const { number: buildNumber, reportToken } = ctx.build;
const file = junitReport === true ? 'chromatic-build-{buildNumber}.xml' : junitReport;
ctx.reportPath = path.resolve(file.replace(/{buildNumber}/g, buildNumber));
const {
app: { build },
} = await client.runQuery(
ReportQuery,
{ buildNumber },
{ Authorization: `Bearer ${reportToken}` }
);
const buildTime = (build.completedAt || Date.now()) - build.createdAt;
const suite = reportBuilder
.testSuite()
.name(`Chromatic build ${build.number}`)
.time(Math.round(buildTime / 1000))
.timestamp(new Date(build.createdAt).toISOString())
.property('buildNumber', build.number)
.property('buildStatus', build.status)
.property('buildUrl', build.webUrl)
.property('storybookUrl', baseStorybookUrl(build.cachedUrl));
build.tests.forEach(({ status, result, spec, parameters }) => {
const suffix = parameters.viewportIsDefault ? '' : ` [${parameters.viewport}px]`;
const testCase = suite
.testCase()
.className(spec.component.name.replace(/[|/]/g, '.')) // transform story path to class path
.name(`${spec.name}${suffix}`);
switch (status) {
case 'FAILED':
testCase.error('Server error while taking snapshot, please try again', status);
break;
case 'BROKEN':
testCase.error('Snapshot is broken due to an error in your Storybook', status);
break;
case 'DENIED':
testCase.failure('Snapshot was denied by a user', status);
break;
case 'PENDING':
testCase.failure('Snapshot contains visual changes and must be reviewed', status);
break;
default: {
switch (result) {
case 'SKIPPED':
case 'PRESERVED':
testCase.skipped();
break;
default:
}
}
}
});
reportBuilder.writeTo(ctx.reportPath);
log.info(wroteReport(ctx.reportPath));
};
export default createTask({
title: initial.title,
skip: (ctx) => ctx.skip,
steps: [transitionTo(pending), generateReport, transitionTo(success, true)],
});