@camunda/e2e-test-suite 0.0.1287 → 0.0.1289
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/pages/8.8/AppsPage.d.ts +7 -3
- package/dist/pages/8.8/AppsPage.js +96 -26
- package/dist/pages/8.8/ModelerCreatePage.d.ts +3 -0
- package/dist/pages/8.8/ModelerCreatePage.js +25 -0
- package/dist/pages/8.8/UtilitiesPage.js +34 -17
- package/dist/pages/8.8/WorkspaceMembersPage.d.ts +1 -0
- package/dist/pages/8.8/WorkspaceMembersPage.js +21 -10
- package/dist/pages/8.9/AppsPage.d.ts +9 -3
- package/dist/pages/8.9/AppsPage.js +262 -47
- package/dist/pages/8.9/ClusterDetailsPage.d.ts +5 -0
- package/dist/pages/8.9/ClusterDetailsPage.js +92 -9
- package/dist/pages/8.9/ClusterSecretsPage.js +5 -1
- package/dist/pages/8.9/ConnectorMarketplacePage.d.ts +1 -0
- package/dist/pages/8.9/ConnectorMarketplacePage.js +46 -3
- package/dist/pages/8.9/ConsoleOrganizationPage.d.ts +3 -2
- package/dist/pages/8.9/ConsoleOrganizationPage.js +47 -22
- package/dist/pages/8.9/FormJsPage.d.ts +4 -0
- package/dist/pages/8.9/FormJsPage.js +53 -19
- package/dist/pages/8.9/IdpCreatePage.js +5 -0
- package/dist/pages/8.9/ModelerCreatePage.d.ts +5 -0
- package/dist/pages/8.9/ModelerCreatePage.js +153 -21
- package/dist/pages/8.9/ModelerHomePage.d.ts +1 -0
- package/dist/pages/8.9/ModelerHomePage.js +29 -4
- package/dist/pages/8.9/PlayPage.js +11 -1
- package/dist/pages/8.9/ProcessApplicationPage.js +48 -4
- package/dist/pages/8.9/UtilitiesPage.js +57 -17
- package/dist/pages/8.9/WorkspaceMembersPage.d.ts +21 -0
- package/dist/pages/8.9/WorkspaceMembersPage.js +264 -0
- package/dist/tests/8.8/access-user-role-management.spec.js +57 -29
- package/dist/tests/8.8/console-user-flows.spec.js +22 -1
- package/dist/tests/8.8/rba-enabled-v1-user-flows.spec.js +13 -4
- package/dist/tests/8.8/rba-enabled-v2-user-flows.spec.js +50 -14
- package/dist/tests/8.8/test-setup.spec.js +49 -4
- package/dist/tests/8.9/access-user-role-management.spec.js +111 -26
- package/dist/tests/8.9/console-user-flows.spec.js +4 -4
- package/dist/tests/8.9/idp-user-flows.spec.js +2 -1
- package/dist/tests/8.9/rba-enabled-v1-user-flows.spec.js +13 -4
- package/dist/tests/8.9/rba-enabled-v2-user-flows.spec.js +13 -4
- package/dist/tests/8.9/test-setup.spec.js +57 -4
- package/dist/tests/8.9/utr-enabled-user-flows.spec.js +18 -0
- package/dist/tests/8.9/web-modeler-user-flows.spec.js +6 -2
- package/dist/utils/consoleApiHelpers.d.ts +2 -0
- package/dist/utils/consoleApiHelpers.js +50 -4
- package/dist/utils/resetSession.js +6 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ const roleAuthorizations_1 = require("../../utils/roleAuthorizations");
|
|
|
9
9
|
const expectTextWithRetry_1 = require("../../utils/assertionHelpers/expectTextWithRetry");
|
|
10
10
|
const expectTextWithPagination_1 = require("../../utils/assertionHelpers/expectTextWithPagination");
|
|
11
11
|
const users_1 = require("../../utils/users");
|
|
12
|
+
const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
|
|
12
13
|
const mainUser = (0, users_1.getTestUser)('twentySixthUser');
|
|
13
14
|
_8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
14
15
|
const clusterNames = {
|
|
@@ -18,6 +19,10 @@ _8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
|
18
19
|
'RBA On User Flow - Permission for Selected Processes Only': 'Fourth RBA V2 Cluster',
|
|
19
20
|
};
|
|
20
21
|
_8_9_1.test.beforeEach(async ({ page, homePage, clusterPage, loginPage, clusterDetailsPage, appsPage }, testInfo) => {
|
|
22
|
+
// Claimed here, not in each body: creating the cluster and waiting for
|
|
23
|
+
// it to come back Healthy after the authorizations toggle can outlast
|
|
24
|
+
// the default per-test timeout before the body starts.
|
|
25
|
+
_8_9_1.test.slow();
|
|
21
26
|
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, mainUser, (testInfo.workerIndex + 1) * 1000);
|
|
22
27
|
await (0, test_1.expect)(homePage.clusterTab).toBeVisible({ timeout: 120000 });
|
|
23
28
|
await homePage.clickClusters();
|
|
@@ -25,13 +30,20 @@ _8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
|
25
30
|
(0, test_1.expect)(clusterName, `No cluster mapping for test title: "${testInfo.title}")`).toBeTruthy();
|
|
26
31
|
await clusterPage.createClusterIfNotExists(clusterName);
|
|
27
32
|
await (0, UtilitiesPage_1.disableRBA)(clusterName, homePage, clusterPage, clusterDetailsPage, appsPage);
|
|
33
|
+
// The flows below hand off to test users with no elevated or DevOps org
|
|
34
|
+
// role, and Hub only lets those roles assign an environment to a
|
|
35
|
+
// workspace (camunda-hub#28955). Without this, the test user's deploy
|
|
36
|
+
// dialog never offers this cluster and every runProcessInstance retry
|
|
37
|
+
// fails until the test times out. Assign it now, while the elevated
|
|
38
|
+
// main user's session is active. test-setup creates the test users'
|
|
39
|
+
// workspaces up front so that they exist at this point.
|
|
40
|
+
await (0, consoleApiHelpers_1.linkClusterToWorkspacesNamedViaApi)(page, clusterName);
|
|
28
41
|
});
|
|
29
42
|
_8_9_1.test.afterEach(async ({ page }, testInfo) => {
|
|
30
43
|
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
31
44
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
32
45
|
});
|
|
33
46
|
(0, _8_9_1.test)('RBA On User Flow - No User Permission', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, taskPanelPage, taskProcessesPage, operateHomePage, ocIdentityHomePage, ocIdentityAuthorizationsPage, ocIdentityRolesPage, loginPage, settingsPage, }, testInfo) => {
|
|
34
|
-
_8_9_1.test.slow();
|
|
35
47
|
const clusterName = clusterNames[testInfo.title];
|
|
36
48
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
37
49
|
const processName = 'RBA_NO_PERM' + randomString;
|
|
@@ -137,7 +149,6 @@ _8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
|
137
149
|
});
|
|
138
150
|
});
|
|
139
151
|
(0, _8_9_1.test)('RBA On User Flow - Permission for One Process', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, taskPanelPage, taskProcessesPage, operateHomePage, loginPage, ocIdentityHomePage, ocIdentityAuthorizationsPage, ocIdentityRolesPage, settingsPage, }, testInfo) => {
|
|
140
|
-
_8_9_1.test.slow();
|
|
141
152
|
const clusterName = clusterNames[testInfo.title];
|
|
142
153
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
143
154
|
const processName = 'RBA_ONE_PERM' + randomString;
|
|
@@ -292,7 +303,6 @@ _8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
|
292
303
|
});
|
|
293
304
|
});
|
|
294
305
|
(0, _8_9_1.test)('RBA On User Flow - Permission for All Processes with Full Permissions', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, taskPanelPage, taskProcessesPage, operateHomePage, ocIdentityHomePage, ocIdentityAuthorizationsPage, }, testInfo) => {
|
|
295
|
-
_8_9_1.test.slow();
|
|
296
306
|
const clusterName = clusterNames[testInfo.title];
|
|
297
307
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
298
308
|
const processName = 'AFTER_RBA' + randomString;
|
|
@@ -361,7 +371,6 @@ _8_9_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () => {
|
|
|
361
371
|
});
|
|
362
372
|
});
|
|
363
373
|
(0, _8_9_1.test)('RBA On User Flow - Permission for Selected Processes Only', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, taskPanelPage, taskProcessesPage, operateHomePage, ocIdentityHomePage, ocIdentityAuthorizationsPage, ocIdentityRolesPage, loginPage, }, testInfo) => {
|
|
364
|
-
_8_9_1.test.slow();
|
|
365
374
|
const clusterName = clusterNames[testInfo.title];
|
|
366
375
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
367
376
|
const processName = 'RBA_SELECTED_PERM' + randomString;
|
|
@@ -123,11 +123,64 @@ _8_9_1.test.describe('Cluster Setup Tests', () => {
|
|
|
123
123
|
await clusterSecretsPage.createSetOfSecrets(clusterName, connectorSecrets_1.connectorSecretsValues);
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
// The RBA specs hand off to these developer-role users, who cannot assign an
|
|
127
|
+
// environment to a workspace (camunda-hub#28955). Their workspaces must exist
|
|
128
|
+
// before the RBA beforeEach links its cluster to them as the admin main user.
|
|
129
|
+
const rbaHandoffUsers = process.env.IS_AG === 'true' && process.env.RUN_FULL_SUITE !== 'true'
|
|
130
|
+
? []
|
|
131
|
+
: ['4', '5', '6']
|
|
132
|
+
.map((n) => ({
|
|
133
|
+
username: process.env[`C8_USERNAME_TEST_${n}`] ?? '',
|
|
134
|
+
password: process.env[`C8_PASSWORD_TEST_${n}`] ?? '',
|
|
135
|
+
title: `Create Project Folder for RBA hand-off user TEST_${n}`,
|
|
136
|
+
}))
|
|
137
|
+
.filter((user) => user.username !== '' && user.password !== '');
|
|
138
|
+
for (const [index, user] of [
|
|
139
|
+
...(0, users_1.getTestUsers)().map((u, i) => ({
|
|
140
|
+
...u,
|
|
141
|
+
title: `Create Project Folder for User ${i + 1}`,
|
|
142
|
+
})),
|
|
143
|
+
...rbaHandoffUsers,
|
|
144
|
+
].entries()) {
|
|
145
|
+
const isRbaHandoffUser = index >= (0, users_1.getTestUsers)().length;
|
|
146
|
+
(0, _8_9_1.test)(user.title, async ({ page, loginPage, homePage, appsPage, modelerHomePage }, testInfo) => {
|
|
147
|
+
const loggedIn = await _8_9_1.test.step('Log in', async () => {
|
|
148
|
+
// GitHub drops a create-organization job output whose value contains
|
|
149
|
+
// a masked secret, which leaves that slot's password empty. Only the
|
|
150
|
+
// specs that log in as this user need its workspace, and they fail
|
|
151
|
+
// on their own login with loginWithRetry's "no password" error.
|
|
152
|
+
if (index > 0 && user.username && !user.password) {
|
|
153
|
+
console.warn(`${user.title}: no password reached the runner`);
|
|
154
|
+
testInfo.annotations.push({
|
|
155
|
+
type: 'warning',
|
|
156
|
+
description: 'Password job output was dropped; no workspace',
|
|
157
|
+
});
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, user, (testInfo.workerIndex + 1) * 1000);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Every test depends on this setup project. A hand-off slot that
|
|
166
|
+
// this org did not provision (Auth0 rejected it in a PR run) must
|
|
167
|
+
// not block the whole suite; the RBA spec that logs in as that
|
|
168
|
+
// user fails on its own login instead.
|
|
169
|
+
if (!isRbaHandoffUser ||
|
|
170
|
+
!String(error).includes('AUTH0_INVALID_CREDENTIALS')) {
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
console.warn(`${user.title}: ${String(error)}`);
|
|
174
|
+
testInfo.annotations.push({
|
|
175
|
+
type: 'warning',
|
|
176
|
+
description: 'Auth0 rejected this hand-off user; no workspace',
|
|
177
|
+
});
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
130
180
|
});
|
|
181
|
+
if (!loggedIn) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
131
184
|
await _8_9_1.test.step('Navigate to Web Modeler', async () => {
|
|
132
185
|
// Camunda Hub replaced Console + Web Modeler on SaaS: it lands on the
|
|
133
186
|
// Modeler home directly and has no app switcher to wait for.
|
|
@@ -8,7 +8,9 @@ const sleep_1 = require("../../utils/sleep");
|
|
|
8
8
|
const expectTextWithRetry_1 = require("../../utils/assertionHelpers/expectTextWithRetry");
|
|
9
9
|
const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
|
|
10
10
|
const LoginPage_1 = require("../../pages/8.9/LoginPage");
|
|
11
|
+
const WorkspaceMembersPage_1 = require("../../pages/8.9/WorkspaceMembersPage");
|
|
11
12
|
const users_1 = require("../../utils/users");
|
|
13
|
+
const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
|
|
12
14
|
const mainUser = (0, users_1.getTestUser)('twelfthUser');
|
|
13
15
|
_8_9_1.test.describe.parallel('UTR Enabled User Flows Test @tasklistV1', () => {
|
|
14
16
|
const clusterName = 'Test Cluster';
|
|
@@ -129,6 +131,22 @@ _8_9_1.test.describe.parallel('UTR Enabled User Flows Test @tasklistV1', () => {
|
|
|
129
131
|
await ocIdentityGroupsPage.clickGroupId(groupNameMultiple);
|
|
130
132
|
await ocIdentityGroupsPage.assignUserToGroup(testUser2.username);
|
|
131
133
|
});
|
|
134
|
+
// Test user 1 is the org's Developer. Hub shows a non-admin only the
|
|
135
|
+
// environments assigned to a workspace they are Editor or Workspace Admin
|
|
136
|
+
// on (camunda-hub EnvironmentVisibilityResolver), so without this the
|
|
137
|
+
// Tasklist hand-off below finds no "Test Cluster" in the sidebar. Test
|
|
138
|
+
// user 2 is an org Admin and sees every environment already.
|
|
139
|
+
await _8_9_1.test.step('Grant Test User 1 Editor rights on a workspace with the cluster', async () => {
|
|
140
|
+
await appsPage.clickCamundaApps();
|
|
141
|
+
await appsPage.clickModeler();
|
|
142
|
+
await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
|
|
143
|
+
timeout: 120000,
|
|
144
|
+
});
|
|
145
|
+
const workspaceMembersPage = new WorkspaceMembersPage_1.WorkspaceMembersPage(page);
|
|
146
|
+
await workspaceMembersPage.openManageMembers('Cross Component Test Project');
|
|
147
|
+
await workspaceMembersPage.setMemberRole(testUser1.username, 'Editor');
|
|
148
|
+
await (0, consoleApiHelpers_1.linkClusterToWorkspaceViaApi)(page, workspaceMembersPage.workspaceId(), clusterName);
|
|
149
|
+
});
|
|
132
150
|
await _8_9_1.test.step('Navigate to Web Modeler', async () => {
|
|
133
151
|
await appsPage.clickCamundaApps();
|
|
134
152
|
await appsPage.clickModeler();
|
|
@@ -34,7 +34,9 @@ _8_9_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
34
34
|
await (0, mailSlurpClient_1.deleteInbox)(inboxes[testInfo.title]);
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
-
|
|
37
|
+
// Skipped due to bug #29346: https://github.com/camunda/camunda-hub/issues/29346
|
|
38
|
+
// Also tracked in https://github.com/camunda/product-hub/issues/3655
|
|
39
|
+
_8_9_1.test.skip('Form.js Integration with User Task and AI Generated Form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
38
40
|
_8_9_1.test.slow();
|
|
39
41
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
40
42
|
const processName = 'User_Task_Process_With_AI_Form' + randomString;
|
|
@@ -92,7 +94,9 @@ _8_9_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
92
94
|
await operateTabTaskDetailsPage.clickCompleteTaskButton();
|
|
93
95
|
});
|
|
94
96
|
});
|
|
95
|
-
|
|
97
|
+
// Skipped due to bug #29346: https://github.com/camunda/camunda-hub/issues/29346
|
|
98
|
+
// Also tracked in https://github.com/camunda/product-hub/issues/3655
|
|
99
|
+
_8_9_1.test.skip('Form.js Integration with AI generated Start form @ai-external', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
96
100
|
_8_9_1.test.slow();
|
|
97
101
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
98
102
|
const processName = 'AI-generated-Start-form' + randomString;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Page } from '@playwright/test';
|
|
2
|
+
export declare function observeBearerTokens(page: Page): void;
|
|
2
3
|
export declare function resetHubBearerToken(page: Page): void;
|
|
3
4
|
export declare function deleteClusterViaApi(page: Page, clusterName: string): Promise<void>;
|
|
4
5
|
export declare function createClusterViaApi(page: Page, clusterName: string, region?: string, tasklistV2Enabled?: boolean): Promise<string>;
|
|
@@ -13,4 +14,5 @@ export declare function linkClusterToWorkspaceViaApi(page: Page, workspaceId: st
|
|
|
13
14
|
export declare function rememberHubWorkspaceId(page: Page, workspaceId: string): void;
|
|
14
15
|
export declare function getHubWorkspaceId(page: Page): string | undefined;
|
|
15
16
|
export declare function linkClusterToSharedWorkspaceViaApi(page: Page, clusterName: string): Promise<void>;
|
|
17
|
+
export declare function linkClusterToWorkspacesNamedViaApi(page: Page, clusterName: string, workspaceName?: string): Promise<void>;
|
|
16
18
|
export declare function ensureClusterLinkedToSharedWorkspace(page: Page, clusterName: string): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureClusterLinkedToSharedWorkspace = exports.linkClusterToSharedWorkspaceViaApi = exports.getHubWorkspaceId = exports.rememberHubWorkspaceId = exports.linkClusterToWorkspaceViaApi = exports.waitForAiFeaturesEnabledViaApi = exports.areAiFeaturesEnabledViaApi = exports.waitForClusterRestartHealthyViaApi = exports.waitForClusterHealthyViaApi = exports.ensureClientAuditLoggingViaApi = exports.ensureTasklistV2Enabled = exports.ensureClusterViaApi = exports.createClusterViaApi = exports.deleteClusterViaApi = exports.resetHubBearerToken = void 0;
|
|
3
|
+
exports.ensureClusterLinkedToSharedWorkspace = exports.linkClusterToWorkspacesNamedViaApi = exports.linkClusterToSharedWorkspaceViaApi = exports.getHubWorkspaceId = exports.rememberHubWorkspaceId = exports.linkClusterToWorkspaceViaApi = exports.waitForAiFeaturesEnabledViaApi = exports.areAiFeaturesEnabledViaApi = exports.waitForClusterRestartHealthyViaApi = exports.waitForClusterHealthyViaApi = exports.ensureClientAuditLoggingViaApi = exports.ensureTasklistV2Enabled = exports.ensureClusterViaApi = exports.createClusterViaApi = exports.deleteClusterViaApi = exports.resetHubBearerToken = exports.observeBearerTokens = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const sleep_1 = require("./sleep");
|
|
6
6
|
const PLAN_TYPE_ID = '574cde5f-54ae-43c1-851a-e6fb4f03423a';
|
|
@@ -52,6 +52,9 @@ function bearerTokenOf(url, authorization) {
|
|
|
52
52
|
}
|
|
53
53
|
return authorization.slice('Bearer '.length);
|
|
54
54
|
}
|
|
55
|
+
// Exported so a login can start listening before Hub loads. Hub's Console
|
|
56
|
+
// pages go quiet once loaded (cluster updates arrive over one long-lived SSE
|
|
57
|
+
// request), so a first API call on an idle page otherwise sees no request.
|
|
55
58
|
function observeBearerTokens(page) {
|
|
56
59
|
if (tokenObservedPages.has(page)) {
|
|
57
60
|
return;
|
|
@@ -71,6 +74,7 @@ function observeBearerTokens(page) {
|
|
|
71
74
|
}
|
|
72
75
|
});
|
|
73
76
|
}
|
|
77
|
+
exports.observeBearerTokens = observeBearerTokens;
|
|
74
78
|
// Exported so LoginPage can call this before a new login begins. Without it,
|
|
75
79
|
// a page that signs in as a second user keeps answering getHubBearerToken()
|
|
76
80
|
// with the first user's cached token until some later console.cloud/
|
|
@@ -876,9 +880,23 @@ async function linkClusterToWorkspaceViaApi(page, workspaceId, clusterName) {
|
|
|
876
880
|
return;
|
|
877
881
|
}
|
|
878
882
|
const ids = [...new Set([...current.map((e) => e.id), backing.id])];
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
883
|
+
// Hub maps AccessDeniedException and an unresolvable path entity to a bare
|
|
884
|
+
// 404 (ExceptionHandlingAdvice). A PR run saw this PUT 404 once, right
|
|
885
|
+
// after the GET on the same workspace succeeded, and succeed on a retry.
|
|
886
|
+
// Bounded by count, not by toPass's timeout, which would also cut off
|
|
887
|
+
// clusterApiRequest's own 429/5xx backoff. A caller without cluster
|
|
888
|
+
// management access gets a 404 every time and fails below after 3 tries.
|
|
889
|
+
let response;
|
|
890
|
+
let notFoundCount = 0;
|
|
891
|
+
await (0, test_1.expect)(async () => {
|
|
892
|
+
response = await clusterApiRequest(page, 'PUT', url, {
|
|
893
|
+
environmentIds: ids,
|
|
894
|
+
});
|
|
895
|
+
if (response.status() === 404) {
|
|
896
|
+
notFoundCount++;
|
|
897
|
+
}
|
|
898
|
+
(0, test_1.expect)(response.status() !== 404 || notFoundCount >= 3, `PUT ${url} (linking "${clusterName}") returned 404`).toBe(true);
|
|
899
|
+
}).toPass({ intervals: [5000, 10000], timeout: 600000 });
|
|
882
900
|
if (!response.ok()) {
|
|
883
901
|
// clusterApiRequest returns non-2xx for non-transient statuses rather
|
|
884
902
|
// than throwing, so an unchecked call would log success and let the
|
|
@@ -946,6 +964,34 @@ async function linkClusterToSharedWorkspaceViaApi(page, clusterName) {
|
|
|
946
964
|
await linkClusterToWorkspaceViaApi(page, workspaceId, clusterName);
|
|
947
965
|
}
|
|
948
966
|
exports.linkClusterToSharedWorkspaceViaApi = linkClusterToSharedWorkspaceViaApi;
|
|
967
|
+
// Links `clusterName` to EVERY workspace named `workspaceName`, not just the
|
|
968
|
+
// first. Each test user creates its own "Cross Component Test Project"
|
|
969
|
+
// workspace in test-setup, and a user without an elevated or DevOps org role
|
|
970
|
+
// cannot assign an environment to it (camunda-hub#28955: the workspace
|
|
971
|
+
// Environments tab redirects to Members, and the PUT below is gated on
|
|
972
|
+
// hasClusterManagementAccess). A spec that creates a cluster as an elevated
|
|
973
|
+
// user and then hands off to such a user has to make the assignment up front,
|
|
974
|
+
// while the elevated session is still active.
|
|
975
|
+
async function linkClusterToWorkspacesNamedViaApi(page, clusterName, workspaceName = SHARED_HUB_WORKSPACE_NAME) {
|
|
976
|
+
const origin = await hubApiOrigin(page);
|
|
977
|
+
const response = await clusterApiRequest(page, 'GET', `${origin}/api/internal/v2/organizations/${encodeURIComponent(process.env.ORG_ID)}/workspaces?search=${encodeURIComponent(workspaceName)}&sort=name,asc&offset=0&limit=100`);
|
|
978
|
+
if (!response.ok()) {
|
|
979
|
+
throw new Error(`Failed to list workspaces named "${workspaceName}": ` +
|
|
980
|
+
`${response.status()} ${response.statusText()}`);
|
|
981
|
+
}
|
|
982
|
+
const body = (await response.json());
|
|
983
|
+
const data = (body.data ?? body);
|
|
984
|
+
const items = Array.isArray(data.items) ? data.items : [];
|
|
985
|
+
const workspaceIds = items
|
|
986
|
+
.map((item) => (item ?? {}))
|
|
987
|
+
.filter((item) => item.name === workspaceName)
|
|
988
|
+
.map((item) => item.id)
|
|
989
|
+
.filter((id) => typeof id === 'string');
|
|
990
|
+
for (const workspaceId of workspaceIds) {
|
|
991
|
+
await linkClusterToWorkspaceViaApi(page, workspaceId, clusterName);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
exports.linkClusterToWorkspacesNamedViaApi = linkClusterToWorkspacesNamedViaApi;
|
|
949
995
|
// Ensure-link at the point a deploy dialog is about to be opened. Resolves the
|
|
950
996
|
// workspace from the id remembered while the flow was on it, else by name.
|
|
951
997
|
// Cheap and idempotent: it returns early once the environment is assigned.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resetSessionAll = exports.resetSession = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
4
5
|
const consoleApiHelpers_1 = require("./consoleApiHelpers");
|
|
5
6
|
async function resetSession(browser, page) {
|
|
6
7
|
const context = browser.contexts()[0];
|
|
@@ -10,7 +11,11 @@ async function resetSession(browser, page) {
|
|
|
10
11
|
// session reset that re-authenticates as a different user must clear it
|
|
11
12
|
// too, or getUserToken() can return the previous user's cached token.
|
|
12
13
|
(0, consoleApiHelpers_1.resetHubBearerToken)(page);
|
|
13
|
-
|
|
14
|
+
// A logout just before this call can still be redirecting, which aborts
|
|
15
|
+
// the reload with net::ERR_ABORTED; retry until the page settles.
|
|
16
|
+
await (0, test_1.expect)(async () => {
|
|
17
|
+
await page.reload();
|
|
18
|
+
}).toPass({ timeout: 60000 });
|
|
14
19
|
await page.waitForLoadState('domcontentloaded');
|
|
15
20
|
await page.goto('/');
|
|
16
21
|
}
|