1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | const path = require('path');
|
14 | const builder = require('junit-report-builder');
|
15 |
|
16 | class JunitPerformanceReport {
|
17 | constructor() {
|
18 | this._outfile = path.resolve(process.cwd(), 'test-results.xml');
|
19 | this._builder = builder.newBuilder();
|
20 | }
|
21 |
|
22 | withOutfile(value) {
|
23 | this._outfile = value;
|
24 | return this;
|
25 | }
|
26 |
|
27 | appendResults(result, params = {}, strainname = 'default') {
|
28 | this._suite = this._builder.testSuite().name(`Performance Tests on ${result.device.title || result.device} (${result.connection.title}) from ${result.location.name} using ${strainname} strain.`);
|
29 | this._suite.timestamp(result.updatedAt);
|
30 |
|
31 | result.metrics.map((metric) => {
|
32 | const test = this._suite.testCase().className(result.url).name(metric.label);
|
33 | if (!/(_index|-score|_bytes|-size|_count)$/.test(metric.name)) {
|
34 | test.time(metric.value / 1000);
|
35 | }
|
36 | const { status, message } = JunitPerformanceReport.getSuccess(
|
37 | params,
|
38 | metric.name,
|
39 | metric.value,
|
40 | );
|
41 | if (status === 'passed') {
|
42 | test.standardOutput(message);
|
43 | } else if (status === 'failed') {
|
44 | test.failure(message);
|
45 | } else {
|
46 | test.skipped();
|
47 | }
|
48 | return true;
|
49 | });
|
50 | }
|
51 |
|
52 | static hasCustomLimits(params = {}) {
|
53 | return Object.values(params).some((v) => Number.isInteger(v));
|
54 | }
|
55 |
|
56 | static getLimit(params = {}, name) {
|
57 | const value = params[name];
|
58 | if (Number.isInteger(value)) {
|
59 | return value;
|
60 | }
|
61 | if (name === 'lighthouse-performance-score' && !JunitPerformanceReport.hasCustomLimits(params)) {
|
62 | return 80;
|
63 | }
|
64 | if (name === 'lighthouse-accessibility-score' && !JunitPerformanceReport.hasCustomLimits(params)) {
|
65 | return 80;
|
66 | }
|
67 | return undefined;
|
68 | }
|
69 |
|
70 | static getSuccess(params = {}, name, value) {
|
71 | const limit = JunitPerformanceReport.getLimit(params, name);
|
72 | if (!limit) {
|
73 | return { status: 'skipped', message: `No limit set for ${name}. Value ${value} not considered.` };
|
74 | }
|
75 | if (/-score/.test(name)) {
|
76 | if (value >= limit) {
|
77 | return { status: 'passed', message: `Score ${name} of ${value} meets lower bound of ${limit}` };
|
78 | }
|
79 | return { status: 'failed', message: `Score ${name} of ${value} below lower bound of ${limit}` };
|
80 | }
|
81 | if (value >= limit) {
|
82 | return { status: 'failed', message: `Metric ${name} of ${value} exceeds limit of ${limit}` };
|
83 | }
|
84 | return { status: 'passed', message: `Metric ${name} of ${value} below limit of ${limit}` };
|
85 | }
|
86 |
|
87 | writeResults() {
|
88 | this._builder.writeTo(this._outfile);
|
89 | }
|
90 | }
|
91 |
|
92 | module.exports = JunitPerformanceReport;
|