/
snapshot.js
117 lines (102 loc) · 3.22 KB
/
snapshot.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
107
108
109
110
111
112
113
114
115
116
117
/* eslint-disable no-param-reassign */
import { createTask, transitionTo } from '../lib/tasks';
import { delay } from '../lib/utils';
import buildHasChanges from '../ui/messages/errors/buildHasChanges';
import buildHasErrors from '../ui/messages/errors/buildHasErrors';
import buildPassedMessage from '../ui/messages/info/buildPassed';
import speedUpCI from '../ui/messages/info/speedUpCI';
import {
buildComplete,
buildError,
buildFailed,
buildPassed,
initial,
pending,
skipped,
} from '../ui/tasks/snapshot';
const TesterBuildQuery = `
query TesterBuildQuery($buildNumber: Int!) {
app {
build(number: $buildNumber) {
id
status(legacy: false)
autoAcceptChanges
inProgressCount: testCount(statuses: [IN_PROGRESS])
testCount
changeCount
errorCount: testCount(statuses: [BROKEN])
}
}
}
`;
export const takeSnapshots = async (ctx, task) => {
const { client, log, options } = ctx;
const { number: buildNumber, tests } = ctx.build;
if (ctx.build.app.repository && ctx.uploadedBytes && !options.junitReport) {
log.info(speedUpCI(ctx.build.app.repository.provider));
}
const testLabels =
options.interactive &&
tests.map(({ spec, parameters }) => {
const suffix = parameters.viewportIsDefault ? '' : ` [${parameters.viewport}px]`;
return `${spec.component.displayName} › ${spec.name}${suffix}`;
});
const waitForBuild = async () => {
const { app } = await client.runQuery(TesterBuildQuery, { buildNumber });
ctx.build = { ...ctx.build, ...app.build };
if (app.build.status !== 'IN_PROGRESS') {
return ctx.build;
}
if (options.interactive) {
const { inProgressCount, testCount } = ctx.build;
const cursor = testCount - inProgressCount + 1;
const label = testLabels[cursor - 1] || '';
task.output = pending({ ...ctx, cursor, label }).output;
}
await delay(ctx.env.CHROMATIC_POLL_INTERVAL);
return waitForBuild();
};
const build = await waitForBuild();
switch (build.status) {
case 'PASSED':
ctx.exitCode = 0;
ctx.log.info(buildPassedMessage(ctx));
transitionTo(buildPassed, true)(ctx, task);
break;
// They may have sneakily looked at the build while we were waiting
case 'ACCEPTED':
case 'PENDING':
case 'DENIED': {
if (build.autoAcceptChanges || ctx.git.matchesBranch(options.exitZeroOnChanges)) {
ctx.exitCode = 0;
ctx.log.info(buildPassedMessage(ctx));
} else {
ctx.exitCode = 1;
ctx.log.error(buildHasChanges(ctx));
}
transitionTo(buildComplete, true)(ctx, task);
break;
}
case 'BROKEN':
ctx.exitCode = 2;
ctx.log.error(buildHasErrors(ctx));
transitionTo(buildFailed, true)(ctx, task);
break;
case 'FAILED':
case 'CANCELLED':
ctx.exitCode = 3;
transitionTo(buildError, true)(ctx, task);
break;
default:
throw new Error(`Unexpected build status: ${build.status}`);
}
};
export default createTask({
title: initial.title,
skip: (ctx) => {
if (ctx.skip) return true;
if (ctx.skipSnapshots) return skipped(ctx).output;
return false;
},
steps: [transitionTo(pending), takeSnapshots],
});