@camunda/e2e-test-suite 0.0.646 → 0.0.647
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.
|
@@ -100,7 +100,7 @@ class ClusterPage {
|
|
|
100
100
|
.filter({ hasNotText: 'Generation' }); //Filter out header row
|
|
101
101
|
this.tasklistV1Api = page.getByText('Tasklist API v1 (legacy)');
|
|
102
102
|
this.tasklistV2Api = page.getByText('Tasklist API v2');
|
|
103
|
-
this.cluster = (clusterName) => this.clustersList.filter({ hasText: clusterName });
|
|
103
|
+
this.cluster = (clusterName) => this.clustersList.filter({ hasText: clusterName }).first();
|
|
104
104
|
this.clusterHealthiness = (clusterName) => this.cluster(clusterName).getByText(`Healthy`, {
|
|
105
105
|
exact: true,
|
|
106
106
|
});
|
|
@@ -128,31 +128,39 @@ class ClusterPage {
|
|
|
128
128
|
});
|
|
129
129
|
while ((await deleteButtons.count()) > 0) {
|
|
130
130
|
const deleteButton = deleteButtons.nth(0);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 60000 });
|
|
141
|
-
await (0, test_1.expect)(this.confirmDeleteInput).toBeVisible({ timeout: 60000 });
|
|
142
|
-
await this.confirmDeleteInput.click({ force: true, timeout: 60000 });
|
|
143
|
-
await this.confirmDeleteInput.fill('DELETE', { timeout: 60000 });
|
|
144
|
-
const dangerDeleteButtons = await this.dangerDeleteButton.all();
|
|
145
|
-
const lastDangerDeleteButton = dangerDeleteButtons[dangerDeleteButtons.length - 1];
|
|
146
|
-
await lastDangerDeleteButton.click();
|
|
147
|
-
await (0, test_1.expect)(this.page.getByText('Deleting...')).not.toBeVisible({
|
|
148
|
-
timeout: 60000,
|
|
149
|
-
});
|
|
150
|
-
await (0, test_1.expect)(this.dialog).not.toBeVisible({ timeout: 60000 });
|
|
151
|
-
// Refresh the list of delete buttons
|
|
131
|
+
// Wait for the Delete button to become visible — a cluster in a transient
|
|
132
|
+
// state (e.g. just created by a concurrent setup worker) may have the row
|
|
133
|
+
// present in the DOM but the button not yet rendered. Without this wait
|
|
134
|
+
// the while-loop would spin forever since count() stays > 0.
|
|
135
|
+
try {
|
|
136
|
+
await (0, test_1.expect)(deleteButton).toBeVisible({ timeout: 10000 });
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
await this.page.reload({ waitUntil: 'domcontentloaded' }).catch(() => { });
|
|
152
140
|
deleteButtons = this.cluster(name).getByRole('button', {
|
|
153
141
|
name: 'Delete',
|
|
154
142
|
});
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
await deleteButton.click({ force: true, timeout: 60000 });
|
|
155
147
|
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
await this.clickClusterBanner();
|
|
150
|
+
await (0, test_1.expect)(deleteButton).toBeVisible({ timeout: 60000 });
|
|
151
|
+
await deleteButton.click({ force: true, timeout: 60000 });
|
|
152
|
+
}
|
|
153
|
+
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 60000 });
|
|
154
|
+
await (0, test_1.expect)(this.confirmDeleteInput).toBeVisible({ timeout: 60000 });
|
|
155
|
+
await this.confirmDeleteInput.click({ force: true, timeout: 60000 });
|
|
156
|
+
await this.confirmDeleteInput.fill('DELETE', { timeout: 60000 });
|
|
157
|
+
const dangerDeleteButtons = await this.dangerDeleteButton.all();
|
|
158
|
+
const lastDangerDeleteButton = dangerDeleteButtons[dangerDeleteButtons.length - 1];
|
|
159
|
+
await lastDangerDeleteButton.click();
|
|
160
|
+
await (0, test_1.expect)(this.cluster(name).getByText('Deleting...', { exact: true })).not.toBeVisible({ timeout: 60000 });
|
|
161
|
+
await (0, test_1.expect)(this.dialog).not.toBeVisible({ timeout: 60000 });
|
|
162
|
+
// Refresh the list of delete buttons
|
|
163
|
+
deleteButtons = this.cluster(name).getByRole('button', { name: 'Delete' });
|
|
156
164
|
}
|
|
157
165
|
await this.page.waitForTimeout(500);
|
|
158
166
|
}
|
|
@@ -201,6 +209,12 @@ class ClusterPage {
|
|
|
201
209
|
async createCluster(name, region = 'GCP', tasklistV1Api) {
|
|
202
210
|
await this.clickClusterTab();
|
|
203
211
|
await this.deleteCluster(name);
|
|
212
|
+
// A concurrent setup worker (e.g. another version's test suite running in
|
|
213
|
+
// the same org) may have created a same-named cluster in the window between
|
|
214
|
+
// our deleteCluster check and now. Reload and delete again to catch it.
|
|
215
|
+
await this.page.waitForTimeout(3000);
|
|
216
|
+
await this.page.reload({ waitUntil: 'domcontentloaded' }).catch(() => { });
|
|
217
|
+
await this.deleteCluster(name);
|
|
204
218
|
await this.clickCreateNewClusterButton();
|
|
205
219
|
await this.clickClusterNameInput();
|
|
206
220
|
await this.fillClusterNameInput(name);
|
|
@@ -235,22 +249,18 @@ class ClusterPage {
|
|
|
235
249
|
await this.createClusterButton.click();
|
|
236
250
|
}
|
|
237
251
|
async clickClustersBreadcrumb(clusterName) {
|
|
238
|
-
const
|
|
239
|
-
const
|
|
252
|
+
const clusterRow = this.cluster(clusterName);
|
|
253
|
+
const clusterRowVisible = clusterRow
|
|
254
|
+
.getByText('Creating', { exact: true })
|
|
255
|
+
.or(clusterRow.getByText('Healthy', { exact: true }));
|
|
240
256
|
try {
|
|
241
257
|
await (0, test_1.expect)(this.clustersBreadcrumb).toBeVisible({ timeout: 60000 });
|
|
242
258
|
await this.clustersBreadcrumb.click({ timeout: 60000 });
|
|
243
|
-
await (0, test_1.expect)(
|
|
244
|
-
timeout: 30000,
|
|
245
|
-
});
|
|
259
|
+
await (0, test_1.expect)(clusterRow.getByText('Creating', { exact: true })).toBeVisible({ timeout: 30000 });
|
|
246
260
|
}
|
|
247
261
|
catch (error) {
|
|
248
262
|
await this.clickClusterBanner();
|
|
249
|
-
await (0, test_1.expect)(
|
|
250
|
-
.getByText(creatingCheckRegex)
|
|
251
|
-
.or(this.page.getByText(healthyCheckRegex))).toBeVisible({
|
|
252
|
-
timeout: 30000,
|
|
253
|
-
});
|
|
263
|
+
await (0, test_1.expect)(clusterRowVisible).toBeVisible({ timeout: 30000 });
|
|
254
264
|
}
|
|
255
265
|
}
|
|
256
266
|
async clickClusterLink(name) {
|
|
@@ -1023,6 +1023,61 @@ class ModelerCreatePage {
|
|
|
1023
1023
|
}
|
|
1024
1024
|
async completePlayConfiguration(clusterName) {
|
|
1025
1025
|
const timeout = 30000;
|
|
1026
|
+
// New flow (8.10+): "Setup environment" panel with three steps:
|
|
1027
|
+
// 1. Connect cluster → "Configure environment" modal → select cluster → Save
|
|
1028
|
+
// 2. Deploy process → wait for success banner
|
|
1029
|
+
// 3. Configure scenario
|
|
1030
|
+
const setupDeployButton = this.page
|
|
1031
|
+
.getByText('Deploy process')
|
|
1032
|
+
.locator('..')
|
|
1033
|
+
.getByRole('button', { name: 'Deploy' });
|
|
1034
|
+
const configureScenarioButton = this.page.getByRole('button', {
|
|
1035
|
+
name: 'Configure scenario',
|
|
1036
|
+
});
|
|
1037
|
+
// Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
|
|
1038
|
+
// button to appear. Using .or() avoids separate sequential timeouts that would
|
|
1039
|
+
// both expire before the page finishes loading on a slow cluster.
|
|
1040
|
+
const setupOrContinue = setupDeployButton.or(this.continueToPlayButton);
|
|
1041
|
+
const panelAppeared = await setupOrContinue
|
|
1042
|
+
.first()
|
|
1043
|
+
.isVisible({ timeout: 15000 })
|
|
1044
|
+
.catch(() => false);
|
|
1045
|
+
if (!panelAppeared) {
|
|
1046
|
+
// Neither appeared — Play is already configured and ready.
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const isNewFlow = await setupDeployButton.isVisible().catch(() => false);
|
|
1050
|
+
if (isNewFlow) {
|
|
1051
|
+
// Step 1: connect cluster if not yet connected (modal with cluster dropdown)
|
|
1052
|
+
const connectClusterButton = this.page.getByRole('button', {
|
|
1053
|
+
name: 'Connect cluster',
|
|
1054
|
+
});
|
|
1055
|
+
const needsConnect = await connectClusterButton
|
|
1056
|
+
.isVisible({ timeout: 3000 })
|
|
1057
|
+
.catch(() => false);
|
|
1058
|
+
if (needsConnect) {
|
|
1059
|
+
await connectClusterButton.click({ timeout });
|
|
1060
|
+
const configureEnvDialog = this.page
|
|
1061
|
+
.getByRole('dialog')
|
|
1062
|
+
.filter({ hasText: 'Configure environment' });
|
|
1063
|
+
await configureEnvDialog.getByRole('combobox').click({ timeout });
|
|
1064
|
+
await this.page
|
|
1065
|
+
.getByRole('option', { name: new RegExp(clusterName, 'i') })
|
|
1066
|
+
.click({ timeout });
|
|
1067
|
+
await configureEnvDialog
|
|
1068
|
+
.getByRole('button', { name: 'Save' })
|
|
1069
|
+
.click({ timeout });
|
|
1070
|
+
}
|
|
1071
|
+
// Step 2: deploy — wait for enabled; button stays disabled until the cluster
|
|
1072
|
+
// connection is confirmed by the backend after the Save in step 1.
|
|
1073
|
+
await (0, test_1.expect)(setupDeployButton).toBeEnabled({ timeout: 30000 });
|
|
1074
|
+
await setupDeployButton.click({ timeout });
|
|
1075
|
+
await (0, test_1.expect)(this.page.getByText('Process has been successfully deployed')).toBeVisible({ timeout: 90000 });
|
|
1076
|
+
// Step 3: configure scenario
|
|
1077
|
+
await configureScenarioButton.click({ timeout });
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
// Legacy flow: select cluster via dialog, then click Continue.
|
|
1026
1081
|
let attempts = 0;
|
|
1027
1082
|
const maxRetries = 2;
|
|
1028
1083
|
while (attempts < maxRetries) {
|
|
@@ -62,9 +62,9 @@ class ModelerHomePage {
|
|
|
62
62
|
this.homeBreadcrumb = page.locator('[data-test="breadcrumb-home"]');
|
|
63
63
|
this.openOrganizationsButton = page.getByLabel('Open Organizations');
|
|
64
64
|
this.manageButton = page.getByRole('menuitem', { name: 'Manage' });
|
|
65
|
-
this.crossComponentProjectFolder = page
|
|
66
|
-
exact: true
|
|
67
|
-
|
|
65
|
+
this.crossComponentProjectFolder = page
|
|
66
|
+
.getByTitle(this.defaultFolderName, { exact: true })
|
|
67
|
+
.first();
|
|
68
68
|
this.rows = page.getByRole('row');
|
|
69
69
|
this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
|
|
70
70
|
this.messageBanner = page.locator('[data-test="close-top-banner"]');
|