@datadog/datadog-ci 2.40.0 → 2.40.2

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 (271) hide show
  1. package/dist/__tests__/cli.test.d.ts +1 -0
  2. package/dist/__tests__/cli.test.js +41 -0
  3. package/dist/__tests__/cli.test.js.map +1 -0
  4. package/dist/commands/cloud-run/__tests__/fixtures.d.ts +2 -0
  5. package/dist/commands/cloud-run/__tests__/fixtures.js +12 -0
  6. package/dist/commands/cloud-run/__tests__/fixtures.js.map +1 -0
  7. package/dist/commands/cloud-run/__tests__/flare.test.d.ts +1 -0
  8. package/dist/commands/cloud-run/__tests__/flare.test.js +557 -0
  9. package/dist/commands/cloud-run/__tests__/flare.test.js.map +1 -0
  10. package/dist/commands/deployment/__tests__/mark.test.d.ts +1 -0
  11. package/dist/commands/deployment/__tests__/mark.test.js +47 -0
  12. package/dist/commands/deployment/__tests__/mark.test.js.map +1 -0
  13. package/dist/commands/dora/__tests__/deployment.test.d.ts +1 -0
  14. package/dist/commands/dora/__tests__/deployment.test.js +201 -0
  15. package/dist/commands/dora/__tests__/deployment.test.js.map +1 -0
  16. package/dist/commands/dsyms/__tests__/upload.test.d.ts +1 -0
  17. package/dist/commands/dsyms/__tests__/upload.test.js +346 -0
  18. package/dist/commands/dsyms/__tests__/upload.test.js.map +1 -0
  19. package/dist/commands/dsyms/__tests__/utils.test.d.ts +1 -0
  20. package/dist/commands/dsyms/__tests__/utils.test.js +100 -0
  21. package/dist/commands/dsyms/__tests__/utils.test.js.map +1 -0
  22. package/dist/commands/dsyms/upload.js +3 -3
  23. package/dist/commands/dsyms/upload.js.map +1 -1
  24. package/dist/commands/dsyms/utils.js +4 -2
  25. package/dist/commands/dsyms/utils.js.map +1 -1
  26. package/dist/commands/elf-symbols/__tests__/elf.test.d.ts +1 -0
  27. package/dist/commands/elf-symbols/__tests__/elf.test.js +813 -0
  28. package/dist/commands/elf-symbols/__tests__/elf.test.js.map +1 -0
  29. package/dist/commands/elf-symbols/__tests__/upload.test.d.ts +1 -0
  30. package/dist/commands/elf-symbols/__tests__/upload.test.js +249 -0
  31. package/dist/commands/elf-symbols/__tests__/upload.test.js.map +1 -0
  32. package/dist/commands/elf-symbols/upload.js +2 -3
  33. package/dist/commands/elf-symbols/upload.js.map +1 -1
  34. package/dist/commands/flutter-symbols/__tests__/upload.test.d.ts +1 -0
  35. package/dist/commands/flutter-symbols/__tests__/upload.test.js +617 -0
  36. package/dist/commands/flutter-symbols/__tests__/upload.test.js.map +1 -0
  37. package/dist/commands/flutter-symbols/upload.js +2 -2
  38. package/dist/commands/flutter-symbols/upload.js.map +1 -1
  39. package/dist/commands/gate/__tests__/evaluate.test.d.ts +1 -0
  40. package/dist/commands/gate/__tests__/evaluate.test.js +398 -0
  41. package/dist/commands/gate/__tests__/evaluate.test.js.map +1 -0
  42. package/dist/commands/gate/__tests__/scope.test.d.ts +1 -0
  43. package/dist/commands/gate/__tests__/scope.test.js +29 -0
  44. package/dist/commands/gate/__tests__/scope.test.js.map +1 -0
  45. package/dist/commands/git-metadata/__tests__/git.test.d.ts +1 -0
  46. package/dist/commands/git-metadata/__tests__/git.test.js +132 -0
  47. package/dist/commands/git-metadata/__tests__/git.test.js.map +1 -0
  48. package/dist/commands/git-metadata/__tests__/gitdb.test.d.ts +1 -0
  49. package/dist/commands/git-metadata/__tests__/gitdb.test.js +1386 -0
  50. package/dist/commands/git-metadata/__tests__/gitdb.test.js.map +1 -0
  51. package/dist/commands/git-metadata/__tests__/library.test.d.ts +1 -0
  52. package/dist/commands/git-metadata/__tests__/library.test.js +118 -0
  53. package/dist/commands/git-metadata/__tests__/library.test.js.map +1 -0
  54. package/dist/commands/git-metadata/__tests__/upload.test.d.ts +1 -0
  55. package/dist/commands/git-metadata/__tests__/upload.test.js +52 -0
  56. package/dist/commands/git-metadata/__tests__/upload.test.js.map +1 -0
  57. package/dist/commands/junit/__tests__/id.test.d.ts +1 -0
  58. package/dist/commands/junit/__tests__/id.test.js +24 -0
  59. package/dist/commands/junit/__tests__/id.test.js.map +1 -0
  60. package/dist/commands/junit/__tests__/upload.test.d.ts +1 -0
  61. package/dist/commands/junit/__tests__/upload.test.js +495 -0
  62. package/dist/commands/junit/__tests__/upload.test.js.map +1 -0
  63. package/dist/commands/junit/upload.js +5 -3
  64. package/dist/commands/junit/upload.js.map +1 -1
  65. package/dist/commands/lambda/__tests__/fixtures.d.ts +51 -0
  66. package/dist/commands/lambda/__tests__/fixtures.js +146 -0
  67. package/dist/commands/lambda/__tests__/fixtures.js.map +1 -0
  68. package/dist/commands/lambda/__tests__/flare.test.d.ts +1 -0
  69. package/dist/commands/lambda/__tests__/flare.test.js +730 -0
  70. package/dist/commands/lambda/__tests__/flare.test.js.map +1 -0
  71. package/dist/commands/lambda/__tests__/functions/commons.test.d.ts +1 -0
  72. package/dist/commands/lambda/__tests__/functions/commons.test.js +791 -0
  73. package/dist/commands/lambda/__tests__/functions/commons.test.js.map +1 -0
  74. package/dist/commands/lambda/__tests__/functions/instrument.part1.test.d.ts +1 -0
  75. package/dist/commands/lambda/__tests__/functions/instrument.part1.test.js +386 -0
  76. package/dist/commands/lambda/__tests__/functions/instrument.part1.test.js.map +1 -0
  77. package/dist/commands/lambda/__tests__/functions/instrument.part2.test.d.ts +1 -0
  78. package/dist/commands/lambda/__tests__/functions/instrument.part2.test.js +721 -0
  79. package/dist/commands/lambda/__tests__/functions/instrument.part2.test.js.map +1 -0
  80. package/dist/commands/lambda/__tests__/functions/uninstrument.test.d.ts +1 -0
  81. package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +513 -0
  82. package/dist/commands/lambda/__tests__/functions/uninstrument.test.js.map +1 -0
  83. package/dist/commands/lambda/__tests__/functions/versionChecker.test.d.ts +1 -0
  84. package/dist/commands/lambda/__tests__/functions/versionChecker.test.js +33 -0
  85. package/dist/commands/lambda/__tests__/functions/versionChecker.test.js.map +1 -0
  86. package/dist/commands/lambda/__tests__/instrument.test.d.ts +1 -0
  87. package/dist/commands/lambda/__tests__/instrument.test.js +1511 -0
  88. package/dist/commands/lambda/__tests__/instrument.test.js.map +1 -0
  89. package/dist/commands/lambda/__tests__/loggroup.test.d.ts +1 -0
  90. package/dist/commands/lambda/__tests__/loggroup.test.js +340 -0
  91. package/dist/commands/lambda/__tests__/loggroup.test.js.map +1 -0
  92. package/dist/commands/lambda/__tests__/prompt.test.d.ts +1 -0
  93. package/dist/commands/lambda/__tests__/prompt.test.js +206 -0
  94. package/dist/commands/lambda/__tests__/prompt.test.js.map +1 -0
  95. package/dist/commands/lambda/__tests__/tags.test.d.ts +1 -0
  96. package/dist/commands/lambda/__tests__/tags.test.js +305 -0
  97. package/dist/commands/lambda/__tests__/tags.test.js.map +1 -0
  98. package/dist/commands/lambda/__tests__/uninstrument.test.d.ts +1 -0
  99. package/dist/commands/lambda/__tests__/uninstrument.test.js +722 -0
  100. package/dist/commands/lambda/__tests__/uninstrument.test.js.map +1 -0
  101. package/dist/commands/measure/__tests__/measure.test.d.ts +1 -0
  102. package/dist/commands/measure/__tests__/measure.test.js +110 -0
  103. package/dist/commands/measure/__tests__/measure.test.js.map +1 -0
  104. package/dist/commands/react-native/__tests__/codepush.test.d.ts +1 -0
  105. package/dist/commands/react-native/__tests__/codepush.test.js +161 -0
  106. package/dist/commands/react-native/__tests__/codepush.test.js.map +1 -0
  107. package/dist/commands/react-native/__tests__/interfaces.test.d.ts +1 -0
  108. package/dist/commands/react-native/__tests__/interfaces.test.js +33 -0
  109. package/dist/commands/react-native/__tests__/interfaces.test.js.map +1 -0
  110. package/dist/commands/react-native/__tests__/upload.test.d.ts +1 -0
  111. package/dist/commands/react-native/__tests__/upload.test.js +238 -0
  112. package/dist/commands/react-native/__tests__/upload.test.js.map +1 -0
  113. package/dist/commands/react-native/__tests__/utils.test.d.ts +1 -0
  114. package/dist/commands/react-native/__tests__/utils.test.js +27 -0
  115. package/dist/commands/react-native/__tests__/utils.test.js.map +1 -0
  116. package/dist/commands/react-native/__tests__/xcode.test.d.ts +1 -0
  117. package/dist/commands/react-native/__tests__/xcode.test.js +465 -0
  118. package/dist/commands/react-native/__tests__/xcode.test.js.map +1 -0
  119. package/dist/commands/sarif/__tests__/upload.test.d.ts +1 -0
  120. package/dist/commands/sarif/__tests__/upload.test.js +228 -0
  121. package/dist/commands/sarif/__tests__/upload.test.js.map +1 -0
  122. package/dist/commands/sarif/upload.js +2 -2
  123. package/dist/commands/sarif/upload.js.map +1 -1
  124. package/dist/commands/sbom/__tests__/payload.test.d.ts +1 -0
  125. package/dist/commands/sbom/__tests__/payload.test.js +262 -0
  126. package/dist/commands/sbom/__tests__/payload.test.js.map +1 -0
  127. package/dist/commands/sbom/__tests__/validation.test.d.ts +1 -0
  128. package/dist/commands/sbom/__tests__/validation.test.js +41 -0
  129. package/dist/commands/sbom/__tests__/validation.test.js.map +1 -0
  130. package/dist/commands/sourcemaps/__tests__/upload.test.d.ts +1 -0
  131. package/dist/commands/sourcemaps/__tests__/upload.test.js +270 -0
  132. package/dist/commands/sourcemaps/__tests__/upload.test.js.map +1 -0
  133. package/dist/commands/sourcemaps/__tests__/utils.test.d.ts +1 -0
  134. package/dist/commands/sourcemaps/__tests__/utils.test.js +31 -0
  135. package/dist/commands/sourcemaps/__tests__/utils.test.js.map +1 -0
  136. package/dist/commands/sourcemaps/upload.js +2 -2
  137. package/dist/commands/sourcemaps/upload.js.map +1 -1
  138. package/dist/commands/stepfunctions/__tests__/awsCommands.test.d.ts +1 -0
  139. package/dist/commands/stepfunctions/__tests__/awsCommands.test.js +192 -0
  140. package/dist/commands/stepfunctions/__tests__/awsCommands.test.js.map +1 -0
  141. package/dist/commands/stepfunctions/__tests__/fixtures/aws-resources.d.ts +6 -0
  142. package/dist/commands/stepfunctions/__tests__/fixtures/aws-resources.js +45 -0
  143. package/dist/commands/stepfunctions/__tests__/fixtures/aws-resources.js.map +1 -0
  144. package/dist/commands/stepfunctions/__tests__/fixtures/cli.d.ts +5 -0
  145. package/dist/commands/stepfunctions/__tests__/fixtures/cli.js +19 -0
  146. package/dist/commands/stepfunctions/__tests__/fixtures/cli.js.map +1 -0
  147. package/dist/commands/stepfunctions/__tests__/helpers.test.d.ts +1 -0
  148. package/dist/commands/stepfunctions/__tests__/helpers.test.js +205 -0
  149. package/dist/commands/stepfunctions/__tests__/helpers.test.js.map +1 -0
  150. package/dist/commands/stepfunctions/__tests__/instrument.test.d.ts +1 -0
  151. package/dist/commands/stepfunctions/__tests__/instrument.test.js +431 -0
  152. package/dist/commands/stepfunctions/__tests__/instrument.test.js.map +1 -0
  153. package/dist/commands/stepfunctions/__tests__/uninstrument.test.d.ts +1 -0
  154. package/dist/commands/stepfunctions/__tests__/uninstrument.test.js +166 -0
  155. package/dist/commands/stepfunctions/__tests__/uninstrument.test.js.map +1 -0
  156. package/dist/commands/synthetics/__tests__/api.test.d.ts +1 -0
  157. package/dist/commands/synthetics/__tests__/api.test.js +422 -0
  158. package/dist/commands/synthetics/__tests__/api.test.js.map +1 -0
  159. package/dist/commands/synthetics/__tests__/cli.test.d.ts +1 -0
  160. package/dist/commands/synthetics/__tests__/cli.test.js +1325 -0
  161. package/dist/commands/synthetics/__tests__/cli.test.js.map +1 -0
  162. package/dist/commands/synthetics/__tests__/fixtures.d.ts +149 -0
  163. package/dist/commands/synthetics/__tests__/fixtures.js +507 -0
  164. package/dist/commands/synthetics/__tests__/fixtures.js.map +1 -0
  165. package/dist/commands/synthetics/__tests__/mobile.test.d.ts +1 -0
  166. package/dist/commands/synthetics/__tests__/mobile.test.js +376 -0
  167. package/dist/commands/synthetics/__tests__/mobile.test.js.map +1 -0
  168. package/dist/commands/synthetics/__tests__/reporters/default.test.d.ts +1 -0
  169. package/dist/commands/synthetics/__tests__/reporters/default.test.js +354 -0
  170. package/dist/commands/synthetics/__tests__/reporters/default.test.js.map +1 -0
  171. package/dist/commands/synthetics/__tests__/reporters/junit.test.d.ts +1 -0
  172. package/dist/commands/synthetics/__tests__/reporters/junit.test.js +353 -0
  173. package/dist/commands/synthetics/__tests__/reporters/junit.test.js.map +1 -0
  174. package/dist/commands/synthetics/__tests__/reporters/mobile/app-upload.test.d.ts +1 -0
  175. package/dist/commands/synthetics/__tests__/reporters/mobile/app-upload.test.js +232 -0
  176. package/dist/commands/synthetics/__tests__/reporters/mobile/app-upload.test.js.map +1 -0
  177. package/dist/commands/synthetics/__tests__/run-tests-lib.test.d.ts +1 -0
  178. package/dist/commands/synthetics/__tests__/run-tests-lib.test.js +735 -0
  179. package/dist/commands/synthetics/__tests__/run-tests-lib.test.js.map +1 -0
  180. package/dist/commands/synthetics/__tests__/test.test.d.ts +1 -0
  181. package/dist/commands/synthetics/__tests__/test.test.js +33 -0
  182. package/dist/commands/synthetics/__tests__/test.test.js.map +1 -0
  183. package/dist/commands/synthetics/__tests__/tunnel/crypto.test.d.ts +1 -0
  184. package/dist/commands/synthetics/__tests__/tunnel/crypto.test.js +21 -0
  185. package/dist/commands/synthetics/__tests__/tunnel/crypto.test.js.map +1 -0
  186. package/dist/commands/synthetics/__tests__/tunnel/tunnel.test.d.ts +1 -0
  187. package/dist/commands/synthetics/__tests__/tunnel/tunnel.test.js +80 -0
  188. package/dist/commands/synthetics/__tests__/tunnel/tunnel.test.js.map +1 -0
  189. package/dist/commands/synthetics/__tests__/tunnel/websocket.test.d.ts +1 -0
  190. package/dist/commands/synthetics/__tests__/tunnel/websocket.test.js +109 -0
  191. package/dist/commands/synthetics/__tests__/tunnel/websocket.test.js.map +1 -0
  192. package/dist/commands/synthetics/__tests__/utils/internal.test.d.ts +1 -0
  193. package/dist/commands/synthetics/__tests__/utils/internal.test.js +186 -0
  194. package/dist/commands/synthetics/__tests__/utils/internal.test.js.map +1 -0
  195. package/dist/commands/synthetics/__tests__/utils/public.test.d.ts +1 -0
  196. package/dist/commands/synthetics/__tests__/utils/public.test.js +1526 -0
  197. package/dist/commands/synthetics/__tests__/utils/public.test.js.map +1 -0
  198. package/dist/commands/synthetics/api.d.ts +1 -1
  199. package/dist/commands/synthetics/api.js +10 -5
  200. package/dist/commands/synthetics/api.js.map +1 -1
  201. package/dist/commands/synthetics/run-tests-command.d.ts +1 -0
  202. package/dist/commands/synthetics/run-tests-command.js +3 -2
  203. package/dist/commands/synthetics/run-tests-command.js.map +1 -1
  204. package/dist/commands/synthetics/run-tests-lib.js +0 -4
  205. package/dist/commands/synthetics/run-tests-lib.js.map +1 -1
  206. package/dist/commands/synthetics/test.js +9 -1
  207. package/dist/commands/synthetics/test.js.map +1 -1
  208. package/dist/commands/synthetics/utils/public.js +3 -3
  209. package/dist/commands/synthetics/utils/public.js.map +1 -1
  210. package/dist/commands/tag/__tests__/tag.test.d.ts +1 -0
  211. package/dist/commands/tag/__tests__/tag.test.js +75 -0
  212. package/dist/commands/tag/__tests__/tag.test.js.map +1 -0
  213. package/dist/commands/trace/__tests__/trace.test.d.ts +1 -0
  214. package/dist/commands/trace/__tests__/trace.test.js +145 -0
  215. package/dist/commands/trace/__tests__/trace.test.js.map +1 -0
  216. package/dist/commands/trace/trace.js +1 -1
  217. package/dist/commands/trace/trace.js.map +1 -1
  218. package/dist/commands/unity-symbols/__tests__/upload.test.d.ts +1 -0
  219. package/dist/commands/unity-symbols/__tests__/upload.test.js +369 -0
  220. package/dist/commands/unity-symbols/__tests__/upload.test.js.map +1 -0
  221. package/dist/commands/unity-symbols/upload.js +2 -2
  222. package/dist/commands/unity-symbols/upload.js.map +1 -1
  223. package/dist/helpers/__tests__/app.test.d.ts +1 -0
  224. package/dist/helpers/__tests__/app.test.js +31 -0
  225. package/dist/helpers/__tests__/app.test.js.map +1 -0
  226. package/dist/helpers/__tests__/ci.test.d.ts +1 -0
  227. package/dist/helpers/__tests__/ci.test.js +252 -0
  228. package/dist/helpers/__tests__/ci.test.js.map +1 -0
  229. package/dist/helpers/__tests__/fixtures.d.ts +33 -0
  230. package/dist/helpers/__tests__/fixtures.js +71 -0
  231. package/dist/helpers/__tests__/fixtures.js.map +1 -0
  232. package/dist/helpers/__tests__/flare.test.d.ts +1 -0
  233. package/dist/helpers/__tests__/flare.test.js +226 -0
  234. package/dist/helpers/__tests__/flare.test.js.map +1 -0
  235. package/dist/helpers/__tests__/fs.test.d.ts +1 -0
  236. package/dist/helpers/__tests__/fs.test.js +189 -0
  237. package/dist/helpers/__tests__/fs.test.js.map +1 -0
  238. package/dist/helpers/__tests__/plist.test.d.ts +1 -0
  239. package/dist/helpers/__tests__/plist.test.js +43 -0
  240. package/dist/helpers/__tests__/plist.test.js.map +1 -0
  241. package/dist/helpers/__tests__/prompt.test.d.ts +1 -0
  242. package/dist/helpers/__tests__/prompt.test.js +71 -0
  243. package/dist/helpers/__tests__/prompt.test.js.map +1 -0
  244. package/dist/helpers/__tests__/retry.test.d.ts +1 -0
  245. package/dist/helpers/__tests__/retry.test.js +99 -0
  246. package/dist/helpers/__tests__/retry.test.js.map +1 -0
  247. package/dist/helpers/__tests__/tags.test.d.ts +1 -0
  248. package/dist/helpers/__tests__/tags.test.js +71 -0
  249. package/dist/helpers/__tests__/tags.test.js.map +1 -0
  250. package/dist/helpers/__tests__/upload.test.d.ts +1 -0
  251. package/dist/helpers/__tests__/upload.test.js +231 -0
  252. package/dist/helpers/__tests__/upload.test.js.map +1 -0
  253. package/dist/helpers/__tests__/user-provided-git.test.d.ts +1 -0
  254. package/dist/helpers/__tests__/user-provided-git.test.js +119 -0
  255. package/dist/helpers/__tests__/user-provided-git.test.js.map +1 -0
  256. package/dist/helpers/__tests__/utils.test.d.ts +1 -0
  257. package/dist/helpers/__tests__/utils.test.js +429 -0
  258. package/dist/helpers/__tests__/utils.test.js.map +1 -0
  259. package/dist/helpers/__tests__/validation.test.d.ts +1 -0
  260. package/dist/helpers/__tests__/validation.test.js +25 -0
  261. package/dist/helpers/__tests__/validation.test.js.map +1 -0
  262. package/dist/helpers/git/__tests__/format-git-sourcemaps-data.test.d.ts +1 -0
  263. package/dist/helpers/git/__tests__/format-git-sourcemaps-data.test.js +103 -0
  264. package/dist/helpers/git/__tests__/format-git-sourcemaps-data.test.js.map +1 -0
  265. package/dist/helpers/git/__tests__/format-git-span-data.test.d.ts +1 -0
  266. package/dist/helpers/git/__tests__/format-git-span-data.test.js +121 -0
  267. package/dist/helpers/git/__tests__/format-git-span-data.test.js.map +1 -0
  268. package/dist/helpers/git/__tests__/get-git-data.test.d.ts +1 -0
  269. package/dist/helpers/git/__tests__/get-git-data.test.js +72 -0
  270. package/dist/helpers/git/__tests__/get-git-data.test.js.map +1 -0
  271. package/package.json +4 -6
@@ -0,0 +1,1526 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ jest.mock('glob');
39
+ jest.mock('fs');
40
+ jest.mock('child_process');
41
+ jest.unmock('chalk');
42
+ jest.mock('path', () => {
43
+ const actualPath = jest.requireActual('path');
44
+ return Object.assign(Object.assign({}, actualPath), { relative: (from, to) => {
45
+ if (from === '/path/to/project' && to === '/path/to/another-project') {
46
+ return '../another-project';
47
+ }
48
+ if (from === '/path/to/project' && to === '/other-path/to/project') {
49
+ return '../../../other-path/to/project';
50
+ }
51
+ if (from === '/path/to/git/repository' && to === '/path/to/another-project') {
52
+ return '../../another-project';
53
+ }
54
+ if (from === '/path/to/git/repository' && to === '/other-path/to/project') {
55
+ return '../../../../other-path/to/project';
56
+ }
57
+ if (from.endsWith('subfolder') || to.endsWith('subfolder')) {
58
+ return 'subfolder';
59
+ }
60
+ if (to === '..') {
61
+ return '..';
62
+ }
63
+ return '.';
64
+ } });
65
+ });
66
+ const child_process_1 = __importDefault(require("child_process"));
67
+ const fs = __importStar(require("fs"));
68
+ const process_1 = __importDefault(require("process"));
69
+ const axios_1 = __importDefault(require("axios"));
70
+ const deep_extend_1 = __importDefault(require("deep-extend"));
71
+ const glob_1 = require("glob");
72
+ process_1.default.env.DATADOG_SYNTHETICS_CI_TRIGGER_APP = 'env_default';
73
+ const ciHelpers = __importStar(require("../../../../helpers/ci"));
74
+ const api_1 = require("../../api");
75
+ const errors_1 = require("../../errors");
76
+ const interfaces_1 = require("../../interfaces");
77
+ const mobile = __importStar(require("../../mobile"));
78
+ const run_tests_command_1 = require("../../run-tests-command");
79
+ const utils = __importStar(require("../../utils/public"));
80
+ const fixtures_1 = require("../fixtures");
81
+ describe('utils', () => {
82
+ const apiConfiguration = {
83
+ apiKey: '123',
84
+ appKey: '123',
85
+ baseIntakeUrl: 'baseintake',
86
+ baseUnstableUrl: 'baseUnstable',
87
+ baseUrl: 'base',
88
+ proxyOpts: { protocol: 'http' },
89
+ };
90
+ const api = (0, api_1.apiConstructor)(apiConfiguration);
91
+ describe('getSuites', () => {
92
+ const GLOB = 'testGlob';
93
+ const FILES = ['file1', 'file2'];
94
+ const FILES_CONTENT = {
95
+ file1: '{"tests":"file1"}',
96
+ file2: '{"tests":"file2"}',
97
+ };
98
+ jest.spyOn(glob_1.glob, 'glob').mockResolvedValue(FILES);
99
+ fs.readFile.mockImplementation((path, opts, callback) => callback(undefined, FILES_CONTENT[path]));
100
+ child_process_1.default.exec.mockImplementation((command, callback) => callback(undefined, '.', ''));
101
+ test('should get suites', () => __awaiter(void 0, void 0, void 0, function* () {
102
+ const suites = yield utils.getSuites(GLOB, fixtures_1.mockReporter);
103
+ expect(JSON.stringify(suites)).toBe(`[{"name":"file1","content":${FILES_CONTENT.file1}},{"name":"file2","content":${FILES_CONTENT.file2}}]`);
104
+ }));
105
+ });
106
+ describe('getFilePathRelativeToRepo', () => {
107
+ test('datadog-ci is not run in a git repository', () => __awaiter(void 0, void 0, void 0, function* () {
108
+ const pathToProject = '/path/to/project';
109
+ jest.spyOn(process_1.default, 'cwd').mockImplementation(() => pathToProject);
110
+ child_process_1.default.exec.mockImplementation((command, callback) => callback(Error('Not a git repository'), '', ''));
111
+ // Use the process working directory instead of the git repository's top level.
112
+ yield expect(utils.getFilePathRelativeToRepo('config.json')).resolves.toEqual('config.json');
113
+ yield expect(utils.getFilePathRelativeToRepo('./config.json')).resolves.toEqual('config.json');
114
+ yield expect(utils.getFilePathRelativeToRepo(`${pathToProject}/config.json`)).resolves.toEqual('config.json');
115
+ // Those cases will show a broken hyperlink in the GitLab test report because the file is outside of the project.
116
+ yield expect(utils.getFilePathRelativeToRepo('../config.json')).resolves.toEqual('../config.json');
117
+ yield expect(utils.getFilePathRelativeToRepo('/path/to/another-project/config.json')).resolves.toEqual('../another-project/config.json');
118
+ yield expect(utils.getFilePathRelativeToRepo('/other-path/to/project/config.json')).resolves.toEqual('../../../other-path/to/project/config.json');
119
+ }));
120
+ test('datadog-ci is run in the root of a git repository', () => __awaiter(void 0, void 0, void 0, function* () {
121
+ const pathToGitRepository = '/path/to/git/repository';
122
+ jest.spyOn(process_1.default, 'cwd').mockImplementation(() => pathToGitRepository);
123
+ child_process_1.default.exec.mockImplementation((command, callback) => callback(undefined, pathToGitRepository, ''));
124
+ yield expect(utils.getFilePathRelativeToRepo('config.json')).resolves.toEqual('config.json');
125
+ yield expect(utils.getFilePathRelativeToRepo('./config.json')).resolves.toEqual('config.json');
126
+ yield expect(utils.getFilePathRelativeToRepo(`${pathToGitRepository}/config.json`)).resolves.toEqual('config.json');
127
+ yield expect(utils.getFilePathRelativeToRepo('subfolder/config.json')).resolves.toEqual('subfolder/config.json');
128
+ yield expect(utils.getFilePathRelativeToRepo('./subfolder/config.json')).resolves.toEqual('subfolder/config.json');
129
+ yield expect(utils.getFilePathRelativeToRepo(`${pathToGitRepository}/subfolder/config.json`)).resolves.toEqual('subfolder/config.json');
130
+ // Those cases will show a broken hyperlink in the GitLab test report because the file is outside of the repository.
131
+ yield expect(utils.getFilePathRelativeToRepo('../config.json')).resolves.toEqual('../config.json');
132
+ yield expect(utils.getFilePathRelativeToRepo('/path/to/another-project/config.json')).resolves.toEqual('../../another-project/config.json');
133
+ yield expect(utils.getFilePathRelativeToRepo('/other-path/to/project/config.json')).resolves.toEqual('../../../../other-path/to/project/config.json');
134
+ }));
135
+ test('datadog-ci is run in a subfolder of a git repository', () => __awaiter(void 0, void 0, void 0, function* () {
136
+ const pathToGitRepositorySubfolder = '/path/to/git/repository/subfolder';
137
+ jest.spyOn(process_1.default, 'cwd').mockImplementation(() => pathToGitRepositorySubfolder);
138
+ child_process_1.default.exec.mockImplementation((command, callback) => callback(undefined, '/path/to/git/repository', ''));
139
+ // ...so the relative path must be prefixed with the subfolder.
140
+ yield expect(utils.getFilePathRelativeToRepo('config.json')).resolves.toEqual('subfolder/config.json');
141
+ yield expect(utils.getFilePathRelativeToRepo('./config.json')).resolves.toEqual('subfolder/config.json');
142
+ yield expect(utils.getFilePathRelativeToRepo(`${pathToGitRepositorySubfolder}/config.json`)).resolves.toEqual('subfolder/config.json');
143
+ }));
144
+ });
145
+ describe('runTest', () => {
146
+ beforeEach(() => {
147
+ jest.restoreAllMocks();
148
+ });
149
+ const fakeId = '123-456-789';
150
+ const fakeTrigger = {
151
+ batch_id: 'bid',
152
+ locations: [],
153
+ };
154
+ test('should run test', () => __awaiter(void 0, void 0, void 0, function* () {
155
+ jest.spyOn(api, 'triggerTests').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return fakeTrigger; }));
156
+ const output = yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]);
157
+ expect(output).toEqual(fakeTrigger);
158
+ }));
159
+ test('runTests sends batch metadata', () => __awaiter(void 0, void 0, void 0, function* () {
160
+ jest.spyOn(ciHelpers, 'getCIMetadata').mockImplementation(() => undefined);
161
+ const payloadMetadataSpy = jest.fn();
162
+ jest.spyOn(axios_1.default, 'create').mockImplementation((() => (request) => {
163
+ payloadMetadataSpy(request.data.metadata);
164
+ if (request.url === '/synthetics/tests/trigger/ci') {
165
+ return { data: fakeTrigger };
166
+ }
167
+ }));
168
+ yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]);
169
+ expect(payloadMetadataSpy).toHaveBeenCalledWith(undefined);
170
+ const metadata = {
171
+ ci: { job: { name: 'job' }, pipeline: {}, provider: { name: 'jest' }, stage: {} },
172
+ git: { commit: { author: {}, committer: {}, message: 'test' } },
173
+ };
174
+ jest.spyOn(ciHelpers, 'getCIMetadata').mockImplementation(() => metadata);
175
+ yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]);
176
+ expect(payloadMetadataSpy).toHaveBeenCalledWith(metadata);
177
+ }));
178
+ test('runTests api call includes trigger app header', () => __awaiter(void 0, void 0, void 0, function* () {
179
+ jest.spyOn(ciHelpers, 'getCIMetadata').mockImplementation(() => undefined);
180
+ const headersMetadataSpy = jest.fn();
181
+ jest.spyOn(axios_1.default, 'create').mockImplementation((() => (request) => {
182
+ headersMetadataSpy(request.headers);
183
+ if (request.url === '/synthetics/tests/trigger/ci') {
184
+ return { data: fakeTrigger };
185
+ }
186
+ }));
187
+ yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]);
188
+ expect(headersMetadataSpy).toHaveBeenCalledWith(expect.objectContaining({ 'X-Trigger-App': 'env_default' }));
189
+ utils.setCiTriggerApp('unit_test');
190
+ yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]);
191
+ expect(headersMetadataSpy).toHaveBeenCalledWith(expect.objectContaining({ 'X-Trigger-App': 'unit_test' }));
192
+ }));
193
+ test('runTests api call does not send deprecated properties', () => __awaiter(void 0, void 0, void 0, function* () {
194
+ jest.spyOn(ciHelpers, 'getCIMetadata').mockImplementation(() => undefined);
195
+ const testsPayloadSpy = jest.fn();
196
+ jest.spyOn(axios_1.default, 'create').mockImplementation((() => (request) => {
197
+ testsPayloadSpy(request.data.tests);
198
+ if (request.url === '/synthetics/tests/trigger/ci') {
199
+ return { data: fakeTrigger };
200
+ }
201
+ }));
202
+ yield utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING, pollingTimeout: 1 }]);
203
+ expect(testsPayloadSpy).toHaveBeenCalledWith([
204
+ {
205
+ public_id: fakeId,
206
+ executionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
207
+ // no pollingTimeout
208
+ },
209
+ ]);
210
+ }));
211
+ test('should run test with publicId from url', () => __awaiter(void 0, void 0, void 0, function* () {
212
+ jest.spyOn(api, 'triggerTests').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return fakeTrigger; }));
213
+ const output = yield utils.runTests(api, [
214
+ {
215
+ executionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
216
+ public_id: `http://localhost/synthetics/tests/details/${fakeId}`,
217
+ },
218
+ ]);
219
+ expect(output).toEqual(fakeTrigger);
220
+ }));
221
+ test('triggerTests throws', () => __awaiter(void 0, void 0, void 0, function* () {
222
+ jest.spyOn(api, 'triggerTests').mockImplementation(() => {
223
+ throw (0, fixtures_1.getAxiosHttpError)(502, { message: 'Server Error' });
224
+ });
225
+ yield expect(utils.runTests(api, [{ public_id: fakeId, executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }])).rejects.toThrow(/Failed to trigger tests:/);
226
+ }));
227
+ });
228
+ describe('getTestsToTrigger', () => {
229
+ const fakeTests = {
230
+ '123-456-789': {
231
+ config: { request: { url: 'http://example.org/' } },
232
+ name: 'Fake Test',
233
+ public_id: '123-456-789',
234
+ suite: 'Suite 1',
235
+ },
236
+ 'mob-ile-tes': {
237
+ config: {},
238
+ name: 'Fake Mobile Test',
239
+ options: {
240
+ mobileApplication: {
241
+ applicationId: 'appId',
242
+ referenceId: 'versionId',
243
+ referenceType: 'version',
244
+ },
245
+ },
246
+ public_id: 'mob-ile-tes',
247
+ suite: 'Suite 3',
248
+ type: 'mobile',
249
+ },
250
+ 'ski-ppe-d01': {
251
+ config: { request: { url: 'http://example.org/' } },
252
+ name: 'Skipped Fake Test',
253
+ options: { ci: { executionRule: 'skipped' } },
254
+ public_id: 'ski-ppe-d01',
255
+ suite: 'Suite 3',
256
+ },
257
+ };
258
+ beforeEach(() => {
259
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
260
+ axiosMock.mockImplementation((() => (e) => {
261
+ const publicId = e.url.slice(18);
262
+ if (fakeTests[publicId]) {
263
+ return { data: fakeTests[publicId] };
264
+ }
265
+ throw (0, fixtures_1.getAxiosHttpError)(404, { errors: ['Not found'] });
266
+ }));
267
+ });
268
+ test('only existing tests are returned', () => __awaiter(void 0, void 0, void 0, function* () {
269
+ const triggerConfigs = [
270
+ { suite: 'Suite 1', config: {}, id: '123-456-789' },
271
+ { suite: 'Suite 2', config: {}, id: '987-654-321' },
272
+ { suite: 'Suite 3', config: {}, id: 'ski-ppe-d01' },
273
+ ];
274
+ const { tests, overriddenTestsToTrigger, initialSummary } = yield utils.getTestsToTrigger(api, triggerConfigs, fixtures_1.mockReporter);
275
+ expect(tests).toStrictEqual([fakeTests['123-456-789']]);
276
+ expect(overriddenTestsToTrigger).toStrictEqual([{ public_id: '123-456-789' }, { public_id: 'ski-ppe-d01' }]);
277
+ const expectedSummary = {
278
+ criticalErrors: 0,
279
+ expected: 0,
280
+ failed: 0,
281
+ failedNonBlocking: 0,
282
+ passed: 0,
283
+ previouslyPassed: 0,
284
+ skipped: 1,
285
+ testsNotFound: new Set(['987-654-321']),
286
+ timedOut: 0,
287
+ };
288
+ expect(initialSummary).toEqual(expectedSummary);
289
+ }));
290
+ test('no tests triggered throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
291
+ yield expect(utils.getTestsToTrigger(api, [], fixtures_1.mockReporter)).rejects.toEqual(new errors_1.CiError('NO_TESTS_TO_RUN'));
292
+ }));
293
+ describe('too many tests to trigger', () => {
294
+ const fakeApi = Object.assign(Object.assign({}, api), { getTest: (id) => {
295
+ if (id === 'missing') {
296
+ throw new Error('Request error');
297
+ }
298
+ const test = Object.assign({}, (0, fixtures_1.getApiTest)(id));
299
+ if (id === 'skipped') {
300
+ test.options.ci = { executionRule: interfaces_1.ExecutionRule.SKIPPED };
301
+ }
302
+ return Promise.resolve(test);
303
+ } });
304
+ test('trim and warn if from search', () => __awaiter(void 0, void 0, void 0, function* () {
305
+ const tooManyTests = Array(run_tests_command_1.MAX_TESTS_TO_TRIGGER + 10).fill({ id: 'stu-vwx-yza' });
306
+ const tests = yield utils.getTestsToTrigger(fakeApi, tooManyTests, fixtures_1.mockReporter, true);
307
+ expect(tests.tests.length).toBe(run_tests_command_1.MAX_TESTS_TO_TRIGGER);
308
+ expect(fixtures_1.mockReporter.initErrors).toMatchSnapshot();
309
+ }));
310
+ test('fails outside of search', () => __awaiter(void 0, void 0, void 0, function* () {
311
+ const tooManyTests = Array(run_tests_command_1.MAX_TESTS_TO_TRIGGER + 10).fill({ id: 'stu-vwx-yza' });
312
+ yield expect(utils.getTestsToTrigger(fakeApi, tooManyTests, fixtures_1.mockReporter, false)).rejects.toEqual(new Error(`Cannot trigger more than ${run_tests_command_1.MAX_TESTS_TO_TRIGGER} tests (received ${tooManyTests.length})`));
313
+ }));
314
+ test('does not account for skipped/not found tests outside of search', () => __awaiter(void 0, void 0, void 0, function* () {
315
+ const tooManyTests = [
316
+ ...Array(run_tests_command_1.MAX_TESTS_TO_TRIGGER).fill({ id: 'stu-vwx-yza' }),
317
+ { id: 'skipped' },
318
+ { id: 'missing' },
319
+ ];
320
+ const tests = yield utils.getTestsToTrigger(fakeApi, tooManyTests, fixtures_1.mockReporter, true);
321
+ expect(tests.tests.length).toBe(run_tests_command_1.MAX_TESTS_TO_TRIGGER);
322
+ }));
323
+ });
324
+ test('call uploadApplicationAndOverrideConfig on mobile test', () => __awaiter(void 0, void 0, void 0, function* () {
325
+ const spy = jest.spyOn(mobile, 'uploadMobileApplicationsAndUpdateOverrideConfigs').mockImplementation();
326
+ const triggerConfigs = [
327
+ { suite: 'Suite 1', config: {}, id: '123-456-789' },
328
+ { suite: 'Suite 3', config: {}, id: 'mob-ile-tes' },
329
+ ];
330
+ yield utils.getTestsToTrigger(api, triggerConfigs, fixtures_1.mockReporter);
331
+ expect(spy).toHaveBeenCalledTimes(1);
332
+ }));
333
+ });
334
+ describe('getTestAndOverrideConfig', () => {
335
+ test('Forbidden error when getting a test', () => __awaiter(void 0, void 0, void 0, function* () {
336
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
337
+ axiosMock.mockImplementation((() => (e) => {
338
+ throw (0, fixtures_1.getAxiosHttpError)(403, { message: 'Forbidden' });
339
+ }));
340
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
341
+ yield expect(() => utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)())).rejects.toThrow('Failed to get test: could not query https://app.datadoghq.com/example\nForbidden\n');
342
+ }));
343
+ test('Passes when public ID is valid', () => __awaiter(void 0, void 0, void 0, function* () {
344
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
345
+ axiosMock.mockImplementation((() => (e) => {
346
+ return { data: { subtype: 'http', public_id: '123-456-789' } };
347
+ }));
348
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
349
+ expect(yield utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)())).toEqual(expect.objectContaining({ test: expect.objectContaining({ public_id: '123-456-789', subtype: 'http' }) }));
350
+ }));
351
+ test('Fails when public ID is NOT valid', () => __awaiter(void 0, void 0, void 0, function* () {
352
+ const expectedError = new errors_1.CiError('INVALID_CONFIG', `No valid public ID found in: \`a123-456-789\``);
353
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: 'a123-456-789' };
354
+ yield expect(utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)())).rejects.toThrow(expectedError);
355
+ }));
356
+ test('Passes when the tunnel is enabled for HTTP test', () => __awaiter(void 0, void 0, void 0, function* () {
357
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
358
+ axiosMock.mockImplementation((() => (e) => {
359
+ return { data: { subtype: 'http', public_id: '123-456-789' } };
360
+ }));
361
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
362
+ expect(yield utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)(), true)).toEqual(expect.objectContaining({ test: expect.objectContaining({ public_id: '123-456-789', subtype: 'http' }) }));
363
+ }));
364
+ test('Passes when the tunnel is enabled for Browser test', () => __awaiter(void 0, void 0, void 0, function* () {
365
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
366
+ axiosMock.mockImplementation((() => (e) => {
367
+ return { data: { type: 'browser', public_id: '123-456-789' } };
368
+ }));
369
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
370
+ expect(yield utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)(), true)).toEqual(expect.objectContaining({ test: expect.objectContaining({ public_id: '123-456-789', type: 'browser' }) }));
371
+ }));
372
+ test('Passes when the tunnel is enabled for Multi step test with HTTP steps only', () => __awaiter(void 0, void 0, void 0, function* () {
373
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
374
+ axiosMock.mockImplementation((() => (e) => {
375
+ return {
376
+ data: {
377
+ type: 'api',
378
+ subtype: 'multi',
379
+ config: { steps: [{ subtype: 'http' }, { subtype: 'http' }] },
380
+ public_id: '123-456-789',
381
+ },
382
+ };
383
+ }));
384
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
385
+ expect(yield utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)(), true)).toEqual(expect.objectContaining({
386
+ test: expect.objectContaining({
387
+ public_id: '123-456-789',
388
+ type: 'api',
389
+ subtype: 'multi',
390
+ config: { steps: [{ subtype: 'http' }, { subtype: 'http' }] },
391
+ }),
392
+ }));
393
+ }));
394
+ test('Fails when the tunnel is enabled for an unsupported test type', () => __awaiter(void 0, void 0, void 0, function* () {
395
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
396
+ axiosMock.mockImplementation((() => (e) => {
397
+ return { data: { subtype: 'grpc', type: 'api', public_id: '123-456-789' } };
398
+ }));
399
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
400
+ yield expect(() => utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)(), true)).rejects.toThrow('The tunnel is only supported with HTTP API tests and Browser tests (public ID: 123-456-789, type: api, sub-type: grpc).');
401
+ }));
402
+ test('Fails when the tunnel is enabled for unsupported steps in a Multi step test', () => __awaiter(void 0, void 0, void 0, function* () {
403
+ const axiosMock = jest.spyOn(axios_1.default, 'create');
404
+ axiosMock.mockImplementation((() => (e) => {
405
+ return {
406
+ data: {
407
+ type: 'api',
408
+ subtype: 'multi',
409
+ config: { steps: [{ subtype: 'dns' }, { subtype: 'ssl' }, { subtype: 'http' }] },
410
+ public_id: '123-456-789',
411
+ },
412
+ };
413
+ }));
414
+ const triggerConfig = { suite: 'Suite 1', config: {}, id: '123-456-789' };
415
+ yield expect(() => utils.getTestAndOverrideConfig(api, triggerConfig, fixtures_1.mockReporter, (0, fixtures_1.getSummary)(), true)).rejects.toThrow('The tunnel is only supported with HTTP API tests and Browser tests (public ID: 123-456-789, type: api, sub-type: multi, step sub-types: [dns, ssl]).');
416
+ }));
417
+ });
418
+ describe('normalizePublicId', () => {
419
+ test('should normalize public ID', () => {
420
+ expect(utils.normalizePublicId('http://localhost/synthetics/tests/details/123-456-789')).toBe('123-456-789');
421
+ expect(utils.normalizePublicId('123-456-789')).toBe('123-456-789');
422
+ });
423
+ test('should be undefined if id is invalid', () => {
424
+ expect(utils.normalizePublicId('http://localhost/synthetics/tests/details/123-456-7890')).toBe(undefined);
425
+ expect(utils.normalizePublicId('0123-456-789')).toBe(undefined);
426
+ });
427
+ });
428
+ describe('getOverriddenConfig', () => {
429
+ test('empty config returns simple payload', () => {
430
+ const publicId = 'abc-def-ghi';
431
+ expect(utils.getOverriddenConfig({ public_id: publicId }, publicId, fixtures_1.mockReporter)).toEqual({
432
+ public_id: publicId,
433
+ });
434
+ });
435
+ test('strictest executionRule is forwarded when it has to be', () => {
436
+ const expectHandledConfigToBe = (expectedExecutionRule, configExecutionRule, testExecutionRule) => {
437
+ const publicId = 'abc-def-ghi';
438
+ const fakeTest = {
439
+ config: { request: { url: 'http://example.org/path' } },
440
+ options: {},
441
+ public_id: publicId,
442
+ };
443
+ if (testExecutionRule) {
444
+ fakeTest.options.ci = { executionRule: testExecutionRule };
445
+ }
446
+ const configOverride = configExecutionRule ? { executionRule: configExecutionRule } : undefined;
447
+ const overriddenConfig = utils.getOverriddenConfig(fakeTest, publicId, fixtures_1.mockReporter, configOverride);
448
+ expect(overriddenConfig.public_id).toBe(publicId);
449
+ expect(overriddenConfig.executionRule).toBe(expectedExecutionRule);
450
+ };
451
+ const BLOCKING = interfaces_1.ExecutionRule.BLOCKING;
452
+ const NON_BLOCKING = interfaces_1.ExecutionRule.NON_BLOCKING;
453
+ const SKIPPED = interfaces_1.ExecutionRule.SKIPPED;
454
+ // No override => nothing, let the backend decide
455
+ expectHandledConfigToBe(undefined);
456
+ // CI config overrides only
457
+ expectHandledConfigToBe(BLOCKING, BLOCKING);
458
+ expectHandledConfigToBe(NON_BLOCKING, NON_BLOCKING);
459
+ expectHandledConfigToBe(SKIPPED, SKIPPED);
460
+ // Test config only => nothing, let the backend decide
461
+ expectHandledConfigToBe(undefined, undefined, BLOCKING);
462
+ expectHandledConfigToBe(undefined, undefined, NON_BLOCKING);
463
+ expectHandledConfigToBe(undefined, undefined, SKIPPED);
464
+ // Strictest executionRule is forwarded
465
+ expectHandledConfigToBe(NON_BLOCKING, BLOCKING, NON_BLOCKING);
466
+ expectHandledConfigToBe(SKIPPED, SKIPPED, BLOCKING);
467
+ expectHandledConfigToBe(SKIPPED, NON_BLOCKING, SKIPPED);
468
+ expectHandledConfigToBe(SKIPPED, SKIPPED, NON_BLOCKING);
469
+ });
470
+ test('startUrl is not parsable', () => {
471
+ const envVars = Object.assign({}, process_1.default.env);
472
+ process_1.default.env = { CUSTOMVAR: '/newPath' };
473
+ const publicId = 'abc-def-ghi';
474
+ const fakeTest = {
475
+ config: { request: { url: 'http://{{ FAKE_VAR }}/path' } },
476
+ public_id: publicId,
477
+ type: 'browser',
478
+ };
479
+ const configOverride = {
480
+ startUrl: 'https://{{FAKE_VAR}}/newPath?oldPath={{CUSTOMVAR}}',
481
+ };
482
+ const expectedUrl = 'https://{{FAKE_VAR}}/newPath?oldPath=/newPath';
483
+ const overriddenConfig = utils.getOverriddenConfig(fakeTest, publicId, fixtures_1.mockReporter, configOverride);
484
+ expect(overriddenConfig.public_id).toBe(publicId);
485
+ expect(overriddenConfig.startUrl).toBe(expectedUrl);
486
+ process_1.default.env = envVars;
487
+ });
488
+ test('config overrides are applied', () => {
489
+ const publicId = 'abc-def-ghi';
490
+ const fakeTest = {
491
+ config: { request: { url: 'http://example.org/path' } },
492
+ public_id: publicId,
493
+ type: 'browser',
494
+ };
495
+ const configOverride = {
496
+ allowInsecureCertificates: true,
497
+ basicAuth: { username: 'user', password: 'password' },
498
+ body: 'body',
499
+ bodyType: 'application/json',
500
+ cookies: 'name=value;',
501
+ defaultStepTimeout: 15,
502
+ deviceIds: ['device_id'],
503
+ executionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
504
+ followRedirects: true,
505
+ headers: { 'header-name': 'value' },
506
+ locations: ['location'],
507
+ pollingTimeout: 60 * 1000,
508
+ retry: { count: 5, interval: 30 },
509
+ startUrl: 'http://127.0.0.1:60/newPath',
510
+ startUrlSubstitutionRegex: '.*',
511
+ testTimeout: 360,
512
+ tunnel: { host: 'host', id: 'id', privateKey: 'privateKey' },
513
+ variables: { VAR_1: 'value' },
514
+ };
515
+ expect(utils.getOverriddenConfig(fakeTest, publicId, fixtures_1.mockReporter, configOverride)).toEqual(Object.assign(Object.assign({}, configOverride), { public_id: publicId }));
516
+ });
517
+ });
518
+ describe('getTestOverridesCount', () => {
519
+ test('should count overrides', () => {
520
+ expect(utils.getTestOverridesCount({})).toBe(0);
521
+ // If the user sets anything, even an empty array or object, it counts as an override
522
+ expect(utils.getTestOverridesCount({ deviceIds: [] })).toBe(1);
523
+ expect(utils.getTestOverridesCount({ headers: {} })).toBe(1);
524
+ expect(utils.getTestOverridesCount({ deviceIds: ['a'] })).toBe(1);
525
+ expect(utils.getTestOverridesCount({ pollingTimeout: 123 })).toBe(1);
526
+ // Should ignore the default value for the pollingTimeout
527
+ expect(utils.getTestOverridesCount({ pollingTimeout: run_tests_command_1.DEFAULT_POLLING_TIMEOUT })).toBe(0);
528
+ });
529
+ });
530
+ describe('hasResultPassed', () => {
531
+ test('complete result', () => {
532
+ const result = {
533
+ device: { height: 1100, id: 'chrome.laptop_large', width: 1440 },
534
+ duration: 0,
535
+ passed: true,
536
+ startUrl: '',
537
+ stepDetails: [],
538
+ };
539
+ expect(utils.hasResultPassed(result, false, false, true)).toBeTruthy();
540
+ expect(utils.hasResultPassed(result, false, true, true)).toBeTruthy();
541
+ result.passed = false;
542
+ expect(utils.hasResultPassed(result, false, false, true)).toBeFalsy();
543
+ expect(utils.hasResultPassed(result, false, true, true)).toBeFalsy();
544
+ });
545
+ test('result with error', () => {
546
+ const result = {
547
+ device: { height: 1100, id: 'chrome.laptop_large', width: 1440 },
548
+ duration: 0,
549
+ failure: {
550
+ code: 'ERRABORTED',
551
+ message: 'Connection aborted',
552
+ },
553
+ passed: false,
554
+ startUrl: '',
555
+ stepDetails: [],
556
+ };
557
+ expect(utils.hasResultPassed(result, false, false, true)).toBeFalsy();
558
+ expect(utils.hasResultPassed(result, false, true, true)).toBeFalsy();
559
+ });
560
+ test('result with unhealthy result', () => {
561
+ const result = {
562
+ device: { height: 1100, id: 'chrome.laptop_large', width: 1440 },
563
+ duration: 0,
564
+ failure: {
565
+ code: 'ERRABORTED',
566
+ message: 'Connection aborted',
567
+ },
568
+ passed: false,
569
+ startUrl: '',
570
+ stepDetails: [],
571
+ unhealthy: true,
572
+ };
573
+ expect(utils.hasResultPassed(result, false, false, true)).toBeTruthy();
574
+ expect(utils.hasResultPassed(result, false, true, true)).toBeFalsy();
575
+ });
576
+ test('result with timeout result', () => {
577
+ const result = {
578
+ device: { height: 1100, id: 'chrome.laptop_large', width: 1440 },
579
+ duration: 0,
580
+ passed: false,
581
+ startUrl: '',
582
+ stepDetails: [],
583
+ };
584
+ expect(utils.hasResultPassed(result, true, true, true)).toBeFalsy();
585
+ expect(utils.hasResultPassed(result, true, true, false)).toBeTruthy();
586
+ });
587
+ });
588
+ describe('getExecutionRule', () => {
589
+ const cases = [
590
+ [undefined, undefined, interfaces_1.ExecutionRule.BLOCKING],
591
+ [undefined, interfaces_1.ExecutionRule.BLOCKING, interfaces_1.ExecutionRule.BLOCKING],
592
+ [undefined, interfaces_1.ExecutionRule.NON_BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING],
593
+ [interfaces_1.ExecutionRule.BLOCKING, undefined, interfaces_1.ExecutionRule.BLOCKING],
594
+ [interfaces_1.ExecutionRule.BLOCKING, interfaces_1.ExecutionRule.BLOCKING, interfaces_1.ExecutionRule.BLOCKING],
595
+ [interfaces_1.ExecutionRule.BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING],
596
+ [interfaces_1.ExecutionRule.NON_BLOCKING, undefined, interfaces_1.ExecutionRule.NON_BLOCKING],
597
+ [interfaces_1.ExecutionRule.NON_BLOCKING, interfaces_1.ExecutionRule.BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING],
598
+ [interfaces_1.ExecutionRule.NON_BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING, interfaces_1.ExecutionRule.NON_BLOCKING],
599
+ ];
600
+ test.each(cases)('execution rule: %s, result execution rule: %s. Expected rule: %s', (testRule, resultRule, expectedRule) => {
601
+ const test = (0, fixtures_1.getApiTest)('abc-def-ghi');
602
+ expect(utils.getExecutionRule(testRule ? Object.assign(Object.assign({}, test), { options: Object.assign(Object.assign({}, test.options), { ci: { executionRule: testRule } }) }) : test, resultRule ? { executionRule: resultRule } : {})).toEqual(expectedRule);
603
+ });
604
+ });
605
+ describe('getResultOutcome', () => {
606
+ const cases = [
607
+ [true, interfaces_1.ExecutionRule.BLOCKING, undefined, "passed" /* utils.ResultOutcome.Passed */],
608
+ [
609
+ true,
610
+ interfaces_1.ExecutionRule.SKIPPED,
611
+ { decision: 'skip', reason: 'passed', linked_result_id: '' },
612
+ "previously-passed" /* utils.ResultOutcome.PreviouslyPassed */,
613
+ ],
614
+ [true, interfaces_1.ExecutionRule.NON_BLOCKING, undefined, "passed-non-blocking" /* utils.ResultOutcome.PassedNonBlocking */],
615
+ [false, interfaces_1.ExecutionRule.BLOCKING, undefined, "failed" /* utils.ResultOutcome.Failed */],
616
+ [false, interfaces_1.ExecutionRule.NON_BLOCKING, undefined, "failed-non-blocking" /* utils.ResultOutcome.FailedNonBlocking */],
617
+ ];
618
+ test.each(cases)('Result passed: %s, execution rule: %s. Expected outcome: %s', (passed, resultRule, selectiveRerun, expectedOutcome) => {
619
+ jest.spyOn(utils, 'getExecutionRule').mockReturnValue(resultRule);
620
+ const test = (0, fixtures_1.getApiTest)('abc-def-ghi');
621
+ const result = (0, fixtures_1.getApiResult)('1', test);
622
+ result.executionRule = resultRule;
623
+ result.passed = passed;
624
+ result.selectiveRerun = selectiveRerun;
625
+ expect(utils.getResultOutcome(result)).toEqual(expectedOutcome);
626
+ });
627
+ });
628
+ describe('waitForResults', () => {
629
+ beforeEach(() => {
630
+ jest.useFakeTimers();
631
+ jest.spyOn(utils, 'wait').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return jest.advanceTimersByTime(5000); }));
632
+ });
633
+ afterEach(() => {
634
+ jest.useRealTimers();
635
+ jest.restoreAllMocks();
636
+ });
637
+ const batch = (0, fixtures_1.getBatch)();
638
+ const apiTest = (0, fixtures_1.getApiTest)('pid');
639
+ const incompleteServerResult = { eventType: 'created' };
640
+ const result = {
641
+ executionRule: interfaces_1.ExecutionRule.BLOCKING,
642
+ location: fixtures_1.mockLocation.display_name,
643
+ passed: true,
644
+ result: (0, fixtures_1.getBrowserServerResult)({ passed: true }),
645
+ resultId: 'rid',
646
+ retries: 0,
647
+ selectiveRerun: undefined,
648
+ test: apiTest,
649
+ timedOut: false,
650
+ timestamp: 0,
651
+ };
652
+ const pollResult = {
653
+ check: result.test,
654
+ result: result.result,
655
+ resultID: result.resultId,
656
+ timestamp: result.timestamp,
657
+ };
658
+ const trigger = { batch_id: 'bid', locations: [fixtures_1.mockLocation] };
659
+ const mockApi = ({ getBatchImplementation, pollResultsImplementation, } = {}) => {
660
+ const getBatchMock = jest
661
+ .spyOn(api, 'getBatch')
662
+ .mockImplementation(getBatchImplementation || (() => __awaiter(void 0, void 0, void 0, function* () { return (0, deep_extend_1.default)({}, batch); })));
663
+ const pollResultsMock = jest
664
+ .spyOn(api, 'pollResults')
665
+ .mockImplementation(pollResultsImplementation || (() => __awaiter(void 0, void 0, void 0, function* () { return [(0, deep_extend_1.default)({}, pollResult)]; })));
666
+ return { getBatchMock, pollResultsMock };
667
+ };
668
+ const waiter = {
669
+ promise: Promise.resolve(),
670
+ resolve: () => { },
671
+ start() {
672
+ this.promise = new Promise((resolve) => (this.resolve = resolve));
673
+ },
674
+ };
675
+ test('should poll result ids', () => __awaiter(void 0, void 0, void 0, function* () {
676
+ mockApi();
677
+ expect(yield utils.waitForResults(api, trigger, [result.test], {
678
+ batchTimeout: 120000,
679
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
680
+ failOnCriticalErrors: false,
681
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
682
+ }, fixtures_1.mockReporter)).toEqual([result]);
683
+ }));
684
+ test('should show results as they arrive', () => __awaiter(void 0, void 0, void 0, function* () {
685
+ jest.spyOn(utils, 'wait').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return waiter.resolve(); }));
686
+ const tests = [result.test, Object.assign(Object.assign({}, result.test), { public_id: 'other-public-id' })];
687
+ // === STEP 1 === (batch 'in_progress')
688
+ waiter.start();
689
+ mockApi({
690
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
691
+ return ({
692
+ status: 'in_progress',
693
+ results: [
694
+ Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()),
695
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { result_id: 'rid-2' }),
696
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
697
+ ],
698
+ });
699
+ }),
700
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return [(0, deep_extend_1.default)({}, pollResult)]; }),
701
+ });
702
+ const resultsPromise = utils.waitForResults(api, trigger, tests, {
703
+ batchTimeout: 120000,
704
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
705
+ failOnCriticalErrors: false,
706
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
707
+ }, fixtures_1.mockReporter);
708
+ // Wait for the 2 tests (initial)
709
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(1, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id);
710
+ yield waiter.promise;
711
+ // No results received
712
+ expect(fixtures_1.mockReporter.resultReceived).not.toHaveBeenCalled();
713
+ expect(fixtures_1.mockReporter.resultEnd).not.toHaveBeenCalled();
714
+ // Still waiting for the 2 tests
715
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(2, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
716
+ // === STEP 2 === (batch 'in_progress')
717
+ waiter.start();
718
+ mockApi({
719
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
720
+ return ({
721
+ status: 'in_progress',
722
+ results: [
723
+ Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()),
724
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
725
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
726
+ ],
727
+ });
728
+ }),
729
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
730
+ return [
731
+ (0, deep_extend_1.default)({}, pollResult),
732
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }),
733
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-3' }),
734
+ ];
735
+ }),
736
+ });
737
+ yield waiter.promise;
738
+ // One result received
739
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(1, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed', result_id: 'rid-2' }));
740
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(1, Object.assign(Object.assign({}, result), { resultId: 'rid-2' }), fixtures_1.MOCK_BASE_URL, 'bid');
741
+ // Still waiting for 2 tests
742
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(3, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
743
+ // === STEP 3 === (batch 'in_progress')
744
+ waiter.start();
745
+ mockApi({
746
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
747
+ return ({
748
+ status: 'in_progress',
749
+ results: [
750
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
751
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
752
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
753
+ ],
754
+ });
755
+ }),
756
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
757
+ return [
758
+ (0, deep_extend_1.default)({}, pollResult),
759
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }),
760
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-3' }),
761
+ ];
762
+ }),
763
+ });
764
+ yield waiter.promise;
765
+ // One result received
766
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(2, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed' }));
767
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(2, result, fixtures_1.MOCK_BASE_URL, 'bid');
768
+ // Now waiting for 1 test
769
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(4, [tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
770
+ // === STEP 4 === (batch 'in_progress')
771
+ waiter.start();
772
+ mockApi({
773
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
774
+ return ({
775
+ status: 'in_progress',
776
+ results: [
777
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
778
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
779
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { retries: 0, test_public_id: 'other-public-id', timed_out: false, result_id: 'rid-3' }),
780
+ ],
781
+ });
782
+ }),
783
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
784
+ return [
785
+ (0, deep_extend_1.default)({}, pollResult),
786
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }),
787
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-3' }),
788
+ ];
789
+ }),
790
+ });
791
+ yield waiter.promise;
792
+ // One result received
793
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(3, Object.assign(Object.assign({}, batch.results[0]), { status: 'in_progress', test_public_id: 'other-public-id', result_id: 'rid-3' }));
794
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(3, Object.assign(Object.assign({}, result), { resultId: 'rid-3' }), fixtures_1.MOCK_BASE_URL, 'bid');
795
+ // Now waiting for 1 test
796
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(5, [tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
797
+ // === STEP 5 === (batch 'passed')
798
+ mockApi({
799
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
800
+ return ({
801
+ status: 'passed',
802
+ results: [
803
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
804
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
805
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { retries: 1, test_public_id: 'other-public-id', result_id: 'rid-3-final' }),
806
+ ],
807
+ });
808
+ }),
809
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
810
+ return [
811
+ (0, deep_extend_1.default)({}, pollResult),
812
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }),
813
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-3-final' }),
814
+ ];
815
+ }),
816
+ });
817
+ expect(yield resultsPromise).toEqual([
818
+ result,
819
+ Object.assign(Object.assign({}, result), { resultId: 'rid-2' }),
820
+ Object.assign(Object.assign({}, result), { resultId: 'rid-3-final', retries: 1 }),
821
+ ]);
822
+ // One result received
823
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(4, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed', test_public_id: 'other-public-id', result_id: 'rid-3-final', retries: 1 }));
824
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(4, Object.assign(Object.assign({}, result), { resultId: 'rid-3-final', retries: 1 }), fixtures_1.MOCK_BASE_URL, 'bid');
825
+ // Do not report when there are no tests to wait anymore
826
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenCalledTimes(5);
827
+ }));
828
+ test('skipped results are reported as received', () => __awaiter(void 0, void 0, void 0, function* () {
829
+ jest.spyOn(utils, 'wait').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return waiter.resolve(); }));
830
+ const tests = [result.test, Object.assign(Object.assign({}, result.test), { public_id: 'other-public-id' })];
831
+ // === STEP 1 === (batch 'in_progress')
832
+ waiter.start();
833
+ mockApi({
834
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
835
+ return ({
836
+ status: 'in_progress',
837
+ results: [
838
+ Object.assign({}, (0, fixtures_1.getSkippedResultInBatch)()),
839
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-2' }),
840
+ ],
841
+ });
842
+ }),
843
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return [Object.assign(Object.assign({}, pollResult), { resultID: 'rid-2' })]; }),
844
+ });
845
+ const resultsPromise = utils.waitForResults(api, trigger, tests, {
846
+ batchTimeout: 120000,
847
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
848
+ failOnCriticalErrors: false,
849
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
850
+ }, fixtures_1.mockReporter);
851
+ // Wait for the 2 tests (initial)
852
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(1, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id);
853
+ yield waiter.promise;
854
+ // The skipped result is received
855
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(1, Object.assign({}, (0, fixtures_1.getSkippedResultInBatch)()));
856
+ // And marked as passed because it's selective re-run
857
+ const skippedResult = {
858
+ executionRule: interfaces_1.ExecutionRule.SKIPPED,
859
+ passed: true,
860
+ resultId: '123',
861
+ selectiveRerun: { decision: 'skip', reason: 'passed', linked_result_id: '123' },
862
+ test: result.test,
863
+ timedOut: false,
864
+ };
865
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(1, skippedResult, fixtures_1.MOCK_BASE_URL, 'bid');
866
+ // Now waiting for the remaining test
867
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(2, [tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 1);
868
+ // === STEP 2 === (batch 'passed')
869
+ mockApi({
870
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
871
+ return ({
872
+ status: 'passed',
873
+ results: [
874
+ Object.assign({}, (0, fixtures_1.getSkippedResultInBatch)()),
875
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-2' }),
876
+ ],
877
+ });
878
+ }),
879
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return [(0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' })]; }),
880
+ });
881
+ expect(yield resultsPromise).toEqual([Object.assign({}, skippedResult), Object.assign(Object.assign({}, result), { resultId: 'rid-2' })]);
882
+ // One result received
883
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(2, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed', test_public_id: 'other-public-id', result_id: 'rid-2' }));
884
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(2, Object.assign(Object.assign({}, result), { resultId: 'rid-2' }), fixtures_1.MOCK_BASE_URL, 'bid');
885
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenCalledTimes(2);
886
+ }));
887
+ test('should wait for incomplete results', () => __awaiter(void 0, void 0, void 0, function* () {
888
+ jest.spyOn(utils, 'wait').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return waiter.resolve(); }));
889
+ const tests = [result.test, Object.assign(Object.assign({}, result.test), { public_id: 'other-public-id' })];
890
+ // === STEP 1 === (batch 'in_progress')
891
+ waiter.start();
892
+ mockApi({
893
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
894
+ return ({
895
+ status: 'in_progress',
896
+ results: [
897
+ Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()),
898
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
899
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
900
+ ],
901
+ });
902
+ }),
903
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return [Object.assign(Object.assign({}, pollResult), { resultID: 'rid-2', result: incompleteServerResult })]; }),
904
+ });
905
+ const resultsPromise = utils.waitForResults(api, trigger, tests, {
906
+ batchTimeout: 120000,
907
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
908
+ failOnCriticalErrors: false,
909
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
910
+ }, fixtures_1.mockReporter);
911
+ // Wait for the 2 tests (initial)
912
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(1, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id);
913
+ yield waiter.promise;
914
+ // One result received
915
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(1, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed', result_id: 'rid-2' }));
916
+ // But the data from `/poll_results` data is not available yet, so we should wait more before reporting
917
+ expect(fixtures_1.mockReporter.resultEnd).not.toHaveBeenCalled();
918
+ // Still waiting for 2 tests
919
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(2, [tests[0], tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
920
+ // === STEP 2 === (batch 'in_progress')
921
+ waiter.start();
922
+ mockApi({
923
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
924
+ return ({
925
+ status: 'in_progress',
926
+ results: [
927
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
928
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
929
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
930
+ ],
931
+ });
932
+ }),
933
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
934
+ return [
935
+ Object.assign(Object.assign({}, pollResult), { result: incompleteServerResult }),
936
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }), // just became available
937
+ ];
938
+ }),
939
+ });
940
+ yield waiter.promise;
941
+ // One result received
942
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(2, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed' }));
943
+ // Result 2 just became available, so it should be reported
944
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(1, Object.assign(Object.assign({}, result), { resultId: 'rid-2' }), fixtures_1.MOCK_BASE_URL, 'bid');
945
+ // Now waiting for 1 test
946
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenNthCalledWith(3, [tests[1]], fixtures_1.MOCK_BASE_URL, trigger.batch_id, 0);
947
+ // === STEP 3 === (batch 'passed')
948
+ mockApi({
949
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
950
+ return ({
951
+ status: 'passed',
952
+ results: [
953
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
954
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: 'rid-2' }),
955
+ Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { test_public_id: 'other-public-id', result_id: 'rid-3' }),
956
+ ],
957
+ });
958
+ }),
959
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
960
+ return [
961
+ Object.assign(Object.assign({}, pollResult), { result: incompleteServerResult }),
962
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-2' }),
963
+ (0, deep_extend_1.default)({}, pollResult, { resultID: 'rid-3' }),
964
+ ];
965
+ }),
966
+ });
967
+ expect(yield resultsPromise).toEqual([
968
+ Object.assign(Object.assign({}, result), { resultId: 'rid', result: incompleteServerResult }),
969
+ Object.assign(Object.assign({}, result), { resultId: 'rid-2' }),
970
+ Object.assign(Object.assign({}, result), { resultId: 'rid-3' }),
971
+ ]);
972
+ // One result received
973
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenNthCalledWith(3, Object.assign(Object.assign({}, batch.results[0]), { status: 'passed', test_public_id: 'other-public-id', result_id: 'rid-3' }));
974
+ // Result 3 was available instantly
975
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(2, Object.assign(Object.assign({}, result), { resultId: 'rid-3' }), fixtures_1.MOCK_BASE_URL, 'bid');
976
+ // Result 1 never became available
977
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(3, Object.assign(Object.assign({}, result), { resultId: 'rid', result: incompleteServerResult }), fixtures_1.MOCK_BASE_URL, 'bid');
978
+ expect(fixtures_1.mockReporter.error).toHaveBeenCalledWith('The full information for result rid was incomplete at the end of the batch.\n\n');
979
+ // Do not report when there are no tests to wait anymore
980
+ expect(fixtures_1.mockReporter.testsWait).toHaveBeenCalledTimes(3);
981
+ }));
982
+ test('object in each result should be different even if they share the same public ID (config overrides)', () => __awaiter(void 0, void 0, void 0, function* () {
983
+ mockApi({
984
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
985
+ return ({
986
+ results: [(0, fixtures_1.getPassedResultInBatch)(), Object.assign(Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), { result_id: '3' })],
987
+ status: 'passed',
988
+ });
989
+ }),
990
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
991
+ return [
992
+ (0, deep_extend_1.default)({}, pollResult),
993
+ // The test object from the second result has an overridden start URL
994
+ (0, deep_extend_1.default)({}, pollResult, { check: { config: { request: { url: 'https://reddit.com/' } } }, resultID: '3' }),
995
+ ];
996
+ }),
997
+ });
998
+ const results = yield utils.waitForResults(api, trigger, [result.test, result.test], {
999
+ batchTimeout: 0,
1000
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1001
+ failOnCriticalErrors: false,
1002
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1003
+ }, fixtures_1.mockReporter);
1004
+ expect(results.map(({ test }) => test.config.request.url)).toEqual(['http://fake.url', 'https://reddit.com/']);
1005
+ }));
1006
+ test('results should be timed out if the backend says so', () => __awaiter(void 0, void 0, void 0, function* () {
1007
+ mockApi({
1008
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1009
+ return ({
1010
+ status: 'failed',
1011
+ results: [Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()), Object.assign(Object.assign({}, (0, fixtures_1.getFailedResultInBatch)()), { result_id: '3', timed_out: true })],
1012
+ });
1013
+ }),
1014
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1015
+ return [
1016
+ Object.assign(Object.assign({}, pollResult), { result: Object.assign({}, pollResult.result) }),
1017
+ Object.assign(Object.assign({}, pollResult), { result: Object.assign({}, pollResult.result), resultID: '3' }),
1018
+ ];
1019
+ }),
1020
+ });
1021
+ const expectedTimeoutResult = Object.assign(Object.assign({}, result), { result: Object.assign(Object.assign({}, result.result), { failure: { code: 'TIMEOUT', message: 'The batch timed out before receiving the result.' }, passed: false }), resultId: '3', timedOut: true });
1022
+ expect(yield utils.waitForResults(api, trigger, [result.test, result.test], {
1023
+ batchTimeout: 3000,
1024
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1025
+ failOnCriticalErrors: false,
1026
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1027
+ }, fixtures_1.mockReporter)).toEqual([result, expectedTimeoutResult]);
1028
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenCalledTimes(2);
1029
+ // `resultEnd` should return the same data as `waitForResults`
1030
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(1, result, fixtures_1.MOCK_BASE_URL, 'bid');
1031
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(2, expectedTimeoutResult, fixtures_1.MOCK_BASE_URL, 'bid');
1032
+ // Failed directly.
1033
+ expect(utils.wait).toHaveBeenCalledTimes(0);
1034
+ }));
1035
+ test('results should be timed out with a different error if the backend did not say so', () => __awaiter(void 0, void 0, void 0, function* () {
1036
+ mockApi({
1037
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1038
+ return ({
1039
+ status: 'in_progress',
1040
+ results: [
1041
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
1042
+ Object.assign(Object.assign({}, (0, fixtures_1.getInProgressResultInBatch)()), { result_id: '3' }),
1043
+ ],
1044
+ });
1045
+ }),
1046
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1047
+ return [
1048
+ Object.assign(Object.assign({}, pollResult), { result: Object.assign({}, pollResult.result) }),
1049
+ Object.assign(Object.assign({}, pollResult), { result: Object.assign({}, pollResult.result), resultID: '3' }),
1050
+ ];
1051
+ }),
1052
+ });
1053
+ const expectedDeadlineResult = Object.assign(Object.assign({}, result), { result: Object.assign(Object.assign({}, result.result), { failure: {
1054
+ code: 'BATCH_TIMEOUT_RUNAWAY',
1055
+ message: "The batch didn't timeout after the expected timeout period.",
1056
+ }, passed: false }), resultId: '3', timedOut: true });
1057
+ yield expect(utils.waitForResults(api, trigger, [result.test, result.test], {
1058
+ batchTimeout: 3000,
1059
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1060
+ failOnCriticalErrors: false,
1061
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1062
+ }, fixtures_1.mockReporter)).rejects.toThrow(new errors_1.BatchTimeoutRunawayError());
1063
+ // Residual results are never 'received': we force-end them.
1064
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenCalledTimes(1);
1065
+ // `resultEnd` should return the same data as `waitForResults`
1066
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(1, result, fixtures_1.MOCK_BASE_URL, 'bid');
1067
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenNthCalledWith(2, expectedDeadlineResult, fixtures_1.MOCK_BASE_URL, 'bid');
1068
+ // Initial wait + 3 polling cycles.
1069
+ expect(utils.wait).toHaveBeenCalledTimes(4);
1070
+ }));
1071
+ test('results failure should be ignored if timed out', () => __awaiter(void 0, void 0, void 0, function* () {
1072
+ // The original failure of a result received between timing out in batch poll
1073
+ // and retrieving it should be ignored in favor of timeout.
1074
+ mockApi({
1075
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1076
+ return ({
1077
+ status: 'failed',
1078
+ results: [Object.assign(Object.assign({}, (0, fixtures_1.getFailedResultInBatch)()), { timed_out: true })],
1079
+ });
1080
+ }),
1081
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1082
+ return [
1083
+ Object.assign(Object.assign({}, pollResult), { passed: false, result: Object.assign(Object.assign({}, pollResult.result), { failure: { code: 'FAILURE', message: 'Original failure, should be ignored' }, passed: false }) }),
1084
+ ];
1085
+ }),
1086
+ });
1087
+ expect(yield utils.waitForResults(api, trigger, [result.test], {
1088
+ batchTimeout: 0,
1089
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1090
+ failOnCriticalErrors: false,
1091
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1092
+ }, fixtures_1.mockReporter)).toStrictEqual([
1093
+ Object.assign(Object.assign({}, result), { result: Object.assign(Object.assign({}, result.result), { failure: { code: 'TIMEOUT', message: 'The batch timed out before receiving the result.' }, passed: false }), timedOut: true }),
1094
+ ]);
1095
+ }));
1096
+ test('results should be timed out if batch result is timed out', () => __awaiter(void 0, void 0, void 0, function* () {
1097
+ const batchWithTimeoutResult = Object.assign(Object.assign({}, batch), { results: [Object.assign(Object.assign({}, (0, fixtures_1.getFailedResultInBatch)()), { timed_out: true })] });
1098
+ mockApi({ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return batchWithTimeoutResult; }) });
1099
+ expect(yield utils.waitForResults(api, trigger, [result.test], {
1100
+ batchTimeout: 120000,
1101
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1102
+ failOnCriticalErrors: false,
1103
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1104
+ }, fixtures_1.mockReporter)).toEqual([
1105
+ Object.assign(Object.assign({}, result), { result: Object.assign(Object.assign({}, result.result), { failure: { code: 'TIMEOUT', message: 'The batch timed out before receiving the result.' }, passed: false }), timedOut: true }),
1106
+ ]);
1107
+ }));
1108
+ test('wait between batch polling', () => __awaiter(void 0, void 0, void 0, function* () {
1109
+ const { getBatchMock } = mockApi({
1110
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () {
1111
+ return getBatchMock.mock.calls.length === 3 ? batch : Object.assign(Object.assign({}, batch), { status: 'in_progress' });
1112
+ }),
1113
+ });
1114
+ expect(yield utils.waitForResults(api, trigger, [result.test], {
1115
+ batchTimeout: 120000,
1116
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1117
+ failOnCriticalErrors: false,
1118
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1119
+ }, fixtures_1.mockReporter)).toEqual([result]);
1120
+ expect(getBatchMock).toHaveBeenCalledTimes(3);
1121
+ expect(utils.wait).toHaveBeenCalledTimes(2);
1122
+ }));
1123
+ test('correct number of passed and timed out results', () => __awaiter(void 0, void 0, void 0, function* () {
1124
+ const pollTimeoutResult = Object.assign(Object.assign({}, (0, deep_extend_1.default)({}, pollResult)), { resultID: 'another-id' });
1125
+ const batchWithTimeoutResult = Object.assign(Object.assign({}, batch), { results: [
1126
+ Object.assign({}, (0, fixtures_1.getPassedResultInBatch)()),
1127
+ Object.assign(Object.assign({}, (0, fixtures_1.getFailedResultInBatch)()), { timed_out: true, result_id: pollTimeoutResult.resultID }),
1128
+ ] });
1129
+ mockApi({
1130
+ getBatchImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return batchWithTimeoutResult; }),
1131
+ pollResultsImplementation: () => __awaiter(void 0, void 0, void 0, function* () { return [pollResult, pollTimeoutResult]; }),
1132
+ });
1133
+ expect(yield utils.waitForResults(api, trigger, [result.test], {
1134
+ batchTimeout: 2000,
1135
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1136
+ failOnCriticalErrors: false,
1137
+ failOnTimeout: false,
1138
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1139
+ }, fixtures_1.mockReporter)).toEqual([
1140
+ Object.assign(Object.assign({}, result), { passed: true, timedOut: false }),
1141
+ Object.assign(Object.assign({}, result), { passed: true, timedOut: true, resultId: pollTimeoutResult.resultID, result: Object.assign(Object.assign({}, result.result), { failure: {
1142
+ code: 'TIMEOUT',
1143
+ message: 'The batch timed out before receiving the result.',
1144
+ }, passed: false }) }),
1145
+ ]);
1146
+ expect(fixtures_1.mockReporter.resultReceived).toHaveBeenCalledTimes(2);
1147
+ expect(fixtures_1.mockReporter.resultEnd).toHaveBeenCalledTimes(2);
1148
+ }));
1149
+ test('tunnel failure', () => __awaiter(void 0, void 0, void 0, function* () {
1150
+ mockApi();
1151
+ const mockTunnel = {
1152
+ keepAlive: () => __awaiter(void 0, void 0, void 0, function* () {
1153
+ throw new Error('keepAlive failed');
1154
+ }),
1155
+ };
1156
+ yield utils.waitForResults(api, trigger, [result.test], {
1157
+ batchTimeout: 2000,
1158
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1159
+ failOnCriticalErrors: true,
1160
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1161
+ }, fixtures_1.mockReporter, mockTunnel);
1162
+ expect(fixtures_1.mockReporter.error).toHaveBeenCalledWith('The tunnel has stopped working, this may have affected the results.');
1163
+ }));
1164
+ test('location when tunnel', () => __awaiter(void 0, void 0, void 0, function* () {
1165
+ mockApi();
1166
+ const mockTunnel = { keepAlive: () => __awaiter(void 0, void 0, void 0, function* () { return true; }) };
1167
+ let results = yield utils.waitForResults(api, trigger, [result.test], {
1168
+ batchTimeout: 2000,
1169
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1170
+ failOnCriticalErrors: true,
1171
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1172
+ }, fixtures_1.mockReporter, mockTunnel);
1173
+ expect(results[0].location).toBe('Tunneled');
1174
+ const newTest = Object.assign({}, result.test);
1175
+ newTest.type = 'api';
1176
+ newTest.subtype = 'http';
1177
+ results = yield utils.waitForResults(api, trigger, [newTest], {
1178
+ batchTimeout: 2000,
1179
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1180
+ failOnCriticalErrors: true,
1181
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1182
+ }, fixtures_1.mockReporter, mockTunnel);
1183
+ expect(results[0].location).toBe('Tunneled');
1184
+ newTest.type = 'api';
1185
+ newTest.subtype = 'ssl';
1186
+ results = yield utils.waitForResults(api, trigger, [newTest], {
1187
+ batchTimeout: 2000,
1188
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1189
+ failOnCriticalErrors: true,
1190
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1191
+ }, fixtures_1.mockReporter, mockTunnel);
1192
+ expect(results[0].location).toBe('Frankfurt (AWS)');
1193
+ }));
1194
+ test('pollResults throws', () => __awaiter(void 0, void 0, void 0, function* () {
1195
+ const { pollResultsMock } = mockApi({
1196
+ pollResultsImplementation: () => {
1197
+ throw (0, fixtures_1.getAxiosHttpError)(502, { message: 'Poll results server error' });
1198
+ },
1199
+ });
1200
+ yield expect(utils.waitForResults(api, trigger, [result.test], {
1201
+ batchTimeout: 2000,
1202
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1203
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1204
+ }, fixtures_1.mockReporter)).rejects.toThrow('Failed to poll results: could not query https://app.datadoghq.com/example\nPoll results server error\n');
1205
+ expect(pollResultsMock).toHaveBeenCalledWith([result.resultId]);
1206
+ }));
1207
+ test('getBatch throws', () => __awaiter(void 0, void 0, void 0, function* () {
1208
+ const { getBatchMock } = mockApi({
1209
+ getBatchImplementation: () => {
1210
+ throw (0, fixtures_1.getAxiosHttpError)(502, { message: 'Get batch server error' });
1211
+ },
1212
+ });
1213
+ yield expect(utils.waitForResults(api, trigger, [result.test], {
1214
+ batchTimeout: 2000,
1215
+ datadogSite: run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite,
1216
+ subdomain: run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain,
1217
+ }, fixtures_1.mockReporter)).rejects.toThrow('Failed to get batch: could not query https://app.datadoghq.com/example\nGet batch server error\n');
1218
+ expect(getBatchMock).toHaveBeenCalledWith(trigger.batch_id);
1219
+ }));
1220
+ });
1221
+ test('getStrictestExecutionRule', () => {
1222
+ const BLOCKING = interfaces_1.ExecutionRule.BLOCKING;
1223
+ const NON_BLOCKING = interfaces_1.ExecutionRule.NON_BLOCKING;
1224
+ const SKIPPED = interfaces_1.ExecutionRule.SKIPPED;
1225
+ expect(utils.getStrictestExecutionRule(BLOCKING, NON_BLOCKING)).toBe(NON_BLOCKING);
1226
+ expect(utils.getStrictestExecutionRule(NON_BLOCKING, BLOCKING)).toBe(NON_BLOCKING);
1227
+ expect(utils.getStrictestExecutionRule(NON_BLOCKING, SKIPPED)).toBe(SKIPPED);
1228
+ expect(utils.getStrictestExecutionRule(BLOCKING, undefined)).toBe(BLOCKING);
1229
+ expect(utils.getStrictestExecutionRule(SKIPPED, undefined)).toBe(SKIPPED);
1230
+ });
1231
+ describe('retry', () => {
1232
+ test('retry works fine', () => __awaiter(void 0, void 0, void 0, function* () {
1233
+ const result = yield utils.retry(() => __awaiter(void 0, void 0, void 0, function* () { return 42; }), () => 1);
1234
+ expect(result).toBe(42);
1235
+ }));
1236
+ test('retry works fine after some retries', () => __awaiter(void 0, void 0, void 0, function* () {
1237
+ let counter = 0;
1238
+ const start = +new Date();
1239
+ const result = yield utils.retry(() => __awaiter(void 0, void 0, void 0, function* () {
1240
+ if (counter === 3) {
1241
+ return 42;
1242
+ }
1243
+ counter += 1;
1244
+ throw new Error('');
1245
+ }), (retries) => 100 * (retries + 1));
1246
+ const end = +new Date();
1247
+ const approximateWait = 100 + 100 * 2 + 100 * 3;
1248
+ expect(result).toBe(42);
1249
+ expect(counter).toBe(3);
1250
+ expect(end - start - approximateWait < 50).toBeTruthy();
1251
+ }));
1252
+ test('retry rethrows after some retries', () => __awaiter(void 0, void 0, void 0, function* () {
1253
+ let counter = 0;
1254
+ yield expect(utils.retry(() => __awaiter(void 0, void 0, void 0, function* () {
1255
+ counter += 1;
1256
+ throw new Error('FAILURE');
1257
+ }), (retries) => {
1258
+ if (retries < 2) {
1259
+ return 1;
1260
+ }
1261
+ })).rejects.toThrow('FAILURE');
1262
+ expect(counter).toBe(3);
1263
+ }));
1264
+ });
1265
+ test('parseVariablesFromCli', () => {
1266
+ const mockLogFunction = (message) => undefined;
1267
+ expect(utils.parseVariablesFromCli(['TEST=42'], mockLogFunction)).toEqual({ TEST: '42' });
1268
+ expect(utils.parseVariablesFromCli(['TEST=42 with some spaces'], mockLogFunction)).toEqual({
1269
+ TEST: '42 with some spaces',
1270
+ });
1271
+ expect(utils.parseVariablesFromCli(['TEST=42=43=44'], mockLogFunction)).toEqual({ TEST: '42=43=44' });
1272
+ expect(utils.parseVariablesFromCli(['TEST='], mockLogFunction)).toEqual({ TEST: '' });
1273
+ expect(utils.parseVariablesFromCli([''], mockLogFunction)).toBeUndefined();
1274
+ expect(utils.parseVariablesFromCli(undefined, mockLogFunction)).toBeUndefined();
1275
+ });
1276
+ describe('sortResultsByOutcome', () => {
1277
+ const results = (0, fixtures_1.getResults)([
1278
+ { executionRule: interfaces_1.ExecutionRule.NON_BLOCKING, passed: false },
1279
+ { executionRule: interfaces_1.ExecutionRule.BLOCKING, passed: true },
1280
+ { executionRule: interfaces_1.ExecutionRule.BLOCKING, passed: false },
1281
+ { executionRule: interfaces_1.ExecutionRule.NON_BLOCKING, passed: true },
1282
+ ]);
1283
+ test('should sort tests with success, non_blocking failures then failures', () => __awaiter(void 0, void 0, void 0, function* () {
1284
+ const sortedResults = [...results];
1285
+ sortedResults.sort(utils.sortResultsByOutcome());
1286
+ expect(sortedResults.map((r) => r.resultId)).toStrictEqual(['3', '1', '0', '2']);
1287
+ }));
1288
+ });
1289
+ describe('Render results', () => {
1290
+ const emptySummary = (0, fixtures_1.getSummary)();
1291
+ const cases = [
1292
+ {
1293
+ description: '1 API test with 1 config override, 1 result (passed)',
1294
+ expected: {
1295
+ exitCode: 0,
1296
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 1, passed: 1 }),
1297
+ },
1298
+ failOnCriticalErrors: false,
1299
+ failOnTimeout: false,
1300
+ results: (0, fixtures_1.getResults)([{ passed: true }]),
1301
+ summary: Object.assign({}, emptySummary),
1302
+ },
1303
+ {
1304
+ description: '1 API test with 1 config override, 1 result (failed timeout), no fail on timeout, no fail on critical errors',
1305
+ expected: {
1306
+ exitCode: 0,
1307
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 1, passed: 1, timedOut: 1 }),
1308
+ },
1309
+ failOnCriticalErrors: false,
1310
+ failOnTimeout: false,
1311
+ results: (0, fixtures_1.getResults)([{ timedOut: true }]),
1312
+ summary: Object.assign({}, emptySummary),
1313
+ },
1314
+ {
1315
+ description: '1 API test with 1 config override, 1 result (failed timeout), fail on timeout, no fail on critical errors',
1316
+ expected: {
1317
+ exitCode: 1,
1318
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 1, failed: 1 }),
1319
+ },
1320
+ failOnCriticalErrors: false,
1321
+ failOnTimeout: true,
1322
+ results: (0, fixtures_1.getResults)([{ timedOut: true }]),
1323
+ summary: Object.assign({}, emptySummary),
1324
+ },
1325
+ {
1326
+ description: '1 API test with 1 config override, 1 result (failed critical error), no fail on timeout, no fail on critical errors',
1327
+ expected: {
1328
+ exitCode: 0,
1329
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 1, passed: 1, criticalErrors: 1 }),
1330
+ },
1331
+ failOnCriticalErrors: false,
1332
+ failOnTimeout: false,
1333
+ results: (0, fixtures_1.getResults)([{ unhealthy: true }]),
1334
+ summary: Object.assign({}, emptySummary),
1335
+ },
1336
+ {
1337
+ description: '1 API test with 1 config override, 1 result (failed critical error), no fail on timeout, fail on critical errors',
1338
+ expected: {
1339
+ exitCode: 1,
1340
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 1, criticalErrors: 0, failed: 1 }),
1341
+ },
1342
+ failOnCriticalErrors: true,
1343
+ failOnTimeout: false,
1344
+ results: (0, fixtures_1.getResults)([{ unhealthy: true }]),
1345
+ summary: Object.assign({}, emptySummary),
1346
+ },
1347
+ {
1348
+ description: '1 API test (blocking) with 4 config overrides (1 skipped), 3 results (1 passed, 1 failed, 1 failed non-blocking)',
1349
+ expected: {
1350
+ exitCode: 1,
1351
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 3, failed: 1, failedNonBlocking: 1, passed: 1, skipped: 1 }),
1352
+ },
1353
+ failOnCriticalErrors: false,
1354
+ failOnTimeout: false,
1355
+ results: (0, fixtures_1.getResults)([{ passed: true }, { executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }, {}]),
1356
+ summary: Object.assign(Object.assign({}, emptySummary), { skipped: 1 }),
1357
+ },
1358
+ {
1359
+ description: '1 API test (non-blocking) with 4 config overrides (1 skipped), 3 results (1 passed, 1 failed, 1 failed non-blocking)',
1360
+ expected: {
1361
+ exitCode: 0,
1362
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 3, failedNonBlocking: 2, passed: 1, skipped: 1 }),
1363
+ },
1364
+ failOnCriticalErrors: false,
1365
+ failOnTimeout: false,
1366
+ results: (0, fixtures_1.getResults)([
1367
+ {
1368
+ executionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
1369
+ testExecutionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
1370
+ },
1371
+ { passed: true, testExecutionRule: interfaces_1.ExecutionRule.NON_BLOCKING },
1372
+ {
1373
+ testExecutionRule: interfaces_1.ExecutionRule.NON_BLOCKING,
1374
+ },
1375
+ ]),
1376
+ summary: Object.assign(Object.assign({}, emptySummary), { skipped: 1 }),
1377
+ },
1378
+ {
1379
+ description: '3 API tests (blocking) with 1 config override each, 3 results (1 failed non-blocking, 1 failed, 1 passed)',
1380
+ expected: {
1381
+ exitCode: 1,
1382
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 3, failed: 1, failedNonBlocking: 1, passed: 1 }),
1383
+ },
1384
+ failOnCriticalErrors: false,
1385
+ failOnTimeout: false,
1386
+ results: (0, fixtures_1.getResults)([{}, { passed: true }, { executionRule: interfaces_1.ExecutionRule.NON_BLOCKING }]),
1387
+ summary: Object.assign({}, emptySummary),
1388
+ },
1389
+ {
1390
+ description: '4 API tests, 3 results (2 passed, of which 1 comes from previous CI run, 1 skipped)',
1391
+ expected: {
1392
+ exitCode: 0,
1393
+ summary: Object.assign(Object.assign({}, emptySummary), { expected: 2, passed: 2, previouslyPassed: 1, skipped: 1 }),
1394
+ },
1395
+ failOnCriticalErrors: false,
1396
+ failOnTimeout: false,
1397
+ results: (0, fixtures_1.getResults)([
1398
+ { passed: true },
1399
+ {
1400
+ executionRule: interfaces_1.ExecutionRule.SKIPPED,
1401
+ selectiveRerun: { decision: 'skip', reason: 'passed', linked_result_id: '' },
1402
+ },
1403
+ ]),
1404
+ summary: Object.assign(Object.assign({}, emptySummary), { skipped: 1 }),
1405
+ },
1406
+ ];
1407
+ test.each(cases)('$description', (testCase) => __awaiter(void 0, void 0, void 0, function* () {
1408
+ testCase.results.forEach((result) => {
1409
+ result.passed = utils.hasResultPassed(result.result, result.timedOut, testCase.failOnCriticalErrors, testCase.failOnTimeout);
1410
+ });
1411
+ jest.spyOn(api, 'getSyntheticsOrgSettings').mockResolvedValue({ onDemandConcurrencyCap: 1 });
1412
+ const config = Object.assign(Object.assign({}, run_tests_command_1.DEFAULT_COMMAND_CONFIG), { failOnCriticalErrors: testCase.failOnCriticalErrors, failOnTimeout: testCase.failOnTimeout, appKey: 'appKey', apiKey: 'apiKey' });
1413
+ const startTime = Date.now();
1414
+ utils.renderResults({
1415
+ config,
1416
+ orgSettings: { onDemandConcurrencyCap: 1 },
1417
+ reporter: fixtures_1.mockReporter,
1418
+ results: testCase.results,
1419
+ startTime,
1420
+ summary: testCase.summary,
1421
+ });
1422
+ const exitCode = utils.toExitCode(utils.getExitReason(config, { results: testCase.results }));
1423
+ expect(fixtures_1.mockReporter.reportStart).toHaveBeenCalledWith({ startTime });
1424
+ const baseUrl = `https://${run_tests_command_1.DEFAULT_COMMAND_CONFIG.subdomain}.${run_tests_command_1.DEFAULT_COMMAND_CONFIG.datadogSite}/`;
1425
+ expect(testCase.summary).toEqual(testCase.expected.summary);
1426
+ expect(fixtures_1.mockReporter.runEnd).toHaveBeenCalledWith(testCase.expected.summary, baseUrl, {
1427
+ onDemandConcurrencyCap: 1,
1428
+ });
1429
+ expect(exitCode).toBe(testCase.expected.exitCode);
1430
+ }));
1431
+ });
1432
+ describe('getExitReason', () => {
1433
+ test('should return failing-tests if any tests have failed', () => {
1434
+ const config = run_tests_command_1.DEFAULT_COMMAND_CONFIG;
1435
+ const results = (0, fixtures_1.getResults)([{ passed: false }]);
1436
+ expect(utils.getExitReason(config, { results })).toBe('failing-tests');
1437
+ });
1438
+ test.each([
1439
+ { failOnMissingTests: true, errorCode: 'NO_TESTS_TO_RUN', expectedExitReason: 'missing-tests' },
1440
+ { failOnMissingTests: true, errorCode: 'MISSING_TESTS', expectedExitReason: 'missing-tests' },
1441
+ { failOnMissingTests: false, errorCode: 'NO_TESTS_TO_RUN', expectedExitReason: 'passed' },
1442
+ { failOnMissingTests: false, errorCode: 'MISSING_TESTS', expectedExitReason: 'passed' },
1443
+ ])('should return $expectedExitReason when $errorCode if failOnMissingTests flag is $failOnMissingTests', ({ failOnMissingTests, errorCode, expectedExitReason: exitReason }) => {
1444
+ const config = Object.assign(Object.assign({}, run_tests_command_1.DEFAULT_COMMAND_CONFIG), { failOnMissingTests });
1445
+ const error = new errors_1.CiError(errorCode);
1446
+ expect(utils.getExitReason(config, { error })).toBe(exitReason);
1447
+ });
1448
+ test.each([
1449
+ { failOnCriticalErrorsFlag: true, exitReason: 'critical-error' },
1450
+ { failOnCriticalErrorsFlag: false, exitReason: 'passed' },
1451
+ ])('should return $exitReason when failOnCriticalErrors flag is $failOnCriticalErrorsFlag', ({ failOnCriticalErrorsFlag, exitReason }) => {
1452
+ const config = Object.assign(Object.assign({}, run_tests_command_1.DEFAULT_COMMAND_CONFIG), { failOnCriticalErrors: failOnCriticalErrorsFlag });
1453
+ const error = new errors_1.CriticalError('AUTHORIZATION_ERROR');
1454
+ expect(utils.getExitReason(config, { error })).toBe(exitReason);
1455
+ });
1456
+ test('should return passed if all tests have passed and there were no errors', () => {
1457
+ const config = run_tests_command_1.DEFAULT_COMMAND_CONFIG;
1458
+ const results = (0, fixtures_1.getResults)([{ passed: true }]);
1459
+ expect(utils.getExitReason(config, { results })).toBe('passed');
1460
+ });
1461
+ });
1462
+ describe('getDatadogHost', () => {
1463
+ test('should default to datadog us api', () => __awaiter(void 0, void 0, void 0, function* () {
1464
+ process_1.default.env = {};
1465
+ expect(utils.getDatadogHost({ useIntake: false, apiVersion: 'v1', config: fixtures_1.ciConfig })).toBe('https://api.datadoghq.com/api/v1');
1466
+ expect(utils.getDatadogHost({ useIntake: false, apiVersion: 'unstable', config: fixtures_1.ciConfig })).toBe('https://api.datadoghq.com/api/unstable');
1467
+ expect(utils.getDatadogHost({ useIntake: true, apiVersion: 'v1', config: fixtures_1.ciConfig })).toBe('https://intake.synthetics.datadoghq.com/api/v1');
1468
+ }));
1469
+ test('should use DD_API_HOST_OVERRIDE', () => __awaiter(void 0, void 0, void 0, function* () {
1470
+ process_1.default.env = { DD_API_HOST_OVERRIDE: 'https://foobar' };
1471
+ expect(utils.getDatadogHost({ useIntake: true, apiVersion: 'v1', config: fixtures_1.ciConfig })).toBe('https://foobar/api/v1');
1472
+ expect(utils.getDatadogHost({ useIntake: true, apiVersion: 'v1', config: fixtures_1.ciConfig })).toBe('https://foobar/api/v1');
1473
+ }));
1474
+ test('should use Synthetics intake endpoint', () => __awaiter(void 0, void 0, void 0, function* () {
1475
+ process_1.default.env = {};
1476
+ expect(utils.getDatadogHost({
1477
+ apiVersion: 'v1',
1478
+ config: Object.assign(Object.assign({}, fixtures_1.ciConfig), { datadogSite: 'datadoghq.com' }),
1479
+ useIntake: true,
1480
+ })).toBe('https://intake.synthetics.datadoghq.com/api/v1');
1481
+ expect(utils.getDatadogHost({
1482
+ apiVersion: 'v1',
1483
+ config: Object.assign(Object.assign({}, fixtures_1.ciConfig), { datadogSite: 'datad0g.com' }),
1484
+ useIntake: true,
1485
+ })).toBe('https://intake.synthetics.datad0g.com/api/v1');
1486
+ }));
1487
+ });
1488
+ describe('getSyntheticsOrgSettings', () => {
1489
+ beforeEach(() => {
1490
+ jest.restoreAllMocks();
1491
+ });
1492
+ test('failing to get org settings is not important enough to throw', () => __awaiter(void 0, void 0, void 0, function* () {
1493
+ jest.spyOn(api, 'getSyntheticsOrgSettings').mockImplementation(() => {
1494
+ throw (0, fixtures_1.getAxiosHttpError)(502, { message: 'Server Error' });
1495
+ });
1496
+ const config = apiConfiguration;
1497
+ expect(yield utils.getOrgSettings(fixtures_1.mockReporter, config)).toBeUndefined();
1498
+ }));
1499
+ });
1500
+ describe('reportCiError', () => {
1501
+ test.each([
1502
+ 'NO_TESTS_TO_RUN',
1503
+ 'MISSING_TESTS',
1504
+ 'AUTHORIZATION_ERROR',
1505
+ 'INVALID_CONFIG',
1506
+ 'MISSING_APP_KEY',
1507
+ 'MISSING_API_KEY',
1508
+ 'POLL_RESULTS_FAILED',
1509
+ 'TUNNEL_START_FAILED',
1510
+ 'TOO_MANY_TESTS_TO_TRIGGER',
1511
+ 'TRIGGER_TESTS_FAILED',
1512
+ 'UNAVAILABLE_TEST_CONFIG',
1513
+ 'UNAVAILABLE_TUNNEL_CONFIG',
1514
+ ])('should report %s error', (errorCode) => __awaiter(void 0, void 0, void 0, function* () {
1515
+ const error = new errors_1.CiError(errorCode);
1516
+ utils.reportCiError(error, fixtures_1.mockReporter);
1517
+ expect(fixtures_1.mockReporter.error).toMatchSnapshot();
1518
+ }));
1519
+ test('should report default Error if no CiError was matched', () => __awaiter(void 0, void 0, void 0, function* () {
1520
+ const error = new errors_1.CiError('ERROR');
1521
+ utils.reportCiError(error, fixtures_1.mockReporter);
1522
+ expect(fixtures_1.mockReporter.error).toMatchSnapshot();
1523
+ }));
1524
+ });
1525
+ });
1526
+ //# sourceMappingURL=public.test.js.map