@elastic/synthetics 1.0.0-beta.2 → 1.0.0-beta.22
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/CHANGELOG.md +235 -0
- package/NOTICE.txt +250 -0
- package/README.md +2 -1
- package/dist/cli.js +87 -56
- package/dist/cli.js.map +1 -1
- package/dist/common_types.d.ts +116 -14
- package/dist/common_types.d.ts.map +1 -1
- package/dist/config.d.ts +2 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -5
- package/dist/config.js.map +1 -1
- package/dist/core/browser-service.js +5 -5
- package/dist/core/browser-service.js.map +1 -1
- package/dist/core/expect.d.ts +177 -0
- package/dist/core/expect.d.ts.map +1 -0
- package/dist/core/expect.js +33 -0
- package/dist/core/expect.js.map +1 -0
- package/dist/core/gatherer.d.ts +4 -7
- package/dist/core/gatherer.d.ts.map +1 -1
- package/dist/core/gatherer.js +39 -12
- package/dist/core/gatherer.js.map +1 -1
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +0 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +3 -16
- package/dist/core/logger.js.map +1 -1
- package/dist/core/runner.d.ts +54 -45
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +181 -71
- package/dist/core/runner.js.map +1 -1
- package/dist/dsl/journey.d.ts +13 -4
- package/dist/dsl/journey.d.ts.map +1 -1
- package/dist/dsl/journey.js +40 -1
- package/dist/dsl/journey.js.map +1 -1
- package/dist/formatter/javascript.d.ts +73 -0
- package/dist/formatter/javascript.d.ts.map +1 -0
- package/dist/formatter/javascript.js +274 -0
- package/dist/formatter/javascript.js.map +1 -0
- package/dist/helpers.d.ts +33 -12
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +108 -54
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/parse_args.d.ts +5 -2
- package/dist/parse_args.d.ts.map +1 -1
- package/dist/parse_args.js +59 -16
- package/dist/parse_args.js.map +1 -1
- package/dist/plugins/browser-console.d.ts +5 -8
- package/dist/plugins/browser-console.d.ts.map +1 -1
- package/dist/plugins/browser-console.js +27 -8
- package/dist/plugins/browser-console.js.map +1 -1
- package/dist/plugins/network.d.ts +23 -20
- package/dist/plugins/network.d.ts.map +1 -1
- package/dist/plugins/network.js +149 -124
- package/dist/plugins/network.js.map +1 -1
- package/dist/plugins/performance.d.ts +5 -5
- package/dist/plugins/performance.d.ts.map +1 -1
- package/dist/plugins/performance.js +5 -5
- package/dist/plugins/performance.js.map +1 -1
- package/dist/plugins/plugin-manager.d.ts +11 -11
- package/dist/plugins/plugin-manager.d.ts.map +1 -1
- package/dist/plugins/plugin-manager.js +40 -24
- package/dist/plugins/plugin-manager.js.map +1 -1
- package/dist/plugins/tracing.d.ts +10 -25
- package/dist/plugins/tracing.d.ts.map +1 -1
- package/dist/plugins/tracing.js +40 -26
- package/dist/plugins/tracing.js.map +1 -1
- package/dist/reporters/base.d.ts +0 -1
- package/dist/reporters/base.d.ts.map +1 -1
- package/dist/reporters/base.js +34 -32
- package/dist/reporters/base.js.map +1 -1
- package/dist/reporters/json.d.ts +46 -59
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +188 -70
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/junit.d.ts.map +1 -1
- package/dist/reporters/junit.js +7 -7
- package/dist/reporters/junit.js.map +1 -1
- package/dist/sdk/lh-trace-processor.d.ts +304 -0
- package/dist/sdk/lh-trace-processor.d.ts.map +1 -0
- package/dist/sdk/lh-trace-processor.js +832 -0
- package/dist/sdk/lh-trace-processor.js.map +1 -0
- package/dist/sdk/trace-metrics.d.ts +61 -0
- package/dist/sdk/trace-metrics.d.ts.map +1 -0
- package/dist/sdk/trace-metrics.js +252 -0
- package/dist/sdk/trace-metrics.js.map +1 -0
- package/dist/sdk/trace-processor.d.ts +106 -0
- package/dist/sdk/trace-processor.d.ts.map +1 -0
- package/dist/sdk/trace-processor.js +74 -0
- package/dist/sdk/trace-processor.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1575
- package/package.json +27 -16
- package/src/cli.ts +68 -45
- package/src/common_types.ts +138 -14
- package/src/config.ts +2 -5
- package/src/core/expect.ts +187 -0
- package/src/core/gatherer.ts +48 -24
- package/src/core/index.ts +6 -6
- package/src/core/logger.ts +1 -12
- package/src/core/runner.ts +259 -112
- package/src/dsl/journey.ts +28 -6
- package/src/formatter/javascript.ts +330 -0
- package/src/helpers.ts +114 -24
- package/src/index.ts +7 -6
- package/src/parse_args.ts +97 -22
- package/src/plugins/browser-console.ts +30 -13
- package/src/plugins/network.ts +175 -159
- package/src/plugins/performance.ts +7 -7
- package/src/plugins/plugin-manager.ts +47 -36
- package/src/plugins/tracing.ts +43 -54
- package/src/reporters/base.ts +29 -23
- package/src/reporters/json.ts +259 -80
- package/src/reporters/junit.ts +1 -1
- package/src/sdk/lh-trace-processor.ts +1033 -0
- package/src/sdk/trace-metrics.ts +287 -0
- package/src/sdk/trace-processor.ts +147 -0
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import {
|
|
26
|
+
import { Driver } from '../common_types';
|
|
27
27
|
|
|
28
28
|
const supportedMetrics = new Set<string>([
|
|
29
29
|
'Timestamp',
|
|
@@ -41,7 +41,7 @@ const supportedMetrics = new Set<string>([
|
|
|
41
41
|
'JSHeapTotalSize',
|
|
42
42
|
]);
|
|
43
43
|
|
|
44
|
-
export interface
|
|
44
|
+
export interface PageMetrics {
|
|
45
45
|
Timestamp?: number;
|
|
46
46
|
Documents?: number;
|
|
47
47
|
Frames?: number;
|
|
@@ -58,22 +58,22 @@ export interface Metrics {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export class PerformanceManager {
|
|
61
|
-
constructor(private
|
|
61
|
+
constructor(private driver: Driver) {}
|
|
62
62
|
|
|
63
63
|
async start() {
|
|
64
|
-
await this.client.send('Performance.enable');
|
|
64
|
+
await this.driver.client.send('Performance.enable');
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
async stop() {
|
|
68
|
-
await this.client.send('Performance.disable');
|
|
68
|
+
await this.driver.client.send('Performance.disable');
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
async getMetrics() {
|
|
72
|
-
const { metrics } = await this.client.send('Performance.getMetrics');
|
|
72
|
+
const { metrics } = await this.driver.client.send('Performance.getMetrics');
|
|
73
73
|
return this.buildMetricsObject(metrics);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
private buildMetricsObject(metrics = []):
|
|
76
|
+
private buildMetricsObject(metrics = []): PageMetrics {
|
|
77
77
|
const result = {};
|
|
78
78
|
for (const metric of metrics) {
|
|
79
79
|
if (supportedMetrics.has(metric.name)) result[metric.name] = metric.value;
|
|
@@ -23,79 +23,90 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import {
|
|
26
|
+
import { PluginOutput, Driver } from '../common_types';
|
|
27
27
|
import {
|
|
28
28
|
BrowserConsole,
|
|
29
|
-
BrowserMessage,
|
|
30
29
|
NetworkManager,
|
|
31
30
|
PerformanceManager,
|
|
32
31
|
Tracing,
|
|
33
|
-
|
|
32
|
+
TraceOptions,
|
|
34
33
|
} from './';
|
|
35
|
-
import { Driver } from '../core/gatherer';
|
|
36
34
|
import { Step } from '../dsl';
|
|
37
35
|
|
|
38
36
|
type PluginType = 'network' | 'trace' | 'performance' | 'browserconsole';
|
|
39
|
-
|
|
40
|
-
type PluginOutput = {
|
|
41
|
-
filmstrips?: Array<FilmStrip>;
|
|
42
|
-
networkinfo?: Array<NetworkInfo>;
|
|
43
|
-
browserconsole?: Array<BrowserMessage>;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
37
|
type Plugin = NetworkManager | Tracing | PerformanceManager | BrowserConsole;
|
|
38
|
+
type PluginOptions = TraceOptions;
|
|
47
39
|
|
|
48
40
|
export class PluginManager {
|
|
49
|
-
protected plugins = new Map<
|
|
50
|
-
|
|
41
|
+
protected plugins = new Map<PluginType, Plugin>();
|
|
42
|
+
public PLUGIN_TYPES: Array<PluginType> = [
|
|
43
|
+
'network',
|
|
44
|
+
'trace',
|
|
45
|
+
'performance',
|
|
46
|
+
'browserconsole',
|
|
47
|
+
];
|
|
51
48
|
constructor(private driver: Driver) {}
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
register(type: PluginType, options: PluginOptions) {
|
|
54
51
|
let instance: Plugin;
|
|
55
52
|
switch (type) {
|
|
56
53
|
case 'network':
|
|
57
|
-
instance = new NetworkManager();
|
|
58
|
-
await instance.start(this.driver.client);
|
|
54
|
+
instance = new NetworkManager(this.driver);
|
|
59
55
|
break;
|
|
60
56
|
case 'trace':
|
|
61
|
-
instance = new Tracing();
|
|
62
|
-
await instance.start(this.driver.client);
|
|
57
|
+
instance = new Tracing(this.driver, options);
|
|
63
58
|
break;
|
|
64
59
|
case 'performance':
|
|
65
|
-
instance = new PerformanceManager(this.driver
|
|
66
|
-
instance.start();
|
|
60
|
+
instance = new PerformanceManager(this.driver);
|
|
67
61
|
break;
|
|
68
62
|
case 'browserconsole':
|
|
69
|
-
instance = new BrowserConsole(this.driver
|
|
70
|
-
instance.start();
|
|
63
|
+
instance = new BrowserConsole(this.driver);
|
|
71
64
|
break;
|
|
72
65
|
}
|
|
66
|
+
instance && this.plugins.set(type, instance);
|
|
67
|
+
return instance;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
registerAll(options: PluginOptions) {
|
|
71
|
+
for (const type of this.PLUGIN_TYPES) {
|
|
72
|
+
this.register(type, options);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
unregisterAll() {
|
|
77
|
+
for (const type of this.PLUGIN_TYPES) {
|
|
78
|
+
this.plugins.delete(type);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
73
81
|
|
|
74
|
-
|
|
82
|
+
async stop(type: PluginType) {
|
|
83
|
+
const instance = this.plugins.get(type);
|
|
84
|
+
if (instance) {
|
|
85
|
+
return await instance.stop();
|
|
86
|
+
}
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async start(type: PluginType) {
|
|
91
|
+
const instance = this.plugins.get(type);
|
|
92
|
+
instance && (await instance.start());
|
|
75
93
|
return instance;
|
|
76
94
|
}
|
|
77
95
|
|
|
78
|
-
get
|
|
79
|
-
return this.plugins.get(
|
|
96
|
+
get(type: PluginType) {
|
|
97
|
+
return this.plugins.get(type);
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
onStep(step: Step) {
|
|
83
|
-
this.get(
|
|
84
|
-
this.get(
|
|
101
|
+
(this.get('browserconsole') as BrowserConsole)._currentStep = step;
|
|
102
|
+
(this.get('network') as NetworkManager)._currentStep = step;
|
|
85
103
|
}
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
const data = {
|
|
89
|
-
filmstrips: [],
|
|
90
|
-
networkinfo: [],
|
|
91
|
-
browserconsole: null,
|
|
92
|
-
};
|
|
105
|
+
output() {
|
|
106
|
+
const data: PluginOutput = {};
|
|
93
107
|
for (const [, plugin] of this.plugins) {
|
|
94
108
|
if (plugin instanceof NetworkManager) {
|
|
95
109
|
data.networkinfo = plugin.stop();
|
|
96
|
-
} else if (plugin instanceof Tracing) {
|
|
97
|
-
const result = await plugin.stop(this.driver.client);
|
|
98
|
-
data.filmstrips = filterFilmstrips(result);
|
|
99
110
|
} else if (plugin instanceof BrowserConsole) {
|
|
100
111
|
data.browserconsole = plugin.stop();
|
|
101
112
|
}
|
package/src/plugins/tracing.ts
CHANGED
|
@@ -23,80 +23,60 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
26
|
+
import { Driver, PluginOutput } from '../common_types';
|
|
27
|
+
import { Filmstrips } from '../sdk/trace-metrics';
|
|
28
|
+
import { TraceEvent, TraceProcessor } from '../sdk/trace-processor';
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*/
|
|
34
|
-
type TraceEvent = {
|
|
35
|
-
name: string;
|
|
36
|
-
// event category
|
|
37
|
-
cat: string;
|
|
38
|
-
// process id
|
|
39
|
-
pid: number;
|
|
40
|
-
// thread id
|
|
41
|
-
tid: number;
|
|
42
|
-
// event phase
|
|
43
|
-
ph?: string;
|
|
44
|
-
args?: {
|
|
45
|
-
snapshot: string;
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* Platform specific monotonic non decreasing clock time
|
|
49
|
-
* https://source.chromium.org/chromium/chromium/src/+/master:base/time/time.h;l=936;bpv=0;bpt=0
|
|
50
|
-
*/
|
|
51
|
-
ts: number;
|
|
30
|
+
export type TraceOptions = {
|
|
31
|
+
filmstrips?: boolean;
|
|
32
|
+
trace?: boolean;
|
|
52
33
|
};
|
|
53
34
|
|
|
54
|
-
export function filterFilmstrips(
|
|
55
|
-
traceEvents: Array<TraceEvent>
|
|
56
|
-
): Array<FilmStrip> {
|
|
57
|
-
const events = traceEvents.filter(event => {
|
|
58
|
-
const { args, cat, name } = event;
|
|
59
|
-
return (
|
|
60
|
-
name === 'Screenshot' &&
|
|
61
|
-
cat === 'disabled-by-default-devtools.screenshot' &&
|
|
62
|
-
args?.snapshot
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return events.map(event => ({
|
|
67
|
-
snapshot: event.args.snapshot,
|
|
68
|
-
ts: event.ts,
|
|
69
|
-
startTime: convertTraceTimestamp(event.ts),
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
35
|
/**
|
|
74
|
-
* Custom Tracer that
|
|
36
|
+
* Custom Tracer that listenes for events from specified categories
|
|
75
37
|
* https://chromedevtools.github.io/devtools-protocol/tot/Tracing/
|
|
76
38
|
*/
|
|
77
39
|
export class Tracing {
|
|
78
|
-
|
|
40
|
+
constructor(private driver: Driver, private options: TraceOptions) {}
|
|
41
|
+
|
|
42
|
+
async start() {
|
|
79
43
|
const includedCategories = [
|
|
80
44
|
// exclude all default categories
|
|
81
45
|
'-*',
|
|
82
|
-
// capture screenshots
|
|
83
|
-
'disabled-by-default-devtools.screenshot',
|
|
84
46
|
];
|
|
85
|
-
|
|
47
|
+
if (this.options.filmstrips) {
|
|
48
|
+
// capture screenshots - up to 450 max for each trace (https://goo.gl/rBfhn4)
|
|
49
|
+
includedCategories.push('disabled-by-default-devtools.screenshot');
|
|
50
|
+
}
|
|
51
|
+
if (this.options.trace) {
|
|
52
|
+
includedCategories.push(
|
|
53
|
+
// Used instead of 'toplevel' in Chrome 71+
|
|
54
|
+
'disabled-by-default-lighthouse',
|
|
55
|
+
// Cumulative Layout Shift metric
|
|
56
|
+
'loading',
|
|
57
|
+
// UserTiming marks/measures
|
|
58
|
+
'blink.user_timing',
|
|
59
|
+
// Most of the events we need are from these two categories
|
|
60
|
+
// Includes FCP, LCP, Main thread frames, process, etc.
|
|
61
|
+
'devtools.timeline',
|
|
62
|
+
'disabled-by-default-devtools.timeline'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
await this.driver.client.send('Tracing.start', {
|
|
86
66
|
/**
|
|
87
67
|
* Using `ReportEvents` makes gathering trace events
|
|
88
68
|
* much faster as opposed to using `ReturnAsStream` mode
|
|
89
69
|
*/
|
|
90
70
|
transferMode: 'ReportEvents',
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
},
|
|
71
|
+
categories: includedCategories.join(','),
|
|
72
|
+
options: 'sampling-frequency=10000', // 1000 is default
|
|
94
73
|
});
|
|
95
74
|
}
|
|
96
75
|
|
|
97
|
-
async stop(
|
|
76
|
+
async stop() {
|
|
98
77
|
const events = [];
|
|
99
78
|
const collectListener = payload => events.push(...payload.value);
|
|
79
|
+
const { client } = this.driver;
|
|
100
80
|
client.on('Tracing.dataCollected', collectListener);
|
|
101
81
|
|
|
102
82
|
const [traceEvents] = await Promise.all([
|
|
@@ -108,6 +88,15 @@ export class Tracing {
|
|
|
108
88
|
),
|
|
109
89
|
client.send('Tracing.end'),
|
|
110
90
|
]);
|
|
111
|
-
|
|
91
|
+
const output: Partial<PluginOutput> = {};
|
|
92
|
+
if (this.options.filmstrips) {
|
|
93
|
+
output.filmstrips = Filmstrips.compute(traceEvents as Array<TraceEvent>);
|
|
94
|
+
}
|
|
95
|
+
if (this.options.trace) {
|
|
96
|
+
Object.assign(output, {
|
|
97
|
+
...TraceProcessor.computeTrace(traceEvents as Array<TraceEvent>),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return output;
|
|
112
101
|
}
|
|
113
102
|
}
|
package/src/reporters/base.ts
CHANGED
|
@@ -64,28 +64,19 @@ export default class BaseReporter {
|
|
|
64
64
|
|
|
65
65
|
constructor(public runner: Runner, options: ReporterOptions = {}) {
|
|
66
66
|
this.fd = options.fd || process.stdout.fd;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
/**
|
|
68
|
+
* minLength is set to 1 byte to make sure we flush the
|
|
69
|
+
* content even if its the last byte on the stream buffer
|
|
70
|
+
* before destroying the pipe with underlying file descriptor
|
|
71
|
+
*/
|
|
72
|
+
this.stream = new SonicBoom({ fd: this.fd, sync: true, minLength: 1 });
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
*/
|
|
79
|
-
setImmediate(() => this.stream.end());
|
|
80
|
-
} else {
|
|
81
|
-
/**
|
|
82
|
-
* If the user has passed a custom FD we don't close the FD, but we do flush it
|
|
83
|
-
* to give them more control. This is important because FDs should only be closed
|
|
84
|
-
* once, and the primary use case for custom FDs is being called by heartbeat, which
|
|
85
|
-
* closes the FD after the process exits
|
|
86
|
-
*/
|
|
87
|
-
this.stream.flush();
|
|
88
|
-
}
|
|
74
|
+
// flushSync is used here to make sure all the data from the underlying
|
|
75
|
+
// SonicBoom stream buffer is completely written to the fd before closing
|
|
76
|
+
// the process
|
|
77
|
+
this.runner.on('end', () => this.stream.flushSync());
|
|
78
|
+
|
|
79
|
+
this._registerListeners();
|
|
89
80
|
}
|
|
90
81
|
|
|
91
82
|
_registerListeners() {
|
|
@@ -108,16 +99,31 @@ export default class BaseReporter {
|
|
|
108
99
|
result[status]++;
|
|
109
100
|
});
|
|
110
101
|
|
|
102
|
+
this.runner.on('journey:end', ({ error }) => {
|
|
103
|
+
const { failed, succeeded, skipped } = result;
|
|
104
|
+
const total = failed + succeeded + skipped;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Render the error on the terminal only when no steps could
|
|
108
|
+
* be executed which means the error happened in one of the hooks
|
|
109
|
+
*/
|
|
110
|
+
if (total === 0 && error) {
|
|
111
|
+
this.write(renderError(error));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
111
115
|
this.runner.on('end', () => {
|
|
112
116
|
const { failed, succeeded, skipped } = result;
|
|
113
117
|
const total = failed + succeeded + skipped;
|
|
114
118
|
|
|
119
|
+
let message = '\n';
|
|
115
120
|
if (total === 0) {
|
|
116
|
-
|
|
121
|
+
message = 'No tests found!';
|
|
122
|
+
message += ` (${renderDuration(now())} ms) \n`;
|
|
123
|
+
this.write(message);
|
|
117
124
|
return;
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
let message = '\n';
|
|
121
127
|
message += succeeded > 0 ? green(` ${succeeded} passed`) : '';
|
|
122
128
|
message += failed > 0 ? red(` ${failed} failed`) : '';
|
|
123
129
|
message += skipped > 0 ? cyan(` ${skipped} skipped`) : '';
|