@camunda/e2e-test-suite 0.0.924 → 0.0.925
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/utils/apiHelpers.js +19 -2
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +32 -7
- package/package.json +1 -1
package/dist/utils/apiHelpers.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.updateClusterDataFilters = exports.getClusterDataFilters = exports.getTestClusterUuid = exports.authConsoleManagementAPI = exports.updateCollectionScope = exports.createSingleProcessReport = exports.createDashboard = exports.createCollection = exports.getOptimizeCookieSm = exports.getOptimizeCoockie = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.waitForProcessInstanceVisible = exports.createProcessInstance = exports.deployProcess = exports.waitForInboundWebhookRegistered = exports.waitForConnectorsReady = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.buildZeebeApiUrl = exports.retryOn500 = exports.sendRequestAndAssertResponse = exports.assertUnauthorizedResponseBody = exports.expectUnauthorizedErrorBody = exports.assertResponseStatus = exports.getApiRequestContext = void 0;
|
|
7
7
|
const test_1 = require("@playwright/test");
|
|
8
8
|
const sleep_1 = require("./sleep");
|
|
9
|
+
const randomSleep_1 = require("./randomSleep");
|
|
9
10
|
const fs_1 = __importDefault(require("fs"));
|
|
10
11
|
const path_1 = __importDefault(require("path"));
|
|
11
12
|
const os_1 = __importDefault(require("os"));
|
|
@@ -604,7 +605,14 @@ async function createStringClusterVariable(authToken, environment = 'saas', cust
|
|
|
604
605
|
exports.createStringClusterVariable = createStringClusterVariable;
|
|
605
606
|
async function getOptimizeCoockie(page) {
|
|
606
607
|
const optimizeUrl = process.env.CAMUNDA_OPTIMIZE_BASE_URL;
|
|
607
|
-
const maxLoginAttempts =
|
|
608
|
+
const maxLoginAttempts = 4;
|
|
609
|
+
// This hook runs once per worker that picks up any test from an Optimize
|
|
610
|
+
// describe, so with 37 workers dozens of full interactive Auth0 logins for
|
|
611
|
+
// the same user fire within the same second. Stagger the first navigation to
|
|
612
|
+
// spread that burst -- it is enough on its own to trip Auth0's tenant-wide
|
|
613
|
+
// rate limit, which then fails every worker at once. Retries back off via
|
|
614
|
+
// randomSleep below, so this only needs to run once.
|
|
615
|
+
await (0, randomSleep_1.randomSleep)(0, 15000);
|
|
608
616
|
// Auth0 can fail or rate-limit concurrent logins. Retry the whole flow if
|
|
609
617
|
// loginToApp throws (e.g. waitForURL times out after a bad Auth0 redirect).
|
|
610
618
|
for (let loginAttempt = 0; loginAttempt < maxLoginAttempts; loginAttempt++) {
|
|
@@ -616,9 +624,18 @@ async function getOptimizeCoockie(page) {
|
|
|
616
624
|
}
|
|
617
625
|
catch (error) {
|
|
618
626
|
if (loginAttempt < maxLoginAttempts - 1) {
|
|
627
|
+
const rateLimited = String(error).includes(utils_1.AUTH0_RATE_LIMIT);
|
|
619
628
|
console.warn(`getOptimizeCoockie: login attempt ${loginAttempt + 1} failed, retrying after backoff...`, error);
|
|
620
629
|
await page.goto('about:blank');
|
|
621
|
-
|
|
630
|
+
if (rateLimited) {
|
|
631
|
+
// Auth0 rate-limit windows commonly last 30-90s. Back off long
|
|
632
|
+
// enough to outlast the window; a 5-10s backoff just retries inside
|
|
633
|
+
// the same window and burns the attempt budget for nothing.
|
|
634
|
+
await (0, randomSleep_1.randomSleep)(60000, 90000);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
await (0, randomSleep_1.randomSleep)(10000, 20000);
|
|
638
|
+
}
|
|
622
639
|
}
|
|
623
640
|
else {
|
|
624
641
|
throw error;
|
package/dist/utils/utils.d.ts
CHANGED
package/dist/utils/utils.js
CHANGED
|
@@ -1,25 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loginToApp = void 0;
|
|
3
|
+
exports.loginToApp = exports.AUTH0_RATE_LIMIT = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const LoginPage_1 = require("../pages/8.8/LoginPage");
|
|
6
|
+
exports.AUTH0_RATE_LIMIT = 'AUTH0_RATE_LIMIT';
|
|
7
|
+
async function throwIfRateLimited(loginPage) {
|
|
8
|
+
const rateLimited = await loginPage.rateLimitError
|
|
9
|
+
.first()
|
|
10
|
+
.isVisible()
|
|
11
|
+
.catch(() => false);
|
|
12
|
+
if (rateLimited) {
|
|
13
|
+
throw new Error(`${exports.AUTH0_RATE_LIMIT}: identity provider returned an error page`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
async function loginToApp(appName, page) {
|
|
7
17
|
await page.goto(appName, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
8
18
|
await page.waitForLoadState('networkidle', { timeout: 30000 }).catch(() => { });
|
|
9
19
|
const loginPage = new LoginPage_1.LoginPage(page);
|
|
10
|
-
|
|
20
|
+
// Auth0 serves a tenant-wide rate-limit error page that carries none of the
|
|
21
|
+
// usual auth controls. Settle on whichever of the two actually renders, then
|
|
22
|
+
// classify: waiting on usernameInput alone burns the full 60s before the
|
|
23
|
+
// caller can tell a rate limit apart from a slow login form, and the caller
|
|
24
|
+
// needs that distinction to pick a backoff long enough to outlast the window.
|
|
25
|
+
await (0, test_1.expect)(loginPage.usernameInput.or(loginPage.rateLimitError.first())).toBeVisible({ timeout: 60000 });
|
|
26
|
+
await throwIfRateLimited(loginPage);
|
|
11
27
|
await loginPage.fillUsername(process.env.C8_USERNAME);
|
|
12
28
|
await (0, test_1.expect)(loginPage.usernameInput).toHaveValue(process.env.C8_USERNAME);
|
|
13
29
|
await (0, test_1.expect)(loginPage.loginMessage).toBeVisible();
|
|
14
30
|
await loginPage.clickContinueButton();
|
|
15
|
-
await (0, test_1.expect)(loginPage.passwordInput).toBeVisible({ timeout: 90000 });
|
|
31
|
+
await (0, test_1.expect)(loginPage.passwordInput.or(loginPage.rateLimitError.first())).toBeVisible({ timeout: 90000 });
|
|
32
|
+
await throwIfRateLimited(loginPage);
|
|
16
33
|
await loginPage.fillPassword(process.env.C8_PASSWORD);
|
|
17
34
|
await (0, test_1.expect)(loginPage.passwordHeading).toBeVisible({ timeout: 90000 });
|
|
18
35
|
await loginPage.clickLoginButton();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
try {
|
|
37
|
+
await page.waitForURL((url) => url.toString().startsWith(appName), {
|
|
38
|
+
timeout: 60000,
|
|
39
|
+
waitUntil: 'commit',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Auth0 can also serve the rate-limit page as the response to the password
|
|
44
|
+
// submit, in which case the redirect back to appName never happens.
|
|
45
|
+
await throwIfRateLimited(loginPage);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
23
48
|
await page
|
|
24
49
|
.waitForLoadState('domcontentloaded', { timeout: 30000 })
|
|
25
50
|
.catch(() => { });
|