@azure/playwright 1.1.2 → 1.1.3-alpha.20260310.1

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 (168) hide show
  1. package/dist/browser/common/types.d.ts +1 -1
  2. package/dist/browser/common/types.d.ts.map +1 -1
  3. package/dist/browser/common/types.js.map +1 -1
  4. package/dist/browser/index.d.ts +1 -1
  5. package/dist/browser/index.d.ts.map +1 -1
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/browser/utils/PlaywrightServiceClient.d.ts +1 -1
  8. package/dist/browser/utils/PlaywrightServiceClient.d.ts.map +1 -1
  9. package/dist/browser/utils/PlaywrightServiceClient.js.map +1 -1
  10. package/dist/browser/utils/playwrightReporterStorageManager.d.ts.map +1 -1
  11. package/dist/browser/utils/playwrightReporterStorageManager.js.map +1 -1
  12. package/dist/browser/utils/utils.d.ts +2 -2
  13. package/dist/browser/utils/utils.d.ts.map +1 -1
  14. package/dist/browser/utils/utils.js.map +1 -1
  15. package/dist/commonjs/common/constants.js +127 -95
  16. package/dist/commonjs/common/constants.js.map +7 -1
  17. package/dist/commonjs/common/customerConfig.js +31 -14
  18. package/dist/commonjs/common/customerConfig.js.map +7 -1
  19. package/dist/commonjs/common/entraIdAccessToken.js +106 -83
  20. package/dist/commonjs/common/entraIdAccessToken.js.map +7 -1
  21. package/dist/commonjs/common/environmentVariables.js +43 -24
  22. package/dist/commonjs/common/environmentVariables.js.map +7 -1
  23. package/dist/commonjs/common/executor.js +88 -67
  24. package/dist/commonjs/common/executor.js.map +7 -1
  25. package/dist/commonjs/common/httpService.js +54 -35
  26. package/dist/commonjs/common/httpService.js.map +7 -1
  27. package/dist/commonjs/common/logger.js +28 -8
  28. package/dist/commonjs/common/logger.js.map +7 -1
  29. package/dist/commonjs/common/messages.js +189 -169
  30. package/dist/commonjs/common/messages.js.map +7 -1
  31. package/dist/commonjs/common/playwrightServiceConfig.js +113 -98
  32. package/dist/commonjs/common/playwrightServiceConfig.js.map +7 -1
  33. package/dist/commonjs/common/state.js +30 -10
  34. package/dist/commonjs/common/state.js.map +7 -1
  35. package/dist/commonjs/common/types.d.ts +1 -1
  36. package/dist/commonjs/common/types.d.ts.map +1 -1
  37. package/dist/commonjs/common/types.js +15 -5
  38. package/dist/commonjs/common/types.js.map +7 -1
  39. package/dist/commonjs/core/global/playwright-service-global-setup.js +52 -26
  40. package/dist/commonjs/core/global/playwright-service-global-setup.js.map +7 -1
  41. package/dist/commonjs/core/global/playwright-service-global-teardown.js +49 -20
  42. package/dist/commonjs/core/global/playwright-service-global-teardown.js.map +7 -1
  43. package/dist/commonjs/core/initializePlaywrightServiceTestRun.js +39 -27
  44. package/dist/commonjs/core/initializePlaywrightServiceTestRun.js.map +7 -1
  45. package/dist/commonjs/core/playwrightService.js +166 -205
  46. package/dist/commonjs/core/playwrightService.js.map +7 -1
  47. package/dist/commonjs/core/playwrightServiceEntra.js +67 -48
  48. package/dist/commonjs/core/playwrightServiceEntra.js.map +7 -1
  49. package/dist/commonjs/core/playwrightServiceUtils.d.ts +1 -1
  50. package/dist/commonjs/core/playwrightServiceUtils.d.ts.map +1 -0
  51. package/dist/commonjs/core/playwrightServiceUtils.js +44 -11
  52. package/dist/commonjs/core/playwrightServiceUtils.js.map +7 -0
  53. package/dist/commonjs/index.d.ts +1 -1
  54. package/dist/commonjs/index.d.ts.map +1 -1
  55. package/dist/commonjs/index.js +36 -18
  56. package/dist/commonjs/index.js.map +7 -1
  57. package/dist/commonjs/reporter/index.js +34 -15
  58. package/dist/commonjs/reporter/index.js.map +7 -1
  59. package/dist/commonjs/reporter/playwrightReporter.js +222 -216
  60. package/dist/commonjs/reporter/playwrightReporter.js.map +7 -1
  61. package/dist/commonjs/tsdoc-metadata.json +1 -1
  62. package/dist/commonjs/utils/PlaywrightServiceClient.d.ts +1 -1
  63. package/dist/commonjs/utils/PlaywrightServiceClient.d.ts.map +1 -1
  64. package/dist/commonjs/utils/PlaywrightServiceClient.js +140 -91
  65. package/dist/commonjs/utils/PlaywrightServiceClient.js.map +7 -1
  66. package/dist/commonjs/utils/cIInfoProvider.js +81 -74
  67. package/dist/commonjs/utils/cIInfoProvider.js.map +7 -1
  68. package/dist/commonjs/utils/getPackageVersion.d.ts +1 -1
  69. package/dist/commonjs/utils/getPackageVersion.d.ts.map +1 -0
  70. package/dist/commonjs/utils/getPackageVersion.js +50 -19
  71. package/dist/commonjs/utils/getPackageVersion.js.map +7 -0
  72. package/dist/commonjs/utils/getPlaywrightVersion.js +42 -21
  73. package/dist/commonjs/utils/getPlaywrightVersion.js.map +7 -1
  74. package/dist/commonjs/utils/packageManager.js +59 -40
  75. package/dist/commonjs/utils/packageManager.js.map +7 -1
  76. package/dist/commonjs/utils/parseJwt.js +37 -17
  77. package/dist/commonjs/utils/parseJwt.js.map +7 -1
  78. package/dist/commonjs/utils/playwrightReporterStorageManager.d.ts.map +1 -1
  79. package/dist/commonjs/utils/playwrightReporterStorageManager.js +381 -342
  80. package/dist/commonjs/utils/playwrightReporterStorageManager.js.map +7 -1
  81. package/dist/commonjs/utils/utils.d.ts +2 -2
  82. package/dist/commonjs/utils/utils.d.ts.map +1 -1
  83. package/dist/commonjs/utils/utils.js +417 -369
  84. package/dist/commonjs/utils/utils.js.map +7 -1
  85. package/dist/esm/common/constants.js +92 -92
  86. package/dist/esm/common/constants.js.map +7 -1
  87. package/dist/esm/common/customerConfig.js +11 -11
  88. package/dist/esm/common/customerConfig.js.map +7 -1
  89. package/dist/esm/common/entraIdAccessToken.js +85 -77
  90. package/dist/esm/common/entraIdAccessToken.js.map +7 -1
  91. package/dist/esm/common/environmentVariables.js +19 -19
  92. package/dist/esm/common/environmentVariables.js.map +7 -1
  93. package/dist/esm/common/executor.js +51 -58
  94. package/dist/esm/common/executor.js.map +7 -1
  95. package/dist/esm/common/httpService.js +34 -29
  96. package/dist/esm/common/httpService.js.map +7 -1
  97. package/dist/esm/common/logger.js +4 -4
  98. package/dist/esm/common/logger.js.map +7 -1
  99. package/dist/esm/common/messages.js +166 -166
  100. package/dist/esm/common/messages.js.map +7 -1
  101. package/dist/esm/common/playwrightServiceConfig.js +91 -91
  102. package/dist/esm/common/playwrightServiceConfig.js.map +7 -1
  103. package/dist/esm/common/state.js +7 -7
  104. package/dist/esm/common/state.js.map +7 -1
  105. package/dist/esm/common/types.d.ts +1 -1
  106. package/dist/esm/common/types.d.ts.map +1 -1
  107. package/dist/esm/common/types.js +0 -4
  108. package/dist/esm/common/types.js.map +7 -1
  109. package/dist/esm/core/global/playwright-service-global-setup.js +17 -17
  110. package/dist/esm/core/global/playwright-service-global-setup.js.map +7 -1
  111. package/dist/esm/core/global/playwright-service-global-teardown.js +16 -13
  112. package/dist/esm/core/global/playwright-service-global-teardown.js.map +7 -1
  113. package/dist/esm/core/initializePlaywrightServiceTestRun.js +13 -21
  114. package/dist/esm/core/initializePlaywrightServiceTestRun.js.map +7 -1
  115. package/dist/esm/core/playwrightService.js +144 -195
  116. package/dist/esm/core/playwrightService.js.map +7 -1
  117. package/dist/esm/core/playwrightServiceEntra.js +44 -42
  118. package/dist/esm/core/playwrightServiceEntra.js.map +7 -1
  119. package/dist/esm/core/playwrightServiceUtils.js +6 -8
  120. package/dist/esm/core/playwrightServiceUtils.js.map +7 -1
  121. package/dist/esm/index.d.ts +1 -1
  122. package/dist/esm/index.d.ts.map +1 -1
  123. package/dist/esm/index.js +7 -9
  124. package/dist/esm/index.js.map +7 -1
  125. package/dist/esm/reporter/index.js +4 -11
  126. package/dist/esm/reporter/index.js.map +7 -1
  127. package/dist/esm/reporter/playwrightReporter.js +202 -207
  128. package/dist/esm/reporter/playwrightReporter.js.map +7 -1
  129. package/dist/esm/utils/PlaywrightServiceClient.d.ts +1 -1
  130. package/dist/esm/utils/PlaywrightServiceClient.d.ts.map +1 -1
  131. package/dist/esm/utils/PlaywrightServiceClient.js +120 -85
  132. package/dist/esm/utils/PlaywrightServiceClient.js.map +7 -1
  133. package/dist/esm/utils/cIInfoProvider.js +58 -71
  134. package/dist/esm/utils/cIInfoProvider.js.map +7 -1
  135. package/dist/esm/utils/getPackageVersion.js +12 -17
  136. package/dist/esm/utils/getPackageVersion.js.map +7 -1
  137. package/dist/esm/utils/getPlaywrightVersion.js +15 -13
  138. package/dist/esm/utils/getPlaywrightVersion.js.map +7 -1
  139. package/dist/esm/utils/packageManager.js +37 -37
  140. package/dist/esm/utils/packageManager.js.map +7 -1
  141. package/dist/esm/utils/parseJwt.js +15 -14
  142. package/dist/esm/utils/parseJwt.js.map +7 -1
  143. package/dist/esm/utils/playwrightReporterStorageManager.d.ts.map +1 -1
  144. package/dist/esm/utils/playwrightReporterStorageManager.js +358 -333
  145. package/dist/esm/utils/playwrightReporterStorageManager.js.map +7 -1
  146. package/dist/esm/utils/utils.d.ts +2 -2
  147. package/dist/esm/utils/utils.d.ts.map +1 -1
  148. package/dist/esm/utils/utils.js +377 -350
  149. package/dist/esm/utils/utils.js.map +7 -1
  150. package/dist/react-native/common/types.d.ts +1 -1
  151. package/dist/react-native/common/types.d.ts.map +1 -1
  152. package/dist/react-native/common/types.js.map +1 -1
  153. package/dist/react-native/index.d.ts +1 -1
  154. package/dist/react-native/index.d.ts.map +1 -1
  155. package/dist/react-native/index.js.map +1 -1
  156. package/dist/react-native/utils/PlaywrightServiceClient.d.ts +1 -1
  157. package/dist/react-native/utils/PlaywrightServiceClient.d.ts.map +1 -1
  158. package/dist/react-native/utils/PlaywrightServiceClient.js.map +1 -1
  159. package/dist/react-native/utils/playwrightReporterStorageManager.d.ts.map +1 -1
  160. package/dist/react-native/utils/playwrightReporterStorageManager.js.map +1 -1
  161. package/dist/react-native/utils/utils.d.ts +2 -2
  162. package/dist/react-native/utils/utils.d.ts.map +1 -1
  163. package/dist/react-native/utils/utils.js.map +1 -1
  164. package/package.json +6 -24
  165. package/dist/commonjs/core/playwrightServiceUtils-cjs.cjs.map +0 -1
  166. package/dist/commonjs/core/playwrightServiceUtils-cjs.d.cts.map +0 -1
  167. package/dist/commonjs/utils/getPackageVersion-cjs.cjs.map +0 -1
  168. package/dist/commonjs/utils/getPackageVersion-cjs.d.cts.map +0 -1
@@ -1,115 +1,142 @@
1
- "use strict";
2
- // Copyright (c) Microsoft Corporation.
3
- // Licensed under the MIT License.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.PlaywrightReporterStorageManager = void 0;
6
- const storage_blob_1 = require("@azure/storage-blob");
7
- const logger_js_1 = require("../common/logger.js");
8
- const fs_1 = require("fs");
9
- const path_1 = require("path");
10
- const constants_js_1 = require("../common/constants.js");
11
- const messages_js_1 = require("../common/messages.js");
12
- const utils_js_1 = require("./utils.js");
13
- const playwrightServiceConfig_js_1 = require("../common/playwrightServiceConfig.js");
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var playwrightReporterStorageManager_exports = {};
19
+ __export(playwrightReporterStorageManager_exports, {
20
+ PlaywrightReporterStorageManager: () => PlaywrightReporterStorageManager
21
+ });
22
+ module.exports = __toCommonJS(playwrightReporterStorageManager_exports);
23
+ var import_storage_blob = require("@azure/storage-blob");
24
+ var import_logger = require("../common/logger.js");
25
+ var import_fs = require("fs");
26
+ var import_path = require("path");
27
+ var import_constants = require("../common/constants.js");
28
+ var import_messages = require("../common/messages.js");
29
+ var import_utils = require("./utils.js");
30
+ var import_playwrightServiceConfig = require("../common/playwrightServiceConfig.js");
14
31
  class PlaywrightReporterStorageManager {
15
- // Uploads the HTML report folder to Azure Storage
16
- async uploadHtmlReportFolder(credential, runId, outputFolder, workspaceDetails) {
17
- logger_js_1.coreLogger.info(`Starting HTML report upload for runId: ${runId}, outputFolder: ${outputFolder}`);
18
- const storageAccountName = (0, utils_js_1.getStorageAccountNameFromUri)(workspaceDetails?.storageUri || "") || "unknown";
19
- try {
20
- if (!workspaceDetails.storageUri) {
21
- logger_js_1.coreLogger.error("Storage URI not found in workspace details");
22
- return {
23
- success: false,
24
- errorMessage: messages_js_1.ServiceErrorMessageConstants.STORAGE_URI_NOT_FOUND.message,
25
- };
26
- }
27
- const blobServiceClient = new storage_blob_1.BlobServiceClient(workspaceDetails?.storageUri, credential);
28
- logger_js_1.coreLogger.info("blobServiceClient created successfully.");
29
- const serviceUrlInfo = (0, utils_js_1.populateValuesFromServiceUrl)();
30
- if (!serviceUrlInfo?.accountId) {
31
- logger_js_1.coreLogger.error("Unable to extract workspace ID from service URL");
32
- return {
33
- success: false,
34
- errorMessage: messages_js_1.ServiceErrorMessageConstants.UNABLE_TO_EXTRACT_WORKSPACE_ID.message,
35
- };
36
- }
37
- const containerName = serviceUrlInfo.accountId.toLowerCase().replace(/[^a-z0-9-]/g, "-");
38
- const containerClient = blobServiceClient.getContainerClient(containerName);
39
- const containerExists = await containerClient.exists();
40
- if (!containerExists) {
41
- logger_js_1.coreLogger.info(`Container ${containerName} does not exist. Creating new container.`);
42
- await containerClient.create();
43
- }
44
- else {
45
- logger_js_1.coreLogger.info(`Container ${containerName} already exists.`);
46
- }
47
- const folderName = runId;
48
- console.log(messages_js_1.ServiceErrorMessageConstants.UPLOADING_ARTIFACTS.formatWithDetails(storageAccountName, containerName, folderName));
49
- await this.modifyTraceIndexHtml(outputFolder);
50
- const uploadResults = await this.uploadFolderInParallel(containerClient, outputFolder, outputFolder, folderName);
51
- if (uploadResults.totalFiles === 0) {
52
- return { success: false, errorMessage: "No files found to upload" };
53
- }
54
- const failedFiles = uploadResults.totalFiles - uploadResults.uploadedFiles.length;
55
- if (failedFiles > 0) {
56
- if (uploadResults.failedFileDetails) {
57
- const hasAuthorizationError = uploadResults.failedFileDetails.some((fileDetail) => fileDetail.error.includes("not authorized to perform this operation") ||
58
- fileDetail.error.includes("AuthorizationFailure"));
59
- if (hasAuthorizationError) {
60
- return {
61
- success: false,
62
- errorMessage: messages_js_1.ServiceErrorMessageConstants.STORAGE_AUTHORIZATION_FAILED.formatWithStorageAccount(storageAccountName),
63
- };
64
- }
65
- }
66
- // Get list of failed file names by comparing total files with uploaded files
67
- const uploadedSet = new Set(uploadResults.uploadedFiles);
68
- const allFiles = (0, utils_js_1.collectAllFiles)(outputFolder, outputFolder, folderName);
69
- const failedFileNames = allFiles
70
- .filter((file) => !uploadedSet.has(file.relativePath))
71
- .map((file) => file.relativePath);
72
- return {
73
- success: false,
74
- partialSuccess: true,
75
- failedFileCount: failedFiles,
76
- totalFiles: uploadResults.totalFiles,
77
- failedFiles: failedFileNames,
78
- failedFileDetails: uploadResults.failedFileDetails,
79
- };
80
- }
81
- return { success: true };
82
- }
83
- catch (error) {
84
- const errorMessage = error instanceof Error ? error.message : String(error);
85
- const hasStorageAccountDeletedError = errorMessage.includes("ENOTFOUND") ||
86
- errorMessage.includes("getaddrinfo") ||
87
- errorMessage.includes("not found") ||
88
- errorMessage.includes("404");
89
- if (hasStorageAccountDeletedError) {
90
- return {
91
- success: false,
92
- errorMessage: messages_js_1.ServiceErrorMessageConstants.STORAGE_ACCOUNT_DELETED.formatWithStorageAccount(storageAccountName),
93
- };
94
- }
95
- logger_js_1.coreLogger.error(`Failed to upload HTML report: ${error}`);
96
- return { success: false, errorMessage };
32
+ // Uploads the HTML report folder to Azure Storage
33
+ async uploadHtmlReportFolder(credential, runId, outputFolder, workspaceDetails) {
34
+ import_logger.coreLogger.info(
35
+ `Starting HTML report upload for runId: ${runId}, outputFolder: ${outputFolder}`
36
+ );
37
+ const storageAccountName = (0, import_utils.getStorageAccountNameFromUri)(workspaceDetails?.storageUri || "") || "unknown";
38
+ try {
39
+ if (!workspaceDetails.storageUri) {
40
+ import_logger.coreLogger.error("Storage URI not found in workspace details");
41
+ return {
42
+ success: false,
43
+ errorMessage: import_messages.ServiceErrorMessageConstants.STORAGE_URI_NOT_FOUND.message
44
+ };
45
+ }
46
+ const blobServiceClient = new import_storage_blob.BlobServiceClient(workspaceDetails?.storageUri, credential);
47
+ import_logger.coreLogger.info("blobServiceClient created successfully.");
48
+ const serviceUrlInfo = (0, import_utils.populateValuesFromServiceUrl)();
49
+ if (!serviceUrlInfo?.accountId) {
50
+ import_logger.coreLogger.error("Unable to extract workspace ID from service URL");
51
+ return {
52
+ success: false,
53
+ errorMessage: import_messages.ServiceErrorMessageConstants.UNABLE_TO_EXTRACT_WORKSPACE_ID.message
54
+ };
55
+ }
56
+ const containerName = serviceUrlInfo.accountId.toLowerCase().replace(/[^a-z0-9-]/g, "-");
57
+ const containerClient = blobServiceClient.getContainerClient(containerName);
58
+ const containerExists = await containerClient.exists();
59
+ if (!containerExists) {
60
+ import_logger.coreLogger.info(`Container ${containerName} does not exist. Creating new container.`);
61
+ await containerClient.create();
62
+ } else {
63
+ import_logger.coreLogger.info(`Container ${containerName} already exists.`);
64
+ }
65
+ const folderName = runId;
66
+ console.log(
67
+ import_messages.ServiceErrorMessageConstants.UPLOADING_ARTIFACTS.formatWithDetails(
68
+ storageAccountName,
69
+ containerName,
70
+ folderName
71
+ )
72
+ );
73
+ await this.modifyTraceIndexHtml(outputFolder);
74
+ const uploadResults = await this.uploadFolderInParallel(
75
+ containerClient,
76
+ outputFolder,
77
+ outputFolder,
78
+ folderName
79
+ );
80
+ if (uploadResults.totalFiles === 0) {
81
+ return { success: false, errorMessage: "No files found to upload" };
82
+ }
83
+ const failedFiles = uploadResults.totalFiles - uploadResults.uploadedFiles.length;
84
+ if (failedFiles > 0) {
85
+ if (uploadResults.failedFileDetails) {
86
+ const hasAuthorizationError = uploadResults.failedFileDetails.some(
87
+ (fileDetail) => fileDetail.error.includes("not authorized to perform this operation") || fileDetail.error.includes("AuthorizationFailure")
88
+ );
89
+ if (hasAuthorizationError) {
90
+ return {
91
+ success: false,
92
+ errorMessage: import_messages.ServiceErrorMessageConstants.STORAGE_AUTHORIZATION_FAILED.formatWithStorageAccount(
93
+ storageAccountName
94
+ )
95
+ };
96
+ }
97
97
  }
98
+ const uploadedSet = new Set(uploadResults.uploadedFiles);
99
+ const allFiles = (0, import_utils.collectAllFiles)(outputFolder, outputFolder, folderName);
100
+ const failedFileNames = allFiles.filter((file) => !uploadedSet.has(file.relativePath)).map((file) => file.relativePath);
101
+ return {
102
+ success: false,
103
+ partialSuccess: true,
104
+ failedFileCount: failedFiles,
105
+ totalFiles: uploadResults.totalFiles,
106
+ failedFiles: failedFileNames,
107
+ failedFileDetails: uploadResults.failedFileDetails
108
+ };
109
+ }
110
+ return { success: true };
111
+ } catch (error) {
112
+ const errorMessage = error instanceof Error ? error.message : String(error);
113
+ const hasStorageAccountDeletedError = errorMessage.includes("ENOTFOUND") || errorMessage.includes("getaddrinfo") || errorMessage.includes("not found") || errorMessage.includes("404");
114
+ if (hasStorageAccountDeletedError) {
115
+ return {
116
+ success: false,
117
+ errorMessage: import_messages.ServiceErrorMessageConstants.STORAGE_ACCOUNT_DELETED.formatWithStorageAccount(
118
+ storageAccountName
119
+ )
120
+ };
121
+ }
122
+ import_logger.coreLogger.error(`Failed to upload HTML report: ${error}`);
123
+ return { success: false, errorMessage };
98
124
  }
99
- async modifyTraceIndexHtml(outputFolder) {
100
- logger_js_1.coreLogger.info(`Starting trace modification for folder: ${outputFolder}`);
101
- const indexPath = (0, path_1.join)(outputFolder, "trace/index.html");
102
- const localIndexPath = (0, path_1.join)(outputFolder, "trace/index.local.html");
103
- if (!(0, fs_1.existsSync)(indexPath)) {
104
- logger_js_1.coreLogger.error(`trace/index.html not found at path: ${indexPath}`);
105
- return;
106
- }
107
- logger_js_1.coreLogger.info(`Found trace/index.html at: ${indexPath}`);
108
- try {
109
- const originalHtml = (0, fs_1.readFileSync)(indexPath, "utf-8");
110
- (0, fs_1.writeFileSync)(localIndexPath, originalHtml, "utf-8");
111
- logger_js_1.coreLogger.info(`Backed up original trace viewer to: ${localIndexPath}`);
112
- const redirectTraceviewerScript = `<!DOCTYPE html>
125
+ }
126
+ async modifyTraceIndexHtml(outputFolder) {
127
+ import_logger.coreLogger.info(`Starting trace modification for folder: ${outputFolder}`);
128
+ const indexPath = (0, import_path.join)(outputFolder, "trace/index.html");
129
+ const localIndexPath = (0, import_path.join)(outputFolder, "trace/index.local.html");
130
+ if (!(0, import_fs.existsSync)(indexPath)) {
131
+ import_logger.coreLogger.error(`trace/index.html not found at path: ${indexPath}`);
132
+ return;
133
+ }
134
+ import_logger.coreLogger.info(`Found trace/index.html at: ${indexPath}`);
135
+ try {
136
+ const originalHtml = (0, import_fs.readFileSync)(indexPath, "utf-8");
137
+ (0, import_fs.writeFileSync)(localIndexPath, originalHtml, "utf-8");
138
+ import_logger.coreLogger.info(`Backed up original trace viewer to: ${localIndexPath}`);
139
+ const redirectTraceviewerScript = `<!DOCTYPE html>
113
140
  <html>
114
141
  <head>
115
142
  <meta charset="utf-8">
@@ -207,250 +234,262 @@ class PlaywrightReporterStorageManager {
207
234
  </body>
208
235
  </html>
209
236
  `;
210
- (0, fs_1.writeFileSync)(indexPath, redirectTraceviewerScript, "utf-8");
211
- logger_js_1.coreLogger.info("Successfully updated TraceViewer index file");
212
- }
213
- catch (error) {
214
- logger_js_1.coreLogger.error(`Error modifying trace/index.html: ${error instanceof Error ? error.message : String(error)}`);
215
- return;
216
- }
237
+ (0, import_fs.writeFileSync)(indexPath, redirectTraceviewerScript, "utf-8");
238
+ import_logger.coreLogger.info("Successfully updated TraceViewer index file");
239
+ } catch (error) {
240
+ import_logger.coreLogger.error(
241
+ `Error modifying trace/index.html: ${error instanceof Error ? error.message : String(error)}`
242
+ );
243
+ return;
217
244
  }
218
- // Uploads the entire Playwright HTML report folder after tests complete.
219
- async uploadPlaywrightHtmlReportAfterTests(outputFolderName, workspaceMetadata) {
220
- try {
221
- logger_js_1.coreLogger.info(`Starting post-test HTML report upload, folder name: ${outputFolderName || "default (playwright-report)"}`);
222
- const cred = playwrightServiceConfig_js_1.PlaywrightServiceConfig.instance.credential;
223
- if (!cred) {
224
- logger_js_1.coreLogger.error("No credential found for authentication");
225
- return {
226
- success: false,
227
- errorMessage: messages_js_1.ServiceErrorMessageConstants.NO_CRED_ENTRA_AUTH_ERROR.message,
228
- };
229
- }
230
- logger_js_1.coreLogger.info("Credential found for authentication");
231
- const folderName = outputFolderName || "playwright-report";
232
- const outputFolderPath = (0, path_1.join)(process.cwd(), folderName);
233
- if (!(0, fs_1.existsSync)(outputFolderPath)) {
234
- logger_js_1.coreLogger.error(`HTML report folder not found: ${outputFolderPath}`);
235
- return {
236
- success: false,
237
- errorMessage: messages_js_1.ServiceErrorMessageConstants.PLAYWRIGHT_TEST_REPORT_NOT_FOUND.formatWithFolder(folderName),
238
- };
239
- }
240
- logger_js_1.coreLogger.info(`HTML report folder found: ${outputFolderPath}`);
241
- const testRunId = playwrightServiceConfig_js_1.PlaywrightServiceConfig.instance.runId;
242
- logger_js_1.coreLogger.info(`Starting upload for test run ID: ${testRunId}`);
243
- const result = await this.uploadHtmlReportFolder(cred, testRunId, outputFolderPath, workspaceMetadata);
244
- logger_js_1.coreLogger.info(`Completed upload for test run ID: ${testRunId}`);
245
- return result;
246
- }
247
- catch (error) {
248
- const errorMessage = error instanceof Error ? error.message : String(error);
249
- logger_js_1.coreLogger.error(`Upload failed: ${errorMessage}`);
250
- return { success: false, errorMessage };
251
- }
252
- }
253
- // Parallel Upload Engine - Core upload orchestration with performance optimization
254
- async uploadFolderInParallel(containerClient, folderPath, basePath, runIdFolderPrefix) {
255
- // Sort by size descending - upload large files first for better parallelization
256
- const filesToUpload = (0, utils_js_1.collectAllFiles)(folderPath, basePath, runIdFolderPrefix).sort((a, b) => b.size - a.size);
257
- if (filesToUpload.length === 0) {
258
- return { uploadedFiles: [], failedFiles: [], totalFiles: 0, totalSize: 0, uploadTime: 0 };
259
- }
260
- const totalSize = filesToUpload.reduce((sum, file) => sum + file.size, 0);
261
- const concurrency = (0, utils_js_1.calculateOptimalConcurrency)(filesToUpload);
262
- logger_js_1.coreLogger.info(`Calculated optimal concurrency: ${concurrency} for ${filesToUpload.length} files (total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB)`);
263
- const uploadStartTime = Date.now();
264
- logger_js_1.coreLogger.info(`Starting parallel upload with ${concurrency} concurrent operations`);
265
- const results = await this.uploadWithConcurrencyControl(containerClient, filesToUpload, concurrency);
266
- const uploadEndTime = Date.now();
267
- const uploadTime = uploadEndTime - uploadStartTime;
268
- logger_js_1.coreLogger.info(`Upload completed in ${uploadTime}ms (${(uploadTime / 1000).toFixed(2)}s)`);
269
- const failed = results.filter((r) => r.status === "rejected").length;
270
- const successful = results.filter((r) => r.status === "fulfilled").length;
271
- logger_js_1.coreLogger.info(`Upload results: ${successful} successful, ${failed} failed out of ${results.length} total files`);
272
- if (failed > 0) {
273
- const errors = results
274
- .filter((r) => r.status === "rejected")
275
- .map((r) => r.reason.message)
276
- .slice(0, 5); // Show first 5 errors
277
- errors.forEach((error, index) => {
278
- logger_js_1.coreLogger.error(` ${index + 1}. ${error}`);
279
- });
280
- // Get failed file names and their error messages
281
- const uploadedSet = new Set(results
282
- .filter((r) => r.status === "fulfilled")
283
- .map((r) => r.value));
284
- const failedFileNames = filesToUpload
285
- .filter((file) => !uploadedSet.has(file.relativePath))
286
- .map((file) => file.relativePath);
287
- // Create detailed error mapping
288
- const failedFileDetails = [];
289
- results.forEach((result, index) => {
290
- if (result.status === "rejected") {
291
- const fileName = filesToUpload[index]?.relativePath || `File at index ${index}`;
292
- const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);
293
- failedFileDetails.push({ fileName, error: errorMessage });
294
- }
295
- });
296
- // Log error but don't throw to prevent breaking HTML reporter
297
- logger_js_1.coreLogger.error(`Upload failed: ${failed} files could not be uploaded. Sample errors: ${errors.join(", ")}`);
298
- return {
299
- uploadedFiles: results
300
- .filter((r) => r.status === "fulfilled")
301
- .map((r) => r.value),
302
- failedFiles: failedFileNames,
303
- failedFileDetails,
304
- totalFiles: filesToUpload.length,
305
- totalSize,
306
- uploadTime,
307
- };
308
- }
309
- const uploadedFiles = results
310
- .filter((r) => r.status === "fulfilled")
311
- .map((r) => r.value);
245
+ }
246
+ // Uploads the entire Playwright HTML report folder after tests complete.
247
+ async uploadPlaywrightHtmlReportAfterTests(outputFolderName, workspaceMetadata) {
248
+ try {
249
+ import_logger.coreLogger.info(
250
+ `Starting post-test HTML report upload, folder name: ${outputFolderName || "default (playwright-report)"}`
251
+ );
252
+ const cred = import_playwrightServiceConfig.PlaywrightServiceConfig.instance.credential;
253
+ if (!cred) {
254
+ import_logger.coreLogger.error("No credential found for authentication");
255
+ return {
256
+ success: false,
257
+ errorMessage: import_messages.ServiceErrorMessageConstants.NO_CRED_ENTRA_AUTH_ERROR.message
258
+ };
259
+ }
260
+ import_logger.coreLogger.info("Credential found for authentication");
261
+ const folderName = outputFolderName || "playwright-report";
262
+ const outputFolderPath = (0, import_path.join)(process.cwd(), folderName);
263
+ if (!(0, import_fs.existsSync)(outputFolderPath)) {
264
+ import_logger.coreLogger.error(`HTML report folder not found: ${outputFolderPath}`);
312
265
  return {
313
- uploadedFiles,
314
- failedFiles: [],
315
- totalFiles: filesToUpload.length,
316
- totalSize,
317
- uploadTime,
266
+ success: false,
267
+ errorMessage: import_messages.ServiceErrorMessageConstants.PLAYWRIGHT_TEST_REPORT_NOT_FOUND.formatWithFolder(
268
+ folderName
269
+ )
318
270
  };
271
+ }
272
+ import_logger.coreLogger.info(`HTML report folder found: ${outputFolderPath}`);
273
+ const testRunId = import_playwrightServiceConfig.PlaywrightServiceConfig.instance.runId;
274
+ import_logger.coreLogger.info(`Starting upload for test run ID: ${testRunId}`);
275
+ const result = await this.uploadHtmlReportFolder(
276
+ cred,
277
+ testRunId,
278
+ outputFolderPath,
279
+ workspaceMetadata
280
+ );
281
+ import_logger.coreLogger.info(`Completed upload for test run ID: ${testRunId}`);
282
+ return result;
283
+ } catch (error) {
284
+ const errorMessage = error instanceof Error ? error.message : String(error);
285
+ import_logger.coreLogger.error(`Upload failed: ${errorMessage}`);
286
+ return { success: false, errorMessage };
319
287
  }
320
- // Concurrency Control System - Manages parallel execution with controlled resource usage
321
- async uploadWithConcurrencyControl(containerClient, files, concurrency) {
322
- const uploadTasks = files.map((fileInfo) => async () => {
323
- try {
324
- await this.uploadSingleFileOptimized(containerClient, fileInfo);
325
- return fileInfo.relativePath;
326
- }
327
- catch (error) {
328
- logger_js_1.coreLogger.error(`Failed to upload file: ${fileInfo.relativePath} - ${error instanceof Error ? error.message : "Unknown error"}`);
329
- throw error;
330
- }
331
- });
332
- return this.executeWithOptimizedBatching(uploadTasks, concurrency);
288
+ }
289
+ // Parallel Upload Engine - Core upload orchestration with performance optimization
290
+ async uploadFolderInParallel(containerClient, folderPath, basePath, runIdFolderPrefix) {
291
+ const filesToUpload = (0, import_utils.collectAllFiles)(folderPath, basePath, runIdFolderPrefix).sort(
292
+ (a, b) => b.size - a.size
293
+ );
294
+ if (filesToUpload.length === 0) {
295
+ return { uploadedFiles: [], failedFiles: [], totalFiles: 0, totalSize: 0, uploadTime: 0 };
333
296
  }
334
- // Optimized Batch Execution Engine - High-performance task processing system
335
- async executeWithOptimizedBatching(tasks, concurrency) {
336
- const results = new Array(tasks.length);
337
- let completedTasks = 0;
338
- // Splits tasks into optimal batches to balance memory usage vs. throughput
339
- const batchSize = Math.min(constants_js_1.UploadConstants.BATCH_SIZE, concurrency * 2);
340
- const batches = [];
341
- // Each batch will be processed with full concurrency before moving to next batch
342
- for (let i = 0; i < tasks.length; i += batchSize) {
343
- batches.push(tasks.slice(i, i + batchSize));
344
- }
345
- // Process each batch sequentially to maintain memory efficiency
346
- logger_js_1.coreLogger.info(`Processing ${batches.length} batches with ${batchSize} tasks per batch`);
347
- for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {
348
- const batch = batches[batchIndex];
349
- const batchStartIndex = batchIndex * batchSize;
350
- logger_js_1.coreLogger.info(`Starting batch ${batchIndex + 1}/${batches.length} with ${batch.length} tasks`);
351
- // Transform each task into a promise that captures results at correct index
352
- const batchPromises = batch.map(async (task, taskIndex) => {
353
- const globalIndex = batchStartIndex + taskIndex;
354
- try {
355
- const result = await task();
356
- results[globalIndex] = { status: "fulfilled", value: result };
357
- return result;
358
- }
359
- catch (error) {
360
- results[globalIndex] = { status: "rejected", reason: error };
361
- logger_js_1.coreLogger.error(`Task failed at index ${globalIndex}: ${error instanceof Error ? error.message : "Unknown error"}`);
362
- return;
363
- }
364
- });
365
- const executing = [];
366
- for (const promise of batchPromises) {
367
- if (executing.length >= concurrency) {
368
- await Promise.race(executing);
369
- }
370
- const wrappedPromise = promise
371
- .then((result) => {
372
- completedTasks++;
373
- return result;
374
- })
375
- .catch(() => {
376
- completedTasks++;
377
- })
378
- .finally(() => {
379
- // Cleanup: remove completed promise from executing array
380
- const index = executing.indexOf(wrappedPromise);
381
- if (index > -1)
382
- executing.splice(index, 1);
383
- });
384
- executing.push(wrappedPromise);
385
- }
386
- // Wait for all promises in current batch to complete before moving to next batch
387
- await Promise.allSettled(executing);
388
- logger_js_1.coreLogger.info(`Completed batch ${batchIndex + 1}/${batches.length}`);
297
+ const totalSize = filesToUpload.reduce((sum, file) => sum + file.size, 0);
298
+ const concurrency = (0, import_utils.calculateOptimalConcurrency)(filesToUpload);
299
+ import_logger.coreLogger.info(
300
+ `Calculated optimal concurrency: ${concurrency} for ${filesToUpload.length} files (total size: ${(totalSize / 1024 / 1024).toFixed(2)} MB)`
301
+ );
302
+ const uploadStartTime = Date.now();
303
+ import_logger.coreLogger.info(`Starting parallel upload with ${concurrency} concurrent operations`);
304
+ const results = await this.uploadWithConcurrencyControl(
305
+ containerClient,
306
+ filesToUpload,
307
+ concurrency
308
+ );
309
+ const uploadEndTime = Date.now();
310
+ const uploadTime = uploadEndTime - uploadStartTime;
311
+ import_logger.coreLogger.info(`Upload completed in ${uploadTime}ms (${(uploadTime / 1e3).toFixed(2)}s)`);
312
+ const failed = results.filter((r) => r.status === "rejected").length;
313
+ const successful = results.filter((r) => r.status === "fulfilled").length;
314
+ import_logger.coreLogger.info(
315
+ `Upload results: ${successful} successful, ${failed} failed out of ${results.length} total files`
316
+ );
317
+ if (failed > 0) {
318
+ const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason.message).slice(0, 5);
319
+ errors.forEach((error, index) => {
320
+ import_logger.coreLogger.error(` ${index + 1}. ${error}`);
321
+ });
322
+ const uploadedSet = new Set(
323
+ results.filter((r) => r.status === "fulfilled").map((r) => r.value)
324
+ );
325
+ const failedFileNames = filesToUpload.filter((file) => !uploadedSet.has(file.relativePath)).map((file) => file.relativePath);
326
+ const failedFileDetails = [];
327
+ results.forEach((result, index) => {
328
+ if (result.status === "rejected") {
329
+ const fileName = filesToUpload[index]?.relativePath || `File at index ${index}`;
330
+ const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);
331
+ failedFileDetails.push({ fileName, error: errorMessage });
389
332
  }
390
- return results;
333
+ });
334
+ import_logger.coreLogger.error(
335
+ `Upload failed: ${failed} files could not be uploaded. Sample errors: ${errors.join(", ")}`
336
+ );
337
+ return {
338
+ uploadedFiles: results.filter((r) => r.status === "fulfilled").map((r) => r.value),
339
+ failedFiles: failedFileNames,
340
+ failedFileDetails,
341
+ totalFiles: filesToUpload.length,
342
+ totalSize,
343
+ uploadTime
344
+ };
345
+ }
346
+ const uploadedFiles = results.filter((r) => r.status === "fulfilled").map((r) => r.value);
347
+ return {
348
+ uploadedFiles,
349
+ failedFiles: [],
350
+ totalFiles: filesToUpload.length,
351
+ totalSize,
352
+ uploadTime
353
+ };
354
+ }
355
+ // Concurrency Control System - Manages parallel execution with controlled resource usage
356
+ async uploadWithConcurrencyControl(containerClient, files, concurrency) {
357
+ const uploadTasks = files.map((fileInfo) => async () => {
358
+ try {
359
+ await this.uploadSingleFileOptimized(containerClient, fileInfo);
360
+ return fileInfo.relativePath;
361
+ } catch (error) {
362
+ import_logger.coreLogger.error(
363
+ `Failed to upload file: ${fileInfo.relativePath} - ${error instanceof Error ? error.message : "Unknown error"}`
364
+ );
365
+ throw error;
366
+ }
367
+ });
368
+ return this.executeWithOptimizedBatching(uploadTasks, concurrency);
369
+ }
370
+ // Optimized Batch Execution Engine - High-performance task processing system
371
+ async executeWithOptimizedBatching(tasks, concurrency) {
372
+ const results = new Array(tasks.length);
373
+ let completedTasks = 0;
374
+ const batchSize = Math.min(import_constants.UploadConstants.BATCH_SIZE, concurrency * 2);
375
+ const batches = [];
376
+ for (let i = 0; i < tasks.length; i += batchSize) {
377
+ batches.push(tasks.slice(i, i + batchSize));
391
378
  }
392
- // Individual File Upload with Retry Logic
393
- async uploadSingleFileOptimized(containerClient, fileInfo) {
394
- logger_js_1.coreLogger.info(`Uploading file: ${fileInfo.relativePath} (${(fileInfo.size / 1024).toFixed(2)} KB, ${fileInfo.contentType})`);
395
- const blockBlobClient = containerClient.getBlockBlobClient(fileInfo.relativePath);
396
- const maxRetries = constants_js_1.UploadConstants.MAX_RETRY_ATTEMPTS;
397
- const baseDelay = constants_js_1.UploadConstants.RETRY_BASE_DELAY;
398
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
399
- try {
400
- await this.performOptimizedUpload(blockBlobClient, fileInfo);
401
- return;
402
- }
403
- catch (error) {
404
- const isLastAttempt = attempt === maxRetries;
405
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
406
- logger_js_1.coreLogger.info(`Upload attempt ${attempt} failed for ${fileInfo.relativePath}: ${errorMessage}`);
407
- if (isLastAttempt) {
408
- logger_js_1.coreLogger.error(`All retry attempts exhausted for ${fileInfo.relativePath}: ${errorMessage}`);
409
- if (error instanceof Error) {
410
- throw error;
411
- }
412
- throw new Error(`Upload failed for ${fileInfo.relativePath} after ${maxRetries} attempts: ${errorMessage}`);
413
- }
414
- // Exponential backoff with jitter (Azure SDK pattern)
415
- const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500;
416
- logger_js_1.coreLogger.info(`Retrying upload for ${fileInfo.relativePath} in ${delay.toFixed(0)}ms (attempt ${attempt + 1}/${maxRetries})`);
417
- await new Promise((_resolve) => setTimeout(_resolve, delay));
418
- }
379
+ import_logger.coreLogger.info(`Processing ${batches.length} batches with ${batchSize} tasks per batch`);
380
+ for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {
381
+ const batch = batches[batchIndex];
382
+ const batchStartIndex = batchIndex * batchSize;
383
+ import_logger.coreLogger.info(
384
+ `Starting batch ${batchIndex + 1}/${batches.length} with ${batch.length} tasks`
385
+ );
386
+ const batchPromises = batch.map(async (task, taskIndex) => {
387
+ const globalIndex = batchStartIndex + taskIndex;
388
+ try {
389
+ const result = await task();
390
+ results[globalIndex] = { status: "fulfilled", value: result };
391
+ return result;
392
+ } catch (error) {
393
+ results[globalIndex] = { status: "rejected", reason: error };
394
+ import_logger.coreLogger.error(
395
+ `Task failed at index ${globalIndex}: ${error instanceof Error ? error.message : "Unknown error"}`
396
+ );
397
+ return;
398
+ }
399
+ });
400
+ const executing = [];
401
+ for (const promise of batchPromises) {
402
+ if (executing.length >= concurrency) {
403
+ await Promise.race(executing);
419
404
  }
405
+ const wrappedPromise = promise.then((result) => {
406
+ completedTasks++;
407
+ return result;
408
+ }).catch(() => {
409
+ completedTasks++;
410
+ }).finally(() => {
411
+ const index = executing.indexOf(wrappedPromise);
412
+ if (index > -1) executing.splice(index, 1);
413
+ });
414
+ executing.push(wrappedPromise);
415
+ }
416
+ await Promise.allSettled(executing);
417
+ import_logger.coreLogger.info(`Completed batch ${batchIndex + 1}/${batches.length}`);
420
418
  }
421
- // Multi-Strategy Upload Engine - Optimized upload based on file characteristics
422
- async performOptimizedUpload(blockBlobClient, fileInfo) {
423
- if (fileInfo.size <= constants_js_1.UploadConstants.SMALL_FILE_THRESHOLD) {
424
- // DIRECT UPLOAD: Optimal for small files (≤1MB)
425
- const fileContent = (0, fs_1.readFileSync)(fileInfo.fullPath);
426
- await blockBlobClient.upload(fileContent, fileContent.length, {
427
- blobHTTPHeaders: {
428
- blobContentType: fileInfo.contentType,
429
- },
430
- });
419
+ return results;
420
+ }
421
+ // Individual File Upload with Retry Logic
422
+ async uploadSingleFileOptimized(containerClient, fileInfo) {
423
+ import_logger.coreLogger.info(
424
+ `Uploading file: ${fileInfo.relativePath} (${(fileInfo.size / 1024).toFixed(2)} KB, ${fileInfo.contentType})`
425
+ );
426
+ const blockBlobClient = containerClient.getBlockBlobClient(fileInfo.relativePath);
427
+ const maxRetries = import_constants.UploadConstants.MAX_RETRY_ATTEMPTS;
428
+ const baseDelay = import_constants.UploadConstants.RETRY_BASE_DELAY;
429
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
430
+ try {
431
+ await this.performOptimizedUpload(blockBlobClient, fileInfo);
432
+ return;
433
+ } catch (error) {
434
+ const isLastAttempt = attempt === maxRetries;
435
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
436
+ import_logger.coreLogger.info(
437
+ `Upload attempt ${attempt} failed for ${fileInfo.relativePath}: ${errorMessage}`
438
+ );
439
+ if (isLastAttempt) {
440
+ import_logger.coreLogger.error(
441
+ `All retry attempts exhausted for ${fileInfo.relativePath}: ${errorMessage}`
442
+ );
443
+ if (error instanceof Error) {
444
+ throw error;
445
+ }
446
+ throw new Error(
447
+ `Upload failed for ${fileInfo.relativePath} after ${maxRetries} attempts: ${errorMessage}`
448
+ );
431
449
  }
432
- else if (fileInfo.size <= constants_js_1.UploadConstants.LARGE_FILE_THRESHOLD) {
433
- // BLOCK UPLOAD: Optimal for medium files (1MB - 100MB)
434
- const fileContent = (0, fs_1.readFileSync)(fileInfo.fullPath);
435
- await blockBlobClient.uploadData(fileContent, {
436
- blobHTTPHeaders: {
437
- blobContentType: fileInfo.contentType,
438
- },
439
- blockSize: constants_js_1.UploadConstants.OPTIMIZED_BLOCK_SIZE,
440
- concurrency: constants_js_1.UploadConstants.PER_FILE_CONCURRENCY,
441
- });
450
+ const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 500;
451
+ import_logger.coreLogger.info(
452
+ `Retrying upload for ${fileInfo.relativePath} in ${delay.toFixed(0)}ms (attempt ${attempt + 1}/${maxRetries})`
453
+ );
454
+ await new Promise((_resolve) => setTimeout(_resolve, delay));
455
+ }
456
+ }
457
+ }
458
+ // Multi-Strategy Upload Engine - Optimized upload based on file characteristics
459
+ async performOptimizedUpload(blockBlobClient, fileInfo) {
460
+ if (fileInfo.size <= import_constants.UploadConstants.SMALL_FILE_THRESHOLD) {
461
+ const fileContent = (0, import_fs.readFileSync)(fileInfo.fullPath);
462
+ await blockBlobClient.upload(fileContent, fileContent.length, {
463
+ blobHTTPHeaders: {
464
+ blobContentType: fileInfo.contentType
442
465
  }
443
- else {
444
- // STREAMING UPLOAD: Optimal for large files (>100MB)
445
- const stream = (0, fs_1.createReadStream)(fileInfo.fullPath);
446
- await blockBlobClient.uploadStream(stream, constants_js_1.UploadConstants.STREAM_BUFFER_SIZE, constants_js_1.UploadConstants.LARGE_FILE_CONCURRENCY, {
447
- blobHTTPHeaders: {
448
- blobContentType: fileInfo.contentType,
449
- },
450
- });
466
+ });
467
+ } else if (fileInfo.size <= import_constants.UploadConstants.LARGE_FILE_THRESHOLD) {
468
+ const fileContent = (0, import_fs.readFileSync)(fileInfo.fullPath);
469
+ await blockBlobClient.uploadData(fileContent, {
470
+ blobHTTPHeaders: {
471
+ blobContentType: fileInfo.contentType
472
+ },
473
+ blockSize: import_constants.UploadConstants.OPTIMIZED_BLOCK_SIZE,
474
+ concurrency: import_constants.UploadConstants.PER_FILE_CONCURRENCY
475
+ });
476
+ } else {
477
+ const stream = (0, import_fs.createReadStream)(fileInfo.fullPath);
478
+ await blockBlobClient.uploadStream(
479
+ stream,
480
+ import_constants.UploadConstants.STREAM_BUFFER_SIZE,
481
+ import_constants.UploadConstants.LARGE_FILE_CONCURRENCY,
482
+ {
483
+ blobHTTPHeaders: {
484
+ blobContentType: fileInfo.contentType
485
+ }
451
486
  }
452
- logger_js_1.coreLogger.info(`Successfully uploaded: ${fileInfo.relativePath}`);
487
+ );
453
488
  }
489
+ import_logger.coreLogger.info(`Successfully uploaded: ${fileInfo.relativePath}`);
490
+ }
454
491
  }
455
- exports.PlaywrightReporterStorageManager = PlaywrightReporterStorageManager;
456
- //# sourceMappingURL=playwrightReporterStorageManager.js.map
492
+ // Annotate the CommonJS export names for ESM import in node:
493
+ 0 && (module.exports = {
494
+ PlaywrightReporterStorageManager
495
+ });