creevey 0.10.0-beta.40 → 0.10.0-beta.42
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.
- package/dist/client/web/assets/{index-B0Xv0lOY.js → index-C47njyZV.js} +2 -2
- package/dist/client/web/index.html +1 -1
- package/dist/server/config.js +3 -2
- package/dist/server/config.js.map +1 -1
- package/dist/server/master/runner.js +6 -4
- package/dist/server/master/runner.js.map +1 -1
- package/dist/server/{reporter.d.ts → reporters/creevey.d.ts} +0 -4
- package/dist/server/reporters/creevey.js +63 -0
- package/dist/server/reporters/creevey.js.map +1 -0
- package/dist/server/reporters/index.d.ts +2 -0
- package/dist/server/reporters/index.js +16 -0
- package/dist/server/reporters/index.js.map +1 -0
- package/dist/server/reporters/junit.d.ts +16 -0
- package/dist/server/reporters/junit.js +167 -0
- package/dist/server/reporters/junit.js.map +1 -0
- package/dist/server/reporters/teamcity.d.ts +7 -0
- package/dist/server/reporters/teamcity.js +60 -0
- package/dist/server/reporters/teamcity.js.map +1 -0
- package/dist/server/worker/start.js +2 -0
- package/dist/server/worker/start.js.map +1 -1
- package/dist/types.d.ts +7 -3
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/server/config.ts +2 -1
- package/src/server/master/runner.ts +6 -4
- package/src/server/reporters/creevey.ts +71 -0
- package/src/server/reporters/index.ts +11 -0
- package/src/server/reporters/junit.ts +207 -0
- package/src/server/reporters/teamcity.ts +74 -0
- package/src/server/worker/start.ts +2 -0
- package/src/types.ts +7 -4
- package/dist/server/reporter.js +0 -117
- package/dist/server/reporter.js.map +0 -1
- package/src/server/reporter.ts +0 -141
package/src/server/reporter.ts
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
import chalk from 'chalk';
|
2
|
-
import Logger from 'loglevel';
|
3
|
-
import prefix from 'loglevel-plugin-prefix';
|
4
|
-
import { FakeTest, Images, isDefined, isImageError, TEST_EVENTS } from '../types.js';
|
5
|
-
import EventEmitter from 'events';
|
6
|
-
|
7
|
-
const testLevels: Record<string, string> = {
|
8
|
-
INFO: chalk.green('PASS'),
|
9
|
-
WARN: chalk.yellow('START'),
|
10
|
-
ERROR: chalk.red('FAIL'),
|
11
|
-
};
|
12
|
-
|
13
|
-
export class CreeveyReporter {
|
14
|
-
private logger: Logger.Logger | null = null;
|
15
|
-
// TODO Output in better way, like vitest, maybe
|
16
|
-
constructor(runner: EventEmitter) {
|
17
|
-
runner.on(TEST_EVENTS.TEST_BEGIN, (test: FakeTest) => {
|
18
|
-
this.getLogger(test.creevey).warn(chalk.cyan(test.fullTitle()));
|
19
|
-
});
|
20
|
-
runner.on(TEST_EVENTS.TEST_PASS, (test: FakeTest) => {
|
21
|
-
this.getLogger(test.creevey).info(chalk.cyan(test.fullTitle()), chalk.gray(`(${test.duration} ms)`));
|
22
|
-
});
|
23
|
-
runner.on(TEST_EVENTS.TEST_FAIL, (test: FakeTest, error) => {
|
24
|
-
this.getLogger(test.creevey).error(
|
25
|
-
chalk.cyan(test.fullTitle()),
|
26
|
-
chalk.gray(`(${test.duration} ms)`),
|
27
|
-
'\n ',
|
28
|
-
this.getErrors(
|
29
|
-
error,
|
30
|
-
(error, imageName) => `${chalk.bold(imageName ?? test.creevey.browserName)}:${error}`,
|
31
|
-
(error) => error.stack ?? error.message,
|
32
|
-
).join('\n '),
|
33
|
-
);
|
34
|
-
});
|
35
|
-
}
|
36
|
-
|
37
|
-
private getLogger(options: { sessionId: string; browserName: string }) {
|
38
|
-
if (this.logger) return this.logger;
|
39
|
-
const { sessionId, browserName } = options;
|
40
|
-
const testLogger = Logger.getLogger(sessionId);
|
41
|
-
|
42
|
-
this.logger = prefix.apply(testLogger, {
|
43
|
-
format(level) {
|
44
|
-
return `[${browserName}:${chalk.gray(process.pid)}] ${testLevels[level]} => ${chalk.gray(sessionId)}`;
|
45
|
-
},
|
46
|
-
});
|
47
|
-
|
48
|
-
return this.logger;
|
49
|
-
}
|
50
|
-
|
51
|
-
private getErrors(
|
52
|
-
error: unknown,
|
53
|
-
imageErrorToString: (error: string, imageName?: string) => string,
|
54
|
-
errorToString: (error: Error) => string,
|
55
|
-
): string[] {
|
56
|
-
const errors = [];
|
57
|
-
if (!(error instanceof Error)) {
|
58
|
-
errors.push(error as string);
|
59
|
-
} else if (!isImageError(error)) {
|
60
|
-
errors.push(errorToString(error));
|
61
|
-
} else if (typeof error.images == 'string') {
|
62
|
-
errors.push(imageErrorToString(error.images));
|
63
|
-
} else {
|
64
|
-
const imageErrors = error.images ?? {};
|
65
|
-
Object.keys(imageErrors).forEach((imageName) => {
|
66
|
-
errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
|
67
|
-
});
|
68
|
-
}
|
69
|
-
return errors;
|
70
|
-
}
|
71
|
-
}
|
72
|
-
|
73
|
-
export class TeamcityReporter {
|
74
|
-
constructor(runner: EventEmitter) {
|
75
|
-
runner.on(TEST_EVENTS.TEST_BEGIN, (test: FakeTest) => {
|
76
|
-
console.log(`##teamcity[testStarted name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
77
|
-
});
|
78
|
-
|
79
|
-
runner.on(TEST_EVENTS.TEST_PASS, (test: FakeTest) => {
|
80
|
-
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
81
|
-
});
|
82
|
-
|
83
|
-
runner.on(TEST_EVENTS.TEST_FAIL, (test: FakeTest, error: Error) => {
|
84
|
-
const browserName = this.escape(test.creevey.browserName);
|
85
|
-
Object.entries(test.creevey.images).forEach(([name, image]) => {
|
86
|
-
if (!image) return;
|
87
|
-
const filePath = test
|
88
|
-
.titlePath()
|
89
|
-
.slice(0, -1)
|
90
|
-
.concat(name == browserName ? [] : [browserName])
|
91
|
-
.map(this.escape)
|
92
|
-
.join('/');
|
93
|
-
|
94
|
-
const { error: _, ...rest } = image;
|
95
|
-
Object.values(rest as Partial<Images>)
|
96
|
-
.filter(isDefined)
|
97
|
-
.forEach((fileName) => {
|
98
|
-
console.log(
|
99
|
-
`##teamcity[publishArtifacts '${test.creevey.reportDir}/${filePath}/${fileName} => report/${filePath}']`,
|
100
|
-
);
|
101
|
-
console.log(
|
102
|
-
`##teamcity[testMetadata testName='${this.escape(
|
103
|
-
test.fullTitle(),
|
104
|
-
)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`,
|
105
|
-
);
|
106
|
-
});
|
107
|
-
});
|
108
|
-
|
109
|
-
// Output failed test as passed due TC don't support retry mechanic
|
110
|
-
// https://teamcity-support.jetbrains.com/hc/en-us/community/posts/207216829-Count-test-as-successful-if-at-least-one-try-is-successful?page=1#community_comment_207394125
|
111
|
-
|
112
|
-
if (test.creevey.willRetry)
|
113
|
-
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
114
|
-
else
|
115
|
-
console.log(
|
116
|
-
`##teamcity[testFailed name='${this.escape(test.fullTitle())}' message='${this.escape(
|
117
|
-
error.message,
|
118
|
-
)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`,
|
119
|
-
);
|
120
|
-
});
|
121
|
-
}
|
122
|
-
|
123
|
-
private escape = (str: string): string => {
|
124
|
-
if (!str) return '';
|
125
|
-
return (
|
126
|
-
str
|
127
|
-
.toString()
|
128
|
-
// eslint-disable-next-line no-control-regex
|
129
|
-
.replace(/\x1B.*?m/g, '')
|
130
|
-
.replace(/\|/g, '||')
|
131
|
-
.replace(/\n/g, '|n')
|
132
|
-
.replace(/\r/g, '|r')
|
133
|
-
.replace(/\[/g, '|[')
|
134
|
-
.replace(/\]/g, '|]')
|
135
|
-
.replace(/\u0085/g, '|x')
|
136
|
-
.replace(/\u2028/g, '|l')
|
137
|
-
.replace(/\u2029/g, '|p')
|
138
|
-
.replace(/'/g, "|'")
|
139
|
-
);
|
140
|
-
};
|
141
|
-
}
|