@elastic/synthetics 1.14.0 → 1.16.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.
Files changed (87) hide show
  1. package/dist/cli.js +23 -4
  2. package/dist/cli.js.map +1 -1
  3. package/dist/common_types.d.ts +9 -16
  4. package/dist/common_types.d.ts.map +1 -1
  5. package/dist/core/gatherer.d.ts +3 -1
  6. package/dist/core/gatherer.d.ts.map +1 -1
  7. package/dist/core/gatherer.js +42 -35
  8. package/dist/core/gatherer.js.map +1 -1
  9. package/dist/core/globals.d.ts +27 -0
  10. package/dist/core/globals.d.ts.map +1 -0
  11. package/dist/core/globals.js +41 -0
  12. package/dist/core/globals.js.map +1 -0
  13. package/dist/core/index.d.ts +0 -2
  14. package/dist/core/index.d.ts.map +1 -1
  15. package/dist/core/index.js +13 -25
  16. package/dist/core/index.js.map +1 -1
  17. package/dist/core/mfa.d.ts +4 -0
  18. package/dist/core/mfa.d.ts.map +1 -1
  19. package/dist/core/mfa.js.map +1 -1
  20. package/dist/core/runner.d.ts +30 -39
  21. package/dist/core/runner.d.ts.map +1 -1
  22. package/dist/core/runner.js +174 -179
  23. package/dist/core/runner.js.map +1 -1
  24. package/dist/dsl/journey.d.ts +24 -16
  25. package/dist/dsl/journey.d.ts.map +1 -1
  26. package/dist/dsl/journey.js +28 -15
  27. package/dist/dsl/journey.js.map +1 -1
  28. package/dist/dsl/monitor.d.ts +1 -0
  29. package/dist/dsl/monitor.d.ts.map +1 -1
  30. package/dist/dsl/monitor.js.map +1 -1
  31. package/dist/dsl/step.d.ts +12 -6
  32. package/dist/dsl/step.d.ts.map +1 -1
  33. package/dist/dsl/step.js +11 -3
  34. package/dist/dsl/step.js.map +1 -1
  35. package/dist/helpers.d.ts +1 -0
  36. package/dist/helpers.d.ts.map +1 -1
  37. package/dist/helpers.js +1 -0
  38. package/dist/helpers.js.map +1 -1
  39. package/dist/index.js +10 -10
  40. package/dist/index.js.map +1 -1
  41. package/dist/options.d.ts +1 -0
  42. package/dist/options.d.ts.map +1 -1
  43. package/dist/options.js +18 -0
  44. package/dist/options.js.map +1 -1
  45. package/dist/push/index.d.ts.map +1 -1
  46. package/dist/push/index.js +1 -1
  47. package/dist/push/index.js.map +1 -1
  48. package/dist/push/monitor.d.ts +1 -0
  49. package/dist/push/monitor.d.ts.map +1 -1
  50. package/dist/push/monitor.js +18 -1
  51. package/dist/push/monitor.js.map +1 -1
  52. package/dist/reporters/base.d.ts +3 -3
  53. package/dist/reporters/base.d.ts.map +1 -1
  54. package/dist/reporters/base.js +6 -6
  55. package/dist/reporters/base.js.map +1 -1
  56. package/dist/reporters/build_kite_cli.d.ts +2 -4
  57. package/dist/reporters/build_kite_cli.d.ts.map +1 -1
  58. package/dist/reporters/build_kite_cli.js +8 -10
  59. package/dist/reporters/build_kite_cli.js.map +1 -1
  60. package/dist/reporters/json.d.ts +4 -9
  61. package/dist/reporters/json.d.ts.map +1 -1
  62. package/dist/reporters/json.js +31 -40
  63. package/dist/reporters/json.js.map +1 -1
  64. package/dist/reporters/junit.d.ts +2 -2
  65. package/dist/reporters/junit.d.ts.map +1 -1
  66. package/dist/reporters/junit.js +7 -7
  67. package/dist/reporters/junit.js.map +1 -1
  68. package/package.json +2 -2
  69. package/src/cli.ts +24 -5
  70. package/src/common_types.ts +9 -16
  71. package/src/core/gatherer.ts +44 -37
  72. package/src/core/globals.ts +37 -0
  73. package/src/core/index.ts +12 -25
  74. package/src/core/mfa.ts +5 -0
  75. package/src/core/runner.ts +201 -202
  76. package/src/dsl/journey.ts +42 -23
  77. package/src/dsl/monitor.ts +1 -0
  78. package/src/dsl/step.ts +16 -7
  79. package/src/helpers.ts +4 -3
  80. package/src/index.ts +2 -2
  81. package/src/options.ts +22 -0
  82. package/src/push/index.ts +3 -4
  83. package/src/push/monitor.ts +20 -0
  84. package/src/reporters/base.ts +8 -12
  85. package/src/reporters/build_kite_cli.ts +13 -18
  86. package/src/reporters/json.ts +35 -52
  87. package/src/reporters/junit.ts +8 -10
package/src/cli.ts CHANGED
@@ -27,6 +27,8 @@
27
27
 
28
28
  import { program, Option } from 'commander';
29
29
  import { cwd } from 'process';
30
+ import { bold } from 'kleur/colors';
31
+ import { resolve } from 'path';
30
32
  import { CliArgs, PushOptions } from './common_types';
31
33
  import { reporters } from './reporters';
32
34
  import {
@@ -36,7 +38,7 @@ import {
36
38
  } from './options';
37
39
  import { globalSetup } from './loader';
38
40
  import { run } from './';
39
- import { runner } from './core';
41
+ import { runner } from './core/globals';
40
42
  import { SyntheticsLocations } from './dsl/monitor';
41
43
  import { push, loadSettings, validatePush, warnIfThrottled } from './push';
42
44
  import {
@@ -45,13 +47,13 @@ import {
45
47
  renderLocations,
46
48
  LocationCmdOptions,
47
49
  } from './locations';
48
- import { resolve } from 'path';
49
50
  import { Generator } from './generator';
50
- import { error } from './helpers';
51
+ import { error, write } from './helpers';
51
52
  import { LocationsMap } from './locations/public-locations';
52
53
  import { createLightweightMonitors } from './push/monitor';
53
54
  import { getVersion } from './push/kibana_api';
54
55
  import { installTransform } from './core/transform';
56
+ import { totp, TOTPCmdOptions } from './core/mfa';
55
57
 
56
58
  /* eslint-disable-next-line @typescript-eslint/no-var-requires */
57
59
  const { name, version } = require('../package.json');
@@ -65,6 +67,7 @@ const {
65
67
  configOpt,
66
68
  tags,
67
69
  match,
70
+ fields,
68
71
  } = getCommonCommandOpts();
69
72
 
70
73
  program
@@ -191,9 +194,9 @@ program
191
194
  'the target Kibana spaces for the pushed monitors — spaces help you organise pushed monitors.'
192
195
  )
193
196
  .option('-y, --yes', 'skip all questions and run non-interactively')
194
-
195
197
  .addOption(pattern)
196
198
  .addOption(tags)
199
+ .addOption(fields)
197
200
  .addOption(match)
198
201
  .addOption(params)
199
202
  .addOption(playwrightOpts)
@@ -214,7 +217,7 @@ program
214
217
  'push'
215
218
  )) as PushOptions;
216
219
  await validatePush(options, settings);
217
- const monitors = runner.buildMonitors(options);
220
+ const monitors = runner._buildMonitors(options);
218
221
  if ((options as CliArgs).throttling == null) {
219
222
  warnIfThrottled(monitors);
220
223
  }
@@ -272,4 +275,20 @@ program
272
275
  }
273
276
  });
274
277
 
278
+ // TOTP command
279
+ program
280
+ .command('totp <secret>')
281
+ .description('Generate a Time-based One-Time token using the provided secret.')
282
+ .option('--issuer <issuer>', 'Provider or Service the secret is associated with.')
283
+ .option('--label <label>', 'Account Identifier (default: SyntheticsTOTP)')
284
+ .action((secret, cmdOpts: TOTPCmdOptions) => {
285
+ try {
286
+ const token = totp(secret, cmdOpts)
287
+ write(bold(`OTP Token: ${token}`));
288
+ } catch (e) {
289
+ error(e);
290
+ process.exit(1);
291
+ }
292
+ });
293
+
275
294
  program.parse(process.argv);
@@ -32,9 +32,10 @@ import {
32
32
  Page,
33
33
  APIRequestContext,
34
34
  } from 'playwright-core';
35
- import { Step } from './dsl';
35
+ import { Journey, Step } from './dsl';
36
36
  import { BuiltInReporterName, ReporterInstance } from './reporters';
37
37
  import { AlertConfig, MonitorConfig } from './dsl/monitor';
38
+ import { RunnerInfo } from './core/runner';
38
39
 
39
40
  export type VoidCallback = () => void;
40
41
  export type Location = {
@@ -51,9 +52,10 @@ export type Params = Record<string, any>;
51
52
  export type HooksArgs = {
52
53
  env: string;
53
54
  params: Params;
55
+ info: RunnerInfo;
54
56
  };
55
57
  export type HooksCallback = (args: HooksArgs) => void;
56
- export type StatusValue = 'succeeded' | 'failed' | 'skipped';
58
+ export type StatusValue = 'pending' | 'succeeded' | 'failed' | 'skipped';
57
59
 
58
60
  export type NetworkConditions = {
59
61
  offline: boolean;
@@ -221,6 +223,7 @@ type BaseArgs = {
221
223
  schedule?: MonitorConfig['schedule'];
222
224
  locations?: MonitorConfig['locations'];
223
225
  privateLocations?: MonitorConfig['privateLocations'];
226
+ fields?: MonitorConfig['fields'];
224
227
  };
225
228
 
226
229
  export type CliArgs = BaseArgs & {
@@ -255,6 +258,7 @@ export type PushOptions = Partial<ProjectSettings> &
255
258
  kibanaVersion?: string;
256
259
  yes?: boolean;
257
260
  tags?: Array<string>;
261
+ fields?: MonitorConfig['fields'];
258
262
  alert?: AlertConfig;
259
263
  retestOnFailure?: MonitorConfig['retestOnFailure'];
260
264
  enabled?: boolean;
@@ -282,12 +286,10 @@ export type SyntheticsConfig = {
282
286
  };
283
287
 
284
288
  /** Runner Payload types */
285
- export type JourneyResult = {
286
- status: StatusValue;
287
- error?: Error;
289
+ export type JourneyResult = Partial<Journey> & {
288
290
  networkinfo?: PluginOutput['networkinfo'];
289
291
  browserconsole?: PluginOutput['browserconsole'];
290
- steps?: Array<StepResult>;
292
+ stepsresults?: Array<StepResult>;
291
293
  };
292
294
 
293
295
  export type TestError = {
@@ -299,9 +301,6 @@ export type TestError = {
299
301
  };
300
302
 
301
303
  export type StepResult = {
302
- status: StatusValue;
303
- url?: string;
304
- error?: Error;
305
304
  pagemetrics?: PageMetrics;
306
305
  filmstrips?: PluginOutput['filmstrips'];
307
306
  metrics?: PluginOutput['metrics'];
@@ -321,14 +320,8 @@ export type JourneyStartResult = {
321
320
 
322
321
  export type JourneyEndResult = JourneyStartResult &
323
322
  JourneyResult & {
324
- start: number;
325
- end: number;
326
323
  browserDelay: number;
327
324
  options: RunOptions;
328
- timestamp: number;
329
325
  };
330
326
 
331
- export type StepEndResult = StepResult & {
332
- start: number;
333
- end: number;
334
- };
327
+ export type StepEndResult = StepResult
@@ -43,25 +43,37 @@ const DEFAULT_TIMEOUT = 50000;
43
43
  */
44
44
  export class Gatherer {
45
45
  static browser: ChromiumBrowser;
46
+ static pluginManager: PluginManager;
46
47
 
47
- static async setupDriver(options: RunOptions): Promise<Driver> {
48
- log('Gatherer: setup driver');
49
- const { wsEndpoint, playwrightOptions } = options;
48
+ static async launchBrowser(options: RunOptions) {
49
+ if (Gatherer.browser != null) {
50
+ return;
51
+ }
50
52
 
51
- if (Gatherer.browser == null) {
52
- if (wsEndpoint) {
53
- log(`Gatherer: connecting to WS endpoint: ${wsEndpoint}`);
54
- Gatherer.browser = await chromium.connect(wsEndpoint);
55
- } else {
56
- Gatherer.browser = await chromium.launch({
57
- ...playwrightOptions,
58
- args: [
59
- ...(playwrightOptions?.headless ? ['--disable-gpu'] : []),
60
- ...(playwrightOptions?.args ?? []),
61
- ],
62
- });
63
- }
53
+ log('Gatherer: setup browser');
54
+ const { wsEndpoint, playwrightOptions } = options;
55
+ if (wsEndpoint) {
56
+ log(`Gatherer: connecting to WS endpoint: ${wsEndpoint}`);
57
+ Gatherer.browser = await chromium.connect(wsEndpoint);
58
+ } else {
59
+ Gatherer.browser = await chromium.launch({
60
+ ...playwrightOptions,
61
+ args: [
62
+ ...(playwrightOptions?.headless ? ['--disable-gpu'] : []),
63
+ ...(playwrightOptions?.args ?? []),
64
+ ],
65
+ });
64
66
  }
67
+ // Register sig int handler to close the browser
68
+ process.on('SIGINT', async () => {
69
+ await Gatherer.stop();
70
+ process.exit(130);
71
+ });
72
+ }
73
+
74
+ static async setupDriver(options: RunOptions): Promise<Driver> {
75
+ await Gatherer.launchBrowser(options);
76
+ const { playwrightOptions } = options;
65
77
  const context = await Gatherer.browser.newContext({
66
78
  ...playwrightOptions,
67
79
  userAgent: await Gatherer.getUserAgent(playwrightOptions?.userAgent),
@@ -84,12 +96,6 @@ export class Gatherer {
84
96
  const page = await context.newPage();
85
97
  const client = await context.newCDPSession(page);
86
98
  const request = await apiRequest.newContext({ ...playwrightOptions });
87
-
88
- // Register sig int handler to close the browser
89
- process.on('SIGINT', async () => {
90
- await Gatherer.closeBrowser();
91
- process.exit(130);
92
- });
93
99
  return { browser: Gatherer.browser, context, page, client, request };
94
100
  }
95
101
 
@@ -126,14 +132,6 @@ export class Gatherer {
126
132
  }
127
133
  }
128
134
 
129
- static async closeBrowser() {
130
- log(`Gatherer: closing browser`);
131
- if (Gatherer.browser) {
132
- await Gatherer.browser.close();
133
- Gatherer.browser = null;
134
- }
135
- }
136
-
137
135
  /**
138
136
  * Starts recording all events related to the v8 devtools protocol
139
137
  * https://chromedevtools.github.io/devtools-protocol/v8/
@@ -141,13 +139,18 @@ export class Gatherer {
141
139
  static async beginRecording(driver: Driver, options: RunOptions) {
142
140
  log('Gatherer: started recording');
143
141
  const { network, metrics } = options;
144
- const pluginManager = new PluginManager(driver);
145
- pluginManager.registerAll(options);
146
- const plugins = [await pluginManager.start('browserconsole')];
147
- network && plugins.push(await pluginManager.start('network'));
148
- metrics && plugins.push(await pluginManager.start('performance'));
142
+ Gatherer.pluginManager = new PluginManager(driver);
143
+ Gatherer.pluginManager.registerAll(options);
144
+ const plugins = [await Gatherer.pluginManager.start('browserconsole')];
145
+ network && plugins.push(await Gatherer.pluginManager.start('network'));
146
+ metrics && plugins.push(await Gatherer.pluginManager.start('performance'));
149
147
  await Promise.all(plugins);
150
- return pluginManager;
148
+ return Gatherer.pluginManager;
149
+ }
150
+
151
+ static async endRecording() {
152
+ log('Gatherer: ended recording');
153
+ await Gatherer.pluginManager.unregisterAll();
151
154
  }
152
155
 
153
156
  static async dispose(driver: Driver) {
@@ -157,6 +160,10 @@ export class Gatherer {
157
160
  }
158
161
 
159
162
  static async stop() {
160
- await Gatherer.closeBrowser();
163
+ log(`Gatherer: closing browser`);
164
+ if (Gatherer.browser) {
165
+ await Gatherer.browser.close();
166
+ Gatherer.browser = null;
167
+ }
161
168
  }
162
169
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * MIT License
3
+ *
4
+ * Copyright (c) 2020-present, Elastic NV
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ */
25
+
26
+ import Runner from './runner';
27
+
28
+ /**
29
+ * Use a gloabl Runner which would be accessed by the runtime and
30
+ * required to handle the local vs global invocation through CLI
31
+ */
32
+ const SYNTHETICS_RUNNER = Symbol.for('SYNTHETICS_RUNNER');
33
+ if (!global[SYNTHETICS_RUNNER]) {
34
+ global[SYNTHETICS_RUNNER] = new Runner();
35
+ }
36
+
37
+ export const runner: Runner = global[SYNTHETICS_RUNNER];
package/src/core/index.ts CHANGED
@@ -30,23 +30,12 @@ import {
30
30
  JourneyWithAnnotations,
31
31
  StepWithAnnotations,
32
32
  } from '../dsl';
33
- import Runner from './runner';
33
+ import { runner } from "./globals"
34
34
  import { VoidCallback, HooksCallback, Location } from '../common_types';
35
35
  import { wrapFnWithLocation } from '../helpers';
36
36
  import { log } from './logger';
37
37
  import { MonitorConfig } from '../dsl/monitor';
38
38
 
39
- /**
40
- * Use a gloabl Runner which would be accessed by the runtime and
41
- * required to handle the local vs global invocation through CLI
42
- */
43
- const SYNTHETICS_RUNNER = Symbol.for('SYNTHETICS_RUNNER');
44
- if (!global[SYNTHETICS_RUNNER]) {
45
- global[SYNTHETICS_RUNNER] = new Runner();
46
- }
47
-
48
- export const runner: Runner = global[SYNTHETICS_RUNNER];
49
-
50
39
  const createJourney = (type?: 'skip' | 'only') =>
51
40
  wrapFnWithLocation(
52
41
  (
@@ -59,12 +48,10 @@ const createJourney = (type?: 'skip' | 'only') =>
59
48
  options = { name: options, id: options };
60
49
  }
61
50
  const j = new Journey(options, callback, location);
62
-
63
51
  if (type) {
64
52
  j[type] = true;
65
53
  }
66
-
67
- runner.addJourney(j);
54
+ runner._addJourney(j);
68
55
  return j;
69
56
  }
70
57
  );
@@ -77,7 +64,7 @@ const createStep = (type?: 'skip' | 'soft' | 'only') =>
77
64
  wrapFnWithLocation(
78
65
  (location: Location, name: string, callback: VoidCallback) => {
79
66
  log(`Step register: ${name}`);
80
- const step = runner.currentJourney?.addStep(name, callback, location);
67
+ const step = runner.journey?._addStep(name, callback, location);
81
68
  if (type) {
82
69
  step[type] = true;
83
70
  }
@@ -96,32 +83,32 @@ export const monitor = {
96
83
  * If the context is inside journey, then set it to journey context
97
84
  * otherwise set to the global monitor which will be used for all journeys
98
85
  */
99
- if (runner.currentJourney) {
100
- runner.currentJourney.updateMonitor(config);
86
+ if (runner.journey) {
87
+ runner.journey._updateMonitor(config);
101
88
  } else {
102
- runner.updateMonitor(config);
89
+ runner._updateMonitor(config);
103
90
  }
104
91
  }),
105
92
  };
106
93
 
107
94
  export const beforeAll = (callback: HooksCallback) => {
108
- runner.addHook('beforeAll', callback);
95
+ runner._addHook('beforeAll', callback);
109
96
  };
110
97
 
111
98
  export const afterAll = (callback: HooksCallback) => {
112
- runner.addHook('afterAll', callback);
99
+ runner._addHook('afterAll', callback);
113
100
  };
114
101
 
115
102
  export const before = (callback: HooksCallback) => {
116
- if (!runner.currentJourney) {
103
+ if (!runner.journey) {
117
104
  throw new Error('before is called outside of the journey context');
118
105
  }
119
- return runner.currentJourney.addHook('before', callback);
106
+ return runner.journey._addHook('before', callback);
120
107
  };
121
108
 
122
109
  export const after = (callback: HooksCallback) => {
123
- if (!runner.currentJourney) {
110
+ if (!runner.journey) {
124
111
  throw new Error('after is called outside of the journey context');
125
112
  }
126
- return runner.currentJourney.addHook('after', callback);
113
+ return runner.journey._addHook('after', callback);
127
114
  };
package/src/core/mfa.ts CHANGED
@@ -60,6 +60,11 @@ type TOTPOptions = {
60
60
  period?: number
61
61
  };
62
62
 
63
+ export type TOTPCmdOptions = {
64
+ issuer?: string
65
+ label?: string
66
+ };
67
+
63
68
  export function totp(secret?: string, options: TOTPOptions = {}) {
64
69
  return new TOTP({ label: "SyntheticsTOTP", secret, ...options }).generate();
65
70
  }