@camunda/e2e-test-suite 0.0.822 → 0.0.824
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.10/ClusterPage.js +4 -1
- package/dist/pages/8.10/FormJsPage.js +1 -1
- package/dist/pages/8.10/HomePage.js +5 -1
- package/dist/pages/8.10/ModelerCreatePage.js +8 -7
- package/dist/pages/8.10/ModelerHomePage.js +2 -2
- package/dist/tests/8.10/console-user-flows.spec.js +11 -0
- package/dist/tests/8.10/test-setup.spec.js +24 -11
- package/dist/tests/c8Run-8.10/connectors-user-flows.spec.js +1 -1
- package/dist/tests/c8Run-8.10/mcp-connector-authentication.spec.js +1 -1
- package/dist/tests/c8Run-8.10/mcp-user-flows.spec.js +1 -1
- package/dist/utils/consoleApiHelpers.d.ts +4 -0
- package/dist/utils/consoleApiHelpers.js +142 -0
- package/package.json +1 -1
|
@@ -102,12 +102,15 @@ class ClusterPage {
|
|
|
102
102
|
.filter({ hasNotText: 'Generation' }); //Filter out header row
|
|
103
103
|
this.tasklistV1Api = page.getByText('Tasklist API v1 (legacy)');
|
|
104
104
|
this.tasklistV2Api = page.getByText('Tasklist API v2');
|
|
105
|
-
this.cluster = (clusterName) => this.clustersList.filter({
|
|
105
|
+
this.cluster = (clusterName) => this.clustersList.filter({
|
|
106
|
+
has: page.getByRole('link', { name: clusterName, exact: true }),
|
|
107
|
+
});
|
|
106
108
|
this.clusterHealthiness = (clusterName) => this.cluster(clusterName).getByText(`Healthy`, {
|
|
107
109
|
exact: true,
|
|
108
110
|
});
|
|
109
111
|
this.clusterLink = (clusterName) => this.cluster(clusterName).getByRole('link', {
|
|
110
112
|
name: clusterName,
|
|
113
|
+
exact: true,
|
|
111
114
|
});
|
|
112
115
|
this.dialog = page.getByRole('dialog');
|
|
113
116
|
this.clusterVersion = (clusterName, versionText) => this.cluster(clusterName).getByText(versionText, { exact: false });
|
|
@@ -126,7 +126,7 @@ class FormJsPage {
|
|
|
126
126
|
await cluster.click();
|
|
127
127
|
await (0, test_1.expect)(this.dialog
|
|
128
128
|
.locator('label')
|
|
129
|
-
.filter({ hasText: clusterName })
|
|
129
|
+
.filter({ hasText: new RegExp(`^${clusterName}`) })
|
|
130
130
|
.getByRole('switch')).toBeChecked({ timeout: 30000 });
|
|
131
131
|
await (0, test_1.expect)(this.dialog).toHaveText(healthyRegex, {
|
|
132
132
|
timeout: healthCheckTimeout,
|
|
@@ -109,7 +109,11 @@ class HomePage {
|
|
|
109
109
|
await (0, test_1.expect)(this.buttonSkipCustomization).toBeVisible({
|
|
110
110
|
timeout: 30000,
|
|
111
111
|
});
|
|
112
|
-
|
|
112
|
+
// Best-effort: dismiss any Carbon modal that has a named close button.
|
|
113
|
+
await this.closeInformationDialog();
|
|
114
|
+
// force: true bypasses the "pointer events intercepted by modal backdrop"
|
|
115
|
+
// check — the same pattern used by closeInformationDialog itself.
|
|
116
|
+
await this.buttonSkipCustomization.click({ timeout: 60000, force: true });
|
|
113
117
|
await this.closeInformationDialog();
|
|
114
118
|
return;
|
|
115
119
|
}
|
|
@@ -610,13 +610,14 @@ class ModelerCreatePage {
|
|
|
610
610
|
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 30000 });
|
|
611
611
|
const healthCheckTimeout = 30000;
|
|
612
612
|
const healthyRegex = new RegExp(`${clusterName}.*?HealthydevManage`);
|
|
613
|
-
const
|
|
614
|
-
await (0, test_1.expect)(cluster).toBeVisible({ timeout: 30000 });
|
|
615
|
-
await cluster.click();
|
|
616
|
-
await (0, test_1.expect)(this.dialog
|
|
613
|
+
const clusterLabel = this.dialog
|
|
617
614
|
.locator('label')
|
|
618
|
-
.filter({ hasText: clusterName })
|
|
619
|
-
|
|
615
|
+
.filter({ hasText: new RegExp(`^${clusterName}`) });
|
|
616
|
+
await (0, test_1.expect)(clusterLabel).toBeVisible({ timeout: 30000 });
|
|
617
|
+
await clusterLabel.click();
|
|
618
|
+
await (0, test_1.expect)(clusterLabel.getByRole('switch')).toBeChecked({
|
|
619
|
+
timeout: 30000,
|
|
620
|
+
});
|
|
620
621
|
await (0, test_1.expect)(this.dialog).toHaveText(healthyRegex, {
|
|
621
622
|
timeout: healthCheckTimeout,
|
|
622
623
|
});
|
|
@@ -1130,7 +1131,7 @@ class ModelerCreatePage {
|
|
|
1130
1131
|
// before saving. This handles environments with multiple clusters.
|
|
1131
1132
|
const clusterLabel = configureEnvDialog
|
|
1132
1133
|
.locator('label')
|
|
1133
|
-
.filter({ hasText: clusterName });
|
|
1134
|
+
.filter({ hasText: new RegExp(`^${clusterName}`) });
|
|
1134
1135
|
const clusterSwitch = clusterLabel.getByRole('switch');
|
|
1135
1136
|
await (0, test_1.expect)(clusterLabel).toBeVisible({ timeout });
|
|
1136
1137
|
const alreadyChecked = (await clusterSwitch.getAttribute('aria-checked')) === 'true';
|
|
@@ -264,7 +264,7 @@ class ModelerHomePage {
|
|
|
264
264
|
async selectCluster(clusterName) {
|
|
265
265
|
//Select the correct cluster if multiple exist
|
|
266
266
|
const baseClusterName = clusterName.split('(')[0].trim();
|
|
267
|
-
const cluster = this.dialog.getByText(
|
|
267
|
+
const cluster = this.dialog.getByText(new RegExp(`^${baseClusterName}`));
|
|
268
268
|
await (0, test_1.expect)(cluster).toBeVisible({
|
|
269
269
|
timeout: 30000,
|
|
270
270
|
});
|
|
@@ -272,7 +272,7 @@ class ModelerHomePage {
|
|
|
272
272
|
await (0, test_1.expect)(this.dialog
|
|
273
273
|
.locator('label')
|
|
274
274
|
.filter({
|
|
275
|
-
hasText: clusterName,
|
|
275
|
+
hasText: new RegExp(`^${clusterName}`),
|
|
276
276
|
})
|
|
277
277
|
.getByRole('switch')).toBeChecked({ timeout: 30000 });
|
|
278
278
|
}
|
|
@@ -66,6 +66,17 @@ _8_10_1.test.describe('Console User Flow Tests @tasklistV2', () => {
|
|
|
66
66
|
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(operateTabProcessInstancePage, operateTabProcessInstancePage.completedIcon, 'completed icon in Operate', 60000);
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
|
+
(0, _8_10_1.test)('Create Cluster', async ({ homePage, clusterPage }) => {
|
|
70
|
+
_8_10_1.test.slow();
|
|
71
|
+
const newClusterName = 'UI Test Cluster';
|
|
72
|
+
await _8_10_1.test.step('Navigate to clusters and create cluster', async () => {
|
|
73
|
+
await homePage.clickClusters();
|
|
74
|
+
await clusterPage.createCluster(newClusterName);
|
|
75
|
+
});
|
|
76
|
+
await _8_10_1.test.step('Assert cluster is healthy', async () => {
|
|
77
|
+
await clusterPage.assertClusterHealthyStatusWithRetry(newClusterName, 300000, 1500000);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
69
80
|
//Waiting infra team to provide DNS configuration for email testing, skipping for now
|
|
70
81
|
_8_10_1.test.skip('Alert Trigger Flow - Email Notification', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, connectorSettingsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
71
82
|
_8_10_1.test.slow();
|
|
@@ -7,6 +7,7 @@ const connectorSecrets_1 = require("../../utils/connectorSecrets");
|
|
|
7
7
|
const mcpSecrets_1 = require("../../utils/mcpSecrets");
|
|
8
8
|
const UtilitiesPage_1 = require("../../pages/8.10/UtilitiesPage");
|
|
9
9
|
const users_1 = require("../../utils/users");
|
|
10
|
+
const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
|
|
10
11
|
_8_10_1.test.describe.configure({ mode: 'parallel' });
|
|
11
12
|
_8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
12
13
|
_8_10_1.test.afterEach(async ({ page }, testInfo) => {
|
|
@@ -26,9 +27,16 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
26
27
|
const clusterName = 'Test Cluster';
|
|
27
28
|
const apiClientName = 'Test_API_Client' + (await (0, _setup_1.generateRandomStringAsync)(3));
|
|
28
29
|
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, users_1.testUsers.mainUser, (testInfo.workerIndex + 1) * 1000);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (process.env.IS_PROD === 'true') {
|
|
31
|
+
await clusterPage.createCluster(clusterName);
|
|
32
|
+
await clusterPage.assertClusterHealthyStatusWithRetry(clusterName, 120000, 1500000);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await (0, consoleApiHelpers_1.deleteClusterViaApi)(page, clusterName);
|
|
36
|
+
const clusterUuid = await (0, consoleApiHelpers_1.createClusterViaApi)(page, clusterName);
|
|
37
|
+
await (0, consoleApiHelpers_1.waitForClusterHealthyViaApi)(page, clusterUuid);
|
|
38
|
+
await homePage.clickClusters();
|
|
39
|
+
}
|
|
32
40
|
await clusterPage.clickClusterLink(clusterName);
|
|
33
41
|
await clusterDetailsPage.assertComponentsHealth();
|
|
34
42
|
if (process.env.IS_AG !== 'true') {
|
|
@@ -55,9 +63,10 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
55
63
|
const apiClientName = 'Test_API_Client' + (await (0, _setup_1.generateRandomStringAsync)(3));
|
|
56
64
|
const mcpClientName = 'MCP_Test_API_Client' + (await (0, _setup_1.generateRandomStringAsync)(3));
|
|
57
65
|
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, users_1.testUsers.mainUser, (testInfo.workerIndex + 1) * 1000);
|
|
66
|
+
await (0, consoleApiHelpers_1.deleteClusterViaApi)(page, clusterName);
|
|
67
|
+
const clusterUuid = await (0, consoleApiHelpers_1.createClusterViaApi)(page, clusterName);
|
|
68
|
+
await (0, consoleApiHelpers_1.waitForClusterHealthyViaApi)(page, clusterUuid, 1500000);
|
|
58
69
|
await homePage.clickClusters();
|
|
59
|
-
await clusterPage.createCluster(clusterName);
|
|
60
|
-
await clusterPage.assertClusterHealthyStatusWithRetry(clusterName, 300000, 1500000);
|
|
61
70
|
await clusterPage.clickClusterLink(clusterName);
|
|
62
71
|
await clusterDetailsPage.assertComponentsHealth();
|
|
63
72
|
await auditLogPage.clickAuditLogTab();
|
|
@@ -79,12 +88,16 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
|
|
|
79
88
|
_8_10_1.test.slow();
|
|
80
89
|
const clusterName = 'AWS Cluster';
|
|
81
90
|
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, users_1.testUsers.mainUser, (testInfo.workerIndex + 1) * 1000);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
if (process.env.IS_PROD === 'true') {
|
|
92
|
+
await clusterPage.createCluster(clusterName, 'AWS');
|
|
93
|
+
await clusterPage.assertClusterHealthyStatusWithRetry(clusterName, 120000, 1500000);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
await (0, consoleApiHelpers_1.deleteClusterViaApi)(page, clusterName);
|
|
97
|
+
const clusterUuid = await (0, consoleApiHelpers_1.createClusterViaApi)(page, clusterName, 'AWS');
|
|
98
|
+
await (0, consoleApiHelpers_1.waitForClusterHealthyViaApi)(page, clusterUuid, 1500000);
|
|
99
|
+
await homePage.clickClusters();
|
|
100
|
+
}
|
|
88
101
|
await clusterPage.clickClusterLink(clusterName);
|
|
89
102
|
await clusterDetailsPage.assertComponentsHealth();
|
|
90
103
|
if (process.env.IS_AG !== 'true') {
|
|
@@ -9,7 +9,7 @@ const sleep_1 = require("../../utils/sleep");
|
|
|
9
9
|
const constants_1 = require("../../utils/constants");
|
|
10
10
|
const apiHelpers_1 = require("../../utils/apiHelpers");
|
|
11
11
|
c8Run_8_10_1.test.beforeAll(async () => {
|
|
12
|
-
await (0, apiHelpers_1.waitForConnectorsReady)();
|
|
12
|
+
await (0, apiHelpers_1.waitForConnectorsReady)(undefined, 600000);
|
|
13
13
|
await Promise.all([
|
|
14
14
|
(0, zeebeClient_1.deploy)('./resources/Basic_Auth_REST_Connector.bpmn'),
|
|
15
15
|
(0, zeebeClient_1.deploy)('./resources/Intermediate_Event_Webhook_Connector_No_Auth_Process.bpmn'),
|
|
@@ -31,7 +31,7 @@ c8Run_8_10_1.test.beforeAll(async () => {
|
|
|
31
31
|
await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12001'); // No auth
|
|
32
32
|
await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12002'); // Basic auth
|
|
33
33
|
await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12004'); // OAuth
|
|
34
|
-
await (0, apiHelpers_1.waitForConnectorsReady)();
|
|
34
|
+
await (0, apiHelpers_1.waitForConnectorsReady)(undefined, 600000);
|
|
35
35
|
await (0, keycloakHelpers_1.validateKeycloakHealth)();
|
|
36
36
|
bearerToken = await (0, keycloakHelpers_1.getAccessToken)();
|
|
37
37
|
await (0, zeebeClient_1.deploy)([
|
|
@@ -12,7 +12,7 @@ c8Run_8_10_1.test.beforeAll(async () => {
|
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
await (0, apiHelpers_1.validateMcpServerHealth)();
|
|
15
|
-
await (0, apiHelpers_1.waitForConnectorsReady)();
|
|
15
|
+
await (0, apiHelpers_1.waitForConnectorsReady)(undefined, 600000);
|
|
16
16
|
await (0, zeebeClient_1.deploy)(['./resources/mcp_server/mcp_remote_client_operations.bpmn']);
|
|
17
17
|
await (0, zeebeClient_1.createInstances)('mcp_remote_client', 1, 1);
|
|
18
18
|
await (0, sleep_1.sleep)(2000);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Page } from '@playwright/test';
|
|
2
|
+
export declare function deleteClusterViaApi(page: Page, clusterName: string): Promise<void>;
|
|
3
|
+
export declare function createClusterViaApi(page: Page, clusterName: string, region?: string): Promise<string>;
|
|
4
|
+
export declare function waitForClusterHealthyViaApi(page: Page, clusterUuid: string, timeoutMs?: number): Promise<void>;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.waitForClusterHealthyViaApi = exports.createClusterViaApi = exports.deleteClusterViaApi = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
const sleep_1 = require("./sleep");
|
|
6
|
+
const PLAN_TYPE_ID = '574cde5f-54ae-43c1-851a-e6fb4f03423a';
|
|
7
|
+
const CHANNEL_ID = 'cf355219-cc2d-4266-83e1-2430998ddf30';
|
|
8
|
+
const GCP_REGION_ID = 'a6fadf1d-b2a0-44ab-b301-2f9aaf6681dc';
|
|
9
|
+
const AWS_REGION_ID = '30fcdd4f-05d7-1c7a-54df-8d9defbd250f';
|
|
10
|
+
const GENERATION_MAP = {
|
|
11
|
+
'8.10': '7df47bbb-8665-4598-b12b-f53338d4aff0',
|
|
12
|
+
'8.9': '32478fdf-dbea-47b9-abe2-e9cbfc6c4324',
|
|
13
|
+
'8.8': '7ff71498-dc2d-486f-9baa-e46b7b503c89',
|
|
14
|
+
'8.7': 'd7ab8eef-9dd2-4b61-8142-fb1e7eea6710',
|
|
15
|
+
};
|
|
16
|
+
function getConsoleBaseUrl() {
|
|
17
|
+
if (process.env.IS_PROD === 'true') {
|
|
18
|
+
return 'https://console.cloud.camunda.io';
|
|
19
|
+
}
|
|
20
|
+
// PLAYWRIGHT_BASE_URL is the UI hostname (console.ultrawombat.com); the actual
|
|
21
|
+
// API backend lives at console.cloud.ultrawombat.com — map accordingly.
|
|
22
|
+
const uiUrl = process.env.PLAYWRIGHT_BASE_URL ?? 'https://console.ultrawombat.com';
|
|
23
|
+
return uiUrl
|
|
24
|
+
.replace('console.ultrawombat.com', 'console.cloud.ultrawombat.com')
|
|
25
|
+
.replace('console.camunda.io', 'console.cloud.camunda.io');
|
|
26
|
+
}
|
|
27
|
+
function getOrgId() {
|
|
28
|
+
const orgId = process.env.ORG_ID;
|
|
29
|
+
if (!orgId)
|
|
30
|
+
throw new Error('ORG_ID env var is not set');
|
|
31
|
+
return orgId;
|
|
32
|
+
}
|
|
33
|
+
// Auth0 SPA JS stores tokens in localStorage under keys starting with @@auth0spajs@@
|
|
34
|
+
// cacheLocation: 'localstorage' is configured in the Console frontend auth store
|
|
35
|
+
async function getUserToken(page) {
|
|
36
|
+
const token = await page.evaluate(() => {
|
|
37
|
+
for (const key of Object.keys(localStorage)) {
|
|
38
|
+
if (key.startsWith('@@auth0spajs@@')) {
|
|
39
|
+
try {
|
|
40
|
+
const data = JSON.parse(localStorage.getItem(key) ?? '');
|
|
41
|
+
if (data?.body?.access_token)
|
|
42
|
+
return data.body.access_token;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// skip malformed entries
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
});
|
|
51
|
+
if (!token) {
|
|
52
|
+
throw new Error('Could not extract access token from browser localStorage — ' +
|
|
53
|
+
'ensure loginWithRetry has been called before any cluster API operations');
|
|
54
|
+
}
|
|
55
|
+
return token;
|
|
56
|
+
}
|
|
57
|
+
async function findClusterByName(page, clusterName) {
|
|
58
|
+
const token = await getUserToken(page);
|
|
59
|
+
const orgId = getOrgId();
|
|
60
|
+
const response = await page.request.get(`${getConsoleBaseUrl()}/api/orgs/${orgId}/clusters`, { headers: { Authorization: `Bearer ${token}` } });
|
|
61
|
+
if (response.status() !== 200)
|
|
62
|
+
return undefined;
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
64
|
+
let data;
|
|
65
|
+
try {
|
|
66
|
+
data = await response.json();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const clusters = Array.isArray(data)
|
|
72
|
+
? data
|
|
73
|
+
: data.clusters ?? [];
|
|
74
|
+
return clusters.find((c) => c.name === clusterName);
|
|
75
|
+
}
|
|
76
|
+
async function deleteClusterViaApi(page, clusterName) {
|
|
77
|
+
const cluster = await findClusterByName(page, clusterName);
|
|
78
|
+
if (!cluster)
|
|
79
|
+
return;
|
|
80
|
+
const token = await getUserToken(page);
|
|
81
|
+
const orgId = getOrgId();
|
|
82
|
+
await page.request.delete(`${getConsoleBaseUrl()}/api/orgs/${orgId}/clusters/${cluster.uuid}`, { headers: { Authorization: `Bearer ${token}` } });
|
|
83
|
+
await (0, sleep_1.sleep)(5000);
|
|
84
|
+
}
|
|
85
|
+
exports.deleteClusterViaApi = deleteClusterViaApi;
|
|
86
|
+
async function resolveGenerationId() {
|
|
87
|
+
const rawVersion = process.env.CLUSTER_VERSION ?? '';
|
|
88
|
+
const minorVersion = rawVersion.match(/^(\d+\.\d+)/)?.[1] ?? rawVersion;
|
|
89
|
+
const generationId = GENERATION_MAP[minorVersion];
|
|
90
|
+
if (generationId)
|
|
91
|
+
return generationId;
|
|
92
|
+
throw new Error(`No generation UUID found for CLUSTER_VERSION="${rawVersion}" ` +
|
|
93
|
+
`(resolved minor: "${minorVersion}"). ` +
|
|
94
|
+
`Known versions: ${Object.keys(GENERATION_MAP).join(', ')}`);
|
|
95
|
+
}
|
|
96
|
+
async function createClusterViaApi(page, clusterName, region = 'GCP') {
|
|
97
|
+
const token = await getUserToken(page);
|
|
98
|
+
const orgId = getOrgId();
|
|
99
|
+
const generationId = await resolveGenerationId();
|
|
100
|
+
const k8sContextId = region.toUpperCase() === 'AWS' ? AWS_REGION_ID : GCP_REGION_ID;
|
|
101
|
+
const createResponse = await page.request.post(`${getConsoleBaseUrl()}/api/orgs/${orgId}/clusters`, {
|
|
102
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
103
|
+
data: {
|
|
104
|
+
name: clusterName,
|
|
105
|
+
planTypeId: PLAN_TYPE_ID,
|
|
106
|
+
channelId: CHANNEL_ID,
|
|
107
|
+
generationId,
|
|
108
|
+
k8sContextId,
|
|
109
|
+
autoUpdate: true,
|
|
110
|
+
stageLabel: 'dev',
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
if (createResponse.status() !== 200 && createResponse.status() !== 201) {
|
|
114
|
+
throw new Error(`Failed to create cluster "${clusterName}": ` +
|
|
115
|
+
`HTTP ${createResponse.status()} - ${await createResponse.text()}`);
|
|
116
|
+
}
|
|
117
|
+
const result = await createResponse.json();
|
|
118
|
+
const clusterId = result.clusterId ??
|
|
119
|
+
result.uuid ??
|
|
120
|
+
result.data?.cluster?.uuid ??
|
|
121
|
+
result.data?.clusterId;
|
|
122
|
+
if (!clusterId) {
|
|
123
|
+
throw new Error(`Cluster creation response missing UUID: ${JSON.stringify(result)}`);
|
|
124
|
+
}
|
|
125
|
+
return clusterId;
|
|
126
|
+
}
|
|
127
|
+
exports.createClusterViaApi = createClusterViaApi;
|
|
128
|
+
async function waitForClusterHealthyViaApi(page, clusterUuid, timeoutMs = 1500000) {
|
|
129
|
+
const orgId = getOrgId();
|
|
130
|
+
const url = `${getConsoleBaseUrl()}/api/orgs/${orgId}/clusters/${clusterUuid}`;
|
|
131
|
+
await (0, test_1.expect)(async () => {
|
|
132
|
+
const token = await getUserToken(page);
|
|
133
|
+
const response = await page.request.get(url, {
|
|
134
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
135
|
+
});
|
|
136
|
+
(0, test_1.expect)(response.status()).toBe(200);
|
|
137
|
+
const data = await response.json();
|
|
138
|
+
const cluster = data.data ?? data;
|
|
139
|
+
(0, test_1.expect)(cluster.status?.ready).toBe('Healthy');
|
|
140
|
+
}).toPass({ timeout: timeoutMs, intervals: [30000, 60000] });
|
|
141
|
+
}
|
|
142
|
+
exports.waitForClusterHealthyViaApi = waitForClusterHealthyViaApi;
|