@elastic/synthetics 1.0.0-beta.2 → 1.0.0-beta.20
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 +228 -0
- package/NOTICE.txt +250 -0
- package/README.md +2 -1
- package/dist/cli.js +80 -49
- package/dist/cli.js.map +1 -1
- package/dist/common_types.d.ts +77 -10
- 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.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 +33 -9
- 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 +1 -1
- 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 +2 -15
- 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 +173 -63
- 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 +100 -46
- 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 +26 -7
- package/dist/plugins/browser-console.js.map +1 -1
- package/dist/plugins/network.d.ts +20 -20
- package/dist/plugins/network.d.ts.map +1 -1
- package/dist/plugins/network.js +110 -108
- 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 +22 -23
- package/dist/reporters/base.js.map +1 -1
- package/dist/reporters/json.d.ts +43 -7
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +181 -35
- package/dist/reporters/json.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 +24 -13
- package/src/cli.ts +68 -45
- package/src/common_types.ts +92 -10
- package/src/config.ts +2 -5
- package/src/core/expect.ts +187 -0
- package/src/core/gatherer.ts +44 -23
- 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 +137 -144
- 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 +24 -23
- package/src/reporters/json.ts +251 -41
- 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,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,14 @@ export default class BaseReporter {
|
|
|
64
64
|
|
|
65
65
|
constructor(public runner: Runner, options: ReporterOptions = {}) {
|
|
66
66
|
this.fd = options.fd || process.stdout.fd;
|
|
67
|
-
|
|
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 });
|
|
68
73
|
this._registerListeners();
|
|
69
|
-
this.runner.on('end', () => this.
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
close() {
|
|
73
|
-
if (this.fd <= 2) {
|
|
74
|
-
/**
|
|
75
|
-
* For stdout/stderr we destroy stream once data is written and run
|
|
76
|
-
* it as the last listener giving enough room for
|
|
77
|
-
* other reporters to write to stream
|
|
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
|
+
this.runner.on('end', () => this.stream.flush());
|
|
89
75
|
}
|
|
90
76
|
|
|
91
77
|
_registerListeners() {
|
|
@@ -108,16 +94,31 @@ export default class BaseReporter {
|
|
|
108
94
|
result[status]++;
|
|
109
95
|
});
|
|
110
96
|
|
|
97
|
+
this.runner.on('journey:end', ({ error }) => {
|
|
98
|
+
const { failed, succeeded, skipped } = result;
|
|
99
|
+
const total = failed + succeeded + skipped;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Render the error on the terminal only when no steps could
|
|
103
|
+
* be executed which means the error happened in one of the hooks
|
|
104
|
+
*/
|
|
105
|
+
if (total === 0 && error) {
|
|
106
|
+
this.write(renderError(error));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
111
110
|
this.runner.on('end', () => {
|
|
112
111
|
const { failed, succeeded, skipped } = result;
|
|
113
112
|
const total = failed + succeeded + skipped;
|
|
114
113
|
|
|
114
|
+
let message = '\n';
|
|
115
115
|
if (total === 0) {
|
|
116
|
-
|
|
116
|
+
message = 'No tests found!';
|
|
117
|
+
message += ` (${renderDuration(now())} ms) \n`;
|
|
118
|
+
this.write(message);
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
let message = '\n';
|
|
121
122
|
message += succeeded > 0 ? green(` ${succeeded} passed`) : '';
|
|
122
123
|
message += failed > 0 ? red(` ${failed} failed`) : '';
|
|
123
124
|
message += skipped > 0 ? cyan(` ${skipped} skipped`) : '';
|