@elastic/synthetics 1.3.0 → 1.5.0
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/bundles/lib/index.js +432 -0
- package/dist/cli.js +23 -14
- package/dist/cli.js.map +1 -1
- package/dist/common_types.d.ts +51 -40
- package/dist/common_types.d.ts.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/core/browser-service.js +2 -2
- package/dist/core/browser-service.js.map +1 -1
- package/dist/core/expect.d.ts +1 -152
- package/dist/core/expect.d.ts.map +1 -1
- package/dist/core/expect.js +14 -5
- package/dist/core/expect.js.map +1 -1
- package/dist/core/gatherer.d.ts +1 -1
- package/dist/core/gatherer.d.ts.map +1 -1
- package/dist/core/gatherer.js +5 -5
- package/dist/core/gatherer.js.map +1 -1
- package/dist/core/runner.d.ts +4 -4
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +8 -7
- package/dist/core/runner.js.map +1 -1
- package/dist/core/transform.d.ts +62 -2
- package/dist/core/transform.d.ts.map +1 -1
- package/dist/dsl/journey.d.ts +5 -5
- package/dist/dsl/journey.d.ts.map +1 -1
- package/dist/dsl/journey.js +0 -1
- package/dist/dsl/journey.js.map +1 -1
- package/dist/dsl/monitor.d.ts +8 -3
- package/dist/dsl/monitor.d.ts.map +1 -1
- package/dist/dsl/monitor.js +1 -0
- package/dist/dsl/monitor.js.map +1 -1
- package/dist/formatter/javascript.d.ts +6 -6
- package/dist/formatter/javascript.d.ts.map +1 -1
- package/dist/generator/index.d.ts +1 -1
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +1 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/helpers.d.ts +1 -6
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +1 -24
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/locations/index.d.ts +13 -5
- package/dist/locations/index.d.ts.map +1 -1
- package/dist/locations/index.js +30 -14
- package/dist/locations/index.js.map +1 -1
- package/dist/options.d.ts +5 -2
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +20 -3
- package/dist/options.js.map +1 -1
- package/dist/plugins/browser-console.d.ts +3 -2
- package/dist/plugins/browser-console.d.ts.map +1 -1
- package/dist/plugins/browser-console.js +33 -7
- package/dist/plugins/browser-console.js.map +1 -1
- package/dist/plugins/network.d.ts +1 -0
- package/dist/plugins/network.d.ts.map +1 -1
- package/dist/plugins/network.js +15 -2
- package/dist/plugins/network.js.map +1 -1
- package/dist/plugins/plugin-manager.d.ts +3 -3
- package/dist/plugins/plugin-manager.d.ts.map +1 -1
- package/dist/plugins/tracing.d.ts +1 -1
- package/dist/plugins/tracing.d.ts.map +1 -1
- package/dist/push/index.d.ts +1 -1
- package/dist/push/index.d.ts.map +1 -1
- package/dist/push/index.js +7 -6
- package/dist/push/index.js.map +1 -1
- package/dist/push/kibana_api.d.ts +5 -5
- package/dist/push/kibana_api.d.ts.map +1 -1
- package/dist/push/kibana_api.js +1 -1
- package/dist/push/kibana_api.js.map +1 -1
- package/dist/push/monitor.d.ts +3 -3
- package/dist/push/monitor.d.ts.map +1 -1
- package/dist/push/monitor.js +22 -9
- package/dist/push/monitor.js.map +1 -1
- package/dist/push/request.d.ts +2 -2
- package/dist/push/request.d.ts.map +1 -1
- package/dist/push/utils.d.ts +3 -3
- package/dist/push/utils.d.ts.map +1 -1
- package/dist/push/utils.js +1 -1
- package/dist/push/utils.js.map +1 -1
- package/dist/reporters/base.d.ts +3 -0
- package/dist/reporters/base.d.ts.map +1 -1
- package/dist/reporters/base.js +20 -22
- package/dist/reporters/base.js.map +1 -1
- package/dist/reporters/index.d.ts +4 -3
- package/dist/reporters/index.d.ts.map +1 -1
- package/dist/reporters/index.js.map +1 -1
- package/dist/reporters/json.d.ts +5 -5
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +29 -1
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/junit.d.ts.map +1 -1
- package/dist/reporters/junit.js +4 -4
- package/dist/reporters/junit.js.map +1 -1
- package/dist/reporters/reporter-util.d.ts +35 -0
- package/dist/reporters/reporter-util.d.ts.map +1 -0
- package/dist/reporters/reporter-util.js +192 -0
- package/dist/reporters/reporter-util.js.map +1 -0
- package/dist/sdk/trace-processor.d.ts +4 -4
- package/dist/sdk/trace-processor.d.ts.map +1 -1
- package/package.json +20 -11
- package/src/cli.ts +23 -22
- package/src/common_types.ts +17 -3
- package/src/config.ts +12 -1
- package/src/core/browser-service.ts +1 -1
- package/src/core/expect.ts +13 -191
- package/src/core/gatherer.ts +1 -1
- package/src/core/runner.ts +15 -9
- package/src/dsl/journey.ts +1 -2
- package/src/dsl/monitor.ts +5 -0
- package/src/generator/index.ts +2 -1
- package/src/helpers.ts +0 -24
- package/src/index.ts +3 -1
- package/src/locations/index.ts +37 -12
- package/src/options.ts +28 -3
- package/src/plugins/browser-console.ts +39 -8
- package/src/plugins/network.ts +16 -3
- package/src/push/index.ts +9 -6
- package/src/push/kibana_api.ts +4 -3
- package/src/push/monitor.ts +26 -9
- package/src/push/utils.ts +3 -3
- package/src/reporters/base.ts +26 -33
- package/src/reporters/index.ts +5 -1
- package/src/reporters/json.ts +33 -3
- package/src/reporters/junit.ts +5 -5
- package/src/reporters/reporter-util.ts +217 -0
package/src/common_types.ts
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
ChromiumBrowserContext,
|
|
32
32
|
Page,
|
|
33
33
|
APIRequestContext,
|
|
34
|
-
} from 'playwright-
|
|
34
|
+
} from 'playwright-core';
|
|
35
35
|
import { Step } from './dsl';
|
|
36
36
|
import { BuiltInReporterName, ReporterInstance } from './reporters';
|
|
37
37
|
import { AlertConfig, MonitorConfig } from './dsl/monitor';
|
|
@@ -43,6 +43,10 @@ export type Location = {
|
|
|
43
43
|
column: number;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
export type StackFrame = Location & {
|
|
47
|
+
function?: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
46
50
|
export type Params = Record<string, any>;
|
|
47
51
|
export type HooksArgs = {
|
|
48
52
|
env: string;
|
|
@@ -213,7 +217,6 @@ type BaseArgs = {
|
|
|
213
217
|
schedule?: MonitorConfig['schedule'];
|
|
214
218
|
locations?: MonitorConfig['locations'];
|
|
215
219
|
privateLocations?: MonitorConfig['privateLocations'];
|
|
216
|
-
alert?: AlertConfig;
|
|
217
220
|
};
|
|
218
221
|
|
|
219
222
|
export type CliArgs = BaseArgs & {
|
|
@@ -223,6 +226,7 @@ export type CliArgs = BaseArgs & {
|
|
|
223
226
|
require?: Array<string>;
|
|
224
227
|
sandbox?: boolean;
|
|
225
228
|
richEvents?: boolean;
|
|
229
|
+
headless?: boolean;
|
|
226
230
|
capability?: Array<string>;
|
|
227
231
|
ignoreHttpsErrors?: boolean;
|
|
228
232
|
};
|
|
@@ -241,8 +245,10 @@ export type RunOptions = BaseArgs & {
|
|
|
241
245
|
export type PushOptions = Partial<ProjectSettings> &
|
|
242
246
|
Partial<BaseArgs> & {
|
|
243
247
|
auth: string;
|
|
244
|
-
kibanaVersion?:
|
|
248
|
+
kibanaVersion?: string;
|
|
245
249
|
yes?: boolean;
|
|
250
|
+
alert?: AlertConfig;
|
|
251
|
+
retestOnFailure?: MonitorConfig['retestOnFailure'];
|
|
246
252
|
};
|
|
247
253
|
|
|
248
254
|
export type ProjectSettings = {
|
|
@@ -273,6 +279,14 @@ export type JourneyResult = {
|
|
|
273
279
|
browserconsole?: PluginOutput['browserconsole'];
|
|
274
280
|
};
|
|
275
281
|
|
|
282
|
+
export type TestError = {
|
|
283
|
+
message: string;
|
|
284
|
+
stack?: string;
|
|
285
|
+
location?: Location;
|
|
286
|
+
// source location highlighting the error source
|
|
287
|
+
source?: string;
|
|
288
|
+
};
|
|
289
|
+
|
|
276
290
|
export type StepResult = {
|
|
277
291
|
status: StatusValue;
|
|
278
292
|
url?: string;
|
package/src/config.ts
CHANGED
|
@@ -27,7 +27,10 @@ import { isAbsolute, resolve, dirname } from 'path';
|
|
|
27
27
|
import { SyntheticsConfig } from './common_types';
|
|
28
28
|
import { isFile } from './helpers';
|
|
29
29
|
|
|
30
|
-
export function readConfig(
|
|
30
|
+
export async function readConfig(
|
|
31
|
+
env: string,
|
|
32
|
+
config?: string
|
|
33
|
+
): Promise<SyntheticsConfig> {
|
|
31
34
|
let options = {};
|
|
32
35
|
const cwd = process.cwd();
|
|
33
36
|
/**
|
|
@@ -47,6 +50,14 @@ export function readConfig(env: string, config?: string): SyntheticsConfig {
|
|
|
47
50
|
}
|
|
48
51
|
if (typeof options === 'function') {
|
|
49
52
|
options = options(env);
|
|
53
|
+
const optionsPromise = options as Promise<SyntheticsConfig>;
|
|
54
|
+
if (
|
|
55
|
+
optionsPromise != null &&
|
|
56
|
+
typeof optionsPromise.then === 'function' &&
|
|
57
|
+
typeof optionsPromise.catch === 'function'
|
|
58
|
+
) {
|
|
59
|
+
options = await optionsPromise;
|
|
60
|
+
}
|
|
50
61
|
}
|
|
51
62
|
return options;
|
|
52
63
|
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
import { URL } from 'url';
|
|
27
27
|
import { createServer } from 'http';
|
|
28
28
|
import { createProxyServer } from 'http-proxy';
|
|
29
|
-
import { chromium } from 'playwright-
|
|
29
|
+
import { chromium } from 'playwright-core';
|
|
30
30
|
import { log } from './logger';
|
|
31
31
|
|
|
32
32
|
export class BrowserService {
|
package/src/core/expect.ts
CHANGED
|
@@ -23,199 +23,21 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
AsymmetricMatcher,
|
|
29
|
-
MatcherState,
|
|
30
|
-
ExpectedAssertionsErrors,
|
|
31
|
-
Inverse,
|
|
32
|
-
PromiseMatchers,
|
|
33
|
-
} from 'expect/build/types';
|
|
26
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
27
|
+
const expectLib = require('../../dist/bundles/lib/index').expect;
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
assertions(arg0: number): void;
|
|
39
|
-
extend(arg0: any): void;
|
|
40
|
-
extractExpectedAssertionsErrors: () => ExpectedAssertionsErrors;
|
|
41
|
-
getState(): MatcherState;
|
|
42
|
-
hasAssertions(): void;
|
|
43
|
-
setState(state: Partial<MatcherState>): void;
|
|
44
|
-
any(expectedObject: any): AsymmetricMatcher;
|
|
45
|
-
anything(): AsymmetricMatcher;
|
|
46
|
-
arrayContaining(sample: Array<unknown>): AsymmetricMatcher;
|
|
47
|
-
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
|
|
48
|
-
stringContaining(expected: string): AsymmetricMatcher;
|
|
49
|
-
stringMatching(expected: string | RegExp): AsymmetricMatcher;
|
|
50
|
-
};
|
|
29
|
+
function notSupported(name: string) {
|
|
30
|
+
throw new Error(`expect.${name} is not supported in @elastic/synthetics.`);
|
|
31
|
+
}
|
|
51
32
|
|
|
52
33
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* impelemed via jest matchers
|
|
56
|
-
*
|
|
57
|
-
* We declare the types in global synthetics namespace which allows
|
|
58
|
-
* users to extend expect functionality without type errors
|
|
34
|
+
* Exclude toHaveScreenshot and toMatchSnapshot from our custom expect
|
|
35
|
+
* since they are expected to be running inside PW test runner for it to work properly.
|
|
59
36
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
* If you know how to test something, `.not` lets you test its opposite.
|
|
65
|
-
*/
|
|
66
|
-
not: Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
67
|
-
/**
|
|
68
|
-
* Use resolves to unwrap the value of a fulfilled promise so any other
|
|
69
|
-
* matcher can be chained. If the promise is rejected the assertion fails.
|
|
70
|
-
*/
|
|
71
|
-
resolves: Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
72
|
-
/**
|
|
73
|
-
* Unwraps the reason of a rejected promise so any other matcher can be chained.
|
|
74
|
-
* If the promise is fulfilled the assertion fails.
|
|
75
|
-
*/
|
|
76
|
-
rejects: Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
77
|
-
/**
|
|
78
|
-
* Checks that a value is what you expect. It uses `===` to check strict equality.
|
|
79
|
-
* Don't use `toBe` with floating-point numbers.
|
|
80
|
-
*/
|
|
81
|
-
toBe(
|
|
82
|
-
expected: unknown
|
|
83
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
84
|
-
/**
|
|
85
|
-
* Using exact equality with floating point numbers is a bad idea.
|
|
86
|
-
* Rounding means that intuitive things fail.
|
|
87
|
-
* The default for numDigits is 2.
|
|
88
|
-
*/
|
|
89
|
-
toBeCloseTo(
|
|
90
|
-
expected: number,
|
|
91
|
-
numDigits?: number
|
|
92
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
93
|
-
/**
|
|
94
|
-
* Ensure that a variable is not undefined.
|
|
95
|
-
*/
|
|
96
|
-
toBeDefined(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
97
|
-
/**
|
|
98
|
-
* When you don't care what a value is, you just want to
|
|
99
|
-
* ensure a value is false in a boolean context.
|
|
100
|
-
*/
|
|
101
|
-
toBeFalsy(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
102
|
-
/**
|
|
103
|
-
* For comparing floating point numbers.
|
|
104
|
-
*/
|
|
105
|
-
toBeGreaterThan(
|
|
106
|
-
expected: number | bigint
|
|
107
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
108
|
-
/**
|
|
109
|
-
* For comparing floating point numbers.
|
|
110
|
-
*/
|
|
111
|
-
toBeGreaterThanOrEqual(
|
|
112
|
-
expected: number | bigint
|
|
113
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
114
|
-
/**
|
|
115
|
-
* Ensure that an object is an instance of a class.
|
|
116
|
-
* This matcher uses `instanceof` underneath.
|
|
117
|
-
*/
|
|
118
|
-
/* eslint-disable-next-line */
|
|
119
|
-
toBeInstanceOf(
|
|
120
|
-
expected: unknown
|
|
121
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
122
|
-
/**
|
|
123
|
-
* For comparing floating point numbers.
|
|
124
|
-
*/
|
|
125
|
-
toBeLessThan(
|
|
126
|
-
expected: number | bigint
|
|
127
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
128
|
-
/**
|
|
129
|
-
* For comparing floating point numbers.
|
|
130
|
-
*/
|
|
131
|
-
toBeLessThanOrEqual(
|
|
132
|
-
expected: number | bigint
|
|
133
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
134
|
-
/**
|
|
135
|
-
* This is the same as `.toBe(null)` but the error messages are a bit nicer.
|
|
136
|
-
* So use `.toBeNull()` when you want to check that something is null.
|
|
137
|
-
*/
|
|
138
|
-
toBeNull(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
139
|
-
/**
|
|
140
|
-
* Use when you don't care what a value is, you just want to ensure a value
|
|
141
|
-
* is true in a boolean context. In JavaScript, there are six falsy values:
|
|
142
|
-
* `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy.
|
|
143
|
-
*/
|
|
144
|
-
toBeTruthy(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
145
|
-
/**
|
|
146
|
-
* Used to check that a variable is undefined.
|
|
147
|
-
*/
|
|
148
|
-
toBeUndefined(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
149
|
-
/**
|
|
150
|
-
* Used to check that a variable is NaN.
|
|
151
|
-
*/
|
|
152
|
-
toBeNaN(): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
153
|
-
/**
|
|
154
|
-
* Used when you want to check that an item is in a list.
|
|
155
|
-
* For testing the items in the list, this uses `===`, a strict equality check.
|
|
156
|
-
*/
|
|
157
|
-
toContain(
|
|
158
|
-
expected: unknown
|
|
159
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
160
|
-
/**
|
|
161
|
-
* Used when you want to check that an item is in a list.
|
|
162
|
-
* For testing the items in the list, this matcher recursively checks the
|
|
163
|
-
* equality of all fields, rather than checking for object identity.
|
|
164
|
-
*/
|
|
165
|
-
toContainEqual(
|
|
166
|
-
expected: unknown
|
|
167
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
168
|
-
/**
|
|
169
|
-
* Used when you want to check that two objects have the same value.
|
|
170
|
-
* This matcher recursively checks the equality of all fields, rather than checking for object identity.
|
|
171
|
-
*/
|
|
172
|
-
toEqual(
|
|
173
|
-
expected: unknown
|
|
174
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
175
|
-
/**
|
|
176
|
-
* Used to check that an object has a `.length` property
|
|
177
|
-
* and it is set to a certain numeric value.
|
|
178
|
-
*/
|
|
179
|
-
toHaveLength(
|
|
180
|
-
expected: number
|
|
181
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
182
|
-
/**
|
|
183
|
-
* Use to check if property at provided reference keyPath exists for an object.
|
|
184
|
-
* For checking deeply nested properties in an object you may use dot notation or an array containing
|
|
185
|
-
* the keyPath for deep references.
|
|
186
|
-
*
|
|
187
|
-
* Optionally, you can provide a value to check if it's equal to the value present at keyPath
|
|
188
|
-
* on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks
|
|
189
|
-
* the equality of all fields.
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
*
|
|
193
|
-
* expect(houseForSale).toHaveProperty('kitchen.area', 20);
|
|
194
|
-
*/
|
|
195
|
-
toHaveProperty(
|
|
196
|
-
keyPath: string | Array<string>,
|
|
197
|
-
value?: unknown
|
|
198
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
199
|
-
/**
|
|
200
|
-
* Check that a string matches a regular expression.
|
|
201
|
-
*/
|
|
202
|
-
toMatch(
|
|
203
|
-
expected: string | RegExp
|
|
204
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
205
|
-
/**
|
|
206
|
-
* Used to check that a JavaScript object matches a subset of the properties of an object
|
|
207
|
-
*/
|
|
208
|
-
toMatchObject(
|
|
209
|
-
expected: Record<string, unknown> | Array<unknown>
|
|
210
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
211
|
-
/**
|
|
212
|
-
* Use to test that objects have the same types as well as structure.
|
|
213
|
-
*/
|
|
214
|
-
toStrictEqual(
|
|
215
|
-
expected: unknown
|
|
216
|
-
): Matchers<R> & Inverse<Matchers<R>> & PromiseMatchers;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
37
|
+
expectLib.extend({
|
|
38
|
+
toHaveScreenshot: () => notSupported('toHaveScreenshot'),
|
|
39
|
+
toMatchSnapshot: () => notSupported('toMatchSnapshot'),
|
|
40
|
+
});
|
|
220
41
|
|
|
221
|
-
export const expect:
|
|
42
|
+
export const expect: typeof import('../../bundles/node_modules/playwright/types/test').expect =
|
|
43
|
+
expectLib;
|
package/src/core/gatherer.ts
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
BrowserContext,
|
|
30
30
|
request as apiRequest,
|
|
31
31
|
selectors,
|
|
32
|
-
} from 'playwright-
|
|
32
|
+
} from 'playwright-core';
|
|
33
33
|
import { PluginManager } from '../plugins';
|
|
34
34
|
import { log } from './logger';
|
|
35
35
|
import { Driver, NetworkConditions, RunOptions } from '../common_types';
|
package/src/core/runner.ts
CHANGED
|
@@ -46,8 +46,11 @@ import {
|
|
|
46
46
|
StepResult,
|
|
47
47
|
PushOptions,
|
|
48
48
|
} from '../common_types';
|
|
49
|
-
import {
|
|
50
|
-
|
|
49
|
+
import {
|
|
50
|
+
PluginManager,
|
|
51
|
+
PerformanceManager,
|
|
52
|
+
filterBrowserMessages,
|
|
53
|
+
} from '../plugins';
|
|
51
54
|
import { Gatherer } from './gatherer';
|
|
52
55
|
import { log } from './logger';
|
|
53
56
|
import { Monitor, MonitorConfig } from '../dsl/monitor';
|
|
@@ -149,12 +152,12 @@ export default class Runner {
|
|
|
149
152
|
* Set up the corresponding reporter and fallback
|
|
150
153
|
* to default reporter if not provided
|
|
151
154
|
*/
|
|
152
|
-
const { reporter, outfd } = options;
|
|
155
|
+
const { reporter, outfd, dryRun } = options;
|
|
153
156
|
const Reporter =
|
|
154
157
|
typeof reporter === 'function'
|
|
155
158
|
? reporter
|
|
156
159
|
: reporters[reporter] || reporters['default'];
|
|
157
|
-
this.#reporter = new Reporter({ fd: outfd });
|
|
160
|
+
this.#reporter = new Reporter({ fd: outfd, dryRun });
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
async runBeforeAllHook(args: HooksArgs) {
|
|
@@ -209,8 +212,9 @@ export default class Runner {
|
|
|
209
212
|
*/
|
|
210
213
|
pluginManager.onStep(step);
|
|
211
214
|
traceEnabled && (await pluginManager.start('trace'));
|
|
212
|
-
//
|
|
213
|
-
|
|
215
|
+
// invoke the step callback by extracting to a variable to get better stack trace
|
|
216
|
+
const cb = step.callback;
|
|
217
|
+
await cb();
|
|
214
218
|
} catch (error) {
|
|
215
219
|
data.status = 'failed';
|
|
216
220
|
data.error = error;
|
|
@@ -288,8 +292,7 @@ export default class Runner {
|
|
|
288
292
|
params,
|
|
289
293
|
});
|
|
290
294
|
/**
|
|
291
|
-
* Exeucute the journey callback which
|
|
292
|
-
* register the steps for the current journey
|
|
295
|
+
* Exeucute the journey callback which registers the steps for current journey
|
|
293
296
|
*/
|
|
294
297
|
journey.callback({ ...context.driver, params });
|
|
295
298
|
}
|
|
@@ -310,7 +313,10 @@ export default class Runner {
|
|
|
310
313
|
timestamp: getTimestamp(),
|
|
311
314
|
options,
|
|
312
315
|
...pluginOutput,
|
|
313
|
-
browserconsole:
|
|
316
|
+
browserconsole: filterBrowserMessages(
|
|
317
|
+
pluginOutput.browserconsole,
|
|
318
|
+
status
|
|
319
|
+
),
|
|
314
320
|
});
|
|
315
321
|
// clear screenshots cache after each journey
|
|
316
322
|
await rm(Runner.screenshotPath, { recursive: true, force: true });
|
package/src/dsl/journey.ts
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
BrowserContext,
|
|
30
30
|
CDPSession,
|
|
31
31
|
APIRequestContext,
|
|
32
|
-
} from 'playwright-
|
|
32
|
+
} from 'playwright-core';
|
|
33
33
|
import { Step } from './step';
|
|
34
34
|
import { VoidCallback, HooksCallback, Params, Location } from '../common_types';
|
|
35
35
|
import { Monitor, MonitorConfig } from './monitor';
|
|
@@ -97,7 +97,6 @@ export class Journey {
|
|
|
97
97
|
...config,
|
|
98
98
|
});
|
|
99
99
|
this.monitor.setSource(this.location);
|
|
100
|
-
this.monitor.setContent(this.callback.toString());
|
|
101
100
|
this.monitor.setFilter({ match: this.name });
|
|
102
101
|
}
|
|
103
102
|
|
package/src/dsl/monitor.ts
CHANGED
|
@@ -72,6 +72,10 @@ export type MonitorConfig = {
|
|
|
72
72
|
params?: Params;
|
|
73
73
|
playwrightOptions?: PlaywrightOptions;
|
|
74
74
|
alert?: AlertConfig;
|
|
75
|
+
/**
|
|
76
|
+
* By default, the monitor will be retested on failure
|
|
77
|
+
*/
|
|
78
|
+
retestOnFailure?: boolean;
|
|
75
79
|
};
|
|
76
80
|
|
|
77
81
|
type MonitorFilter = {
|
|
@@ -109,6 +113,7 @@ export class Monitor {
|
|
|
109
113
|
|
|
110
114
|
/**
|
|
111
115
|
* The underlying journey code of the monitor
|
|
116
|
+
* along with its dependencies
|
|
112
117
|
*/
|
|
113
118
|
setContent(content = '') {
|
|
114
119
|
this.content = content;
|
package/src/generator/index.ts
CHANGED
|
@@ -112,7 +112,8 @@ export class Generator {
|
|
|
112
112
|
}).run();
|
|
113
113
|
|
|
114
114
|
const allLocations = await getLocations({ url, auth });
|
|
115
|
-
const locChoices = formatLocations(allLocations);
|
|
115
|
+
const { allLocations: locChoices } = formatLocations(allLocations);
|
|
116
|
+
|
|
116
117
|
if (locChoices.length === 0) {
|
|
117
118
|
throw 'Follow the docs to set up your first private locations - https://www.elastic.co/guide/en/observability/current/uptime-set-up-choose-agent.html#private-locations';
|
|
118
119
|
}
|
package/src/helpers.ts
CHANGED
|
@@ -234,30 +234,6 @@ export function rewriteErrorStack(stack: string, indexes: [number, number]) {
|
|
|
234
234
|
return stack;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
// formatError prefers receiving proper Errors, but since at runtime
|
|
238
|
-
// non Error exceptions can be thrown, it tolerates though. The
|
|
239
|
-
// redundant type Error | any expresses that.
|
|
240
|
-
export function formatError(error: Error | any) {
|
|
241
|
-
if (error === undefined || error === null) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (!(error instanceof Error)) {
|
|
246
|
-
return {
|
|
247
|
-
message: `Error "${error}" received, with type "${typeof error}". (Do not throw exceptions without using \`new Error("my message")\`)`,
|
|
248
|
-
name: '',
|
|
249
|
-
stack: '',
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
const { name, message, stack } = error;
|
|
253
|
-
const indexes = findPWLogsIndexes(message);
|
|
254
|
-
return {
|
|
255
|
-
name,
|
|
256
|
-
message: rewriteErrorMessage(message, indexes[0]),
|
|
257
|
-
stack: rewriteErrorStack(stack, indexes),
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
|
|
261
237
|
const cwd = process.cwd();
|
|
262
238
|
/**
|
|
263
239
|
* All the settings that are related to the Synthetics is stored
|
package/src/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ export {
|
|
|
43
43
|
after,
|
|
44
44
|
} from './core';
|
|
45
45
|
export { expect } from './core/expect';
|
|
46
|
+
|
|
46
47
|
/**
|
|
47
48
|
* Export all the driver related types to be consumed
|
|
48
49
|
* and used by suites
|
|
@@ -53,7 +54,8 @@ export type {
|
|
|
53
54
|
ChromiumBrowserContext,
|
|
54
55
|
CDPSession,
|
|
55
56
|
APIRequestContext,
|
|
56
|
-
|
|
57
|
+
devices,
|
|
58
|
+
} from 'playwright-core';
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
61
|
* Export the types necessary to write custom reporters
|
package/src/locations/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type LocationAPIResponse = {
|
|
|
42
42
|
locations: Array<LocationMetadata>;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
const PRIVATE_KEYWORD = '(private)';
|
|
45
|
+
export const PRIVATE_KEYWORD = '(private)';
|
|
46
46
|
|
|
47
47
|
export async function getLocations(options: LocationCmdOptions) {
|
|
48
48
|
const resp = await sendReqAndHandleError<LocationAPIResponse>({
|
|
@@ -54,25 +54,33 @@ export async function getLocations(options: LocationCmdOptions) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export function formatLocations(locations: Array<LocationMetadata>) {
|
|
57
|
-
const
|
|
57
|
+
const publicLocations: Array<string> = [];
|
|
58
|
+
const privateLocations: Array<string> = [];
|
|
58
59
|
for (const location of locations) {
|
|
59
60
|
let name = location.label;
|
|
60
61
|
if (location.isServiceManaged) {
|
|
61
62
|
[, name] = name.includes('-') ? name.split('-') : [, name];
|
|
62
63
|
name = name.toLowerCase().trim().split(' ').join('_');
|
|
64
|
+
publicLocations.push(name);
|
|
63
65
|
} else {
|
|
64
|
-
name
|
|
66
|
+
privateLocations.push(name);
|
|
65
67
|
}
|
|
66
|
-
formatted.push(name);
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
publicLocations,
|
|
72
|
+
privateLocations,
|
|
73
|
+
allLocations: publicLocations.concat(
|
|
74
|
+
privateLocations.map(loc => `${loc} ${PRIVATE_KEYWORD}`)
|
|
75
|
+
),
|
|
76
|
+
};
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
export function groupLocations(locations: Array<string>) {
|
|
72
80
|
const grouped = { locations: [], privateLocations: [] };
|
|
73
81
|
for (const loc of locations) {
|
|
74
82
|
if (loc.includes(PRIVATE_KEYWORD)) {
|
|
75
|
-
grouped.privateLocations.push(loc.replace(PRIVATE_KEYWORD, ''));
|
|
83
|
+
grouped.privateLocations.push(loc.replace(PRIVATE_KEYWORD, '').trim());
|
|
76
84
|
} else {
|
|
77
85
|
grouped.locations.push(loc);
|
|
78
86
|
}
|
|
@@ -80,13 +88,30 @@ export function groupLocations(locations: Array<string>) {
|
|
|
80
88
|
return grouped;
|
|
81
89
|
}
|
|
82
90
|
|
|
83
|
-
export function renderLocations(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
export function renderLocations({
|
|
92
|
+
publicLocations,
|
|
93
|
+
privateLocations = [],
|
|
94
|
+
}: {
|
|
95
|
+
privateLocations?: Array<string>;
|
|
96
|
+
publicLocations: Array<string>;
|
|
97
|
+
}) {
|
|
98
|
+
let outer = '';
|
|
99
|
+
if (publicLocations.length) {
|
|
100
|
+
outer = 'Public locations: \n';
|
|
101
|
+
let inner = '';
|
|
102
|
+
for (const location of publicLocations) {
|
|
103
|
+
inner += `* ${location}\n`;
|
|
104
|
+
}
|
|
105
|
+
outer += indent(inner);
|
|
106
|
+
}
|
|
107
|
+
if (privateLocations.length > 0) {
|
|
108
|
+
outer += '\nPrivate locations: \n';
|
|
109
|
+
let privateInner = '';
|
|
110
|
+
for (const location of privateLocations) {
|
|
111
|
+
privateInner += `* ${location}\n`;
|
|
112
|
+
}
|
|
113
|
+
outer += indent(privateInner);
|
|
88
114
|
}
|
|
89
|
-
outer += indent(inner);
|
|
90
115
|
outer += `\nSet default location for monitors via
|
|
91
116
|
- Synthetics config file 'monitors.locations' | 'monitors.privateLocations' field
|
|
92
117
|
- Monitor API 'monitor.use({ locations: ["japan"], privateLocations: ["custom-location"] }')`;
|
package/src/options.ts
CHANGED
|
@@ -31,10 +31,10 @@ import { THROTTLING_WARNING_MSG, error, warn } from './helpers';
|
|
|
31
31
|
|
|
32
32
|
type Mode = 'run' | 'push';
|
|
33
33
|
|
|
34
|
-
export function normalizeOptions(
|
|
34
|
+
export async function normalizeOptions(
|
|
35
35
|
cliArgs: CliArgs,
|
|
36
36
|
mode: Mode = 'run'
|
|
37
|
-
): RunOptions {
|
|
37
|
+
): Promise<RunOptions> {
|
|
38
38
|
const options: RunOptions = {
|
|
39
39
|
...cliArgs,
|
|
40
40
|
environment: process.env['NODE_ENV'] || 'development',
|
|
@@ -85,7 +85,7 @@ export function normalizeOptions(
|
|
|
85
85
|
*/
|
|
86
86
|
const config =
|
|
87
87
|
cliArgs.config || !cliArgs.inline
|
|
88
|
-
? readConfig(options.environment, cliArgs.config)
|
|
88
|
+
? await readConfig(options.environment, cliArgs.config)
|
|
89
89
|
: {};
|
|
90
90
|
|
|
91
91
|
/**
|
|
@@ -106,6 +106,7 @@ export function normalizeOptions(
|
|
|
106
106
|
);
|
|
107
107
|
options.playwrightOptions = {
|
|
108
108
|
...playwrightOpts,
|
|
109
|
+
headless: getHeadlessFlag(cliArgs.headless, playwrightOpts?.headless),
|
|
109
110
|
chromiumSandbox: cliArgs.sandbox ?? playwrightOpts?.chromiumSandbox,
|
|
110
111
|
ignoreHTTPSErrors:
|
|
111
112
|
cliArgs.ignoreHttpsErrors ?? playwrightOpts?.ignoreHTTPSErrors,
|
|
@@ -139,6 +140,18 @@ export function normalizeOptions(
|
|
|
139
140
|
return options;
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
export function getHeadlessFlag(
|
|
144
|
+
cliHeadless: boolean,
|
|
145
|
+
configHeadless?: boolean
|
|
146
|
+
) {
|
|
147
|
+
// if cliHeadless is false, then we don't care about configHeadless
|
|
148
|
+
if (!cliHeadless) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// default is headless
|
|
152
|
+
return configHeadless ?? true;
|
|
153
|
+
}
|
|
154
|
+
|
|
142
155
|
export function validatePushOptions(opts: PushOptions) {
|
|
143
156
|
if (opts.tags || opts.match) {
|
|
144
157
|
throw error(`Aborted. Invalid CLI flags.
|
|
@@ -185,7 +198,19 @@ export function getCommonCommandOpts() {
|
|
|
185
198
|
'RegExp pattern to match journey/monitor files that are different from the default (ex: /*.journey.(ts|js)$/)'
|
|
186
199
|
);
|
|
187
200
|
|
|
201
|
+
const apiDocsLink =
|
|
202
|
+
'API key used for Kibana authentication(https://www.elastic.co/guide/en/kibana/master/api-keys.html).';
|
|
203
|
+
const auth = createOption('--auth <auth>', apiDocsLink).env(
|
|
204
|
+
'SYNTHETICS_API_KEY'
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const authMandatory = createOption('--auth <auth>', apiDocsLink)
|
|
208
|
+
.env('SYNTHETICS_API_KEY')
|
|
209
|
+
.makeOptionMandatory(true);
|
|
210
|
+
|
|
188
211
|
return {
|
|
212
|
+
auth,
|
|
213
|
+
authMandatory,
|
|
189
214
|
params,
|
|
190
215
|
playwrightOpts,
|
|
191
216
|
pattern,
|