@azure/playwright 1.1.3-alpha.20260310.1 → 1.1.3
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.
- package/dist/browser/common/constants.d.ts +3 -0
- package/dist/browser/common/constants.d.ts.map +1 -1
- package/dist/browser/common/constants.js +3 -0
- package/dist/browser/common/constants.js.map +1 -1
- package/dist/browser/common/types.d.ts +8 -0
- package/dist/browser/common/types.d.ts.map +1 -1
- package/dist/browser/common/types.js.map +1 -1
- package/dist/browser/core/playwrightService.d.ts.map +1 -1
- package/dist/browser/core/playwrightService.js +6 -0
- package/dist/browser/core/playwrightService.js.map +1 -1
- package/dist/browser/utils/utils.d.ts.map +1 -1
- package/dist/browser/utils/utils.js +2 -3
- package/dist/browser/utils/utils.js.map +1 -1
- package/dist/commonjs/common/constants.d.ts +3 -0
- package/dist/commonjs/common/constants.d.ts.map +1 -1
- package/dist/commonjs/common/constants.js +97 -126
- package/dist/commonjs/common/constants.js.map +1 -7
- package/dist/commonjs/common/customerConfig.js +14 -31
- package/dist/commonjs/common/customerConfig.js.map +1 -7
- package/dist/commonjs/common/entraIdAccessToken.js +83 -106
- package/dist/commonjs/common/entraIdAccessToken.js.map +1 -7
- package/dist/commonjs/common/environmentVariables.js +24 -43
- package/dist/commonjs/common/environmentVariables.js.map +1 -7
- package/dist/commonjs/common/executor.js +67 -88
- package/dist/commonjs/common/executor.js.map +1 -7
- package/dist/commonjs/common/httpService.js +35 -54
- package/dist/commonjs/common/httpService.js.map +1 -7
- package/dist/commonjs/common/logger.js +8 -28
- package/dist/commonjs/common/logger.js.map +1 -7
- package/dist/commonjs/common/messages.js +169 -189
- package/dist/commonjs/common/messages.js.map +1 -7
- package/dist/commonjs/common/playwrightServiceConfig.js +98 -113
- package/dist/commonjs/common/playwrightServiceConfig.js.map +1 -7
- package/dist/commonjs/common/state.js +10 -30
- package/dist/commonjs/common/state.js.map +1 -7
- package/dist/commonjs/common/types.d.ts +8 -0
- package/dist/commonjs/common/types.d.ts.map +1 -1
- package/dist/commonjs/common/types.js +5 -15
- package/dist/commonjs/common/types.js.map +1 -7
- package/dist/commonjs/core/global/playwright-service-global-setup.js +26 -52
- package/dist/commonjs/core/global/playwright-service-global-setup.js.map +1 -7
- package/dist/commonjs/core/global/playwright-service-global-teardown.js +20 -49
- package/dist/commonjs/core/global/playwright-service-global-teardown.js.map +1 -7
- package/dist/commonjs/core/initializePlaywrightServiceTestRun.js +27 -39
- package/dist/commonjs/core/initializePlaywrightServiceTestRun.js.map +1 -7
- package/dist/commonjs/core/playwrightService.d.ts.map +1 -1
- package/dist/commonjs/core/playwrightService.js +211 -166
- package/dist/commonjs/core/playwrightService.js.map +1 -7
- package/dist/commonjs/core/playwrightServiceEntra.js +48 -67
- package/dist/commonjs/core/playwrightServiceEntra.js.map +1 -7
- package/dist/commonjs/core/playwrightServiceUtils.d.ts.map +1 -1
- package/dist/commonjs/core/playwrightServiceUtils.js +11 -44
- package/dist/commonjs/core/playwrightServiceUtils.js.map +1 -7
- package/dist/commonjs/index.js +18 -36
- package/dist/commonjs/index.js.map +1 -7
- package/dist/commonjs/reporter/index.js +15 -34
- package/dist/commonjs/reporter/index.js.map +1 -7
- package/dist/commonjs/reporter/playwrightReporter.js +216 -222
- package/dist/commonjs/reporter/playwrightReporter.js.map +1 -7
- package/dist/commonjs/utils/PlaywrightServiceClient.js +91 -140
- package/dist/commonjs/utils/PlaywrightServiceClient.js.map +1 -7
- package/dist/commonjs/utils/cIInfoProvider.js +74 -81
- package/dist/commonjs/utils/cIInfoProvider.js.map +1 -7
- package/dist/commonjs/utils/getPackageVersion.d.ts.map +1 -1
- package/dist/commonjs/utils/getPackageVersion.js +19 -50
- package/dist/commonjs/utils/getPackageVersion.js.map +1 -7
- package/dist/commonjs/utils/getPlaywrightVersion.js +21 -42
- package/dist/commonjs/utils/getPlaywrightVersion.js.map +1 -7
- package/dist/commonjs/utils/packageManager.js +40 -59
- package/dist/commonjs/utils/packageManager.js.map +1 -7
- package/dist/commonjs/utils/parseJwt.js +17 -37
- package/dist/commonjs/utils/parseJwt.js.map +1 -7
- package/dist/commonjs/utils/playwrightReporterStorageManager.js +342 -381
- package/dist/commonjs/utils/playwrightReporterStorageManager.js.map +1 -7
- package/dist/commonjs/utils/utils.d.ts.map +1 -1
- package/dist/commonjs/utils/utils.js +368 -417
- package/dist/commonjs/utils/utils.js.map +1 -7
- package/dist/esm/common/constants.d.ts +3 -0
- package/dist/esm/common/constants.d.ts.map +1 -1
- package/dist/esm/common/constants.js +4 -0
- package/dist/esm/common/constants.js.map +2 -2
- package/dist/esm/common/types.d.ts +8 -0
- package/dist/esm/common/types.d.ts.map +1 -1
- package/dist/esm/core/playwrightService.d.ts.map +1 -1
- package/dist/esm/core/playwrightService.js +6 -0
- package/dist/esm/core/playwrightService.js.map +2 -2
- package/dist/esm/utils/utils.d.ts.map +1 -1
- package/dist/esm/utils/utils.js +4 -3
- package/dist/esm/utils/utils.js.map +2 -2
- package/dist/react-native/common/constants.d.ts +3 -0
- package/dist/react-native/common/constants.d.ts.map +1 -1
- package/dist/react-native/common/constants.js +3 -0
- package/dist/react-native/common/constants.js.map +1 -1
- package/dist/react-native/common/types.d.ts +8 -0
- package/dist/react-native/common/types.d.ts.map +1 -1
- package/dist/react-native/common/types.js.map +1 -1
- package/dist/react-native/core/playwrightService.d.ts.map +1 -1
- package/dist/react-native/core/playwrightService.js +6 -0
- package/dist/react-native/core/playwrightService.js.map +1 -1
- package/dist/react-native/utils/utils.d.ts.map +1 -1
- package/dist/react-native/utils/utils.js +2 -3
- package/dist/react-native/utils/utils.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,489 +1,440 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
getAccessToken: () => getAccessToken,
|
|
37
|
-
getAndSetRunId: () => getAndSetRunId,
|
|
38
|
-
getContentType: () => getContentType,
|
|
39
|
-
getHtmlReporterOutputFolder: () => getHtmlReporterOutputFolder,
|
|
40
|
-
getPackageVersion: () => getPackageVersion,
|
|
41
|
-
getPlaywrightVersion: () => import_getPlaywrightVersion2.getPlaywrightVersion,
|
|
42
|
-
getPortalTestRunUrl: () => getPortalTestRunUrl,
|
|
43
|
-
getRunName: () => getRunName,
|
|
44
|
-
getServiceBaseURL: () => getServiceBaseURL,
|
|
45
|
-
getServiceWSEndpoint: () => getServiceWSEndpoint,
|
|
46
|
-
getStorageAccountNameFromUri: () => getStorageAccountNameFromUri,
|
|
47
|
-
getTestRunApiUrl: () => getTestRunApiUrl,
|
|
48
|
-
getTestRunConfig: () => getTestRunConfig,
|
|
49
|
-
getVersionInfo: () => getVersionInfo,
|
|
50
|
-
getWorkspaceMetaDataApiUrl: () => getWorkspaceMetaDataApiUrl,
|
|
51
|
-
isNullOrEmpty: () => isNullOrEmpty,
|
|
52
|
-
isValidGuid: () => isValidGuid,
|
|
53
|
-
parseJwt: () => import_parseJwt2.parseJwt,
|
|
54
|
-
populateValuesFromServiceUrl: () => populateValuesFromServiceUrl,
|
|
55
|
-
resolveTenantDomain: () => resolveTenantDomain,
|
|
56
|
-
throwErrorWithFailureMessage: () => throwErrorWithFailureMessage,
|
|
57
|
-
validateMptPAT: () => validateMptPAT,
|
|
58
|
-
validatePlaywrightVersion: () => validatePlaywrightVersion,
|
|
59
|
-
validateServiceUrl: () => validateServiceUrl,
|
|
60
|
-
warnIfAccessTokenCloseToExpiry: () => warnIfAccessTokenCloseToExpiry
|
|
61
|
-
});
|
|
62
|
-
module.exports = __toCommonJS(utils_exports);
|
|
63
|
-
var import_constants = require("../common/constants.js");
|
|
64
|
-
var import_messages = require("../common/messages.js");
|
|
65
|
-
var import_logger = require("../common/logger.js");
|
|
66
|
-
var import_node_process = __toESM(require("node:process"));
|
|
67
|
-
var import_node_crypto = require("node:crypto");
|
|
68
|
-
var import_parseJwt = require("./parseJwt.js");
|
|
69
|
-
var import_getPlaywrightVersion = require("./getPlaywrightVersion.js");
|
|
70
|
-
var import_entraIdAccessToken = require("../common/entraIdAccessToken.js");
|
|
71
|
-
var import_cIInfoProvider = require("./cIInfoProvider.js");
|
|
72
|
-
var import_child_process = require("child_process");
|
|
73
|
-
var import_getPackageVersion = require("./getPackageVersion.js");
|
|
74
|
-
var import_fs = require("fs");
|
|
75
|
-
var import_path = require("path");
|
|
76
|
-
var import_constants2 = require("../common/constants.js");
|
|
77
|
-
var import_getPlaywrightVersion2 = require("./getPlaywrightVersion.js");
|
|
78
|
-
var import_parseJwt2 = require("./parseJwt.js");
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.getStorageAccountNameFromUri = exports.getTestRunConfig = exports.validatePlaywrightVersion = exports.getVersionInfo = exports.fetchOrValidateAccessToken = exports.warnIfAccessTokenCloseToExpiry = exports.validateMptPAT = exports.ValidateRunID = exports.validateServiceUrl = exports.getServiceWSEndpoint = exports.getAndSetRunId = exports.isValidGuid = exports.getServiceBaseURL = exports.getAccessToken = exports.populateValuesFromServiceUrl = exports.throwErrorWithFailureMessage = exports.exitWithFailureMessage = exports.getPackageVersion = exports.parseJwt = exports.getPlaywrightVersion = void 0;
|
|
6
|
+
exports.getTestRunApiUrl = getTestRunApiUrl;
|
|
7
|
+
exports.isNullOrEmpty = isNullOrEmpty;
|
|
8
|
+
exports.getRunName = getRunName;
|
|
9
|
+
exports.extractErrorMessage = extractErrorMessage;
|
|
10
|
+
exports.getWorkspaceMetaDataApiUrl = getWorkspaceMetaDataApiUrl;
|
|
11
|
+
exports.getHtmlReporterOutputFolder = getHtmlReporterOutputFolder;
|
|
12
|
+
exports.getContentType = getContentType;
|
|
13
|
+
exports.calculateOptimalConcurrency = calculateOptimalConcurrency;
|
|
14
|
+
exports.collectAllFiles = collectAllFiles;
|
|
15
|
+
exports.resolveTenantDomain = resolveTenantDomain;
|
|
16
|
+
exports.getPortalTestRunUrl = getPortalTestRunUrl;
|
|
17
|
+
const tslib_1 = require("tslib");
|
|
18
|
+
const constants_js_1 = require("../common/constants.js");
|
|
19
|
+
const messages_js_1 = require("../common/messages.js");
|
|
20
|
+
const logger_js_1 = require("../common/logger.js");
|
|
21
|
+
const node_process_1 = tslib_1.__importDefault(require("node:process"));
|
|
22
|
+
const node_crypto_1 = require("node:crypto");
|
|
23
|
+
const parseJwt_js_1 = require("./parseJwt.js");
|
|
24
|
+
const getPlaywrightVersion_js_1 = require("./getPlaywrightVersion.js");
|
|
25
|
+
const entraIdAccessToken_js_1 = require("../common/entraIdAccessToken.js");
|
|
26
|
+
const cIInfoProvider_js_1 = require("./cIInfoProvider.js");
|
|
27
|
+
const child_process_1 = require("child_process");
|
|
28
|
+
const getPackageVersion_js_1 = require("./getPackageVersion.js");
|
|
29
|
+
const fs_1 = require("fs");
|
|
30
|
+
const path_1 = require("path");
|
|
31
|
+
// Re-exporting for backward compatibility
|
|
32
|
+
var getPlaywrightVersion_js_2 = require("./getPlaywrightVersion.js");
|
|
33
|
+
Object.defineProperty(exports, "getPlaywrightVersion", { enumerable: true, get: function () { return getPlaywrightVersion_js_2.getPlaywrightVersion; } });
|
|
34
|
+
var parseJwt_js_2 = require("./parseJwt.js");
|
|
35
|
+
Object.defineProperty(exports, "parseJwt", { enumerable: true, get: function () { return parseJwt_js_2.parseJwt; } });
|
|
79
36
|
const getPackageVersion = () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
37
|
+
// hacky way to get package version
|
|
38
|
+
// try from dist folder first (customer perspective)
|
|
39
|
+
const distVersion = (0, getPackageVersion_js_1.getPackageVersionFromFolder)("../../../");
|
|
40
|
+
if (distVersion) {
|
|
41
|
+
return distVersion;
|
|
42
|
+
}
|
|
43
|
+
// if not found, try from src folder (internal test suite)
|
|
44
|
+
const srcVersion = (0, getPackageVersion_js_1.getPackageVersionFromFolder)("../../");
|
|
45
|
+
if (srcVersion) {
|
|
46
|
+
return srcVersion;
|
|
47
|
+
}
|
|
48
|
+
return "unknown-version";
|
|
89
49
|
};
|
|
50
|
+
exports.getPackageVersion = getPackageVersion;
|
|
90
51
|
const exitWithFailureMessage = (error, errorDetails) => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
52
|
+
console.log();
|
|
53
|
+
if (error.formatWithErrorDetails && errorDetails) {
|
|
54
|
+
console.error(error.formatWithErrorDetails(errorDetails));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(error.message);
|
|
58
|
+
}
|
|
59
|
+
// eslint-disable-next-line n/no-process-exit
|
|
60
|
+
node_process_1.default.exit(1);
|
|
98
61
|
};
|
|
62
|
+
exports.exitWithFailureMessage = exitWithFailureMessage;
|
|
99
63
|
const throwErrorWithFailureMessage = (error, errorDetails) => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
64
|
+
console.log();
|
|
65
|
+
const finalMessage = error.formatWithErrorDetails && errorDetails
|
|
66
|
+
? error.formatWithErrorDetails(errorDetails)
|
|
67
|
+
: error.message;
|
|
68
|
+
throw new Error(finalMessage);
|
|
103
69
|
};
|
|
70
|
+
exports.throwErrorWithFailureMessage = throwErrorWithFailureMessage;
|
|
104
71
|
const populateValuesFromServiceUrl = () => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
72
|
+
// Service URL format: wss://<region>.api.playwright.microsoft.com/accounts/<workspace-id>/browsers
|
|
73
|
+
const url = node_process_1.default.env["PLAYWRIGHT_SERVICE_URL"];
|
|
74
|
+
if (url) {
|
|
75
|
+
const parts = url.split("/");
|
|
76
|
+
if (parts.length > 2) {
|
|
77
|
+
const subdomainParts = parts[2].split(".");
|
|
78
|
+
const region = subdomainParts.length > 0 ? subdomainParts[0] : null;
|
|
79
|
+
const domain = subdomainParts.slice(2).join(".");
|
|
80
|
+
const accountId = parts[4];
|
|
81
|
+
return { region: region, domain: domain, accountId: accountId };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
117
85
|
};
|
|
86
|
+
exports.populateValuesFromServiceUrl = populateValuesFromServiceUrl;
|
|
118
87
|
const getAccessToken = () => {
|
|
119
|
-
|
|
88
|
+
return node_process_1.default.env[constants_js_1.ServiceEnvironmentVariable.PLAYWRIGHT_SERVICE_ACCESS_TOKEN];
|
|
120
89
|
};
|
|
90
|
+
exports.getAccessToken = getAccessToken;
|
|
121
91
|
const getServiceBaseURL = () => {
|
|
122
|
-
|
|
92
|
+
return node_process_1.default.env[constants_js_1.ServiceEnvironmentVariable.PLAYWRIGHT_SERVICE_URL];
|
|
123
93
|
};
|
|
94
|
+
exports.getServiceBaseURL = getServiceBaseURL;
|
|
124
95
|
const isValidGuid = (guid) => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
96
|
+
if (!guid) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
100
|
+
return guidRegex.test(guid);
|
|
130
101
|
};
|
|
102
|
+
exports.isValidGuid = isValidGuid;
|
|
131
103
|
const getAndSetRunId = () => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
104
|
+
const runId = (0, node_crypto_1.randomUUID)();
|
|
105
|
+
node_process_1.default.env[constants_js_1.InternalEnvironmentVariables.MPT_SERVICE_RUN_ID] = runId;
|
|
106
|
+
return runId;
|
|
135
107
|
};
|
|
108
|
+
exports.getAndSetRunId = getAndSetRunId;
|
|
136
109
|
const getServiceWSEndpoint = (runId, os, apiVersion) => {
|
|
137
|
-
|
|
110
|
+
return `${(0, exports.getServiceBaseURL)()}?runId=${encodeURIComponent(runId)}&os=${os}&sourceType=${constants_js_1.BrowserSessionSourceType.PLAYWRIGHT_WORKSPACES_TEST_RUN}&api-version=${apiVersion}`;
|
|
138
111
|
};
|
|
112
|
+
exports.getServiceWSEndpoint = getServiceWSEndpoint;
|
|
139
113
|
const validateServiceUrl = () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
114
|
+
const serviceUrl = (0, exports.getServiceBaseURL)();
|
|
115
|
+
if (!serviceUrl) {
|
|
116
|
+
(0, exports.exitWithFailureMessage)(messages_js_1.ServiceErrorMessageConstants.NO_SERVICE_URL_ERROR);
|
|
117
|
+
}
|
|
144
118
|
};
|
|
119
|
+
exports.validateServiceUrl = validateServiceUrl;
|
|
145
120
|
const ValidateRunID = (runID) => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
121
|
+
const isValidRunID = (0, exports.isValidGuid)(runID);
|
|
122
|
+
if (!isValidRunID) {
|
|
123
|
+
const errorMessage = messages_js_1.ServiceErrorMessageConstants.INVALID_RUN_ID_FORMAT.message;
|
|
124
|
+
throw new Error(errorMessage);
|
|
125
|
+
}
|
|
151
126
|
};
|
|
127
|
+
exports.ValidateRunID = ValidateRunID;
|
|
152
128
|
const validateMptPAT = (validationFailureCallback) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
129
|
+
try {
|
|
130
|
+
const accessToken = (0, exports.getAccessToken)();
|
|
131
|
+
const result = (0, exports.populateValuesFromServiceUrl)();
|
|
132
|
+
if (!accessToken) {
|
|
133
|
+
validationFailureCallback(messages_js_1.ServiceErrorMessageConstants.NO_AUTH_ERROR_PAT_TOKEN);
|
|
134
|
+
}
|
|
135
|
+
const claims = (0, parseJwt_js_1.parseJwt)(accessToken);
|
|
136
|
+
if (!claims.exp) {
|
|
137
|
+
validationFailureCallback(messages_js_1.ServiceErrorMessageConstants.INVALID_MPT_PAT_ERROR);
|
|
138
|
+
}
|
|
139
|
+
if (Date.now() >= claims.exp * 1000) {
|
|
140
|
+
validationFailureCallback(messages_js_1.ServiceErrorMessageConstants.EXPIRED_MPT_PAT_ERROR);
|
|
141
|
+
}
|
|
142
|
+
if (result.accountId !== claims.pwid) {
|
|
143
|
+
validationFailureCallback(messages_js_1.ServiceErrorMessageConstants.WORKSPACE_MISMATCH_ERROR);
|
|
144
|
+
}
|
|
165
145
|
}
|
|
166
|
-
|
|
167
|
-
|
|
146
|
+
catch (err) {
|
|
147
|
+
logger_js_1.coreLogger.error(err);
|
|
148
|
+
(0, exports.exitWithFailureMessage)(messages_js_1.ServiceErrorMessageConstants.INVALID_MPT_PAT_ERROR);
|
|
168
149
|
}
|
|
169
|
-
} catch (err) {
|
|
170
|
-
import_logger.coreLogger.error(err);
|
|
171
|
-
exitWithFailureMessage(import_messages.ServiceErrorMessageConstants.INVALID_MPT_PAT_ERROR);
|
|
172
|
-
}
|
|
173
150
|
};
|
|
151
|
+
exports.validateMptPAT = validateMptPAT;
|
|
174
152
|
const isTokenExpiringSoon = (expirationTime, currentTime) => {
|
|
175
|
-
|
|
153
|
+
return expirationTime * 1000 - currentTime <= constants_js_1.Constants.SevenDaysInMS;
|
|
176
154
|
};
|
|
177
155
|
const warnAboutTokenExpiry = (expirationTime, currentTime) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
156
|
+
const daysToExpiration = Math.ceil((expirationTime * 1000 - currentTime) / constants_js_1.Constants.OneDayInMS);
|
|
157
|
+
const expirationDate = new Date(expirationTime * 1000).toLocaleDateString();
|
|
158
|
+
const expirationWarning = `Warning: The access token used for this test run will expire in ${daysToExpiration} days on ${expirationDate}. Generate a new token from the portal to avoid failures. For a simpler, more secure solution, switch to Microsoft Entra ID and eliminate token management. https://learn.microsoft.com/entra/identity/`;
|
|
159
|
+
console.warn(expirationWarning);
|
|
182
160
|
};
|
|
183
161
|
const warnIfAccessTokenCloseToExpiry = () => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
162
|
+
const accessToken = (0, exports.getAccessToken)();
|
|
163
|
+
if (!accessToken) {
|
|
164
|
+
throw new Error(messages_js_1.ServiceErrorMessageConstants.NO_AUTH_ERROR_PAT_TOKEN.message);
|
|
165
|
+
}
|
|
166
|
+
const claims = (0, parseJwt_js_1.parseJwt)(accessToken);
|
|
167
|
+
const currentTime = Date.now();
|
|
168
|
+
if (isTokenExpiringSoon(claims.exp, currentTime)) {
|
|
169
|
+
warnAboutTokenExpiry(claims.exp, currentTime);
|
|
170
|
+
}
|
|
193
171
|
};
|
|
172
|
+
exports.warnIfAccessTokenCloseToExpiry = warnIfAccessTokenCloseToExpiry;
|
|
194
173
|
const fetchOrValidateAccessToken = async (credential) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
174
|
+
const entraIdAccessToken = (0, entraIdAccessToken_js_1.createEntraIdAccessToken)(credential);
|
|
175
|
+
// Fetch a token or refresh if needed in a single call
|
|
176
|
+
if (entraIdAccessToken.doesEntraIdAccessTokenNeedRotation()) {
|
|
177
|
+
await entraIdAccessToken.fetchEntraIdAccessToken();
|
|
178
|
+
}
|
|
179
|
+
const token = (0, exports.getAccessToken)();
|
|
180
|
+
if (!token) {
|
|
181
|
+
throw new Error(messages_js_1.ServiceErrorMessageConstants.NO_AUTH_ERROR_ENTRA_TOKEN.message);
|
|
182
|
+
}
|
|
183
|
+
return token;
|
|
204
184
|
};
|
|
185
|
+
exports.fetchOrValidateAccessToken = fetchOrValidateAccessToken;
|
|
205
186
|
const getVersionInfo = (version) => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
187
|
+
const regex = /^(\d+)(?:\.(\d+))?(?:\.(\d+))?/;
|
|
188
|
+
const match = version.match(regex);
|
|
189
|
+
const versionInfo = {
|
|
190
|
+
major: 0,
|
|
191
|
+
minor: 0,
|
|
192
|
+
patch: 0,
|
|
193
|
+
};
|
|
194
|
+
versionInfo.major = match && match[1] ? parseInt(match[1], 10) : 0;
|
|
195
|
+
versionInfo.minor = match && match[2] ? parseInt(match[2], 10) : 0;
|
|
196
|
+
versionInfo.patch = match && match[3] ? parseInt(match[3], 10) : 0;
|
|
197
|
+
return versionInfo;
|
|
217
198
|
};
|
|
199
|
+
exports.getVersionInfo = getVersionInfo;
|
|
218
200
|
const validatePlaywrightVersion = () => {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
201
|
+
const minimumSupportedVersion = constants_js_1.Constants.MinimumSupportedPlaywrightVersion;
|
|
202
|
+
const installedVersion = (0, getPlaywrightVersion_js_1.getPlaywrightVersion)();
|
|
203
|
+
const minimumSupportedVersionInfo = (0, exports.getVersionInfo)(minimumSupportedVersion);
|
|
204
|
+
const installedVersionInfo = (0, exports.getVersionInfo)(installedVersion);
|
|
205
|
+
const isInstalledVersionGreater = installedVersionInfo.major > minimumSupportedVersionInfo.major ||
|
|
206
|
+
(installedVersionInfo.major === minimumSupportedVersionInfo.major &&
|
|
207
|
+
installedVersionInfo.minor >= minimumSupportedVersionInfo.minor);
|
|
208
|
+
if (!isInstalledVersionGreater) {
|
|
209
|
+
(0, exports.exitWithFailureMessage)(messages_js_1.ServiceErrorMessageConstants.INVALID_PLAYWRIGHT_VERSION_ERROR);
|
|
210
|
+
}
|
|
227
211
|
};
|
|
212
|
+
exports.validatePlaywrightVersion = validatePlaywrightVersion;
|
|
228
213
|
const getTestRunConfig = (config) => {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
214
|
+
const maxWorkers = config.workers || config.metadata.actualWorkers;
|
|
215
|
+
const frameWorkVersion = config.version;
|
|
216
|
+
const testRunConfig = {
|
|
217
|
+
framework: {
|
|
218
|
+
name: constants_js_1.RunConfigConstants.TEST_FRAMEWORK_NAME,
|
|
219
|
+
version: frameWorkVersion,
|
|
220
|
+
runnerName: constants_js_1.RunConfigConstants.TEST_FRAMEWORK_RUNNERNAME,
|
|
221
|
+
},
|
|
222
|
+
sdkLanguage: constants_js_1.RunConfigConstants.TEST_SDK_LANGUAGE,
|
|
223
|
+
maxWorkers: maxWorkers,
|
|
224
|
+
};
|
|
225
|
+
return testRunConfig;
|
|
241
226
|
};
|
|
227
|
+
exports.getTestRunConfig = getTestRunConfig;
|
|
242
228
|
function getTestRunApiUrl() {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
229
|
+
const result = (0, exports.populateValuesFromServiceUrl)();
|
|
230
|
+
const runId = node_process_1.default.env[constants_js_1.InternalEnvironmentVariables.MPT_SERVICE_RUN_ID];
|
|
231
|
+
if (!result?.region || !result?.domain || !result?.accountId) {
|
|
232
|
+
(0, exports.exitWithFailureMessage)(messages_js_1.ServiceErrorMessageConstants.NO_SERVICE_URL_ERROR);
|
|
233
|
+
}
|
|
234
|
+
const baseUrl = `https://${result?.region}.${constants_js_1.UrlConstants.ReportingApiSubdomain}.${result?.domain}/${constants_js_1.UrlConstants.PlaywrightWorkspacesPath}/${result?.accountId}/${constants_js_1.UrlConstants.TestRunsPath}`;
|
|
235
|
+
const url = runId ? `${baseUrl}/${runId}` : baseUrl;
|
|
236
|
+
return `${url}?api-version=${constants_js_1.Constants.LatestAPIVersion}`;
|
|
251
237
|
}
|
|
252
238
|
function isNullOrEmpty(str) {
|
|
253
|
-
|
|
239
|
+
return !str || str.trim() === "";
|
|
254
240
|
}
|
|
255
241
|
async function runCommand(command) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
242
|
+
return new Promise((resolve, reject) => {
|
|
243
|
+
(0, child_process_1.exec)(command, (error, stdout, stderr) => {
|
|
244
|
+
if (error) {
|
|
245
|
+
reject(error);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (stderr) {
|
|
249
|
+
reject(new Error(stderr));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
resolve(stdout.trim());
|
|
253
|
+
});
|
|
267
254
|
});
|
|
268
|
-
});
|
|
269
255
|
}
|
|
270
256
|
async function getRunName(ciInfo) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
257
|
+
if (ciInfo.providerName === cIInfoProvider_js_1.CI_PROVIDERS.GITHUB &&
|
|
258
|
+
node_process_1.default.env["GITHUB_EVENT_NAME"] === "pull_request") {
|
|
259
|
+
const prNumber = `${node_process_1.default.env["GITHUB_REF_NAME"]?.split("/")[0]}`;
|
|
260
|
+
const prLink = `${node_process_1.default.env["GITHUB_REPOSITORY"]}/pull/${prNumber}`;
|
|
261
|
+
return `PR# ${prNumber} on Repo: ${node_process_1.default.env["GITHUB_REPOSITORY"]} (${prLink})`;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const gitVersion = await runCommand(constants_js_1.GitHubActionsConstants.GIT_VERSION_COMMAND);
|
|
265
|
+
if (isNullOrEmpty(gitVersion)) {
|
|
266
|
+
throw new Error("Git is not installed on the machine");
|
|
267
|
+
}
|
|
268
|
+
const isInsideWorkTree = await runCommand(constants_js_1.GitHubActionsConstants.GIT_REV_PARSE);
|
|
269
|
+
if (isInsideWorkTree !== "true") {
|
|
270
|
+
throw new Error("Not inside a git repository");
|
|
271
|
+
}
|
|
272
|
+
const gitCommitMessage = await runCommand(constants_js_1.GitHubActionsConstants.GIT_COMMIT_MESSAGE_COMMAND);
|
|
273
|
+
return gitCommitMessage;
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
logger_js_1.coreLogger.error(`Error in getting git commit message: ${err}.`);
|
|
277
|
+
return "";
|
|
278
|
+
}
|
|
291
279
|
}
|
|
292
280
|
function extractErrorMessage(responseBody) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
281
|
+
if (!responseBody) {
|
|
282
|
+
return "";
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const errorResponse = JSON.parse(responseBody);
|
|
286
|
+
if (errorResponse.error && errorResponse.error.message) {
|
|
287
|
+
return errorResponse.error.message;
|
|
288
|
+
}
|
|
289
|
+
return responseBody;
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
return responseBody;
|
|
293
|
+
}
|
|
305
294
|
}
|
|
306
295
|
function getWorkspaceMetaDataApiUrl() {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
296
|
+
const result = (0, exports.populateValuesFromServiceUrl)();
|
|
297
|
+
if (!result?.region || !result?.domain || !result?.accountId) {
|
|
298
|
+
(0, exports.exitWithFailureMessage)(messages_js_1.ServiceErrorMessageConstants.NO_SERVICE_URL_ERROR);
|
|
299
|
+
}
|
|
300
|
+
const baseUrl = `https://${result?.region}.${constants_js_1.UrlConstants.ApiSubdomain}.${result?.domain}/${constants_js_1.UrlConstants.PlaywrightWorkspacesPath}/${result?.accountId}`;
|
|
301
|
+
return `${baseUrl}?api-version=${constants_js_1.Constants.LatestAPIVersion}`;
|
|
313
302
|
}
|
|
314
303
|
function getHtmlReporterOutputFolder(config) {
|
|
315
|
-
|
|
316
|
-
|
|
304
|
+
const defaultFolder = "playwright-report";
|
|
305
|
+
if (!config?.reporter) {
|
|
306
|
+
return defaultFolder;
|
|
307
|
+
}
|
|
308
|
+
for (const reporter of config.reporter) {
|
|
309
|
+
if (Array.isArray(reporter)) {
|
|
310
|
+
const [reporterName, options] = reporter;
|
|
311
|
+
if (reporterName === "html" && options && typeof options === "object") {
|
|
312
|
+
return options.outputFolder || defaultFolder;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else if (typeof reporter === "string" && reporter === "html") {
|
|
316
|
+
return defaultFolder;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
317
319
|
return defaultFolder;
|
|
318
|
-
}
|
|
319
|
-
for (const reporter of config.reporter) {
|
|
320
|
-
if (Array.isArray(reporter)) {
|
|
321
|
-
const [reporterName, options] = reporter;
|
|
322
|
-
if (reporterName === "html" && options && typeof options === "object") {
|
|
323
|
-
return options.outputFolder || defaultFolder;
|
|
324
|
-
}
|
|
325
|
-
} else if (typeof reporter === "string" && reporter === "html") {
|
|
326
|
-
return defaultFolder;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
return defaultFolder;
|
|
330
320
|
}
|
|
331
321
|
function getContentType(filePath) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
322
|
+
const ext = filePath.toLowerCase().split(".").pop();
|
|
323
|
+
const contentTypes = {
|
|
324
|
+
html: "text/html",
|
|
325
|
+
css: "text/css",
|
|
326
|
+
js: "application/javascript",
|
|
327
|
+
json: "application/json",
|
|
328
|
+
png: "image/png",
|
|
329
|
+
jpg: "image/jpeg",
|
|
330
|
+
jpeg: "image/jpeg",
|
|
331
|
+
svg: "image/svg+xml",
|
|
332
|
+
ico: "image/x-icon",
|
|
333
|
+
txt: "text/plain",
|
|
334
|
+
ttf: "font/ttf",
|
|
335
|
+
woff: "font/woff",
|
|
336
|
+
woff2: "font/woff2",
|
|
337
|
+
webmanifest: "application/manifest+json",
|
|
338
|
+
map: "application/json",
|
|
339
|
+
xml: "application/xml",
|
|
340
|
+
pdf: "application/pdf",
|
|
341
|
+
zip: "application/zip",
|
|
342
|
+
};
|
|
343
|
+
return contentTypes[ext || ""] || "application/octet-stream";
|
|
354
344
|
}
|
|
355
345
|
function calculateOptimalConcurrency(files) {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
optimalConcurrency = Math.min(
|
|
374
|
-
import_constants2.UploadConstants.MAX_CONCURRENCY,
|
|
375
|
-
import_constants2.UploadConstants.BASE_CONCURRENCY
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
return Math.floor(optimalConcurrency);
|
|
346
|
+
const totalFiles = files.length;
|
|
347
|
+
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
348
|
+
const avgFileSize = totalSize / totalFiles;
|
|
349
|
+
let optimalConcurrency;
|
|
350
|
+
if (totalFiles <= 10) {
|
|
351
|
+
optimalConcurrency = Math.min(totalFiles, 10);
|
|
352
|
+
}
|
|
353
|
+
else if (avgFileSize < constants_js_1.UploadConstants.SMALL_FILE_THRESHOLD) {
|
|
354
|
+
optimalConcurrency = Math.min(constants_js_1.UploadConstants.MAX_CONCURRENCY, Math.max(constants_js_1.UploadConstants.BASE_CONCURRENCY, totalFiles / 50));
|
|
355
|
+
}
|
|
356
|
+
else if (totalFiles > 1000) {
|
|
357
|
+
optimalConcurrency = Math.min(constants_js_1.UploadConstants.MAX_CONCURRENCY, constants_js_1.UploadConstants.BASE_CONCURRENCY + Math.floor(totalFiles / 200));
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
optimalConcurrency = Math.min(constants_js_1.UploadConstants.MAX_CONCURRENCY, constants_js_1.UploadConstants.BASE_CONCURRENCY);
|
|
361
|
+
}
|
|
362
|
+
return Math.floor(optimalConcurrency);
|
|
379
363
|
}
|
|
380
364
|
function collectAllFiles(folderPath, basePath, runIdFolderPrefix) {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
365
|
+
const files = [];
|
|
366
|
+
const stack = [folderPath];
|
|
367
|
+
while (stack.length > 0) {
|
|
368
|
+
const currentPath = stack.pop();
|
|
369
|
+
try {
|
|
370
|
+
const items = (0, fs_1.readdirSync)(currentPath);
|
|
371
|
+
for (const item of items) {
|
|
372
|
+
const itemPath = (0, path_1.join)(currentPath, item);
|
|
373
|
+
const stats = (0, fs_1.statSync)(itemPath);
|
|
374
|
+
if (stats.isDirectory()) {
|
|
375
|
+
stack.push(itemPath);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
let relativePath = (0, path_1.relative)(basePath, itemPath).split("\\").join("/");
|
|
379
|
+
if (runIdFolderPrefix) {
|
|
380
|
+
relativePath = `${runIdFolderPrefix}/${relativePath}`;
|
|
381
|
+
}
|
|
382
|
+
files.push({
|
|
383
|
+
fullPath: itemPath,
|
|
384
|
+
relativePath,
|
|
385
|
+
size: stats.size,
|
|
386
|
+
contentType: getContentType(itemPath),
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
continue;
|
|
403
393
|
}
|
|
404
|
-
}
|
|
405
|
-
} catch (error) {
|
|
406
|
-
continue;
|
|
407
394
|
}
|
|
408
|
-
|
|
409
|
-
return files;
|
|
395
|
+
return files;
|
|
410
396
|
}
|
|
411
397
|
function resolveTenantDomain(tenantId, tenants) {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
);
|
|
419
|
-
return matchingTenant?.defaultDomain;
|
|
398
|
+
if (!tenantId || tenants.length === 0) {
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
const matchingTenant = tenants.find((t) => t.tenantId === tenantId);
|
|
402
|
+
logger_js_1.coreLogger.info(`Resolved tenant domain: ${JSON.stringify(matchingTenant?.defaultDomain)} for tenant ID: ${tenantId}`);
|
|
403
|
+
return matchingTenant?.defaultDomain;
|
|
420
404
|
}
|
|
421
405
|
function getPortalTestRunUrl(workspaceMetadata, tenantDomain) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
const resourceGroupName = resourceIdParts[resourceGroupIndex + 1];
|
|
436
|
-
const tenantFragment = tenantDomain ? `#@${tenantDomain}` : "#";
|
|
437
|
-
return `${import_constants.UrlConstants.AzurePortalBaseUrl}/${tenantFragment}${import_constants.UrlConstants.ResourcePath}${import_constants.UrlConstants.SubscriptionsPath}/${encodeURIComponent(subscriptionId)}${import_constants.UrlConstants.ResourceGroupsUrlPath}/${encodeURIComponent(resourceGroupName)}${import_constants.UrlConstants.ProvidersPath}/${import_constants.UrlConstants.LoadTestServiceProvider}/${import_constants.UrlConstants.PlaywrightWorkspacesResourceType}/${encodeURIComponent(name)}/${import_constants.UrlConstants.TestRunsRoute}`;
|
|
406
|
+
const { subscriptionId, resourceId, name } = workspaceMetadata ?? {};
|
|
407
|
+
if (!subscriptionId || !resourceId || !name) {
|
|
408
|
+
throw new Error("Missing required workspace metadata: subscriptionId, resourceId, and name are required");
|
|
409
|
+
}
|
|
410
|
+
// Extract resource group from resourceId
|
|
411
|
+
const resourceIdParts = resourceId.split("/");
|
|
412
|
+
const resourceGroupIndex = resourceIdParts.findIndex((part) => part.toLowerCase() === constants_js_1.UrlConstants.ResourceGroupsPath);
|
|
413
|
+
if (resourceGroupIndex === -1 || resourceGroupIndex + 1 >= resourceIdParts.length) {
|
|
414
|
+
throw new Error("Invalid resourceId format: could not extract resource group name");
|
|
415
|
+
}
|
|
416
|
+
const resourceGroupName = resourceIdParts[resourceGroupIndex + 1];
|
|
417
|
+
const tenantFragment = tenantDomain ? `#@${tenantDomain}` : "#";
|
|
418
|
+
return `${constants_js_1.UrlConstants.AzurePortalBaseUrl}/${tenantFragment}${constants_js_1.UrlConstants.ResourcePath}${constants_js_1.UrlConstants.SubscriptionsPath}/${encodeURIComponent(subscriptionId)}${constants_js_1.UrlConstants.ResourceGroupsUrlPath}/${encodeURIComponent(resourceGroupName)}${constants_js_1.UrlConstants.ProvidersPath}/${constants_js_1.UrlConstants.LoadTestServiceProvider}/${constants_js_1.UrlConstants.PlaywrightWorkspacesResourceType}/${encodeURIComponent(name)}/${constants_js_1.UrlConstants.TestRunsRoute}`;
|
|
438
419
|
}
|
|
439
420
|
const getStorageAccountNameFromUri = (storageUri) => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
421
|
+
try {
|
|
422
|
+
if (!storageUri || typeof storageUri !== "string") {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
const url = new URL(storageUri);
|
|
426
|
+
const hostname = url.hostname;
|
|
427
|
+
// Extract storage account name from hostname pattern: {accountname}.blob.core.windows.net
|
|
428
|
+
const match = hostname.match(/^([^.]+)\.blob\.core\.windows\.net$/i);
|
|
429
|
+
if (match && match[1]) {
|
|
430
|
+
return match[1];
|
|
431
|
+
}
|
|
432
|
+
return null;
|
|
443
433
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if (match && match[1]) {
|
|
448
|
-
return match[1];
|
|
434
|
+
catch (error) {
|
|
435
|
+
console.warn("Failed to extract storage account name from URI:", storageUri, error);
|
|
436
|
+
return null;
|
|
449
437
|
}
|
|
450
|
-
return null;
|
|
451
|
-
} catch (error) {
|
|
452
|
-
console.warn("Failed to extract storage account name from URI:", storageUri, error);
|
|
453
|
-
return null;
|
|
454
|
-
}
|
|
455
438
|
};
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
ValidateRunID,
|
|
459
|
-
calculateOptimalConcurrency,
|
|
460
|
-
collectAllFiles,
|
|
461
|
-
exitWithFailureMessage,
|
|
462
|
-
extractErrorMessage,
|
|
463
|
-
fetchOrValidateAccessToken,
|
|
464
|
-
getAccessToken,
|
|
465
|
-
getAndSetRunId,
|
|
466
|
-
getContentType,
|
|
467
|
-
getHtmlReporterOutputFolder,
|
|
468
|
-
getPackageVersion,
|
|
469
|
-
getPlaywrightVersion,
|
|
470
|
-
getPortalTestRunUrl,
|
|
471
|
-
getRunName,
|
|
472
|
-
getServiceBaseURL,
|
|
473
|
-
getServiceWSEndpoint,
|
|
474
|
-
getStorageAccountNameFromUri,
|
|
475
|
-
getTestRunApiUrl,
|
|
476
|
-
getTestRunConfig,
|
|
477
|
-
getVersionInfo,
|
|
478
|
-
getWorkspaceMetaDataApiUrl,
|
|
479
|
-
isNullOrEmpty,
|
|
480
|
-
isValidGuid,
|
|
481
|
-
parseJwt,
|
|
482
|
-
populateValuesFromServiceUrl,
|
|
483
|
-
resolveTenantDomain,
|
|
484
|
-
throwErrorWithFailureMessage,
|
|
485
|
-
validateMptPAT,
|
|
486
|
-
validatePlaywrightVersion,
|
|
487
|
-
validateServiceUrl,
|
|
488
|
-
warnIfAccessTokenCloseToExpiry
|
|
489
|
-
});
|
|
439
|
+
exports.getStorageAccountNameFromUri = getStorageAccountNameFromUri;
|
|
440
|
+
//# sourceMappingURL=utils.js.map
|