@mablhq/mabl-cli 1.59.6 → 1.61.3
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/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +1 -1
- package/core/execution/ApiTestUtils.js +9 -6
- package/core/trainer/trainingSessions-types.js +0 -5
- package/domUtil/index.js +1 -1
- package/execution/index.js +1 -1
- package/execution/index.js.LICENSE.txt +0 -18
- package/mablApi/index.js +1 -1
- package/mablscriptFind/index.js +1 -1
- package/package.json +1 -5
- package/resources/mablFind.js +1 -1
- package/browserTestMonitoring/cloudMonitoringPerformanceMetrics.js +0 -249
- package/browserTestMonitoring/distributions.js +0 -39
- package/browserTestMonitoring/metricsRecorder.js +0 -129
- package/browserTestMonitoring/types.js +0 -8
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.CloudMonitoringPerformanceMetrics = exports.DEFAULT_CLOUD_MONITORING_METRICS_EXPORT_PERIOD_MS = void 0;
|
|
27
|
-
const api_1 = __importStar(require("@opentelemetry/api"));
|
|
28
|
-
const resources_1 = require("@opentelemetry/resources");
|
|
29
|
-
const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
|
|
30
|
-
const opentelemetry_cloud_monitoring_exporter_1 = require("@google-cloud/opentelemetry-cloud-monitoring-exporter");
|
|
31
|
-
const distributions_1 = require("./distributions");
|
|
32
|
-
const DEBUG = false;
|
|
33
|
-
const METRIC_NAME_PREFIX = 'mabl/tests/performance';
|
|
34
|
-
exports.DEFAULT_CLOUD_MONITORING_METRICS_EXPORT_PERIOD_MS = 8000;
|
|
35
|
-
const DEFAULT_METER_PROVIDER_SHUTDOWN_TIMEOUT_MS = 3 * exports.DEFAULT_CLOUD_MONITORING_METRICS_EXPORT_PERIOD_MS + 1000;
|
|
36
|
-
class CloudMonitoringPerformanceMetrics {
|
|
37
|
-
constructor(projectId, runnerId, cloudMonitoringMetricsExportPeriodMs = exports.DEFAULT_CLOUD_MONITORING_METRICS_EXPORT_PERIOD_MS, meterProviderShutdownTimeoutMs = DEFAULT_METER_PROVIDER_SHUTDOWN_TIMEOUT_MS) {
|
|
38
|
-
this.projectId = projectId;
|
|
39
|
-
this.runnerId = runnerId;
|
|
40
|
-
this.cloudMonitoringMetricsExportPeriodMs = cloudMonitoringMetricsExportPeriodMs;
|
|
41
|
-
this.meterProviderShutdownTimeoutMs = meterProviderShutdownTimeoutMs;
|
|
42
|
-
if (DEBUG) {
|
|
43
|
-
api_1.diag.setLogger(new api_1.DiagConsoleLogger(), api_1.DiagLogLevel.ALL);
|
|
44
|
-
}
|
|
45
|
-
this.stepMetricsInstrumentNames = this.generateStepMetricsInstrumentNames();
|
|
46
|
-
this.testMetricsInstrumentNames = this.generateTestMetricsInstrumentNames();
|
|
47
|
-
this.meterProvider = this.initializeOpenTelemetry();
|
|
48
|
-
this.meter = this.meterProvider.getMeter(runnerId);
|
|
49
|
-
this.step = this.initializeStepMetrics();
|
|
50
|
-
this.test = this.initializeTestMetrics();
|
|
51
|
-
}
|
|
52
|
-
async shutdown() {
|
|
53
|
-
await this.meterProvider.shutdown({
|
|
54
|
-
timeoutMillis: this.meterProviderShutdownTimeoutMs,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
generateStepMetricsInstrumentNames() {
|
|
58
|
-
return {
|
|
59
|
-
...this.generateCommonInstrumentNames('step'),
|
|
60
|
-
firstContentfulPaint: this.generateInstrumentName('step', 'firstContentfulPaint'),
|
|
61
|
-
largestContentfulPaint: this.generateInstrumentName('step', 'largestContentfulPaint'),
|
|
62
|
-
cumulativeLayoutShift: this.generateInstrumentName('step', 'cumulativeLayoutShift'),
|
|
63
|
-
timeToFirstByte: this.generateInstrumentName('step', 'timeToFirstByte'),
|
|
64
|
-
domContentLoaded: this.generateInstrumentName('step', 'domContentLoaded'),
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
generateTestMetricsInstrumentNames() {
|
|
68
|
-
return {
|
|
69
|
-
...this.generateCommonInstrumentNames('test'),
|
|
70
|
-
executionTime: this.generateInstrumentName('test', 'execution', 'time'),
|
|
71
|
-
runnerCount: this.generateCountInstrumentName('test', 'runner'),
|
|
72
|
-
firstContentfulPaintFailCount: this.generateCWVFailCountInstrumentName('test', 'firstContentfulPaint'),
|
|
73
|
-
largestContentfulPaintFailCount: this.generateCWVFailCountInstrumentName('test', 'largestContentfulPaint'),
|
|
74
|
-
cumulativeLayoutShiftFailCount: this.generateCWVFailCountInstrumentName('test', 'cumulativeLayoutShift'),
|
|
75
|
-
timeToFirstByteFailCount: this.generateCWVFailCountInstrumentName('test', 'timeToFirstByte'),
|
|
76
|
-
domContentLoadedFailCount: this.generateCWVFailCountInstrumentName('test', 'domContentLoaded'),
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
initializeOpenTelemetry() {
|
|
80
|
-
const StepMetricsViews = {
|
|
81
|
-
executionCount: new sdk_metrics_1.View({
|
|
82
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
83
|
-
instrumentName: this.stepMetricsInstrumentNames.executionCount,
|
|
84
|
-
}),
|
|
85
|
-
failCount: new sdk_metrics_1.View({
|
|
86
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
87
|
-
instrumentName: this.stepMetricsInstrumentNames.failCount,
|
|
88
|
-
}),
|
|
89
|
-
passCount: new sdk_metrics_1.View({
|
|
90
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
91
|
-
instrumentName: this.stepMetricsInstrumentNames.passCount,
|
|
92
|
-
}),
|
|
93
|
-
firstContentfulPaint: new sdk_metrics_1.View({
|
|
94
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.FCPBucketBoundaries, true),
|
|
95
|
-
instrumentName: this.stepMetricsInstrumentNames.firstContentfulPaint,
|
|
96
|
-
}),
|
|
97
|
-
largestContentfulPaint: new sdk_metrics_1.View({
|
|
98
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.LCPBucketBoundaries, true),
|
|
99
|
-
instrumentName: this.stepMetricsInstrumentNames.largestContentfulPaint,
|
|
100
|
-
}),
|
|
101
|
-
cumulativeLayoutShift: new sdk_metrics_1.View({
|
|
102
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.CLSBucketBoundaries, true),
|
|
103
|
-
instrumentName: this.stepMetricsInstrumentNames.cumulativeLayoutShift,
|
|
104
|
-
}),
|
|
105
|
-
timeToFirstByte: new sdk_metrics_1.View({
|
|
106
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.TTFBBucketBoundaries, true),
|
|
107
|
-
instrumentName: this.stepMetricsInstrumentNames.timeToFirstByte,
|
|
108
|
-
}),
|
|
109
|
-
domContentLoaded: new sdk_metrics_1.View({
|
|
110
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.DCLBucketBoundaries, true),
|
|
111
|
-
instrumentName: this.stepMetricsInstrumentNames.domContentLoaded,
|
|
112
|
-
}),
|
|
113
|
-
};
|
|
114
|
-
const TestMetricsViews = {
|
|
115
|
-
executionCount: new sdk_metrics_1.View({
|
|
116
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
117
|
-
instrumentName: this.testMetricsInstrumentNames.executionCount,
|
|
118
|
-
}),
|
|
119
|
-
executionTime: new sdk_metrics_1.View({
|
|
120
|
-
aggregation: new sdk_metrics_1.ExplicitBucketHistogramAggregation(distributions_1.ElapsedExecutionTimeBucketBoundaries, true),
|
|
121
|
-
instrumentName: this.testMetricsInstrumentNames.executionTime,
|
|
122
|
-
}),
|
|
123
|
-
failCount: new sdk_metrics_1.View({
|
|
124
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
125
|
-
instrumentName: this.testMetricsInstrumentNames.failCount,
|
|
126
|
-
}),
|
|
127
|
-
passCount: new sdk_metrics_1.View({
|
|
128
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
129
|
-
instrumentName: this.testMetricsInstrumentNames.passCount,
|
|
130
|
-
}),
|
|
131
|
-
runnerCount: new sdk_metrics_1.View({
|
|
132
|
-
aggregation: new sdk_metrics_1.LastValueAggregation(),
|
|
133
|
-
instrumentName: this.testMetricsInstrumentNames.runnerCount,
|
|
134
|
-
}),
|
|
135
|
-
firstContentfulPaintFailCount: new sdk_metrics_1.View({
|
|
136
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
137
|
-
instrumentName: this.testMetricsInstrumentNames.firstContentfulPaintFailCount,
|
|
138
|
-
}),
|
|
139
|
-
largestContentfulPaintFailCount: new sdk_metrics_1.View({
|
|
140
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
141
|
-
instrumentName: this.testMetricsInstrumentNames.largestContentfulPaintFailCount,
|
|
142
|
-
}),
|
|
143
|
-
cumulativeLayoutShiftFailCount: new sdk_metrics_1.View({
|
|
144
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
145
|
-
instrumentName: this.testMetricsInstrumentNames.cumulativeLayoutShiftFailCount,
|
|
146
|
-
}),
|
|
147
|
-
timeToFirstByteFailCount: new sdk_metrics_1.View({
|
|
148
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
149
|
-
instrumentName: this.testMetricsInstrumentNames.timeToFirstByteFailCount,
|
|
150
|
-
}),
|
|
151
|
-
domContentLoadedFailCount: new sdk_metrics_1.View({
|
|
152
|
-
aggregation: new sdk_metrics_1.SumAggregation(),
|
|
153
|
-
instrumentName: this.testMetricsInstrumentNames.domContentLoadedFailCount,
|
|
154
|
-
}),
|
|
155
|
-
};
|
|
156
|
-
const meterProvider = new sdk_metrics_1.MeterProvider({
|
|
157
|
-
resource: new resources_1.Resource({
|
|
158
|
-
'service.namespace': 'execution',
|
|
159
|
-
'service.name': 'performance-test-runner',
|
|
160
|
-
'host.id': this.runnerId,
|
|
161
|
-
}),
|
|
162
|
-
views: [
|
|
163
|
-
...Object.values(StepMetricsViews),
|
|
164
|
-
...Object.values(TestMetricsViews),
|
|
165
|
-
],
|
|
166
|
-
});
|
|
167
|
-
const exporter = new opentelemetry_cloud_monitoring_exporter_1.MetricExporter({
|
|
168
|
-
prefix: 'custom.googleapis.com',
|
|
169
|
-
projectId: this.projectId,
|
|
170
|
-
});
|
|
171
|
-
meterProvider.addMetricReader(new sdk_metrics_1.PeriodicExportingMetricReader({
|
|
172
|
-
exportIntervalMillis: this.cloudMonitoringMetricsExportPeriodMs,
|
|
173
|
-
exporter,
|
|
174
|
-
}));
|
|
175
|
-
api_1.default.metrics.setGlobalMeterProvider(this.meterProvider);
|
|
176
|
-
return meterProvider;
|
|
177
|
-
}
|
|
178
|
-
initializeStepMetrics() {
|
|
179
|
-
return {
|
|
180
|
-
executionCount: this.initializeStepCount('executionCount'),
|
|
181
|
-
failCount: this.initializeStepCount('failCount'),
|
|
182
|
-
passCount: this.initializeStepCount('passCount'),
|
|
183
|
-
firstContentfulPaint: this.initializeStepTimeHistogram('firstContentfulPaint'),
|
|
184
|
-
largestContentfulPaint: this.initializeStepTimeHistogram('largestContentfulPaint'),
|
|
185
|
-
cumulativeLayoutShift: this.initializeStepTimeHistogram('cumulativeLayoutShift'),
|
|
186
|
-
timeToFirstByte: this.initializeStepTimeHistogram('timeToFirstByte'),
|
|
187
|
-
domContentLoaded: this.initializeStepTimeHistogram('domContentLoaded'),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
initializeTestMetrics() {
|
|
191
|
-
return {
|
|
192
|
-
executionCount: this.initializeTestCount('executionCount'),
|
|
193
|
-
executionTime: this.initializeTestTimeHistogram('executionTime'),
|
|
194
|
-
failCount: this.initializeTestCount('failCount'),
|
|
195
|
-
passCount: this.initializeTestCount('passCount'),
|
|
196
|
-
runnerCount: this.initializeTestCount('runnerCount'),
|
|
197
|
-
firstContentfulPaintFailCount: this.initializeTestCount('firstContentfulPaintFailCount'),
|
|
198
|
-
largestContentfulPaintFailCount: this.initializeTestCount('largestContentfulPaintFailCount'),
|
|
199
|
-
cumulativeLayoutShiftFailCount: this.initializeTestCount('cumulativeLayoutShiftFailCount'),
|
|
200
|
-
timeToFirstByteFailCount: this.initializeTestCount('timeToFirstByteFailCount'),
|
|
201
|
-
domContentLoadedFailCount: this.initializeTestCount('domContentLoadedFailCount'),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
initializeStepCount(instrumentName) {
|
|
205
|
-
return this.initializeCounter(this.stepMetricsInstrumentNames[instrumentName]);
|
|
206
|
-
}
|
|
207
|
-
initializeTestCount(instrumentName) {
|
|
208
|
-
return this.initializeCounter(this.testMetricsInstrumentNames[instrumentName]);
|
|
209
|
-
}
|
|
210
|
-
initializeCounter(instrumentName) {
|
|
211
|
-
return this.meter.createCounter(instrumentName, {
|
|
212
|
-
valueType: api_1.ValueType.INT,
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
initializeStepTimeHistogram(instrumentName) {
|
|
216
|
-
return this.initializeTimeHistogram(this.stepMetricsInstrumentNames[instrumentName]);
|
|
217
|
-
}
|
|
218
|
-
initializeTestTimeHistogram(instrumentName) {
|
|
219
|
-
return this.initializeTimeHistogram(this.testMetricsInstrumentNames[instrumentName]);
|
|
220
|
-
}
|
|
221
|
-
initializeTimeHistogram(instrumentName) {
|
|
222
|
-
const histogram = this.meter.createHistogram(instrumentName, {
|
|
223
|
-
unit: instrumentName === this.stepMetricsInstrumentNames.cumulativeLayoutShift
|
|
224
|
-
? undefined
|
|
225
|
-
: 'ms',
|
|
226
|
-
});
|
|
227
|
-
return histogram;
|
|
228
|
-
}
|
|
229
|
-
generateCommonInstrumentNames(granularity) {
|
|
230
|
-
return {
|
|
231
|
-
executionCount: this.generateCountInstrumentName(granularity, 'execution'),
|
|
232
|
-
failCount: this.generateResultInstrumentName(granularity, 'fail'),
|
|
233
|
-
passCount: this.generateResultInstrumentName(granularity, 'pass'),
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
generateCountInstrumentName(granularity, type) {
|
|
237
|
-
return this.generateInstrumentName(granularity, type, 'count');
|
|
238
|
-
}
|
|
239
|
-
generateResultInstrumentName(granularity, type) {
|
|
240
|
-
return this.generateInstrumentName(granularity, 'result', type);
|
|
241
|
-
}
|
|
242
|
-
generateCWVFailCountInstrumentName(granularity, type) {
|
|
243
|
-
return this.generateInstrumentName(granularity, type, 'failCount');
|
|
244
|
-
}
|
|
245
|
-
generateInstrumentName(granularity, ...path) {
|
|
246
|
-
return `${METRIC_NAME_PREFIX}/${granularity}/${path.join('/')}`;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
exports.CloudMonitoringPerformanceMetrics = CloudMonitoringPerformanceMetrics;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateBucketBoundaries = exports.DCLBucketBoundaries = exports.TTFBBucketBoundaries = exports.CLSBucketBoundaries = exports.LCPBucketBoundaries = exports.FCPBucketBoundaries = exports.ElapsedExecutionTimeBucketBoundaries = void 0;
|
|
4
|
-
exports.ElapsedExecutionTimeBucketBoundaries = generateBucketBoundaries({ limit: 60000, width: 1000 }, { limit: 300000, width: 5000 }, { limit: 3600000, width: 60000 });
|
|
5
|
-
exports.FCPBucketBoundaries = generateBucketBoundaries({ limit: 1800, width: 25 }, { limit: 3000, width: 50 }, { limit: 6000, width: 100 }, { limit: 30000, width: 500 }, { limit: 50000, width: 1000 });
|
|
6
|
-
exports.LCPBucketBoundaries = generateBucketBoundaries({ limit: 1500, width: 25 }, { limit: 2500, width: 50 }, { limit: 4000, width: 75 }, { limit: 8000, width: 250 }, { limit: 30000, width: 500 }, { limit: 60000, width: 1000 });
|
|
7
|
-
exports.CLSBucketBoundaries = generateBucketBoundaries({ limit: 0.1, width: 0.001 }, { limit: 0.25, width: 0.0025 }, { limit: 0.5, width: 0.01 }, { limit: 1, width: 0.05 });
|
|
8
|
-
exports.TTFBBucketBoundaries = generateBucketBoundaries({ limit: 1000, width: 25 }, { limit: 2000, width: 50 }, { limit: 5000, width: 75 }, { limit: 10000, width: 250 }, { limit: 30000, width: 500 }, { limit: 60000, width: 1000 });
|
|
9
|
-
exports.DCLBucketBoundaries = generateBucketBoundaries({ limit: 1000, width: 25 }, { limit: 2000, width: 50 }, { limit: 5000, width: 75 }, { limit: 10000, width: 250 }, { limit: 30000, width: 500 }, { limit: 60000, width: 1000 });
|
|
10
|
-
function generateBucketBoundaries(...rules) {
|
|
11
|
-
if (!rules.length) {
|
|
12
|
-
throw new Error('At least one rule must be specified');
|
|
13
|
-
}
|
|
14
|
-
return rules
|
|
15
|
-
.reduce((boundaries, rule, index) => {
|
|
16
|
-
const { limit, width } = rule;
|
|
17
|
-
const previousLimit = boundaries[index][boundaries[index].length - 1];
|
|
18
|
-
if (width <= 0) {
|
|
19
|
-
throw new Error(`Invalid rule specification at index ${index}: width must be positive but was ${width}`);
|
|
20
|
-
}
|
|
21
|
-
if (limit <= previousLimit) {
|
|
22
|
-
throw new Error(`Invalid rule specification at index ${index}: limit ${limit} must be strictly greater than previous limit ${previousLimit}`);
|
|
23
|
-
}
|
|
24
|
-
if (previousLimit + width > limit) {
|
|
25
|
-
throw new Error(`Invalid rule specification at index ${index}: previous limit ${previousLimit} + width ${width} must not exceed limit ${limit}`);
|
|
26
|
-
}
|
|
27
|
-
const correctionFactor = 10000;
|
|
28
|
-
const bucketCount = Math.floor((limit * correctionFactor - previousLimit * correctionFactor) /
|
|
29
|
-
(width * correctionFactor));
|
|
30
|
-
const buckets = [...Array(bucketCount)].map((_value, index) => (previousLimit * correctionFactor +
|
|
31
|
-
width * correctionFactor * (index + 1)) /
|
|
32
|
-
correctionFactor);
|
|
33
|
-
boundaries.push(buckets);
|
|
34
|
-
return boundaries;
|
|
35
|
-
}, [[0]])
|
|
36
|
-
.flat()
|
|
37
|
-
.slice(1);
|
|
38
|
-
}
|
|
39
|
-
exports.generateBucketBoundaries = generateBucketBoundaries;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MetricsRecorder = void 0;
|
|
4
|
-
const cloudMonitoringPerformanceMetrics_1 = require("./cloudMonitoringPerformanceMetrics");
|
|
5
|
-
const Executor_1 = require("../execution/Executor");
|
|
6
|
-
const TestResult_1 = require("../core/execution/TestResult");
|
|
7
|
-
const pureUtil_1 = require("../util/pureUtil");
|
|
8
|
-
class MetricsRecorder {
|
|
9
|
-
constructor(projectId, testMetricLabels, metricsFactory = (projectId, runnerId) => new cloudMonitoringPerformanceMetrics_1.CloudMonitoringPerformanceMetrics(projectId, runnerId), cwvFailureCriteria) {
|
|
10
|
-
this.testMetricLabels = testMetricLabels;
|
|
11
|
-
this.cwvFailureCriteria = cwvFailureCriteria;
|
|
12
|
-
this.metrics = metricsFactory(projectId, testMetricLabels.runner_id);
|
|
13
|
-
}
|
|
14
|
-
async stop() {
|
|
15
|
-
await this.metrics.shutdown();
|
|
16
|
-
}
|
|
17
|
-
recordTestMetricsForResult(testResult, navigationInfo) {
|
|
18
|
-
const testElapsedTimeMillis = testResult.endTime - testResult.startTime;
|
|
19
|
-
const testPassed = testResult.status === TestResult_1.TestResultStatus.passed;
|
|
20
|
-
this.recordTestMetrics({
|
|
21
|
-
executionCount: 1,
|
|
22
|
-
executionTime: testElapsedTimeMillis,
|
|
23
|
-
failCount: testPassed ? 0 : 1,
|
|
24
|
-
passCount: testPassed ? 1 : 0,
|
|
25
|
-
runnerCount: 1,
|
|
26
|
-
...this.getCWVFailCounts(navigationInfo),
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
getCWVFailCounts(navigationInfo) {
|
|
30
|
-
var _a;
|
|
31
|
-
if (!this.cwvFailureCriteria) {
|
|
32
|
-
return {};
|
|
33
|
-
}
|
|
34
|
-
const { relevantStepIds, metricConfiguration } = this.cwvFailureCriteria;
|
|
35
|
-
const relevantNavigationInfo = (_a = relevantStepIds === null || relevantStepIds === void 0 ? void 0 : relevantStepIds.map((stepId) => navigationInfo.get(stepId)).filter(pureUtil_1.isDefined)) !== null && _a !== void 0 ? _a : Array.from(navigationInfo.values());
|
|
36
|
-
const relevantMetric = relevantNavigationInfo.flatMap((navigationInfo) => navigationInfo.metric);
|
|
37
|
-
return metricConfiguration
|
|
38
|
-
.map((configuration) => {
|
|
39
|
-
const { name, threshold } = configuration;
|
|
40
|
-
const hasTestFailed = relevantMetric
|
|
41
|
-
.filter((metric) => metric.name === name)
|
|
42
|
-
.some((metric) => metric.value > threshold);
|
|
43
|
-
return {
|
|
44
|
-
[this.metricNameToTestMeasurementName(name)]: hasTestFailed ? 1 : 0,
|
|
45
|
-
};
|
|
46
|
-
})
|
|
47
|
-
.reduce((measurements, measurement) => Object.assign(measurements, measurement), {});
|
|
48
|
-
}
|
|
49
|
-
metricNameToTestMeasurementName(name) {
|
|
50
|
-
switch (name) {
|
|
51
|
-
case 'FCP':
|
|
52
|
-
return 'firstContentfulPaintFailCount';
|
|
53
|
-
case 'LCP':
|
|
54
|
-
return 'largestContentfulPaintFailCount';
|
|
55
|
-
case 'CLS':
|
|
56
|
-
return 'cumulativeLayoutShiftFailCount';
|
|
57
|
-
case 'TTFB':
|
|
58
|
-
return 'timeToFirstByteFailCount';
|
|
59
|
-
default:
|
|
60
|
-
case 'domContentLoadedEventEnd':
|
|
61
|
-
return 'domContentLoadedFailCount';
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
recordStepMetricsForResult(result) {
|
|
65
|
-
const labels = {
|
|
66
|
-
...this.testMetricLabels,
|
|
67
|
-
step_id: result.stepId,
|
|
68
|
-
};
|
|
69
|
-
this.recordStepMetrics(labels, {
|
|
70
|
-
executionCount: 1,
|
|
71
|
-
failCount: result.status === Executor_1.StepStatus.Failed ? 1 : 0,
|
|
72
|
-
passCount: result.status === Executor_1.StepStatus.Passed ? 1 : 0,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
recordCWVStepMetrics(stepId, metric) {
|
|
76
|
-
const labels = {
|
|
77
|
-
...this.testMetricLabels,
|
|
78
|
-
step_id: stepId,
|
|
79
|
-
};
|
|
80
|
-
this.recordStepMetrics(labels, this.transformCWVStepMetricToStepMeasurement(metric));
|
|
81
|
-
}
|
|
82
|
-
transformCWVStepMetricToStepMeasurement(metric) {
|
|
83
|
-
const { name, value } = metric;
|
|
84
|
-
switch (name) {
|
|
85
|
-
case 'FCP':
|
|
86
|
-
return { firstContentfulPaint: value };
|
|
87
|
-
case 'LCP':
|
|
88
|
-
return { largestContentfulPaint: value };
|
|
89
|
-
case 'CLS':
|
|
90
|
-
return { cumulativeLayoutShift: value };
|
|
91
|
-
case 'TTFB':
|
|
92
|
-
return { timeToFirstByte: value };
|
|
93
|
-
case 'domContentLoadedEventEnd':
|
|
94
|
-
return { domContentLoaded: value };
|
|
95
|
-
default:
|
|
96
|
-
return {};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
recordStepMetrics(labels, measurements) {
|
|
100
|
-
Object.keys(measurements).forEach((name) => {
|
|
101
|
-
const instrument = this.metrics.step[name];
|
|
102
|
-
const value = measurements[name];
|
|
103
|
-
if (value !== undefined && !Number.isNaN(value)) {
|
|
104
|
-
this.recordValue(instrument, value, labels);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
recordTestMetrics(measurements) {
|
|
109
|
-
Object.keys(measurements).forEach((name) => {
|
|
110
|
-
const instrument = this.metrics.test[name];
|
|
111
|
-
const value = measurements[name];
|
|
112
|
-
if (value !== undefined && !Number.isNaN(value)) {
|
|
113
|
-
this.recordValue(instrument, value, this.testMetricLabels);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
recordValue(instrument, value, labels) {
|
|
118
|
-
if (instrument.add) {
|
|
119
|
-
instrument.add(value, labels);
|
|
120
|
-
}
|
|
121
|
-
else if (instrument.record) {
|
|
122
|
-
instrument.record(value, labels);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
console.error('Unexpected instrument type', instrument);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
exports.MetricsRecorder = MetricsRecorder;
|