@elastic/synthetics 1.17.1 → 1.18.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 (90) hide show
  1. package/dist/cli.js.map +1 -1
  2. package/dist/common_types.d.ts.map +1 -1
  3. package/dist/core/globals.d.ts +1 -0
  4. package/dist/core/globals.d.ts.map +1 -1
  5. package/dist/core/globals.js +12 -1
  6. package/dist/core/globals.js.map +1 -1
  7. package/dist/core/index.d.ts +1 -0
  8. package/dist/core/index.d.ts.map +1 -1
  9. package/dist/core/index.js +13 -12
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/logger.d.ts.map +1 -1
  12. package/dist/core/logger.js +2 -7
  13. package/dist/core/logger.js.map +1 -1
  14. package/dist/core/mfa.d.ts.map +1 -1
  15. package/dist/core/mfa.js +1 -1
  16. package/dist/core/runner.d.ts +40 -0
  17. package/dist/core/runner.d.ts.map +1 -1
  18. package/dist/core/runner.js +71 -6
  19. package/dist/core/runner.js.map +1 -1
  20. package/dist/dsl/journey.d.ts +35 -0
  21. package/dist/dsl/journey.d.ts.map +1 -1
  22. package/dist/dsl/journey.js +49 -0
  23. package/dist/dsl/journey.js.map +1 -1
  24. package/dist/dsl/monitor.d.ts +4 -0
  25. package/dist/dsl/monitor.d.ts.map +1 -1
  26. package/dist/dsl/monitor.js +6 -0
  27. package/dist/dsl/monitor.js.map +1 -1
  28. package/dist/dsl/step.d.ts +5 -0
  29. package/dist/dsl/step.d.ts.map +1 -1
  30. package/dist/dsl/step.js +7 -0
  31. package/dist/dsl/step.js.map +1 -1
  32. package/dist/formatter/javascript.d.ts.map +1 -1
  33. package/dist/formatter/javascript.js.map +1 -1
  34. package/dist/generator/utils.d.ts +1 -1
  35. package/dist/helpers.d.ts.map +1 -1
  36. package/dist/helpers.js.map +1 -1
  37. package/dist/plugins/tracing.js.map +1 -1
  38. package/dist/push/bundler.d.ts +2 -5
  39. package/dist/push/bundler.d.ts.map +1 -1
  40. package/dist/push/bundler.js +15 -30
  41. package/dist/push/bundler.js.map +1 -1
  42. package/dist/push/index.d.ts.map +1 -1
  43. package/dist/push/index.js +21 -6
  44. package/dist/push/index.js.map +1 -1
  45. package/dist/push/monitor.d.ts +4 -1
  46. package/dist/push/monitor.d.ts.map +1 -1
  47. package/dist/push/monitor.js +13 -1
  48. package/dist/push/monitor.js.map +1 -1
  49. package/dist/push/run-local.d.ts +27 -0
  50. package/dist/push/run-local.d.ts.map +1 -0
  51. package/dist/push/run-local.js +132 -0
  52. package/dist/push/run-local.js.map +1 -0
  53. package/dist/push/utils.d.ts +2 -0
  54. package/dist/push/utils.d.ts.map +1 -1
  55. package/dist/push/utils.js +33 -1
  56. package/dist/push/utils.js.map +1 -1
  57. package/dist/reporters/base.d.ts.map +1 -1
  58. package/dist/reporters/base.js.map +1 -1
  59. package/dist/reporters/build_kite_cli.d.ts.map +1 -1
  60. package/dist/reporters/build_kite_cli.js.map +1 -1
  61. package/dist/reporters/json.d.ts +1 -1
  62. package/dist/reporters/json.d.ts.map +1 -1
  63. package/dist/reporters/json.js +6 -2
  64. package/dist/reporters/json.js.map +1 -1
  65. package/dist/reporters/junit.d.ts.map +1 -1
  66. package/dist/reporters/junit.js.map +1 -1
  67. package/package.json +8 -5
  68. package/src/cli.ts +8 -3
  69. package/src/common_types.ts +1 -1
  70. package/src/core/globals.ts +12 -0
  71. package/src/core/index.ts +3 -1
  72. package/src/core/logger.ts +2 -8
  73. package/src/core/mfa.ts +11 -11
  74. package/src/core/runner.ts +102 -33
  75. package/src/dsl/journey.ts +63 -1
  76. package/src/dsl/monitor.ts +7 -0
  77. package/src/dsl/step.ts +8 -0
  78. package/src/formatter/javascript.ts +3 -1
  79. package/src/helpers.ts +3 -3
  80. package/src/loader.ts +1 -1
  81. package/src/plugins/tracing.ts +1 -1
  82. package/src/push/bundler.ts +16 -36
  83. package/src/push/index.ts +28 -10
  84. package/src/push/monitor.ts +16 -4
  85. package/src/push/run-local.ts +155 -0
  86. package/src/push/utils.ts +51 -5
  87. package/src/reporters/base.ts +8 -4
  88. package/src/reporters/build_kite_cli.ts +7 -6
  89. package/src/reporters/json.ts +10 -14
  90. package/src/reporters/junit.ts +4 -10
package/src/push/index.ts CHANGED
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import { readFile, writeFile } from 'fs/promises';
26
26
  import { prompt } from 'enquirer';
27
- import { bold, grey } from 'kleur/colors';
27
+ import { bold, underline } from 'kleur/colors';
28
28
  import {
29
29
  getLocalMonitors,
30
30
  buildMonitorSchema,
@@ -57,8 +57,11 @@ import {
57
57
  isBulkAPISupported,
58
58
  isLightweightMonitorSupported,
59
59
  logDiff,
60
+ logGroups,
61
+ printBytes,
60
62
  } from './utils';
61
- import { log } from '../core/logger';
63
+ import { runLocal } from './run-local';
64
+ import { inDebugMode } from '../core/globals';
62
65
 
63
66
  export async function push(monitors: Monitor[], options: PushOptions) {
64
67
  if (parseInt(process.env.CHUNK_SIZE) > 250) {
@@ -84,7 +87,7 @@ export async function push(monitors: Monitor[], options: PushOptions) {
84
87
  const { monitors: remote } = await bulkGetMonitors(options);
85
88
 
86
89
  progress(`preparing ${monitors.length} monitors`);
87
- const schemas = await buildMonitorSchema(monitors, true);
90
+ const { schemas, sizes } = await buildMonitorSchema(monitors, true);
88
91
  const local = getLocalMonitors(schemas);
89
92
 
90
93
  const { newIDs, changedIDs, removedIDs, unchangedIDs } = diffMonitorHashIDs(
@@ -92,6 +95,22 @@ export async function push(monitors: Monitor[], options: PushOptions) {
92
95
  remote
93
96
  );
94
97
  logDiff(newIDs, changedIDs, removedIDs, unchangedIDs);
98
+ if (inDebugMode()) {
99
+ logGroups(sizes, newIDs, changedIDs, removedIDs, unchangedIDs);
100
+ // show bundle size for the whole project
101
+ let totalSize = 0;
102
+ for (const value of sizes.values()) {
103
+ totalSize += value;
104
+ }
105
+ progress('total size of the monitors payload is ' + printBytes(totalSize));
106
+ }
107
+
108
+ if (options.dryRun) {
109
+ progress('Running browser monitors in dry run mode');
110
+ await runLocal(schemas);
111
+ progress('Dry run completed');
112
+ return;
113
+ }
95
114
 
96
115
  const updatedMonitors = new Set<string>([...changedIDs, ...newIDs]);
97
116
  if (updatedMonitors.size > 0) {
@@ -106,7 +125,6 @@ export async function push(monitors: Monitor[], options: PushOptions) {
106
125
  }
107
126
 
108
127
  if (removedIDs.size > 0) {
109
- log(`deleting monitor ids: ${Array.from(removedIDs.keys()).join(', ')}`);
110
128
  if (updatedMonitors.size === 0 && unchangedIDs.size === 0) {
111
129
  await confirmDelete(
112
130
  `Pushing without any monitors will delete all monitors associated with the project.\n Do you want to continue?`,
@@ -126,8 +144,7 @@ export async function push(monitors: Monitor[], options: PushOptions) {
126
144
  );
127
145
  }
128
146
  }
129
-
130
- done(`Pushed: ${grey(getMonitorManagementURL(options.url))}`);
147
+ done(`Pushed: ${underline(getMonitorManagementURL(options.url))} `);
131
148
  }
132
149
 
133
150
  async function confirmDelete(message: string, skip: boolean) {
@@ -223,8 +240,9 @@ export function validateSettings(opts: PushOptions) {
223
240
  - CLI '--schedule <mins>'
224
241
  - Config file 'monitors.schedule' field`;
225
242
  } else if (opts.schedule && !ALLOWED_SCHEDULES.includes(opts.schedule)) {
226
- reason = `Set default schedule(${opts.schedule
227
- }) to one of the allowed values - ${ALLOWED_SCHEDULES.join(',')}`;
243
+ reason = `Set default schedule(${
244
+ opts.schedule
245
+ }) to one of the allowed values - ${ALLOWED_SCHEDULES.join(',')}`;
228
246
  } else if (
229
247
  (opts.locations ?? []).length > 0 &&
230
248
  (opts?.playwrightOptions?.clientCertificates ?? []).filter(cert => {
@@ -301,7 +319,7 @@ export async function pushLegacy(monitors: Monitor[], options: PushOptions) {
301
319
  let schemas: MonitorSchema[] = [];
302
320
  if (monitors.length > 0) {
303
321
  progress(`preparing ${monitors.length} monitors`);
304
- schemas = await buildMonitorSchema(monitors, false);
322
+ ({ schemas } = await buildMonitorSchema(monitors, false));
305
323
  const chunks = getChunks(schemas, 10);
306
324
  for (const chunk of chunks) {
307
325
  await liveProgress(
@@ -320,7 +338,7 @@ export async function pushLegacy(monitors: Monitor[], options: PushOptions) {
320
338
  `deleting all stale monitors`
321
339
  );
322
340
 
323
- done(`Pushed: ${grey(getMonitorManagementURL(options.url))}`);
341
+ done(`Pushed: ${underline(getMonitorManagementURL(options.url))}`);
324
342
  }
325
343
 
326
344
  // prints warning if any of the monitors has throttling settings enabled during push
@@ -42,6 +42,8 @@ import { isParamOptionSupported, normalizeMonitorName } from './utils';
42
42
 
43
43
  // Allowed extensions for lightweight monitor files
44
44
  const ALLOWED_LW_EXTENSIONS = ['.yml', '.yaml'];
45
+ // 1500kB Max Gzipped limit for bundled monitor code to be pushed as Kibana project monitors.
46
+ const SIZE_LIMIT_KB = 1500;
45
47
 
46
48
  export type MonitorSchema = Omit<MonitorConfig, 'locations'> & {
47
49
  locations: string[];
@@ -131,6 +133,7 @@ export async function buildMonitorSchema(monitors: Monitor[], isV2: boolean) {
131
133
  await mkdir(bundlePath, { recursive: true });
132
134
  const bundler = new Bundler();
133
135
  const schemas: MonitorSchema[] = [];
136
+ const sizes: Map<string, number> = new Map();
134
137
 
135
138
  for (const monitor of monitors) {
136
139
  const { source, config, filter, type } = monitor;
@@ -148,6 +151,17 @@ export async function buildMonitorSchema(monitors: Monitor[], isV2: boolean) {
148
151
  monitor.setContent(content);
149
152
  Object.assign(schema, { content, filter });
150
153
  }
154
+ const size = monitor.size();
155
+ const sizeKB = Math.round(size / 1000);
156
+ if (sizeKB > SIZE_LIMIT_KB) {
157
+ let outer = bold(
158
+ `Aborted: Bundled code ${sizeKB}kB exceeds the recommended ${SIZE_LIMIT_KB}kB limit. Please check the dependencies imported.\n`
159
+ );
160
+ const inner = `* ${config.id} - ${source.file}:${source.line}:${source.column}\n`;
161
+ outer += indent(inner);
162
+ throw red(outer);
163
+ }
164
+ sizes.set(config.id, size);
151
165
  /**
152
166
  * Generate hash only after the bundled content is created
153
167
  * to capture code changes in imported files
@@ -159,7 +173,7 @@ export async function buildMonitorSchema(monitors: Monitor[], isV2: boolean) {
159
173
  }
160
174
 
161
175
  await rm(bundlePath, { recursive: true });
162
- return schemas;
176
+ return { schemas, sizes };
163
177
  }
164
178
 
165
179
  export async function createLightweightMonitors(
@@ -225,9 +239,7 @@ export async function createLightweightMonitors(
225
239
  const monitor = mergedConfig[i];
226
240
  // Skip browser monitors from the YML files
227
241
  if (monitor['type'] === 'browser') {
228
- warn(
229
- `Browser monitors from ${file} are skipped.`
230
- );
242
+ warn(`Browser monitors from ${file} are skipped.`);
231
243
  continue;
232
244
  }
233
245
  const { line, col } = lineCounter.linePos(offsets[i]);
@@ -0,0 +1,155 @@
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 { execFileSync, spawn } from 'child_process';
27
+ import { rm, writeFile } from 'fs/promises';
28
+ import { createReadStream } from 'fs';
29
+ import { tmpdir } from 'os';
30
+ import { Extract } from 'unzip-stream';
31
+ import { red } from 'kleur/colors';
32
+ import { join } from 'path';
33
+ import { pathToFileURL } from 'url';
34
+ import { MonitorSchema } from './monitor';
35
+
36
+ async function unzipFile(zipPath, destination) {
37
+ return new Promise<void>((resolve, reject) => {
38
+ createReadStream(zipPath)
39
+ .pipe(Extract({ path: destination }))
40
+ .on('close', resolve)
41
+ .on('error', err =>
42
+ reject(new Error(`failed to extract zip ${zipPath} : ${err.message}`))
43
+ );
44
+ });
45
+ }
46
+
47
+ async function runNpmInstall(directory) {
48
+ return new Promise<void>((resolve, reject) => {
49
+ const flags = [
50
+ '--no-audit', // Prevent audit checks
51
+ '--no-update-notifier', // Prevent update checks
52
+ '--no-fund', // No need for package funding messages here
53
+ '--package-lock=false', // no need to write package lock here
54
+ '--progress=false', // no need to display progress
55
+ ];
56
+
57
+ const npmInstall = spawn('npm', ['install', ...flags], {
58
+ cwd: directory,
59
+ stdio: 'ignore',
60
+ });
61
+ npmInstall.on('close', code => {
62
+ if (code === 0) {
63
+ resolve();
64
+ } else {
65
+ reject(new Error(`npm install failed with exit code ${code}`));
66
+ }
67
+ });
68
+ npmInstall.on('error', err =>
69
+ reject(new Error(`failed to setup: ${err.message}`))
70
+ );
71
+ });
72
+ }
73
+
74
+ async function runTest(directory, schema: MonitorSchema) {
75
+ return new Promise<void>((resolve, reject) => {
76
+ const runTest = spawn(
77
+ 'npx',
78
+ [
79
+ '@elastic/synthetics',
80
+ '.',
81
+ '--playwright-options',
82
+ JSON.stringify(schema.playwrightOptions),
83
+ '--params',
84
+ JSON.stringify(schema.params),
85
+ ],
86
+ {
87
+ cwd: directory,
88
+ stdio: 'inherit',
89
+ }
90
+ );
91
+
92
+ runTest.on('close', resolve);
93
+ runTest.on('error', err => {
94
+ reject(
95
+ new Error(`Failed to execute @elastic/synthetics : ${err.message}`)
96
+ );
97
+ });
98
+ });
99
+ }
100
+
101
+ async function writePkgJSON(dir: string, synthPath: string) {
102
+ const packageJsonContent = {
103
+ name: 'project-journey',
104
+ private: 'true',
105
+ dependencies: {
106
+ '@elastic/synthetics': pathToFileURL(synthPath),
107
+ },
108
+ };
109
+ await writeFile(
110
+ join(dir, 'package.json'),
111
+ JSON.stringify(packageJsonContent, null, 2),
112
+ 'utf-8'
113
+ );
114
+ }
115
+
116
+ async function extract(
117
+ schema: MonitorSchema,
118
+ zipPath: string,
119
+ unzipPath: string
120
+ ) {
121
+ if (schema.type !== 'browser') {
122
+ return;
123
+ }
124
+ const content = schema.content;
125
+ await writeFile(zipPath, content, 'base64');
126
+ await unzipFile(zipPath, unzipPath);
127
+ }
128
+
129
+ export async function runLocal(schemas: MonitorSchema[]) {
130
+ // lookup installed bin path of a node module
131
+ const resolvedPath = execFileSync('which', ['elastic-synthetics'], {
132
+ encoding: 'utf8',
133
+ }).trim();
134
+ const synthPath = resolvedPath.replace(
135
+ join('bin', 'elastic-synthetics'),
136
+ join('lib', 'node_modules', '@elastic/synthetics')
137
+ );
138
+ const rand = Date.now();
139
+ const zipPath = join(tmpdir(), `synthetics-zip-${rand}.zip`);
140
+ const unzipPath = join(tmpdir(), `synthetics-unzip-${rand}`);
141
+ try {
142
+ for (const schema of schemas) {
143
+ await extract(schema, zipPath, unzipPath);
144
+ }
145
+ await writePkgJSON(unzipPath, synthPath);
146
+ await runNpmInstall(unzipPath);
147
+ // TODO: figure out a way to collect all params and Playwright options
148
+ await runTest(unzipPath, schemas[0]);
149
+ } catch (e) {
150
+ throw red(`Aborted: ${e.message}`);
151
+ } finally {
152
+ await rm(zipPath, { recursive: true, force: true });
153
+ await rm(unzipPath, { recursive: true, force: true });
154
+ }
155
+ }
package/src/push/utils.ts CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  import semver from 'semver';
27
27
  import { progress, removeTrailingSlash } from '../helpers';
28
- import { green, red, grey, yellow } from 'kleur/colors';
28
+ import { green, red, grey, yellow, Colorize, bold } from 'kleur/colors';
29
29
  import { PushOptions } from '../common_types';
30
30
  import { Monitor } from '../dsl/monitor';
31
31
 
@@ -37,13 +37,59 @@ export function logDiff<T extends Set<string>>(
37
37
  ) {
38
38
  progress(
39
39
  'Monitor Diff: ' +
40
- green(`Added(${newIDs.size}) `) +
41
- yellow(`Updated(${changedIDs.size}) `) +
42
- red(`Removed(${removedIDs.size}) `) +
43
- grey(`Unchanged(${unchangedIDs.size})`)
40
+ green(`Added(${newIDs.size}) `) +
41
+ yellow(`Updated(${changedIDs.size}) `) +
42
+ red(`Removed(${removedIDs.size}) `) +
43
+ grey(`Unchanged(${unchangedIDs.size})`)
44
44
  );
45
45
  }
46
46
 
47
+ export function logGroups<T extends Set<string>>(
48
+ sizes: Map<string, number>,
49
+ newIDs: T,
50
+ changedIDs: T,
51
+ removedIDs: T,
52
+ unchangedIDs: T
53
+ ) {
54
+ console.groupCollapsed();
55
+ logGroup(sizes, 'Added', newIDs, green);
56
+ logGroup(sizes, 'Updated', changedIDs, yellow);
57
+ logGroup(sizes, 'Removed', removedIDs, red);
58
+ logGroup(sizes, 'Unchanged', unchangedIDs, grey);
59
+ console.groupEnd();
60
+ }
61
+
62
+ function logGroup(
63
+ sizes: Map<string, number>,
64
+ name: string,
65
+ ids: Set<string>,
66
+ color: Colorize
67
+ ) {
68
+ if (ids.size === 0) return;
69
+ // under collapsed group, so giving 2 space for padding
70
+ printLine(process.stdout.columns - 2);
71
+ console.groupCollapsed(color(bold(name)));
72
+ [...ids].forEach(id => {
73
+ console.log(grey(`- ${id} (${printBytes(sizes.get(id))})`));
74
+ });
75
+ console.groupEnd();
76
+ }
77
+
78
+ function printLine(length: number = process.stdout.columns) {
79
+ console.log(grey('-').repeat(length));
80
+ }
81
+
82
+ const BYTE_UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB'];
83
+ export function printBytes(bytes: number) {
84
+ if (bytes <= 0) return '0 B';
85
+ const exponent = Math.min(
86
+ Math.floor(Math.log10(bytes) / 3),
87
+ BYTE_UNITS.length - 1
88
+ );
89
+ bytes /= 1000 ** exponent;
90
+ return `${bytes.toFixed(1)} ${BYTE_UNITS[exponent]}`;
91
+ }
92
+
47
93
  export function getChunks<T>(arr: Array<T>, size: number): Array<T[]> {
48
94
  const chunks = [];
49
95
  for (let i = 0; i < arr.length; i += size) {
@@ -29,7 +29,11 @@ import { renderError, serializeError } from './reporter-util';
29
29
  import { symbols, indent, now } from '../helpers';
30
30
  import { Reporter, ReporterOptions } from '.';
31
31
  import { Journey, Step } from '../dsl';
32
- import { JourneyEndResult, JourneyStartResult, StepResult } from '../common_types';
32
+ import {
33
+ JourneyEndResult,
34
+ JourneyStartResult,
35
+ StepResult,
36
+ } from '../common_types';
33
37
 
34
38
  export function renderDuration(durationMs) {
35
39
  return parseInt(durationMs);
@@ -62,11 +66,11 @@ export default class BaseReporter implements Reporter {
62
66
  this.metrics.registered++;
63
67
  }
64
68
 
65
- onJourneyStart(journey: Journey, { }: JourneyStartResult) {
69
+ onJourneyStart(journey: Journey, {}: JourneyStartResult) {
66
70
  this.write(`\nJourney: ${journey.name}`);
67
71
  }
68
72
 
69
- onStepEnd(_: Journey, step: Step, { }: StepResult) {
73
+ onStepEnd(_: Journey, step: Step, {}: StepResult) {
70
74
  const { status, error } = step;
71
75
  const message = `${symbols[status]} Step: '${step.name}' ${status} ${gray(
72
76
  '(' + renderDuration(step.duration * 1000) + ' ms)'
@@ -80,7 +84,7 @@ export default class BaseReporter implements Reporter {
80
84
  }
81
85
 
82
86
  /* eslint-disable @typescript-eslint/no-unused-vars */
83
- onJourneyEnd(journey: Journey, { }: JourneyEndResult) {
87
+ onJourneyEnd(journey: Journey, {}: JourneyEndResult) {
84
88
  const { failed, succeeded, skipped } = this.metrics;
85
89
  const total = failed + succeeded + skipped;
86
90
  /**
@@ -43,7 +43,7 @@ export default class BuildKiteCLIReporter extends BaseReporter {
43
43
  super(options);
44
44
  }
45
45
 
46
- override onJourneyStart(journey: Journey, { }: JourneyStartResult) {
46
+ override onJourneyStart(journey: Journey, {}: JourneyStartResult) {
47
47
  this.write(`\n--- Journey: ${journey.name}`);
48
48
  }
49
49
 
@@ -57,7 +57,9 @@ export default class BuildKiteCLIReporter extends BaseReporter {
57
57
 
58
58
  override async onJourneyEnd(journey: Journey, result: JourneyEndResult) {
59
59
  super.onJourneyEnd(journey, result);
60
- const message = `${symbols[journey.status]} Took (${renderDuration(journey.duration)} seconds)`;
60
+ const message = `${symbols[journey.status]} Took (${renderDuration(
61
+ journey.duration
62
+ )} seconds)`;
61
63
  this.write(message);
62
64
  }
63
65
 
@@ -76,10 +78,9 @@ export default class BuildKiteCLIReporter extends BaseReporter {
76
78
  const name = red(`Journey: ${journeyName} :slightly_frowning_face:`);
77
79
  this.write(`\n+++ ${name}`);
78
80
  steps.forEach(step => {
79
- const message = `${symbols[step.status]
80
- } Step: '${step.name}' ${step.status} (${renderDuration(
81
- step.duration * 1000
82
- )} ms)`;
81
+ const message = `${symbols[step.status]} Step: '${step.name}' ${
82
+ step.status
83
+ } (${renderDuration(step.duration * 1000)} ms)`;
83
84
  this.write(indent(message));
84
85
  if (step.error) {
85
86
  this.write(renderError(serializeError(step.error)));
@@ -253,14 +253,15 @@ function formatJSONError(error: Error | any) {
253
253
  };
254
254
  }
255
255
 
256
- function journeyInfo(
257
- journey: Partial<Journey>,
258
- type: OutputFields['type'],
259
- ) {
256
+ function journeyInfo(journey: Partial<Journey>, type: OutputFields['type']) {
260
257
  if (!journey) {
261
258
  return;
262
259
  }
263
- const info: JourneyInfo = { name: journey.name, id: journey.id, tags: journey.tags };
260
+ const info: JourneyInfo = {
261
+ name: journey.name,
262
+ id: journey.id,
263
+ tags: journey.tags,
264
+ };
264
265
  const isEnd = type === 'journey/end';
265
266
  if (isEnd) {
266
267
  info.status = journey.status;
@@ -271,7 +272,7 @@ function journeyInfo(
271
272
 
272
273
  function stepInfo(
273
274
  step: Partial<Step>,
274
- type: OutputFields['type'],
275
+ type: OutputFields['type']
275
276
  ): Omit<Partial<Step>, 'duration'> & Duration {
276
277
  if (!step) {
277
278
  return;
@@ -375,8 +376,8 @@ export default class JSONReporter extends BaseReporter {
375
376
  },
376
377
  payload: event.networkConditions
377
378
  ? {
378
- network_conditions: event.networkConditions,
379
- }
379
+ network_conditions: event.networkConditions,
380
+ }
380
381
  : undefined,
381
382
  });
382
383
  }
@@ -400,12 +401,7 @@ export default class JSONReporter extends BaseReporter {
400
401
  override onStepEnd(
401
402
  journey: Journey,
402
403
  step: Step,
403
- {
404
- pagemetrics,
405
- traces,
406
- metrics,
407
- filmstrips,
408
- }: StepEndResult
404
+ { pagemetrics, traces, metrics, filmstrips }: StepEndResult
409
405
  ) {
410
406
  this.writeMetrics(journey, step, 'relative_trace', traces);
411
407
  this.writeMetrics(journey, step, 'experience', metrics);
@@ -25,10 +25,7 @@
25
25
 
26
26
  import { mkdir, writeFile } from 'fs/promises';
27
27
  import { dirname } from 'path';
28
- import {
29
- JourneyEndResult,
30
- JourneyStartResult,
31
- } from '../common_types';
28
+ import { JourneyEndResult, JourneyStartResult } from '../common_types';
32
29
  import { Journey, Step } from '../dsl';
33
30
  import { indent, now } from '../helpers';
34
31
  import BaseReporter from './base';
@@ -59,7 +56,7 @@ export default class JUnitReporter extends BaseReporter {
59
56
  private totalSkipped = 0;
60
57
  #journeyMap = new Map<string, XMLEntry>();
61
58
 
62
- override onJourneyStart(journey: Journey, { }: JourneyStartResult) {
59
+ override onJourneyStart(journey: Journey, {}: JourneyStartResult) {
63
60
  if (!this.#journeyMap.has(journey.name)) {
64
61
  const entry = {
65
62
  name: 'testsuite',
@@ -76,10 +73,7 @@ export default class JUnitReporter extends BaseReporter {
76
73
  }
77
74
  }
78
75
 
79
- override onStepEnd(
80
- journey: Journey,
81
- step: Step,
82
- ) {
76
+ override onStepEnd(journey: Journey, step: Step) {
83
77
  if (!this.#journeyMap.has(journey.name)) {
84
78
  return;
85
79
  }
@@ -117,7 +111,7 @@ export default class JUnitReporter extends BaseReporter {
117
111
  entry.children.push(caseEntry);
118
112
  }
119
113
 
120
- override onJourneyEnd(journey: Journey, { }: JourneyEndResult) {
114
+ override onJourneyEnd(journey: Journey, {}: JourneyEndResult) {
121
115
  if (!this.#journeyMap.has(journey.name)) {
122
116
  return;
123
117
  }