@azure/playwright 1.1.5 → 1.1.6

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 (318) hide show
  1. package/README.md +10 -18
  2. package/dist/commonjs/common/constants.d.ts +6 -1
  3. package/dist/commonjs/common/constants.d.ts.map +1 -1
  4. package/dist/commonjs/common/constants.js +10 -1
  5. package/dist/commonjs/common/constants.js.map +1 -1
  6. package/dist/commonjs/common/messages.d.ts +4 -0
  7. package/dist/commonjs/common/messages.d.ts.map +1 -1
  8. package/dist/commonjs/common/messages.js +6 -0
  9. package/dist/commonjs/common/messages.js.map +1 -1
  10. package/dist/commonjs/common/playwrightServiceConfig.d.ts +2 -1
  11. package/dist/commonjs/common/playwrightServiceConfig.d.ts.map +1 -1
  12. package/dist/commonjs/common/playwrightServiceConfig.js +5 -0
  13. package/dist/commonjs/common/playwrightServiceConfig.js.map +1 -1
  14. package/dist/commonjs/common/types.d.ts +15 -0
  15. package/dist/commonjs/common/types.d.ts.map +1 -1
  16. package/dist/commonjs/common/types.js.map +1 -1
  17. package/dist/commonjs/core/playwrightService.d.ts.map +1 -1
  18. package/dist/commonjs/core/playwrightService.js +7 -7
  19. package/dist/commonjs/core/playwrightService.js.map +1 -1
  20. package/dist/{browser/core/playwrightServiceUtils.d.ts → commonjs/core/playwrightServiceUtils-cjs.d.ts} +1 -1
  21. package/dist/commonjs/core/playwrightServiceUtils-cjs.d.ts.map +1 -0
  22. package/dist/commonjs/core/playwrightServiceUtils-cjs.js +14 -0
  23. package/dist/commonjs/core/playwrightServiceUtils-cjs.js.map +1 -0
  24. package/dist/commonjs/index.d.ts +2 -2
  25. package/dist/commonjs/index.d.ts.map +1 -1
  26. package/dist/commonjs/index.js.map +1 -1
  27. package/dist/commonjs/reporter/playwrightReporter.d.ts.map +1 -1
  28. package/dist/commonjs/reporter/playwrightReporter.js +12 -11
  29. package/dist/commonjs/reporter/playwrightReporter.js.map +1 -1
  30. package/dist/commonjs/tsdoc-metadata.json +1 -1
  31. package/dist/{browser/utils/getPackageVersion.d.ts → commonjs/utils/getPackageVersion-cjs.d.ts} +1 -1
  32. package/dist/commonjs/utils/getPackageVersion-cjs.d.ts.map +1 -0
  33. package/dist/commonjs/utils/{getPackageVersion.js → getPackageVersion-cjs.js} +1 -1
  34. package/dist/commonjs/utils/getPackageVersion-cjs.js.map +1 -0
  35. package/dist/commonjs/utils/parseJwt.d.ts.map +1 -1
  36. package/dist/commonjs/utils/parseJwt.js +2 -3
  37. package/dist/commonjs/utils/parseJwt.js.map +1 -1
  38. package/dist/commonjs/utils/utils.d.ts +3 -2
  39. package/dist/commonjs/utils/utils.d.ts.map +1 -1
  40. package/dist/commonjs/utils/utils.js +33 -6
  41. package/dist/commonjs/utils/utils.js.map +1 -1
  42. package/dist/esm/common/constants.d.ts +6 -1
  43. package/dist/esm/common/constants.d.ts.map +1 -1
  44. package/dist/esm/common/constants.js +9 -0
  45. package/dist/esm/common/constants.js.map +1 -1
  46. package/dist/esm/common/messages.d.ts +4 -0
  47. package/dist/esm/common/messages.d.ts.map +1 -1
  48. package/dist/esm/common/messages.js +6 -0
  49. package/dist/esm/common/messages.js.map +1 -1
  50. package/dist/esm/common/playwrightServiceConfig.d.ts +2 -1
  51. package/dist/esm/common/playwrightServiceConfig.d.ts.map +1 -1
  52. package/dist/esm/common/playwrightServiceConfig.js +6 -1
  53. package/dist/esm/common/playwrightServiceConfig.js.map +1 -1
  54. package/dist/esm/common/types.d.ts +15 -0
  55. package/dist/esm/common/types.d.ts.map +1 -1
  56. package/dist/esm/common/types.js.map +1 -1
  57. package/dist/esm/core/playwrightService.d.ts.map +1 -1
  58. package/dist/esm/core/playwrightService.js +2 -2
  59. package/dist/esm/core/playwrightService.js.map +1 -1
  60. package/dist/esm/core/playwrightServiceUtils.d.ts.map +1 -1
  61. package/dist/esm/core/playwrightServiceUtils.js +4 -2
  62. package/dist/esm/core/playwrightServiceUtils.js.map +1 -1
  63. package/dist/esm/index.d.ts +2 -2
  64. package/dist/esm/index.d.ts.map +1 -1
  65. package/dist/esm/index.js.map +1 -1
  66. package/dist/esm/reporter/playwrightReporter.d.ts.map +1 -1
  67. package/dist/esm/reporter/playwrightReporter.js +13 -12
  68. package/dist/esm/reporter/playwrightReporter.js.map +1 -1
  69. package/dist/esm/utils/getPackageVersion.d.ts.map +1 -1
  70. package/dist/esm/utils/getPackageVersion.js +2 -2
  71. package/dist/esm/utils/getPackageVersion.js.map +1 -1
  72. package/dist/esm/utils/parseJwt.d.ts.map +1 -1
  73. package/dist/esm/utils/parseJwt.js +2 -3
  74. package/dist/esm/utils/parseJwt.js.map +1 -1
  75. package/dist/esm/utils/utils.d.ts +3 -2
  76. package/dist/esm/utils/utils.d.ts.map +1 -1
  77. package/dist/esm/utils/utils.js +29 -3
  78. package/dist/esm/utils/utils.js.map +1 -1
  79. package/package.json +18 -26
  80. package/dist/browser/common/constants.d.ts +0 -104
  81. package/dist/browser/common/constants.d.ts.map +0 -1
  82. package/dist/browser/common/constants.js +0 -106
  83. package/dist/browser/common/constants.js.map +0 -1
  84. package/dist/browser/common/customerConfig.d.ts +0 -8
  85. package/dist/browser/common/customerConfig.d.ts.map +0 -1
  86. package/dist/browser/common/customerConfig.js +0 -16
  87. package/dist/browser/common/customerConfig.js.map +0 -1
  88. package/dist/browser/common/entraIdAccessToken.d.ts +0 -19
  89. package/dist/browser/common/entraIdAccessToken.d.ts.map +0 -1
  90. package/dist/browser/common/entraIdAccessToken.js +0 -108
  91. package/dist/browser/common/entraIdAccessToken.js.map +0 -1
  92. package/dist/browser/common/environmentVariables.d.ts +0 -12
  93. package/dist/browser/common/environmentVariables.d.ts.map +0 -1
  94. package/dist/browser/common/environmentVariables.js +0 -22
  95. package/dist/browser/common/environmentVariables.js.map +0 -1
  96. package/dist/browser/common/executor.d.ts +0 -2
  97. package/dist/browser/common/executor.d.ts.map +0 -1
  98. package/dist/browser/common/executor.js +0 -73
  99. package/dist/browser/common/executor.js.map +0 -1
  100. package/dist/browser/common/httpService.d.ts +0 -5
  101. package/dist/browser/common/httpService.d.ts.map +0 -1
  102. package/dist/browser/common/httpService.js +0 -34
  103. package/dist/browser/common/httpService.js.map +0 -1
  104. package/dist/browser/common/logger.d.ts +0 -2
  105. package/dist/browser/common/logger.d.ts.map +0 -1
  106. package/dist/browser/common/logger.js +0 -5
  107. package/dist/browser/common/logger.js.map +0 -1
  108. package/dist/browser/common/messages.d.ts +0 -165
  109. package/dist/browser/common/messages.d.ts.map +0 -1
  110. package/dist/browser/common/messages.js +0 -167
  111. package/dist/browser/common/messages.js.map +0 -1
  112. package/dist/browser/common/playwrightServiceConfig.d.ts +0 -22
  113. package/dist/browser/common/playwrightServiceConfig.d.ts.map +0 -1
  114. package/dist/browser/common/playwrightServiceConfig.js +0 -102
  115. package/dist/browser/common/playwrightServiceConfig.js.map +0 -1
  116. package/dist/browser/common/state.d.ts +0 -2
  117. package/dist/browser/common/state.d.ts.map +0 -1
  118. package/dist/browser/common/state.js +0 -9
  119. package/dist/browser/common/state.js.map +0 -1
  120. package/dist/browser/common/types.d.ts +0 -207
  121. package/dist/browser/common/types.d.ts.map +0 -1
  122. package/dist/browser/common/types.js +0 -4
  123. package/dist/browser/common/types.js.map +0 -1
  124. package/dist/browser/core/global/playwright-service-global-setup.d.ts +0 -4
  125. package/dist/browser/core/global/playwright-service-global-setup.d.ts.map +0 -1
  126. package/dist/browser/core/global/playwright-service-global-setup.js +0 -25
  127. package/dist/browser/core/global/playwright-service-global-setup.js.map +0 -1
  128. package/dist/browser/core/global/playwright-service-global-teardown.d.ts +0 -4
  129. package/dist/browser/core/global/playwright-service-global-teardown.d.ts.map +0 -1
  130. package/dist/browser/core/global/playwright-service-global-teardown.js +0 -19
  131. package/dist/browser/core/global/playwright-service-global-teardown.js.map +0 -1
  132. package/dist/browser/core/initializePlaywrightServiceTestRun.d.ts +0 -9
  133. package/dist/browser/core/initializePlaywrightServiceTestRun.d.ts.map +0 -1
  134. package/dist/browser/core/initializePlaywrightServiceTestRun.js +0 -26
  135. package/dist/browser/core/initializePlaywrightServiceTestRun.js.map +0 -1
  136. package/dist/browser/core/playwrightService.d.ts +0 -66
  137. package/dist/browser/core/playwrightService.d.ts.map +0 -1
  138. package/dist/browser/core/playwrightService.js +0 -219
  139. package/dist/browser/core/playwrightService.js.map +0 -1
  140. package/dist/browser/core/playwrightServiceEntra.d.ts +0 -15
  141. package/dist/browser/core/playwrightServiceEntra.d.ts.map +0 -1
  142. package/dist/browser/core/playwrightServiceEntra.js +0 -53
  143. package/dist/browser/core/playwrightServiceEntra.js.map +0 -1
  144. package/dist/browser/core/playwrightServiceUtils.d.ts.map +0 -1
  145. package/dist/browser/core/playwrightServiceUtils.js +0 -13
  146. package/dist/browser/core/playwrightServiceUtils.js.map +0 -1
  147. package/dist/browser/index.d.ts +0 -10
  148. package/dist/browser/index.d.ts.map +0 -1
  149. package/dist/browser/index.js +0 -11
  150. package/dist/browser/index.js.map +0 -1
  151. package/dist/browser/package.json +0 -3
  152. package/dist/browser/reporter/index.d.ts +0 -10
  153. package/dist/browser/reporter/index.d.ts.map +0 -1
  154. package/dist/browser/reporter/index.js +0 -12
  155. package/dist/browser/reporter/index.js.map +0 -1
  156. package/dist/browser/reporter/playwrightReporter.d.ts +0 -28
  157. package/dist/browser/reporter/playwrightReporter.d.ts.map +0 -1
  158. package/dist/browser/reporter/playwrightReporter.js +0 -210
  159. package/dist/browser/reporter/playwrightReporter.js.map +0 -1
  160. package/dist/browser/utils/PlaywrightServiceClient.d.ts +0 -9
  161. package/dist/browser/utils/PlaywrightServiceClient.d.ts.map +0 -1
  162. package/dist/browser/utils/PlaywrightServiceClient.js +0 -67
  163. package/dist/browser/utils/PlaywrightServiceClient.js.map +0 -1
  164. package/dist/browser/utils/cIInfoProvider.d.ts +0 -20
  165. package/dist/browser/utils/cIInfoProvider.d.ts.map +0 -1
  166. package/dist/browser/utils/cIInfoProvider.js +0 -75
  167. package/dist/browser/utils/cIInfoProvider.js.map +0 -1
  168. package/dist/browser/utils/getPackageVersion.d.ts.map +0 -1
  169. package/dist/browser/utils/getPackageVersion.js +0 -23
  170. package/dist/browser/utils/getPackageVersion.js.map +0 -1
  171. package/dist/browser/utils/getPlaywrightVersion.d.ts +0 -2
  172. package/dist/browser/utils/getPlaywrightVersion.d.ts.map +0 -1
  173. package/dist/browser/utils/getPlaywrightVersion.js +0 -19
  174. package/dist/browser/utils/getPlaywrightVersion.js.map +0 -1
  175. package/dist/browser/utils/packageManager.d.ts +0 -15
  176. package/dist/browser/utils/packageManager.d.ts.map +0 -1
  177. package/dist/browser/utils/packageManager.js +0 -41
  178. package/dist/browser/utils/packageManager.js.map +0 -1
  179. package/dist/browser/utils/parseJwt.d.ts +0 -4
  180. package/dist/browser/utils/parseJwt.d.ts.map +0 -1
  181. package/dist/browser/utils/parseJwt.js +0 -16
  182. package/dist/browser/utils/parseJwt.js.map +0 -1
  183. package/dist/browser/utils/playwrightReporterStorageManager.d.ts +0 -13
  184. package/dist/browser/utils/playwrightReporterStorageManager.d.ts.map +0 -1
  185. package/dist/browser/utils/playwrightReporterStorageManager.js +0 -452
  186. package/dist/browser/utils/playwrightReporterStorageManager.js.map +0 -1
  187. package/dist/browser/utils/utils.d.ts +0 -57
  188. package/dist/browser/utils/utils.d.ts.map +0 -1
  189. package/dist/browser/utils/utils.js +0 -392
  190. package/dist/browser/utils/utils.js.map +0 -1
  191. package/dist/commonjs/common/environmentVariables.d.ts +0 -12
  192. package/dist/commonjs/common/environmentVariables.d.ts.map +0 -1
  193. package/dist/commonjs/common/environmentVariables.js +0 -26
  194. package/dist/commonjs/common/environmentVariables.js.map +0 -1
  195. package/dist/commonjs/core/playwrightServiceUtils.d.ts +0 -5
  196. package/dist/commonjs/core/playwrightServiceUtils.d.ts.map +0 -1
  197. package/dist/commonjs/core/playwrightServiceUtils.js +0 -12
  198. package/dist/commonjs/core/playwrightServiceUtils.js.map +0 -1
  199. package/dist/commonjs/utils/getPackageVersion.d.ts +0 -2
  200. package/dist/commonjs/utils/getPackageVersion.d.ts.map +0 -1
  201. package/dist/commonjs/utils/getPackageVersion.js.map +0 -1
  202. package/dist/esm/common/environmentVariables.d.ts +0 -12
  203. package/dist/esm/common/environmentVariables.d.ts.map +0 -1
  204. package/dist/esm/common/environmentVariables.js +0 -22
  205. package/dist/esm/common/environmentVariables.js.map +0 -1
  206. package/dist/react-native/common/constants.d.ts +0 -104
  207. package/dist/react-native/common/constants.d.ts.map +0 -1
  208. package/dist/react-native/common/constants.js +0 -106
  209. package/dist/react-native/common/constants.js.map +0 -1
  210. package/dist/react-native/common/customerConfig.d.ts +0 -8
  211. package/dist/react-native/common/customerConfig.d.ts.map +0 -1
  212. package/dist/react-native/common/customerConfig.js +0 -16
  213. package/dist/react-native/common/customerConfig.js.map +0 -1
  214. package/dist/react-native/common/entraIdAccessToken.d.ts +0 -19
  215. package/dist/react-native/common/entraIdAccessToken.d.ts.map +0 -1
  216. package/dist/react-native/common/entraIdAccessToken.js +0 -108
  217. package/dist/react-native/common/entraIdAccessToken.js.map +0 -1
  218. package/dist/react-native/common/environmentVariables.d.ts +0 -12
  219. package/dist/react-native/common/environmentVariables.d.ts.map +0 -1
  220. package/dist/react-native/common/environmentVariables.js +0 -22
  221. package/dist/react-native/common/environmentVariables.js.map +0 -1
  222. package/dist/react-native/common/executor.d.ts +0 -2
  223. package/dist/react-native/common/executor.d.ts.map +0 -1
  224. package/dist/react-native/common/executor.js +0 -73
  225. package/dist/react-native/common/executor.js.map +0 -1
  226. package/dist/react-native/common/httpService.d.ts +0 -5
  227. package/dist/react-native/common/httpService.d.ts.map +0 -1
  228. package/dist/react-native/common/httpService.js +0 -34
  229. package/dist/react-native/common/httpService.js.map +0 -1
  230. package/dist/react-native/common/logger.d.ts +0 -2
  231. package/dist/react-native/common/logger.d.ts.map +0 -1
  232. package/dist/react-native/common/logger.js +0 -5
  233. package/dist/react-native/common/logger.js.map +0 -1
  234. package/dist/react-native/common/messages.d.ts +0 -165
  235. package/dist/react-native/common/messages.d.ts.map +0 -1
  236. package/dist/react-native/common/messages.js +0 -167
  237. package/dist/react-native/common/messages.js.map +0 -1
  238. package/dist/react-native/common/playwrightServiceConfig.d.ts +0 -22
  239. package/dist/react-native/common/playwrightServiceConfig.d.ts.map +0 -1
  240. package/dist/react-native/common/playwrightServiceConfig.js +0 -102
  241. package/dist/react-native/common/playwrightServiceConfig.js.map +0 -1
  242. package/dist/react-native/common/state.d.ts +0 -2
  243. package/dist/react-native/common/state.d.ts.map +0 -1
  244. package/dist/react-native/common/state.js +0 -9
  245. package/dist/react-native/common/state.js.map +0 -1
  246. package/dist/react-native/common/types.d.ts +0 -207
  247. package/dist/react-native/common/types.d.ts.map +0 -1
  248. package/dist/react-native/common/types.js +0 -4
  249. package/dist/react-native/common/types.js.map +0 -1
  250. package/dist/react-native/core/global/playwright-service-global-setup.d.ts +0 -4
  251. package/dist/react-native/core/global/playwright-service-global-setup.d.ts.map +0 -1
  252. package/dist/react-native/core/global/playwright-service-global-setup.js +0 -25
  253. package/dist/react-native/core/global/playwright-service-global-setup.js.map +0 -1
  254. package/dist/react-native/core/global/playwright-service-global-teardown.d.ts +0 -4
  255. package/dist/react-native/core/global/playwright-service-global-teardown.d.ts.map +0 -1
  256. package/dist/react-native/core/global/playwright-service-global-teardown.js +0 -19
  257. package/dist/react-native/core/global/playwright-service-global-teardown.js.map +0 -1
  258. package/dist/react-native/core/initializePlaywrightServiceTestRun.d.ts +0 -9
  259. package/dist/react-native/core/initializePlaywrightServiceTestRun.d.ts.map +0 -1
  260. package/dist/react-native/core/initializePlaywrightServiceTestRun.js +0 -26
  261. package/dist/react-native/core/initializePlaywrightServiceTestRun.js.map +0 -1
  262. package/dist/react-native/core/playwrightService.d.ts +0 -66
  263. package/dist/react-native/core/playwrightService.d.ts.map +0 -1
  264. package/dist/react-native/core/playwrightService.js +0 -219
  265. package/dist/react-native/core/playwrightService.js.map +0 -1
  266. package/dist/react-native/core/playwrightServiceEntra.d.ts +0 -15
  267. package/dist/react-native/core/playwrightServiceEntra.d.ts.map +0 -1
  268. package/dist/react-native/core/playwrightServiceEntra.js +0 -53
  269. package/dist/react-native/core/playwrightServiceEntra.js.map +0 -1
  270. package/dist/react-native/core/playwrightServiceUtils.d.ts +0 -5
  271. package/dist/react-native/core/playwrightServiceUtils.d.ts.map +0 -1
  272. package/dist/react-native/core/playwrightServiceUtils.js +0 -13
  273. package/dist/react-native/core/playwrightServiceUtils.js.map +0 -1
  274. package/dist/react-native/index.d.ts +0 -10
  275. package/dist/react-native/index.d.ts.map +0 -1
  276. package/dist/react-native/index.js +0 -11
  277. package/dist/react-native/index.js.map +0 -1
  278. package/dist/react-native/package.json +0 -3
  279. package/dist/react-native/reporter/index.d.ts +0 -10
  280. package/dist/react-native/reporter/index.d.ts.map +0 -1
  281. package/dist/react-native/reporter/index.js +0 -12
  282. package/dist/react-native/reporter/index.js.map +0 -1
  283. package/dist/react-native/reporter/playwrightReporter.d.ts +0 -28
  284. package/dist/react-native/reporter/playwrightReporter.d.ts.map +0 -1
  285. package/dist/react-native/reporter/playwrightReporter.js +0 -210
  286. package/dist/react-native/reporter/playwrightReporter.js.map +0 -1
  287. package/dist/react-native/utils/PlaywrightServiceClient.d.ts +0 -9
  288. package/dist/react-native/utils/PlaywrightServiceClient.d.ts.map +0 -1
  289. package/dist/react-native/utils/PlaywrightServiceClient.js +0 -67
  290. package/dist/react-native/utils/PlaywrightServiceClient.js.map +0 -1
  291. package/dist/react-native/utils/cIInfoProvider.d.ts +0 -20
  292. package/dist/react-native/utils/cIInfoProvider.d.ts.map +0 -1
  293. package/dist/react-native/utils/cIInfoProvider.js +0 -75
  294. package/dist/react-native/utils/cIInfoProvider.js.map +0 -1
  295. package/dist/react-native/utils/getPackageVersion.d.ts +0 -2
  296. package/dist/react-native/utils/getPackageVersion.d.ts.map +0 -1
  297. package/dist/react-native/utils/getPackageVersion.js +0 -23
  298. package/dist/react-native/utils/getPackageVersion.js.map +0 -1
  299. package/dist/react-native/utils/getPlaywrightVersion.d.ts +0 -2
  300. package/dist/react-native/utils/getPlaywrightVersion.d.ts.map +0 -1
  301. package/dist/react-native/utils/getPlaywrightVersion.js +0 -19
  302. package/dist/react-native/utils/getPlaywrightVersion.js.map +0 -1
  303. package/dist/react-native/utils/packageManager.d.ts +0 -15
  304. package/dist/react-native/utils/packageManager.d.ts.map +0 -1
  305. package/dist/react-native/utils/packageManager.js +0 -41
  306. package/dist/react-native/utils/packageManager.js.map +0 -1
  307. package/dist/react-native/utils/parseJwt.d.ts +0 -4
  308. package/dist/react-native/utils/parseJwt.d.ts.map +0 -1
  309. package/dist/react-native/utils/parseJwt.js +0 -16
  310. package/dist/react-native/utils/parseJwt.js.map +0 -1
  311. package/dist/react-native/utils/playwrightReporterStorageManager.d.ts +0 -13
  312. package/dist/react-native/utils/playwrightReporterStorageManager.d.ts.map +0 -1
  313. package/dist/react-native/utils/playwrightReporterStorageManager.js +0 -452
  314. package/dist/react-native/utils/playwrightReporterStorageManager.js.map +0 -1
  315. package/dist/react-native/utils/utils.d.ts +0 -57
  316. package/dist/react-native/utils/utils.d.ts.map +0 -1
  317. package/dist/react-native/utils/utils.js +0 -392
  318. package/dist/react-native/utils/utils.js.map +0 -1
@@ -1,16 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- export const base64UrlDecode = (base64Url) => {
4
- const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
5
- const buffer = Buffer.from(base64, "base64");
6
- return buffer.toString("utf-8");
7
- };
8
- export const parseJwt = (token) => {
9
- const parts = token.split(".");
10
- if (parts.length !== 3) {
11
- throw new Error("Invalid JWT token.");
12
- }
13
- const payload = base64UrlDecode(parts[1]);
14
- return JSON.parse(payload);
15
- };
16
- //# sourceMappingURL=parseJwt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parseJwt.js","sourceRoot":"","sources":["../../../src/utils/parseJwt.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAU,EAAE;IAC3D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAiB,KAAa,EAAK,EAAE;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;AAClC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { JwtPayload } from \"../common/types.js\";\n\nexport const base64UrlDecode = (base64Url: string): string => {\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const buffer = Buffer.from(base64, \"base64\");\n return buffer.toString(\"utf-8\");\n};\n\nexport const parseJwt = <T = JwtPayload>(token: string): T => {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid JWT token.\");\n }\n const payload = base64UrlDecode(parts[1]!);\n return JSON.parse(payload) as T;\n};\n"]}
@@ -1,13 +0,0 @@
1
- import type { TokenCredential } from "@azure/core-auth";
2
- import type { WorkspaceMetaData, UploadResult } from "../common/types.js";
3
- export declare class PlaywrightReporterStorageManager {
4
- uploadHtmlReportFolder(credential: TokenCredential, runId: string, outputFolder: string, workspaceDetails: WorkspaceMetaData): Promise<UploadResult>;
5
- private modifyTraceIndexHtml;
6
- uploadPlaywrightHtmlReportAfterTests(outputFolderName?: string, workspaceMetadata?: WorkspaceMetaData | null): Promise<UploadResult>;
7
- private uploadFolderInParallel;
8
- private uploadWithConcurrencyControl;
9
- private executeWithOptimizedBatching;
10
- private uploadSingleFileOptimized;
11
- private performOptimizedUpload;
12
- }
13
- //# sourceMappingURL=playwrightReporterStorageManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"playwrightReporterStorageManager.d.ts","sourceRoot":"","sources":["../../../src/utils/playwrightReporterStorageManager.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAaxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE1E,qBAAa,gCAAgC;IAErC,sBAAsB,CAC1B,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,iBAAiB,GAClC,OAAO,CAAC,YAAY,CAAC;YAsHV,oBAAoB;IA+H5B,oCAAoC,CACxC,gBAAgB,CAAC,EAAE,MAAM,EACzB,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAC3C,OAAO,CAAC,YAAY,CAAC;YAiDV,sBAAsB;YA4GtB,4BAA4B;YAwB5B,4BAA4B;YA4E5B,yBAAyB;YA8CzB,sBAAsB;CAsCrC"}
@@ -1,452 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { BlobServiceClient } from "@azure/storage-blob";
4
- import { coreLogger } from "../common/logger.js";
5
- import { readFileSync, writeFileSync, existsSync, createReadStream } from "fs";
6
- import { join } from "path";
7
- import { UploadConstants } from "../common/constants.js";
8
- import { ServiceErrorMessageConstants } from "../common/messages.js";
9
- import { populateValuesFromServiceUrl, calculateOptimalConcurrency, collectAllFiles, getStorageAccountNameFromUri, } from "./utils.js";
10
- import { PlaywrightServiceConfig } from "../common/playwrightServiceConfig.js";
11
- export class PlaywrightReporterStorageManager {
12
- // Uploads the HTML report folder to Azure Storage
13
- async uploadHtmlReportFolder(credential, runId, outputFolder, workspaceDetails) {
14
- coreLogger.info(`Starting HTML report upload for runId: ${runId}, outputFolder: ${outputFolder}`);
15
- const storageAccountName = getStorageAccountNameFromUri(workspaceDetails?.storageUri || "") || "unknown";
16
- try {
17
- if (!workspaceDetails.storageUri) {
18
- coreLogger.error("Storage URI not found in workspace details");
19
- return {
20
- success: false,
21
- errorMessage: ServiceErrorMessageConstants.STORAGE_URI_NOT_FOUND.message,
22
- };
23
- }
24
- const blobServiceClient = new BlobServiceClient(workspaceDetails?.storageUri, credential);
25
- coreLogger.info("blobServiceClient created successfully.");
26
- const serviceUrlInfo = populateValuesFromServiceUrl();
27
- if (!serviceUrlInfo?.accountId) {
28
- coreLogger.error("Unable to extract workspace ID from service URL");
29
- return {
30
- success: false,
31
- errorMessage: ServiceErrorMessageConstants.UNABLE_TO_EXTRACT_WORKSPACE_ID.message,
32
- };
33
- }
34
- const containerName = serviceUrlInfo.accountId.toLowerCase().replace(/[^a-z0-9-]/g, "-");
35
- const containerClient = blobServiceClient.getContainerClient(containerName);
36
- const containerExists = await containerClient.exists();
37
- if (!containerExists) {
38
- coreLogger.info(`Container ${containerName} does not exist. Creating new container.`);
39
- await containerClient.create();
40
- }
41
- else {
42
- coreLogger.info(`Container ${containerName} already exists.`);
43
- }
44
- const folderName = runId;
45
- console.log(ServiceErrorMessageConstants.UPLOADING_ARTIFACTS.formatWithDetails(storageAccountName, containerName, folderName));
46
- await this.modifyTraceIndexHtml(outputFolder);
47
- const uploadResults = await this.uploadFolderInParallel(containerClient, outputFolder, outputFolder, folderName);
48
- if (uploadResults.totalFiles === 0) {
49
- return { success: false, errorMessage: "No files found to upload" };
50
- }
51
- const failedFiles = uploadResults.totalFiles - uploadResults.uploadedFiles.length;
52
- if (failedFiles > 0) {
53
- if (uploadResults.failedFileDetails) {
54
- const hasAuthorizationError = uploadResults.failedFileDetails.some((fileDetail) => fileDetail.error.includes("not authorized to perform this operation") ||
55
- fileDetail.error.includes("AuthorizationFailure"));
56
- if (hasAuthorizationError) {
57
- return {
58
- success: false,
59
- errorMessage: ServiceErrorMessageConstants.STORAGE_AUTHORIZATION_FAILED.formatWithStorageAccount(storageAccountName),
60
- };
61
- }
62
- }
63
- // Get list of failed file names by comparing total files with uploaded files
64
- const uploadedSet = new Set(uploadResults.uploadedFiles);
65
- const allFiles = collectAllFiles(outputFolder, outputFolder, folderName);
66
- const failedFileNames = allFiles
67
- .filter((file) => !uploadedSet.has(file.relativePath))
68
- .map((file) => file.relativePath);
69
- return {
70
- success: false,
71
- partialSuccess: true,
72
- failedFileCount: failedFiles,
73
- totalFiles: uploadResults.totalFiles,
74
- failedFiles: failedFileNames,
75
- failedFileDetails: uploadResults.failedFileDetails,
76
- };
77
- }
78
- return { success: true };
79
- }
80
- catch (error) {
81
- const errorMessage = error instanceof Error ? error.message : String(error);
82
- const hasStorageAccountDeletedError = errorMessage.includes("ENOTFOUND") ||
83
- errorMessage.includes("getaddrinfo") ||
84
- errorMessage.includes("not found") ||
85
- errorMessage.includes("404");
86
- if (hasStorageAccountDeletedError) {
87
- return {
88
- success: false,
89
- errorMessage: ServiceErrorMessageConstants.STORAGE_ACCOUNT_DELETED.formatWithStorageAccount(storageAccountName),
90
- };
91
- }
92
- coreLogger.error(`Failed to upload HTML report: ${error}`);
93
- return { success: false, errorMessage };
94
- }
95
- }
96
- async modifyTraceIndexHtml(outputFolder) {
97
- coreLogger.info(`Starting trace modification for folder: ${outputFolder}`);
98
- const indexPath = join(outputFolder, "trace/index.html");
99
- const localIndexPath = join(outputFolder, "trace/index.local.html");
100
- if (!existsSync(indexPath)) {
101
- coreLogger.error(`trace/index.html not found at path: ${indexPath}`);
102
- return;
103
- }
104
- coreLogger.info(`Found trace/index.html at: ${indexPath}`);
105
- try {
106
- const originalHtml = readFileSync(indexPath, "utf-8");
107
- writeFileSync(localIndexPath, originalHtml, "utf-8");
108
- coreLogger.info(`Backed up original trace viewer to: ${localIndexPath}`);
109
- const redirectTraceviewerScript = `<!DOCTYPE html>
110
- <html>
111
- <head>
112
- <meta charset="utf-8">
113
- <title>Redirecting to Trace Viewer...</title>
114
- </head>
115
- <body>
116
- <script>
117
- /**
118
- * Trace Viewer Redirect Logic
119
- *
120
- * This script handles two scenarios:
121
- * 1. Azure Portal Access (with SAS tokens): Redirects to public Playwright trace viewer at https://trace.playwright.dev/
122
- * - Preserves SAS tokens on the trace URL to allow the public viewer to access the trace file from Azure Storage
123
- * 2. Local Development: Uses the local copy of the trace viewer (index.local.html)
124
- * - Preserves all query parameters including the trace parameter
125
- *
126
- * The script detects the scenario by checking:
127
- * - Presence of SAS tokens (sig, sv parameters) indicates Azure Portal access
128
- * - localhost/file protocol indicates local development
129
- *
130
- * Authentication token preservation:
131
- * - For Azure Portal: SAS tokens are added to the trace URL (not the viewer URL) so the viewer can fetch the trace
132
- * - For local dev: All parameters are forwarded to the local viewer
133
- */
134
- (function() {
135
- function shouldRedirect() {
136
- try {
137
- const currentUrl = new URL(location.href);
138
- const traceParam = currentUrl.searchParams.get('trace');
139
- if (!traceParam) return false;
140
-
141
- // Check if current URL (the index.html itself) has SAS tokens - indicates Azure Portal access
142
- const currentHasSas = currentUrl.searchParams.has('sig') || currentUrl.searchParams.has('sv');
143
-
144
- // Check if we're on localhost or file protocol (cover common local dev scenarios)
145
- const hostname = currentUrl.hostname;
146
- const protocol = currentUrl.protocol;
147
- const isLoopbackV4 =
148
- hostname === 'localhost' ||
149
- hostname === '127.0.0.1' ||
150
- hostname.startsWith('127.');
151
- const isLoopbackV6 =
152
- hostname === '::1' ||
153
- hostname === '[::1]';
154
- const isCustomLocalName =
155
- hostname.endsWith('.localhost') ||
156
- hostname.endsWith('.local');
157
- const isLocalHost =
158
- protocol === 'file:' ||
159
- isLoopbackV4 ||
160
- isLoopbackV6 ||
161
- isCustomLocalName;
162
-
163
- // Redirect to public trace viewer if:
164
- // 1. Current page is accessed with SAS tokens (Azure Portal scenario)
165
- // 2. Not running on localhost/file protocol
166
- return currentHasSas && !isLocalHost;
167
- } catch (e) {
168
- console.error('Trace redirect detection failed', e);
169
- return false;
170
- }
171
- }
172
-
173
- if (shouldRedirect()) {
174
- const url = new URL(location.href);
175
- const traceParam = url.searchParams.get('trace');
176
- const trace = new URL(traceParam, url);
177
-
178
- // Copy all query parameters from the current URL to the trace URL (preserve SAS tokens)
179
- for (const [key, value] of url.searchParams.entries()) {
180
- if (key !== 'trace') {
181
- trace.searchParams.set(key, value);
182
- }
183
- }
184
-
185
- const publicTraceViewer = new URL('https://trace.playwright.dev/');
186
- publicTraceViewer.searchParams.set('trace', trace.toString());
187
-
188
- location.replace(publicTraceViewer.toString());
189
- } else {
190
- // Use the local copy of the Playwright trace viewer when running locally
191
- // Preserve all query parameters including the trace parameter
192
- const currentUrl = new URL(location.href);
193
- const localViewerUrl = new URL('index.local.html', currentUrl);
194
-
195
- // Copy all query parameters to the local viewer URL
196
- for (const [key, value] of currentUrl.searchParams.entries()) {
197
- localViewerUrl.searchParams.set(key, value);
198
- }
199
-
200
- location.replace(localViewerUrl.toString());
201
- }
202
- })();
203
- </script>
204
- </body>
205
- </html>
206
- `;
207
- writeFileSync(indexPath, redirectTraceviewerScript, "utf-8");
208
- coreLogger.info("Successfully updated TraceViewer index file");
209
- }
210
- catch (error) {
211
- coreLogger.error(`Error modifying trace/index.html: ${error instanceof Error ? error.message : String(error)}`);
212
- return;
213
- }
214
- }
215
- // Uploads the entire Playwright HTML report folder after tests complete.
216
- async uploadPlaywrightHtmlReportAfterTests(outputFolderName, workspaceMetadata) {
217
- try {
218
- coreLogger.info(`Starting post-test HTML report upload, folder name: ${outputFolderName || "default (playwright-report)"}`);
219
- const cred = PlaywrightServiceConfig.instance.credential;
220
- if (!cred) {
221
- coreLogger.error("No credential found for authentication");
222
- return {
223
- success: false,
224
- errorMessage: ServiceErrorMessageConstants.NO_CRED_ENTRA_AUTH_ERROR.message,
225
- };
226
- }
227
- coreLogger.info("Credential found for authentication");
228
- const folderName = outputFolderName || "playwright-report";
229
- const outputFolderPath = join(process.cwd(), folderName);
230
- if (!existsSync(outputFolderPath)) {
231
- coreLogger.error(`HTML report folder not found: ${outputFolderPath}`);
232
- return {
233
- success: false,
234
- errorMessage: ServiceErrorMessageConstants.PLAYWRIGHT_TEST_REPORT_NOT_FOUND.formatWithFolder(folderName),
235
- };
236
- }
237
- coreLogger.info(`HTML report folder found: ${outputFolderPath}`);
238
- const testRunId = PlaywrightServiceConfig.instance.runId;
239
- coreLogger.info(`Starting upload for test run ID: ${testRunId}`);
240
- const result = await this.uploadHtmlReportFolder(cred, testRunId, outputFolderPath, workspaceMetadata);
241
- coreLogger.info(`Completed upload for test run ID: ${testRunId}`);
242
- return result;
243
- }
244
- catch (error) {
245
- const errorMessage = error instanceof Error ? error.message : String(error);
246
- coreLogger.error(`Upload failed: ${errorMessage}`);
247
- return { success: false, errorMessage };
248
- }
249
- }
250
- // Parallel Upload Engine - Core upload orchestration with performance optimization
251
- async uploadFolderInParallel(containerClient, folderPath, basePath, runIdFolderPrefix) {
252
- // Sort by size descending - upload large files first for better parallelization
253
- const filesToUpload = collectAllFiles(folderPath, basePath, runIdFolderPrefix).sort((a, b) => b.size - a.size);
254
- if (filesToUpload.length === 0) {
255
- return { uploadedFiles: [], failedFiles: [], totalFiles: 0, totalSize: 0, uploadTime: 0 };
256
- }
257
- const totalSize = filesToUpload.reduce((sum, file) => sum + file.size, 0);
258
- const concurrency = calculateOptimalConcurrency(filesToUpload);
259
- coreLogger.info(`Calculated optimal concurrency: ${concurrency} for ${filesToUpload.length} files (total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB)`);
260
- const uploadStartTime = Date.now();
261
- coreLogger.info(`Starting parallel upload with ${concurrency} concurrent operations`);
262
- const results = await this.uploadWithConcurrencyControl(containerClient, filesToUpload, concurrency);
263
- const uploadEndTime = Date.now();
264
- const uploadTime = uploadEndTime - uploadStartTime;
265
- coreLogger.info(`Upload completed in ${uploadTime}ms (${(uploadTime / 1000).toFixed(2)}s)`);
266
- const failed = results.filter((r) => r.status === "rejected").length;
267
- const successful = results.filter((r) => r.status === "fulfilled").length;
268
- coreLogger.info(`Upload results: ${successful} successful, ${failed} failed out of ${results.length} total files`);
269
- if (failed > 0) {
270
- const errors = results
271
- .filter((r) => r.status === "rejected")
272
- .map((r) => r.reason.message)
273
- .slice(0, 5); // Show first 5 errors
274
- errors.forEach((error, index) => {
275
- coreLogger.error(` ${index + 1}. ${error}`);
276
- });
277
- // Get failed file names and their error messages
278
- const uploadedSet = new Set(results
279
- .filter((r) => r.status === "fulfilled")
280
- .map((r) => r.value));
281
- const failedFileNames = filesToUpload
282
- .filter((file) => !uploadedSet.has(file.relativePath))
283
- .map((file) => file.relativePath);
284
- // Create detailed error mapping
285
- const failedFileDetails = [];
286
- results.forEach((result, index) => {
287
- if (result.status === "rejected") {
288
- const fileName = filesToUpload[index]?.relativePath || `File at index ${index}`;
289
- const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);
290
- failedFileDetails.push({ fileName, error: errorMessage });
291
- }
292
- });
293
- // Log error but don't throw to prevent breaking HTML reporter
294
- coreLogger.error(`Upload failed: ${failed} files could not be uploaded. Sample errors: ${errors.join(", ")}`);
295
- return {
296
- uploadedFiles: results
297
- .filter((r) => r.status === "fulfilled")
298
- .map((r) => r.value),
299
- failedFiles: failedFileNames,
300
- failedFileDetails,
301
- totalFiles: filesToUpload.length,
302
- totalSize,
303
- uploadTime,
304
- };
305
- }
306
- const uploadedFiles = results
307
- .filter((r) => r.status === "fulfilled")
308
- .map((r) => r.value);
309
- return {
310
- uploadedFiles,
311
- failedFiles: [],
312
- totalFiles: filesToUpload.length,
313
- totalSize,
314
- uploadTime,
315
- };
316
- }
317
- // Concurrency Control System - Manages parallel execution with controlled resource usage
318
- async uploadWithConcurrencyControl(containerClient, files, concurrency) {
319
- const uploadTasks = files.map((fileInfo) => async () => {
320
- try {
321
- await this.uploadSingleFileOptimized(containerClient, fileInfo);
322
- return fileInfo.relativePath;
323
- }
324
- catch (error) {
325
- coreLogger.error(`Failed to upload file: ${fileInfo.relativePath} - ${error instanceof Error ? error.message : "Unknown error"}`);
326
- throw error;
327
- }
328
- });
329
- return this.executeWithOptimizedBatching(uploadTasks, concurrency);
330
- }
331
- // Optimized Batch Execution Engine - High-performance task processing system
332
- async executeWithOptimizedBatching(tasks, concurrency) {
333
- const results = new Array(tasks.length);
334
- let completedTasks = 0;
335
- // Splits tasks into optimal batches to balance memory usage vs. throughput
336
- const batchSize = Math.min(UploadConstants.BATCH_SIZE, concurrency * 2);
337
- const batches = [];
338
- // Each batch will be processed with full concurrency before moving to next batch
339
- for (let i = 0; i < tasks.length; i += batchSize) {
340
- batches.push(tasks.slice(i, i + batchSize));
341
- }
342
- // Process each batch sequentially to maintain memory efficiency
343
- coreLogger.info(`Processing ${batches.length} batches with ${batchSize} tasks per batch`);
344
- for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {
345
- const batch = batches[batchIndex];
346
- const batchStartIndex = batchIndex * batchSize;
347
- coreLogger.info(`Starting batch ${batchIndex + 1}/${batches.length} with ${batch.length} tasks`);
348
- // Transform each task into a promise that captures results at correct index
349
- const batchPromises = batch.map(async (task, taskIndex) => {
350
- const globalIndex = batchStartIndex + taskIndex;
351
- try {
352
- const result = await task();
353
- results[globalIndex] = { status: "fulfilled", value: result };
354
- return result;
355
- }
356
- catch (error) {
357
- results[globalIndex] = { status: "rejected", reason: error };
358
- coreLogger.error(`Task failed at index ${globalIndex}: ${error instanceof Error ? error.message : "Unknown error"}`);
359
- return;
360
- }
361
- });
362
- const executing = [];
363
- for (const promise of batchPromises) {
364
- if (executing.length >= concurrency) {
365
- await Promise.race(executing);
366
- }
367
- const wrappedPromise = promise
368
- .then((result) => {
369
- completedTasks++;
370
- return result;
371
- })
372
- .catch(() => {
373
- completedTasks++;
374
- })
375
- .finally(() => {
376
- // Cleanup: remove completed promise from executing array
377
- const index = executing.indexOf(wrappedPromise);
378
- if (index > -1)
379
- executing.splice(index, 1);
380
- });
381
- executing.push(wrappedPromise);
382
- }
383
- // Wait for all promises in current batch to complete before moving to next batch
384
- await Promise.allSettled(executing);
385
- coreLogger.info(`Completed batch ${batchIndex + 1}/${batches.length}`);
386
- }
387
- return results;
388
- }
389
- // Individual File Upload with Retry Logic
390
- async uploadSingleFileOptimized(containerClient, fileInfo) {
391
- coreLogger.info(`Uploading file: ${fileInfo.relativePath} (${(fileInfo.size / 1024).toFixed(2)} KB, ${fileInfo.contentType})`);
392
- const blockBlobClient = containerClient.getBlockBlobClient(fileInfo.relativePath);
393
- const maxRetries = UploadConstants.MAX_RETRY_ATTEMPTS;
394
- const baseDelay = UploadConstants.RETRY_BASE_DELAY;
395
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
396
- try {
397
- await this.performOptimizedUpload(blockBlobClient, fileInfo);
398
- return;
399
- }
400
- catch (error) {
401
- const isLastAttempt = attempt === maxRetries;
402
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
403
- coreLogger.info(`Upload attempt ${attempt} failed for ${fileInfo.relativePath}: ${errorMessage}`);
404
- if (isLastAttempt) {
405
- coreLogger.error(`All retry attempts exhausted for ${fileInfo.relativePath}: ${errorMessage}`);
406
- if (error instanceof Error) {
407
- throw error;
408
- }
409
- throw new Error(`Upload failed for ${fileInfo.relativePath} after ${maxRetries} attempts: ${errorMessage}`);
410
- }
411
- // Exponential backoff with jitter (Azure SDK pattern)
412
- const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500;
413
- coreLogger.info(`Retrying upload for ${fileInfo.relativePath} in ${delay.toFixed(0)}ms (attempt ${attempt + 1}/${maxRetries})`);
414
- await new Promise((_resolve) => setTimeout(_resolve, delay));
415
- }
416
- }
417
- }
418
- // Multi-Strategy Upload Engine - Optimized upload based on file characteristics
419
- async performOptimizedUpload(blockBlobClient, fileInfo) {
420
- if (fileInfo.size <= UploadConstants.SMALL_FILE_THRESHOLD) {
421
- // DIRECT UPLOAD: Optimal for small files (≤1MB)
422
- const fileContent = readFileSync(fileInfo.fullPath);
423
- await blockBlobClient.upload(fileContent, fileContent.length, {
424
- blobHTTPHeaders: {
425
- blobContentType: fileInfo.contentType,
426
- },
427
- });
428
- }
429
- else if (fileInfo.size <= UploadConstants.LARGE_FILE_THRESHOLD) {
430
- // BLOCK UPLOAD: Optimal for medium files (1MB - 100MB)
431
- const fileContent = readFileSync(fileInfo.fullPath);
432
- await blockBlobClient.uploadData(fileContent, {
433
- blobHTTPHeaders: {
434
- blobContentType: fileInfo.contentType,
435
- },
436
- blockSize: UploadConstants.OPTIMIZED_BLOCK_SIZE,
437
- concurrency: UploadConstants.PER_FILE_CONCURRENCY,
438
- });
439
- }
440
- else {
441
- // STREAMING UPLOAD: Optimal for large files (>100MB)
442
- const stream = createReadStream(fileInfo.fullPath);
443
- await blockBlobClient.uploadStream(stream, UploadConstants.STREAM_BUFFER_SIZE, UploadConstants.LARGE_FILE_CONCURRENCY, {
444
- blobHTTPHeaders: {
445
- blobContentType: fileInfo.contentType,
446
- },
447
- });
448
- }
449
- coreLogger.info(`Successfully uploaded: ${fileInfo.relativePath}`);
450
- }
451
- }
452
- //# sourceMappingURL=playwrightReporterStorageManager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"playwrightReporterStorageManager.js","sourceRoot":"","sources":["../../../src/utils/playwrightReporterStorageManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ContainerClient, BlockBlobClient } from \"@azure/storage-blob\";\nimport { BlobServiceClient } from \"@azure/storage-blob\";\nimport type { TokenCredential } from \"@azure/core-auth\";\nimport { coreLogger } from \"../common/logger.js\";\nimport { readFileSync, writeFileSync, existsSync, createReadStream } from \"fs\";\nimport { join } from \"path\";\nimport { UploadConstants } from \"../common/constants.js\";\nimport { ServiceErrorMessageConstants } from \"../common/messages.js\";\nimport {\n populateValuesFromServiceUrl,\n calculateOptimalConcurrency,\n collectAllFiles,\n getStorageAccountNameFromUri,\n} from \"./utils.js\";\nimport { PlaywrightServiceConfig } from \"../common/playwrightServiceConfig.js\";\nimport type { WorkspaceMetaData, UploadResult } from \"../common/types.js\";\n\nexport class PlaywrightReporterStorageManager {\n // Uploads the HTML report folder to Azure Storage\n async uploadHtmlReportFolder(\n credential: TokenCredential,\n runId: string,\n outputFolder: string,\n workspaceDetails: WorkspaceMetaData,\n ): Promise<UploadResult> {\n coreLogger.info(\n `Starting HTML report upload for runId: ${runId}, outputFolder: ${outputFolder}`,\n );\n\n const storageAccountName =\n getStorageAccountNameFromUri(workspaceDetails?.storageUri || \"\") || \"unknown\";\n\n try {\n if (!workspaceDetails.storageUri) {\n coreLogger.error(\"Storage URI not found in workspace details\");\n return {\n success: false,\n errorMessage: ServiceErrorMessageConstants.STORAGE_URI_NOT_FOUND.message,\n };\n }\n\n const blobServiceClient = new BlobServiceClient(workspaceDetails?.storageUri, credential);\n coreLogger.info(\"blobServiceClient created successfully.\");\n const serviceUrlInfo = populateValuesFromServiceUrl();\n if (!serviceUrlInfo?.accountId) {\n coreLogger.error(\"Unable to extract workspace ID from service URL\");\n return {\n success: false,\n errorMessage: ServiceErrorMessageConstants.UNABLE_TO_EXTRACT_WORKSPACE_ID.message,\n };\n }\n\n const containerName = serviceUrlInfo.accountId.toLowerCase().replace(/[^a-z0-9-]/g, \"-\");\n const containerClient = blobServiceClient.getContainerClient(containerName);\n\n const containerExists = await containerClient.exists();\n if (!containerExists) {\n coreLogger.info(`Container ${containerName} does not exist. Creating new container.`);\n await containerClient.create();\n } else {\n coreLogger.info(`Container ${containerName} already exists.`);\n }\n\n const folderName = runId;\n console.log(\n ServiceErrorMessageConstants.UPLOADING_ARTIFACTS.formatWithDetails(\n storageAccountName,\n containerName,\n folderName,\n ),\n );\n\n await this.modifyTraceIndexHtml(outputFolder);\n const uploadResults = await this.uploadFolderInParallel(\n containerClient,\n outputFolder,\n outputFolder,\n folderName,\n );\n\n if (uploadResults.totalFiles === 0) {\n return { success: false, errorMessage: \"No files found to upload\" };\n }\n\n const failedFiles = uploadResults.totalFiles - uploadResults.uploadedFiles.length;\n if (failedFiles > 0) {\n if (uploadResults.failedFileDetails) {\n const hasAuthorizationError = uploadResults.failedFileDetails.some(\n (fileDetail) =>\n fileDetail.error.includes(\"not authorized to perform this operation\") ||\n fileDetail.error.includes(\"AuthorizationFailure\"),\n );\n\n if (hasAuthorizationError) {\n return {\n success: false,\n errorMessage:\n ServiceErrorMessageConstants.STORAGE_AUTHORIZATION_FAILED.formatWithStorageAccount(\n storageAccountName,\n ),\n };\n }\n }\n\n // Get list of failed file names by comparing total files with uploaded files\n const uploadedSet = new Set(uploadResults.uploadedFiles);\n const allFiles = collectAllFiles(outputFolder, outputFolder, folderName);\n const failedFileNames = allFiles\n .filter((file) => !uploadedSet.has(file.relativePath))\n .map((file) => file.relativePath);\n\n return {\n success: false,\n partialSuccess: true,\n failedFileCount: failedFiles,\n totalFiles: uploadResults.totalFiles,\n failedFiles: failedFileNames,\n failedFileDetails: uploadResults.failedFileDetails,\n };\n }\n\n return { success: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const hasStorageAccountDeletedError =\n errorMessage.includes(\"ENOTFOUND\") ||\n errorMessage.includes(\"getaddrinfo\") ||\n errorMessage.includes(\"not found\") ||\n errorMessage.includes(\"404\");\n if (hasStorageAccountDeletedError) {\n return {\n success: false,\n errorMessage:\n ServiceErrorMessageConstants.STORAGE_ACCOUNT_DELETED.formatWithStorageAccount(\n storageAccountName,\n ),\n };\n }\n coreLogger.error(`Failed to upload HTML report: ${error}`);\n return { success: false, errorMessage };\n }\n }\n private async modifyTraceIndexHtml(outputFolder: string): Promise<void> {\n coreLogger.info(`Starting trace modification for folder: ${outputFolder}`);\n const indexPath = join(outputFolder, \"trace/index.html\");\n const localIndexPath = join(outputFolder, \"trace/index.local.html\");\n\n if (!existsSync(indexPath)) {\n coreLogger.error(`trace/index.html not found at path: ${indexPath}`);\n return;\n }\n coreLogger.info(`Found trace/index.html at: ${indexPath}`);\n\n try {\n const originalHtml = readFileSync(indexPath, \"utf-8\");\n writeFileSync(localIndexPath, originalHtml, \"utf-8\");\n coreLogger.info(`Backed up original trace viewer to: ${localIndexPath}`);\n\n const redirectTraceviewerScript = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Redirecting to Trace Viewer...</title>\n</head>\n<body>\n <script>\n /**\n * Trace Viewer Redirect Logic\n * \n * This script handles two scenarios:\n * 1. Azure Portal Access (with SAS tokens): Redirects to public Playwright trace viewer at https://trace.playwright.dev/\n * - Preserves SAS tokens on the trace URL to allow the public viewer to access the trace file from Azure Storage\n * 2. Local Development: Uses the local copy of the trace viewer (index.local.html)\n * - Preserves all query parameters including the trace parameter\n * \n * The script detects the scenario by checking:\n * - Presence of SAS tokens (sig, sv parameters) indicates Azure Portal access\n * - localhost/file protocol indicates local development\n * \n * Authentication token preservation:\n * - For Azure Portal: SAS tokens are added to the trace URL (not the viewer URL) so the viewer can fetch the trace\n * - For local dev: All parameters are forwarded to the local viewer\n */\n (function() {\n function shouldRedirect() {\n try {\n const currentUrl = new URL(location.href);\n const traceParam = currentUrl.searchParams.get('trace');\n if (!traceParam) return false;\n\n // Check if current URL (the index.html itself) has SAS tokens - indicates Azure Portal access\n const currentHasSas = currentUrl.searchParams.has('sig') || currentUrl.searchParams.has('sv');\n \n // Check if we're on localhost or file protocol (cover common local dev scenarios)\n const hostname = currentUrl.hostname;\n const protocol = currentUrl.protocol;\n const isLoopbackV4 =\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.startsWith('127.');\n const isLoopbackV6 =\n hostname === '::1' ||\n hostname === '[::1]';\n const isCustomLocalName =\n hostname.endsWith('.localhost') ||\n hostname.endsWith('.local');\n const isLocalHost =\n protocol === 'file:' ||\n isLoopbackV4 ||\n isLoopbackV6 ||\n isCustomLocalName;\n\n // Redirect to public trace viewer if:\n // 1. Current page is accessed with SAS tokens (Azure Portal scenario)\n // 2. Not running on localhost/file protocol\n return currentHasSas && !isLocalHost;\n } catch (e) {\n console.error('Trace redirect detection failed', e);\n return false;\n }\n }\n\n if (shouldRedirect()) {\n const url = new URL(location.href);\n const traceParam = url.searchParams.get('trace');\n const trace = new URL(traceParam, url);\n\n // Copy all query parameters from the current URL to the trace URL (preserve SAS tokens)\n for (const [key, value] of url.searchParams.entries()) {\n if (key !== 'trace') {\n trace.searchParams.set(key, value);\n }\n }\n\n const publicTraceViewer = new URL('https://trace.playwright.dev/');\n publicTraceViewer.searchParams.set('trace', trace.toString());\n\n location.replace(publicTraceViewer.toString());\n } else {\n // Use the local copy of the Playwright trace viewer when running locally\n // Preserve all query parameters including the trace parameter\n const currentUrl = new URL(location.href);\n const localViewerUrl = new URL('index.local.html', currentUrl);\n \n // Copy all query parameters to the local viewer URL\n for (const [key, value] of currentUrl.searchParams.entries()) {\n localViewerUrl.searchParams.set(key, value);\n }\n \n location.replace(localViewerUrl.toString());\n }\n })();\n </script>\n</body>\n</html>\n`;\n\n writeFileSync(indexPath, redirectTraceviewerScript, \"utf-8\");\n coreLogger.info(\"Successfully updated TraceViewer index file\");\n } catch (error) {\n coreLogger.error(\n `Error modifying trace/index.html: ${error instanceof Error ? error.message : String(error)}`,\n );\n return;\n }\n }\n\n // Uploads the entire Playwright HTML report folder after tests complete.\n\n async uploadPlaywrightHtmlReportAfterTests(\n outputFolderName?: string,\n workspaceMetadata?: WorkspaceMetaData | null,\n ): Promise<UploadResult> {\n try {\n coreLogger.info(\n `Starting post-test HTML report upload, folder name: ${outputFolderName || \"default (playwright-report)\"}`,\n );\n const cred = PlaywrightServiceConfig.instance.credential;\n if (!cred) {\n coreLogger.error(\"No credential found for authentication\");\n return {\n success: false,\n errorMessage: ServiceErrorMessageConstants.NO_CRED_ENTRA_AUTH_ERROR.message,\n };\n }\n coreLogger.info(\"Credential found for authentication\");\n\n const folderName = outputFolderName || \"playwright-report\";\n const outputFolderPath = join(process.cwd(), folderName);\n\n if (!existsSync(outputFolderPath)) {\n coreLogger.error(`HTML report folder not found: ${outputFolderPath}`);\n return {\n success: false,\n errorMessage:\n ServiceErrorMessageConstants.PLAYWRIGHT_TEST_REPORT_NOT_FOUND.formatWithFolder(\n folderName,\n ),\n };\n }\n coreLogger.info(`HTML report folder found: ${outputFolderPath}`);\n\n const testRunId = PlaywrightServiceConfig.instance.runId;\n coreLogger.info(`Starting upload for test run ID: ${testRunId}`);\n const result = await this.uploadHtmlReportFolder(\n cred,\n testRunId,\n outputFolderPath,\n workspaceMetadata!,\n );\n coreLogger.info(`Completed upload for test run ID: ${testRunId}`);\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n coreLogger.error(`Upload failed: ${errorMessage}`);\n return { success: false, errorMessage };\n }\n }\n\n // Parallel Upload Engine - Core upload orchestration with performance optimization\n\n private async uploadFolderInParallel(\n containerClient: ContainerClient,\n folderPath: string,\n basePath: string,\n runIdFolderPrefix?: string,\n ): Promise<{\n uploadedFiles: string[];\n failedFiles: string[];\n failedFileDetails?: Array<{ fileName: string; error: string }>;\n totalFiles: number;\n totalSize: number;\n uploadTime: number;\n }> {\n // Sort by size descending - upload large files first for better parallelization\n const filesToUpload = collectAllFiles(folderPath, basePath, runIdFolderPrefix).sort(\n (a, b) => b.size - a.size,\n );\n\n if (filesToUpload.length === 0) {\n return { uploadedFiles: [], failedFiles: [], totalFiles: 0, totalSize: 0, uploadTime: 0 };\n }\n\n const totalSize = filesToUpload.reduce((sum, file) => sum + file.size, 0);\n\n const concurrency = calculateOptimalConcurrency(filesToUpload);\n coreLogger.info(\n `Calculated optimal concurrency: ${concurrency} for ${filesToUpload.length} files (total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB)`,\n );\n const uploadStartTime = Date.now();\n coreLogger.info(`Starting parallel upload with ${concurrency} concurrent operations`);\n const results = await this.uploadWithConcurrencyControl(\n containerClient,\n filesToUpload,\n concurrency,\n );\n\n const uploadEndTime = Date.now();\n const uploadTime = uploadEndTime - uploadStartTime;\n coreLogger.info(`Upload completed in ${uploadTime}ms (${(uploadTime / 1000).toFixed(2)}s)`);\n\n const failed = results.filter((r) => r.status === \"rejected\").length;\n const successful = results.filter((r) => r.status === \"fulfilled\").length;\n coreLogger.info(\n `Upload results: ${successful} successful, ${failed} failed out of ${results.length} total files`,\n );\n\n if (failed > 0) {\n const errors = results\n .filter((r): r is PromiseRejectedResult => r.status === \"rejected\")\n .map((r) => r.reason.message)\n .slice(0, 5); // Show first 5 errors\n\n errors.forEach((error, index) => {\n coreLogger.error(` ${index + 1}. ${error}`);\n });\n\n // Get failed file names and their error messages\n const uploadedSet = new Set(\n results\n .filter((r): r is PromiseFulfilledResult<string> => r.status === \"fulfilled\")\n .map((r) => r.value),\n );\n const failedFileNames = filesToUpload\n .filter((file) => !uploadedSet.has(file.relativePath))\n .map((file) => file.relativePath);\n\n // Create detailed error mapping\n const failedFileDetails: Array<{ fileName: string; error: string }> = [];\n results.forEach((result, index) => {\n if (result.status === \"rejected\") {\n const fileName = filesToUpload[index]?.relativePath || `File at index ${index}`;\n const errorMessage =\n result.reason instanceof Error ? result.reason.message : String(result.reason);\n failedFileDetails.push({ fileName, error: errorMessage });\n }\n });\n\n // Log error but don't throw to prevent breaking HTML reporter\n coreLogger.error(\n `Upload failed: ${failed} files could not be uploaded. Sample errors: ${errors.join(\", \")}`,\n );\n return {\n uploadedFiles: results\n .filter((r): r is PromiseFulfilledResult<string> => r.status === \"fulfilled\")\n .map((r) => r.value),\n failedFiles: failedFileNames,\n failedFileDetails,\n totalFiles: filesToUpload.length,\n totalSize,\n uploadTime,\n };\n }\n\n const uploadedFiles = results\n .filter((r): r is PromiseFulfilledResult<string> => r.status === \"fulfilled\")\n .map((r) => r.value);\n\n return {\n uploadedFiles,\n failedFiles: [],\n totalFiles: filesToUpload.length,\n totalSize,\n uploadTime,\n };\n }\n\n // Concurrency Control System - Manages parallel execution with controlled resource usage\n\n private async uploadWithConcurrencyControl(\n containerClient: ContainerClient,\n files: Array<{ fullPath: string; relativePath: string; size: number; contentType: string }>,\n concurrency: number,\n ): Promise<PromiseSettledResult<string>[]> {\n const uploadTasks = files.map((fileInfo) => async (): Promise<string> => {\n try {\n await this.uploadSingleFileOptimized(containerClient, fileInfo);\n return fileInfo.relativePath;\n } catch (error) {\n coreLogger.error(\n `Failed to upload file: ${fileInfo.relativePath} - ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n );\n throw error;\n }\n });\n\n return this.executeWithOptimizedBatching(uploadTasks, concurrency);\n }\n\n // Optimized Batch Execution Engine - High-performance task processing system\n\n private async executeWithOptimizedBatching<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number,\n ): Promise<PromiseSettledResult<T>[]> {\n const results: PromiseSettledResult<T>[] = new Array(tasks.length);\n let completedTasks = 0;\n\n // Splits tasks into optimal batches to balance memory usage vs. throughput\n const batchSize = Math.min(UploadConstants.BATCH_SIZE, concurrency * 2);\n const batches: Array<Array<() => Promise<T>>> = [];\n\n // Each batch will be processed with full concurrency before moving to next batch\n for (let i = 0; i < tasks.length; i += batchSize) {\n batches.push(tasks.slice(i, i + batchSize));\n }\n\n // Process each batch sequentially to maintain memory efficiency\n coreLogger.info(`Processing ${batches.length} batches with ${batchSize} tasks per batch`);\n for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {\n const batch = batches[batchIndex];\n const batchStartIndex = batchIndex * batchSize;\n coreLogger.info(\n `Starting batch ${batchIndex + 1}/${batches.length} with ${batch.length} tasks`,\n );\n\n // Transform each task into a promise that captures results at correct index\n const batchPromises = batch.map(async (task, taskIndex) => {\n const globalIndex = batchStartIndex + taskIndex;\n try {\n const result = await task();\n results[globalIndex] = { status: \"fulfilled\", value: result };\n return result;\n } catch (error) {\n results[globalIndex] = { status: \"rejected\", reason: error };\n coreLogger.error(\n `Task failed at index ${globalIndex}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n );\n return;\n }\n });\n\n const executing: Promise<any>[] = [];\n\n for (const promise of batchPromises) {\n if (executing.length >= concurrency) {\n await Promise.race(executing);\n }\n const wrappedPromise = promise\n .then((result) => {\n completedTasks++;\n return result;\n })\n .catch(() => {\n completedTasks++;\n })\n .finally(() => {\n // Cleanup: remove completed promise from executing array\n const index = executing.indexOf(wrappedPromise);\n if (index > -1) executing.splice(index, 1);\n });\n\n executing.push(wrappedPromise);\n }\n\n // Wait for all promises in current batch to complete before moving to next batch\n await Promise.allSettled(executing);\n coreLogger.info(`Completed batch ${batchIndex + 1}/${batches.length}`);\n }\n\n return results;\n }\n\n // Individual File Upload with Retry Logic\n\n private async uploadSingleFileOptimized(\n containerClient: ContainerClient,\n fileInfo: { fullPath: string; relativePath: string; contentType: string; size: number },\n ): Promise<void> {\n coreLogger.info(\n `Uploading file: ${fileInfo.relativePath} (${(fileInfo.size / 1024).toFixed(2)} KB, ${fileInfo.contentType})`,\n );\n const blockBlobClient = containerClient.getBlockBlobClient(fileInfo.relativePath);\n const maxRetries = UploadConstants.MAX_RETRY_ATTEMPTS;\n const baseDelay = UploadConstants.RETRY_BASE_DELAY;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n await this.performOptimizedUpload(blockBlobClient, fileInfo);\n return;\n } catch (error) {\n const isLastAttempt = attempt === maxRetries;\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n coreLogger.info(\n `Upload attempt ${attempt} failed for ${fileInfo.relativePath}: ${errorMessage}`,\n );\n\n if (isLastAttempt) {\n coreLogger.error(\n `All retry attempts exhausted for ${fileInfo.relativePath}: ${errorMessage}`,\n );\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(\n `Upload failed for ${fileInfo.relativePath} after ${maxRetries} attempts: ${errorMessage}`,\n );\n }\n\n // Exponential backoff with jitter (Azure SDK pattern)\n const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500;\n coreLogger.info(\n `Retrying upload for ${fileInfo.relativePath} in ${delay.toFixed(0)}ms (attempt ${attempt + 1}/${maxRetries})`,\n );\n await new Promise((_resolve) => setTimeout(_resolve, delay));\n }\n }\n }\n\n // Multi-Strategy Upload Engine - Optimized upload based on file characteristics\n\n private async performOptimizedUpload(\n blockBlobClient: BlockBlobClient,\n fileInfo: { fullPath: string; relativePath: string; contentType: string; size: number },\n ): Promise<void> {\n if (fileInfo.size <= UploadConstants.SMALL_FILE_THRESHOLD) {\n // DIRECT UPLOAD: Optimal for small files (≤1MB)\n const fileContent = readFileSync(fileInfo.fullPath);\n await blockBlobClient.upload(fileContent, fileContent.length, {\n blobHTTPHeaders: {\n blobContentType: fileInfo.contentType,\n },\n });\n } else if (fileInfo.size <= UploadConstants.LARGE_FILE_THRESHOLD) {\n // BLOCK UPLOAD: Optimal for medium files (1MB - 100MB)\n const fileContent = readFileSync(fileInfo.fullPath);\n await blockBlobClient.uploadData(fileContent, {\n blobHTTPHeaders: {\n blobContentType: fileInfo.contentType,\n },\n blockSize: UploadConstants.OPTIMIZED_BLOCK_SIZE,\n concurrency: UploadConstants.PER_FILE_CONCURRENCY,\n });\n } else {\n // STREAMING UPLOAD: Optimal for large files (>100MB)\n const stream = createReadStream(fileInfo.fullPath);\n await blockBlobClient.uploadStream(\n stream,\n UploadConstants.STREAM_BUFFER_SIZE,\n UploadConstants.LARGE_FILE_CONCURRENCY,\n {\n blobHTTPHeaders: {\n blobContentType: fileInfo.contentType,\n },\n },\n );\n }\n coreLogger.info(`Successfully uploaded: ${fileInfo.relativePath}`);\n }\n}\n"]}
@@ -1,57 +0,0 @@
1
- import type { VersionInfo, RunConfig } from "../common/types.js";
2
- import type { TokenCredential } from "@azure/core-auth";
3
- import type { FullConfig } from "@playwright/test";
4
- import type { CIInfo } from "./cIInfoProvider.js";
5
- export { getPlaywrightVersion } from "./getPlaywrightVersion.js";
6
- export { parseJwt } from "./parseJwt.js";
7
- export declare const getPackageVersion: () => string;
8
- export declare const exitWithFailureMessage: (error: {
9
- key: string;
10
- message: string;
11
- formatWithErrorDetails?: (errorDetails: string) => string;
12
- }, errorDetails?: string) => never;
13
- export declare const throwErrorWithFailureMessage: (error: {
14
- key: string;
15
- message: string;
16
- formatWithErrorDetails?: (errorDetails: string) => string;
17
- }, errorDetails?: string) => never;
18
- export declare const populateValuesFromServiceUrl: () => {
19
- region: string;
20
- domain: string;
21
- accountId: string;
22
- } | null;
23
- export declare const getAccessToken: () => string | undefined;
24
- export declare const getServiceBaseURL: () => string | undefined;
25
- export declare const isValidGuid: (guid: string | null | undefined) => boolean;
26
- export declare const getAndSetRunId: () => string;
27
- export declare const getServiceWSEndpoint: (runId: string, os: string, apiVersion: string) => string;
28
- export declare const validateServiceUrl: () => void;
29
- export declare const ValidateRunID: (runID: string) => void;
30
- export declare const validateMptPAT: (validationFailureCallback: (error: {
31
- key: string;
32
- message: string;
33
- }) => void) => void;
34
- export declare const warnIfAccessTokenCloseToExpiry: () => void;
35
- export declare const fetchOrValidateAccessToken: (credential?: TokenCredential) => Promise<string>;
36
- export declare const getVersionInfo: (version: string) => VersionInfo;
37
- export declare const validatePlaywrightVersion: () => void;
38
- export declare const getTestRunConfig: (config: FullConfig) => RunConfig;
39
- export declare function getTestRunApiUrl(): string;
40
- export declare function isNullOrEmpty(str: string | null | undefined): boolean;
41
- export declare function getRunName(ciInfo: CIInfo): Promise<string>;
42
- export declare function extractErrorMessage(responseBody: string): string;
43
- export declare function getWorkspaceMetaDataApiUrl(): string;
44
- export declare function getHtmlReporterOutputFolder(config: FullConfig | undefined): string;
45
- export declare function getContentType(filePath: string): string;
46
- export declare function calculateOptimalConcurrency(files: Array<{
47
- size: number;
48
- }>): number;
49
- export declare function collectAllFiles(folderPath: string, basePath: string, runIdFolderPrefix?: string): Array<{
50
- fullPath: string;
51
- relativePath: string;
52
- size: number;
53
- contentType: string;
54
- }>;
55
- export declare function getPortalTestRunUrl(resourceId: string): string;
56
- export declare const getStorageAccountNameFromUri: (storageUri: string) => string | null;
57
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/utils.ts"],"names":[],"mappings":"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"}