@datadog/datadog-ci 0.17.9 → 0.17.13

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 (81) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/README.md +9 -2
  3. package/dist/{commands/dependencies/index.d.ts → cli.d.ts} +0 -0
  4. package/dist/cli.js +34 -0
  5. package/dist/commands/{dsyms/index.d.ts → dependencies/cli.d.ts} +0 -0
  6. package/dist/commands/dependencies/{index.js → cli.js} +0 -0
  7. package/dist/commands/dependencies/upload.d.ts +1 -1
  8. package/dist/commands/{git-metadata/index.d.ts → dsyms/cli.d.ts} +0 -0
  9. package/dist/commands/dsyms/{index.js → cli.js} +0 -0
  10. package/dist/commands/dsyms/upload.d.ts +1 -1
  11. package/dist/commands/{junit/index.d.ts → git-metadata/cli.d.ts} +0 -0
  12. package/dist/commands/git-metadata/{index.js → cli.js} +0 -0
  13. package/dist/commands/git-metadata/upload.d.ts +1 -1
  14. package/dist/commands/git-metadata/upload.js +6 -1
  15. package/dist/commands/{lambda/index.d.ts → junit/cli.d.ts} +0 -0
  16. package/dist/commands/junit/{index.js → cli.js} +0 -0
  17. package/dist/commands/junit/upload.d.ts +1 -1
  18. package/dist/commands/junit/upload.js +1 -1
  19. package/dist/commands/lambda/__tests__/fixtures.d.ts +5 -1
  20. package/dist/commands/lambda/__tests__/fixtures.js +13 -2
  21. package/dist/commands/lambda/__tests__/functions/commons.test.js +400 -0
  22. package/dist/commands/lambda/__tests__/functions/instrument.test.js +229 -117
  23. package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +80 -7
  24. package/dist/commands/lambda/__tests__/instrument.test.js +542 -111
  25. package/dist/commands/{sourcemaps/index.d.ts → lambda/__tests__/prompt.test.d.ts} +0 -0
  26. package/dist/commands/lambda/__tests__/prompt.test.js +216 -0
  27. package/dist/commands/lambda/__tests__/uninstrument.test.js +381 -17
  28. package/dist/commands/{trace/index.d.ts → lambda/cli.d.ts} +0 -0
  29. package/dist/commands/lambda/{index.js → cli.js} +0 -0
  30. package/dist/commands/lambda/constants.d.ts +27 -6
  31. package/dist/commands/lambda/constants.js +63 -6
  32. package/dist/commands/lambda/functions/commons.d.ts +49 -4
  33. package/dist/commands/lambda/functions/commons.js +198 -7
  34. package/dist/commands/lambda/functions/instrument.d.ts +5 -14
  35. package/dist/commands/lambda/functions/instrument.js +63 -80
  36. package/dist/commands/lambda/functions/uninstrument.d.ts +3 -2
  37. package/dist/commands/lambda/functions/uninstrument.js +23 -11
  38. package/dist/commands/lambda/instrument.d.ts +2 -1
  39. package/dist/commands/lambda/instrument.js +112 -58
  40. package/dist/commands/lambda/interfaces.d.ts +4 -1
  41. package/dist/commands/lambda/loggroup.js +3 -1
  42. package/dist/commands/lambda/prompt.d.ts +9 -0
  43. package/dist/commands/lambda/prompt.js +187 -0
  44. package/dist/commands/lambda/uninstrument.d.ts +2 -0
  45. package/dist/commands/lambda/uninstrument.js +107 -30
  46. package/dist/commands/sourcemaps/cli.d.ts +1 -0
  47. package/dist/commands/sourcemaps/{index.js → cli.js} +0 -0
  48. package/dist/commands/sourcemaps/upload.d.ts +1 -1
  49. package/dist/commands/synthetics/__tests__/cli.test.js +36 -13
  50. package/dist/commands/synthetics/__tests__/fixtures.js +1 -0
  51. package/dist/commands/synthetics/__tests__/run-test.test.js +48 -2
  52. package/dist/commands/synthetics/__tests__/utils.test.js +11 -4
  53. package/dist/commands/synthetics/__tests__/websocket.test.js +3 -3
  54. package/dist/commands/synthetics/cli.d.ts +1 -26
  55. package/dist/commands/synthetics/cli.js +2 -227
  56. package/dist/commands/synthetics/command.d.ts +27 -0
  57. package/dist/commands/synthetics/command.js +236 -0
  58. package/dist/commands/synthetics/index.d.ts +5 -1
  59. package/dist/commands/synthetics/index.js +31 -2
  60. package/dist/commands/synthetics/interfaces.d.ts +8 -3
  61. package/dist/commands/synthetics/interfaces.js +7 -3
  62. package/dist/commands/synthetics/reporters/default.js +5 -1
  63. package/dist/commands/synthetics/run-test.js +3 -1
  64. package/dist/commands/synthetics/utils.d.ts +3 -3
  65. package/dist/commands/synthetics/utils.js +17 -8
  66. package/dist/commands/trace/api.js +1 -1
  67. package/dist/commands/trace/cli.d.ts +1 -0
  68. package/dist/commands/trace/{index.js → cli.js} +0 -0
  69. package/dist/commands/trace/trace.d.ts +1 -1
  70. package/dist/helpers/__tests__/ci.test.js +97 -136
  71. package/dist/helpers/__tests__/user-provided-git.test.js +81 -27
  72. package/dist/helpers/__tests__/utils.test.js +4 -0
  73. package/dist/helpers/ci.js +54 -95
  74. package/dist/helpers/interfaces.d.ts +28 -2
  75. package/dist/helpers/user-provided-git.d.ts +2 -1
  76. package/dist/helpers/user-provided-git.js +29 -5
  77. package/dist/helpers/utils.d.ts +4 -0
  78. package/dist/helpers/utils.js +18 -1
  79. package/dist/index.d.ts +3 -1
  80. package/dist/index.js +23 -31
  81. package/package.json +10 -8
@@ -1,229 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RunTestCommand = exports.DEFAULT_COMMAND_CONFIG = void 0;
16
- const chalk_1 = __importDefault(require("chalk"));
17
- const clipanion_1 = require("clipanion");
18
- const deep_extend_1 = __importDefault(require("deep-extend"));
19
- const utils_1 = require("../../helpers/utils");
20
- const errors_1 = require("./errors");
21
- const interfaces_1 = require("./interfaces");
22
- const default_1 = require("./reporters/default");
23
- const junit_1 = require("./reporters/junit");
24
- const run_test_1 = require("./run-test");
25
- const utils_2 = require("./utils");
26
- exports.DEFAULT_COMMAND_CONFIG = {
27
- apiKey: '',
28
- appKey: '',
29
- configPath: 'datadog-ci.json',
30
- datadogSite: 'datadoghq.com',
31
- failOnCriticalErrors: false,
32
- failOnTimeout: true,
33
- files: ['{,!(node_modules)/**/}*.synthetics.json'],
34
- global: {},
35
- locations: [],
36
- pollingTimeout: 2 * 60 * 1000,
37
- proxy: { protocol: 'http' },
38
- publicIds: [],
39
- subdomain: 'app',
40
- tunnel: false,
41
- };
42
- class RunTestCommand extends clipanion_1.Command {
43
- constructor() {
44
- super(...arguments);
45
- this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
46
- }
47
- execute() {
48
- return __awaiter(this, void 0, void 0, function* () {
49
- const reporters = [new default_1.DefaultReporter(this)];
50
- this.reporter = utils_2.getReporter(reporters);
51
- if (this.jUnitReport) {
52
- reporters.push(new junit_1.JUnitReporter(this));
53
- }
54
- yield this.resolveConfig();
55
- const startTime = Date.now();
56
- if (this.config.tunnel) {
57
- this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
58
- }
59
- let results;
60
- let summary;
61
- let tests;
62
- let triggers;
63
- try {
64
- ;
65
- ({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
66
- }
67
- catch (error) {
68
- if (error instanceof errors_1.CiError) {
69
- this.reportCiError(error, this.reporter);
70
- if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
71
- return 1;
72
- }
73
- }
74
- return 0;
75
- }
76
- return this.renderResults(results, summary, tests, triggers, startTime);
77
- });
78
- }
79
- getAppBaseURL() {
80
- return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
81
- }
82
- renderResults(results, summary, tests, triggers, startTime) {
83
- var _a, _b, _c, _d;
84
- // Sort tests to show success first then non blocking failures and finally blocking failures.
85
- tests.sort(this.sortTestsByOutcome(results));
86
- // Rendering the results.
87
- (_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
88
- const locationNames = triggers.locations.reduce((mapping, location) => {
89
- mapping[location.id] = location.display_name;
90
- return mapping;
91
- }, {});
92
- let hasSucceeded = true; // Determine if all the tests have succeeded
93
- for (const test of tests) {
94
- const testResults = results[test.public_id];
95
- if (!this.config.failOnTimeout) {
96
- if (!summary.timedOut) {
97
- summary.timedOut = 0;
98
- }
99
- const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
100
- if (hasTimeout) {
101
- summary.timedOut++;
102
- }
103
- }
104
- if (!this.config.failOnCriticalErrors) {
105
- if (!summary.criticalErrors) {
106
- summary.criticalErrors = 0;
107
- }
108
- const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
109
- if (hasCriticalErrors) {
110
- summary.criticalErrors++;
111
- }
112
- }
113
- const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
114
- if (passed) {
115
- summary.passed++;
116
- }
117
- else {
118
- summary.failed++;
119
- if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
120
- hasSucceeded = false;
121
- }
122
- }
123
- (_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
124
- }
125
- (_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
126
- return hasSucceeded ? 0 : 1;
127
- }
128
- reportCiError(error, reporter) {
129
- switch (error.code) {
130
- case 'NO_RESULTS_TO_POLL':
131
- reporter.log('No results to poll.\n');
132
- break;
133
- case 'NO_TESTS_TO_RUN':
134
- reporter.log('No test to run.\n');
135
- break;
136
- case 'MISSING_APP_KEY':
137
- reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
138
- break;
139
- case 'MISSING_API_KEY':
140
- reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
141
- break;
142
- case 'POLL_RESULTS_FAILED':
143
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
144
- break;
145
- case 'TUNNEL_START_FAILED':
146
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
147
- break;
148
- case 'TRIGGER_TESTS_FAILED':
149
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
150
- break;
151
- case 'UNAVAILABLE_TEST_CONFIG':
152
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
153
- break;
154
- case 'UNAVAILABLE_TUNNEL_CONFIG':
155
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
156
- }
157
- }
158
- resolveConfig() {
159
- var _a, _b;
160
- return __awaiter(this, void 0, void 0, function* () {
161
- // Default < file < ENV < CLI
162
- // Override with file config variables
163
- try {
164
- this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
165
- }
166
- catch (error) {
167
- if (this.configPath) {
168
- throw error;
169
- }
170
- }
171
- // Override with ENV variables
172
- this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
173
- apiKey: process.env.DATADOG_API_KEY,
174
- appKey: process.env.DATADOG_APP_KEY,
175
- datadogSite: process.env.DATADOG_SITE,
176
- locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
177
- subdomain: process.env.DATADOG_SUBDOMAIN,
178
- }));
179
- // Override with CLI parameters
180
- this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
181
- apiKey: this.apiKey,
182
- appKey: this.appKey,
183
- configPath: this.configPath,
184
- datadogSite: this.datadogSite,
185
- failOnCriticalErrors: this.failOnCriticalErrors,
186
- failOnTimeout: this.failOnTimeout,
187
- files: this.files,
188
- publicIds: this.publicIds,
189
- subdomain: this.subdomain,
190
- testSearchQuery: this.testSearchQuery,
191
- tunnel: this.tunnel,
192
- }));
193
- if (typeof this.config.files === 'string') {
194
- this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
195
- this.config.files = [this.config.files];
196
- }
197
- });
198
- }
199
- sortTestsByOutcome(results) {
200
- return (t1, t2) => {
201
- var _a, _b;
202
- const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
203
- const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
204
- const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
205
- const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
206
- if (success1 === success2) {
207
- if (isNonBlockingTest1 === isNonBlockingTest2) {
208
- return 0;
209
- }
210
- return isNonBlockingTest1 ? -1 : 1;
211
- }
212
- return success1 ? -1 : 1;
213
- };
214
- }
215
- }
216
- exports.RunTestCommand = RunTestCommand;
217
- RunTestCommand.addPath('synthetics', 'run-tests');
218
- RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
219
- RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
220
- RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
221
- RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
222
- RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
223
- RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
224
- RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
225
- RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
226
- RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
227
- RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
228
- RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
229
- RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
3
+ const command_1 = require("./command");
4
+ module.exports = [command_1.RunTestCommand];
@@ -0,0 +1,27 @@
1
+ import { Command } from 'clipanion';
2
+ import { CommandConfig } from './interfaces';
3
+ export declare const DEFAULT_COMMAND_CONFIG: CommandConfig;
4
+ export declare class RunTestCommand extends Command {
5
+ jUnitReport?: string;
6
+ runName?: string;
7
+ private apiKey?;
8
+ private appKey?;
9
+ private config;
10
+ private configPath?;
11
+ private datadogSite?;
12
+ private failOnCriticalErrors?;
13
+ private failOnTimeout?;
14
+ private files?;
15
+ private publicIds?;
16
+ private reporter?;
17
+ private subdomain?;
18
+ private testSearchQuery?;
19
+ private tunnel?;
20
+ private variableStrings?;
21
+ execute(): Promise<1 | 0>;
22
+ private getAppBaseURL;
23
+ private renderResults;
24
+ private reportCiError;
25
+ private resolveConfig;
26
+ private sortTestsByOutcome;
27
+ }
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RunTestCommand = exports.DEFAULT_COMMAND_CONFIG = void 0;
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const clipanion_1 = require("clipanion");
18
+ const deep_extend_1 = __importDefault(require("deep-extend"));
19
+ const utils_1 = require("../../helpers/utils");
20
+ const errors_1 = require("./errors");
21
+ const interfaces_1 = require("./interfaces");
22
+ const default_1 = require("./reporters/default");
23
+ const junit_1 = require("./reporters/junit");
24
+ const run_test_1 = require("./run-test");
25
+ const utils_2 = require("./utils");
26
+ exports.DEFAULT_COMMAND_CONFIG = {
27
+ apiKey: '',
28
+ appKey: '',
29
+ configPath: 'datadog-ci.json',
30
+ datadogSite: 'datadoghq.com',
31
+ failOnCriticalErrors: false,
32
+ failOnTimeout: true,
33
+ files: ['{,!(node_modules)/**/}*.synthetics.json'],
34
+ global: {},
35
+ locations: [],
36
+ pollingTimeout: 2 * 60 * 1000,
37
+ proxy: { protocol: 'http' },
38
+ publicIds: [],
39
+ subdomain: 'app',
40
+ tunnel: false,
41
+ variableStrings: [],
42
+ };
43
+ class RunTestCommand extends clipanion_1.Command {
44
+ constructor() {
45
+ super(...arguments);
46
+ this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
47
+ }
48
+ execute() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ const reporters = [new default_1.DefaultReporter(this)];
51
+ this.reporter = utils_2.getReporter(reporters);
52
+ if (this.jUnitReport) {
53
+ reporters.push(new junit_1.JUnitReporter(this));
54
+ }
55
+ yield this.resolveConfig();
56
+ const startTime = Date.now();
57
+ if (this.config.tunnel) {
58
+ this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
59
+ }
60
+ let results;
61
+ let summary;
62
+ let tests;
63
+ let triggers;
64
+ try {
65
+ ;
66
+ ({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
67
+ }
68
+ catch (error) {
69
+ if (error instanceof errors_1.CiError) {
70
+ this.reportCiError(error, this.reporter);
71
+ if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
72
+ return 1;
73
+ }
74
+ }
75
+ return 0;
76
+ }
77
+ return this.renderResults(results, summary, tests, triggers, startTime);
78
+ });
79
+ }
80
+ getAppBaseURL() {
81
+ return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
82
+ }
83
+ renderResults(results, summary, tests, triggers, startTime) {
84
+ var _a, _b, _c, _d;
85
+ // Sort tests to show success first then non blocking failures and finally blocking failures.
86
+ tests.sort(this.sortTestsByOutcome(results));
87
+ // Rendering the results.
88
+ (_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
89
+ const locationNames = triggers.locations.reduce((mapping, location) => {
90
+ mapping[location.id] = location.display_name;
91
+ return mapping;
92
+ }, {});
93
+ let hasSucceeded = true; // Determine if all the tests have succeeded
94
+ for (const test of tests) {
95
+ const testResults = results[test.public_id];
96
+ if (!this.config.failOnTimeout) {
97
+ if (!summary.timedOut) {
98
+ summary.timedOut = 0;
99
+ }
100
+ const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
101
+ if (hasTimeout) {
102
+ summary.timedOut++;
103
+ }
104
+ }
105
+ if (!this.config.failOnCriticalErrors) {
106
+ if (!summary.criticalErrors) {
107
+ summary.criticalErrors = 0;
108
+ }
109
+ const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
110
+ if (hasCriticalErrors) {
111
+ summary.criticalErrors++;
112
+ }
113
+ }
114
+ const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
115
+ if (passed) {
116
+ summary.passed++;
117
+ }
118
+ else {
119
+ summary.failed++;
120
+ if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
121
+ hasSucceeded = false;
122
+ }
123
+ }
124
+ (_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
125
+ }
126
+ (_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
127
+ return hasSucceeded ? 0 : 1;
128
+ }
129
+ reportCiError(error, reporter) {
130
+ switch (error.code) {
131
+ case 'NO_RESULTS_TO_POLL':
132
+ reporter.log('No results to poll.\n');
133
+ break;
134
+ case 'NO_TESTS_TO_RUN':
135
+ reporter.log('No test to run.\n');
136
+ break;
137
+ case 'MISSING_APP_KEY':
138
+ reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
139
+ break;
140
+ case 'MISSING_API_KEY':
141
+ reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
142
+ break;
143
+ case 'POLL_RESULTS_FAILED':
144
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
145
+ break;
146
+ case 'TUNNEL_START_FAILED':
147
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
148
+ break;
149
+ case 'TRIGGER_TESTS_FAILED':
150
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
151
+ break;
152
+ case 'UNAVAILABLE_TEST_CONFIG':
153
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
154
+ break;
155
+ case 'UNAVAILABLE_TUNNEL_CONFIG':
156
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
157
+ }
158
+ }
159
+ resolveConfig() {
160
+ var _a, _b;
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ // Default < file < ENV < CLI
163
+ // Override with file config variables
164
+ try {
165
+ this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
166
+ }
167
+ catch (error) {
168
+ if (this.configPath) {
169
+ throw error;
170
+ }
171
+ }
172
+ // Override with ENV variables
173
+ this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
174
+ apiKey: process.env.DATADOG_API_KEY,
175
+ appKey: process.env.DATADOG_APP_KEY,
176
+ datadogSite: process.env.DATADOG_SITE,
177
+ locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
178
+ subdomain: process.env.DATADOG_SUBDOMAIN,
179
+ }));
180
+ // Override with CLI parameters
181
+ this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
182
+ apiKey: this.apiKey,
183
+ appKey: this.appKey,
184
+ configPath: this.configPath,
185
+ datadogSite: this.datadogSite,
186
+ failOnCriticalErrors: this.failOnCriticalErrors,
187
+ failOnTimeout: this.failOnTimeout,
188
+ files: this.files,
189
+ publicIds: this.publicIds,
190
+ subdomain: this.subdomain,
191
+ testSearchQuery: this.testSearchQuery,
192
+ tunnel: this.tunnel,
193
+ }));
194
+ // Override with Global CLI parameters
195
+ this.config.global = deep_extend_1.default(this.config.global, utils_1.removeUndefinedValues({
196
+ variables: utils_2.parseVariablesFromCli(this.variableStrings, (log) => { var _a; return (_a = this.reporter) === null || _a === void 0 ? void 0 : _a.log(log); }),
197
+ }));
198
+ if (typeof this.config.files === 'string') {
199
+ this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
200
+ this.config.files = [this.config.files];
201
+ }
202
+ });
203
+ }
204
+ sortTestsByOutcome(results) {
205
+ return (t1, t2) => {
206
+ var _a, _b;
207
+ const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
208
+ const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
209
+ const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
210
+ const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
211
+ if (success1 === success2) {
212
+ if (isNonBlockingTest1 === isNonBlockingTest2) {
213
+ return 0;
214
+ }
215
+ return isNonBlockingTest1 ? -1 : 1;
216
+ }
217
+ return success1 ? -1 : 1;
218
+ };
219
+ }
220
+ }
221
+ exports.RunTestCommand = RunTestCommand;
222
+ RunTestCommand.addPath('synthetics', 'run-tests');
223
+ RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
224
+ RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
225
+ RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
226
+ RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
227
+ RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
228
+ RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
229
+ RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
230
+ RunTestCommand.addOption('jUnitReport', clipanion_1.Command.String('-j,--jUnitReport'));
231
+ RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
232
+ RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
233
+ RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
234
+ RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
235
+ RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
236
+ RunTestCommand.addOption('variableStrings', clipanion_1.Command.Array('-v,--variable'));
@@ -1 +1,5 @@
1
- export {};
1
+ export { CiError } from './errors';
2
+ export * from './interfaces';
3
+ export { DefaultReporter } from './reporters/default';
4
+ export { executeTests } from './run-test';
5
+ export * as utils from './utils';
@@ -1,4 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ var __importStar = (this && this.__importStar) || function (mod) {
18
+ if (mod && mod.__esModule) return mod;
19
+ var result = {};
20
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
21
+ __setModuleDefault(result, mod);
22
+ return result;
23
+ };
2
24
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const cli_1 = require("./cli");
4
- module.exports = [cli_1.RunTestCommand];
25
+ exports.utils = exports.executeTests = exports.DefaultReporter = exports.CiError = void 0;
26
+ var errors_1 = require("./errors");
27
+ Object.defineProperty(exports, "CiError", { enumerable: true, get: function () { return errors_1.CiError; } });
28
+ __exportStar(require("./interfaces"), exports);
29
+ var default_1 = require("./reporters/default");
30
+ Object.defineProperty(exports, "DefaultReporter", { enumerable: true, get: function () { return default_1.DefaultReporter; } });
31
+ var run_test_1 = require("./run-test");
32
+ Object.defineProperty(exports, "executeTests", { enumerable: true, get: function () { return run_test_1.executeTests; } });
33
+ exports.utils = __importStar(require("./utils"));
@@ -179,12 +179,16 @@ export declare enum Operator {
179
179
  doesNotContain = "doesNotContain",
180
180
  is = "is",
181
181
  isNot = "isNot",
182
+ isInLessThan = "isInLessThan",
183
+ isInMoreThan = "isInMoreThan",
182
184
  lessThan = "lessThan",
185
+ lessThanOrEqual = "lessThanOrEqual",
186
+ moreThan = "moreThan",
187
+ moreThanOrEqual = "moreThanOrEqual",
183
188
  matches = "matches",
184
189
  doesNotMatch = "doesNotMatch",
185
- validates = "validates",
186
- isInMoreThan = "isInMoreThan",
187
- isInLessThan = "isInLessThan"
190
+ validatesJSONPath = "validatesJSONPath",
191
+ validatesXPath = "validatesXPath"
188
192
  }
189
193
  export interface User {
190
194
  email: string;
@@ -335,6 +339,7 @@ export interface SyntheticsCIConfig {
335
339
  subdomain: string;
336
340
  testSearchQuery?: string;
337
341
  tunnel: boolean;
342
+ variableStrings: string[];
338
343
  }
339
344
  export interface CommandConfig extends SyntheticsCIConfig {
340
345
  failOnTimeout: boolean;
@@ -13,12 +13,16 @@ var Operator;
13
13
  Operator["doesNotContain"] = "doesNotContain";
14
14
  Operator["is"] = "is";
15
15
  Operator["isNot"] = "isNot";
16
+ Operator["isInLessThan"] = "isInLessThan";
17
+ Operator["isInMoreThan"] = "isInMoreThan";
16
18
  Operator["lessThan"] = "lessThan";
19
+ Operator["lessThanOrEqual"] = "lessThanOrEqual";
20
+ Operator["moreThan"] = "moreThan";
21
+ Operator["moreThanOrEqual"] = "moreThanOrEqual";
17
22
  Operator["matches"] = "matches";
18
23
  Operator["doesNotMatch"] = "doesNotMatch";
19
- Operator["validates"] = "validates";
20
- Operator["isInMoreThan"] = "isInMoreThan";
21
- Operator["isInLessThan"] = "isInLessThan";
24
+ Operator["validatesJSONPath"] = "validatesJSONPath";
25
+ Operator["validatesXPath"] = "validatesXPath";
22
26
  })(Operator = exports.Operator || (exports.Operator = {}));
23
27
  var ExecutionRule;
24
28
  (function (ExecutionRule) {
@@ -50,9 +50,13 @@ const readableOperation = {
50
50
  [interfaces_1.Operator.lessThan]: 'should be less than',
51
51
  [interfaces_1.Operator.matches]: 'should match',
52
52
  [interfaces_1.Operator.doesNotMatch]: 'should not match',
53
- [interfaces_1.Operator.validates]: 'will expire in less than',
54
53
  [interfaces_1.Operator.isInLessThan]: 'will expire in less than',
55
54
  [interfaces_1.Operator.isInMoreThan]: 'will expire in more than',
55
+ [interfaces_1.Operator.lessThanOrEqual]: 'should be less than or equal to',
56
+ [interfaces_1.Operator.moreThan]: 'should be more than',
57
+ [interfaces_1.Operator.moreThanOrEqual]: 'should be less than or equal to',
58
+ [interfaces_1.Operator.validatesJSONPath]: 'assert on JSONPath extracted value',
59
+ [interfaces_1.Operator.validatesXPath]: 'assert on XPath extracted value',
56
60
  };
57
61
  const renderApiError = (errorCode, errorMessage, color) => {
58
62
  if (errorCode === 'INCORRECT_ASSERTION') {
@@ -98,9 +98,11 @@ const executeTests = (reporter, config) => __awaiter(void 0, void 0, void 0, fun
98
98
  }
99
99
  catch (error) {
100
100
  const isCriticalError = api_1.is5xxError(error);
101
- yield stopTunnel();
102
101
  throw new (isCriticalError ? errors_1.CriticalError : errors_1.CiError)('POLL_RESULTS_FAILED');
103
102
  }
103
+ finally {
104
+ yield stopTunnel();
105
+ }
104
106
  return { results, summary, tests, triggers };
105
107
  });
106
108
  exports.executeTests = executeTests;
@@ -22,6 +22,6 @@ export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: Trigger
22
22
  }>;
23
23
  export declare const runTests: (api: APIHelper, testsToTrigger: TestPayload[]) => Promise<Trigger>;
24
24
  export declare const retry: <T, E extends Error>(func: () => Promise<T>, shouldRetryAfterWait: (retries: number, error: E) => number | undefined) => Promise<T>;
25
- export declare const removeUndefinedValues: <T extends {
26
- [key: string]: any;
27
- }>(object: T) => T;
25
+ export declare const parseVariablesFromCli: (variableArguments: string[] | undefined, logFunction: (log: string) => void) => {
26
+ [key: string]: string;
27
+ } | undefined;