@camunda/e2e-test-suite 0.0.1388 → 0.0.1390
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.
|
@@ -132,7 +132,12 @@ class ClusterPage {
|
|
|
132
132
|
// deleteCluster needs it -- while everything that means "the one cluster
|
|
133
133
|
// under test" goes through this single row, so a duplicate can no longer
|
|
134
134
|
// turn an ordinary visibility check into a strict-mode violation.
|
|
135
|
-
|
|
135
|
+
// createCluster's pre-clean leaves same-named rows in "Deleting" for
|
|
136
|
+
// minutes, and they can sort above the new cluster; that row never shows
|
|
137
|
+
// Creating/Healthy, so it must not be picked as the cluster under test.
|
|
138
|
+
this.clusterRow = (clusterName) => this.cluster(clusterName)
|
|
139
|
+
.filter({ hasNotText: /Deleting/ })
|
|
140
|
+
.first();
|
|
136
141
|
this.clusterHealthiness = (clusterName) => this.clusterRow(clusterName).getByText(`Healthy`, {
|
|
137
142
|
exact: true,
|
|
138
143
|
});
|
|
@@ -203,35 +208,104 @@ class ClusterPage {
|
|
|
203
208
|
}
|
|
204
209
|
}
|
|
205
210
|
async deleteCluster(name) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
// A full reload in the Hub shell bounces through /login, the identity
|
|
212
|
+
// provider and /login-callback (~35s) before the SPA pushes its returnUrl
|
|
213
|
+
// back to /clusters. Counting rows mid-bounce throws "Execution context
|
|
214
|
+
// was destroyed", so wait for the clusters page to have settled first.
|
|
215
|
+
await this.page.waitForURL((url) => /\/clusters\/?$/.test(url.pathname), {
|
|
216
|
+
timeout: 120000,
|
|
217
|
+
});
|
|
218
|
+
await (0, test_1.expect)(this.createNewClusterButton).toBeVisible({ timeout: 60000 });
|
|
219
|
+
// Hub's clusters data table renders skeleton rows (no links) while it
|
|
220
|
+
// fetches, and the "Create new cluster" button is visible before the data
|
|
221
|
+
// arrives. Counting matching rows at that point always returned 0, so the
|
|
222
|
+
// pre-clean was skipped and every run left one more same-named cluster
|
|
223
|
+
// behind until the org ran out of G3-Dev reservations (the type tile then
|
|
224
|
+
// renders disabled). Wait for the first loaded row before counting.
|
|
225
|
+
await this.clustersList
|
|
226
|
+
.getByRole('link')
|
|
227
|
+
.first()
|
|
228
|
+
.waitFor({ timeout: 30000 })
|
|
229
|
+
.catch(() => false);
|
|
230
|
+
// Rows whose deletion is already in progress keep the name until the
|
|
231
|
+
// backend removes them; exclude them so the loop does not revisit them.
|
|
232
|
+
const deletableRows = () => this.clustersList
|
|
233
|
+
.filter({
|
|
234
|
+
has: this.page.getByRole('link', { name, exact: true }),
|
|
235
|
+
})
|
|
236
|
+
.filter({ hasNotText: /Deleting/ });
|
|
237
|
+
if ((await deletableRows().count()) <= 0) {
|
|
209
238
|
console.log(`No clusters found with name ${name}, skipping deletion.`);
|
|
210
239
|
return;
|
|
211
240
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (await
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
241
|
+
// Legacy Console rendered a per-row "Delete" button; Hub's design-system
|
|
242
|
+
// data table instead puts it in the row's "Row actions" kebab menu.
|
|
243
|
+
const deleteMenuItem = this.page.getByRole('menuitem', { name: /^Delete/ });
|
|
244
|
+
const confirmInput = this.confirmDeleteInput.or(this.dialog.getByRole('textbox'));
|
|
245
|
+
const maxDeletions = 50;
|
|
246
|
+
for (let i = 0; i < maxDeletions; i++) {
|
|
247
|
+
if ((await deletableRows().count()) <= 0)
|
|
248
|
+
break;
|
|
249
|
+
const row = deletableRows().first();
|
|
250
|
+
const rowAction = row
|
|
251
|
+
.getByRole('button', { name: 'Delete' })
|
|
252
|
+
.or(row.getByRole('button', { name: 'Row actions', exact: true }));
|
|
253
|
+
try {
|
|
254
|
+
await (0, test_1.expect)(rowAction).toBeVisible({ timeout: 10000 });
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// A cluster in a transient state (e.g. just created by a concurrent
|
|
258
|
+
// setup worker) may have its row present before the action renders.
|
|
259
|
+
await this.page.reload({ waitUntil: 'domcontentloaded' });
|
|
260
|
+
await this.clustersList.getByRole('link').first().waitFor({
|
|
261
|
+
timeout: 30000,
|
|
262
|
+
});
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
// Rows share the cluster name, so remember this row's unique link (it
|
|
266
|
+
// carries the cluster id) to recognise when this cluster is gone.
|
|
267
|
+
const clusterHref = await row
|
|
268
|
+
.getByRole('link', { name, exact: true })
|
|
269
|
+
.getAttribute('href');
|
|
270
|
+
await rowAction.click({ timeout: 60000 });
|
|
271
|
+
// isVisible() does not wait, so a kebab menu that opens a moment after
|
|
272
|
+
// the click was missed and the confirm dialog never appeared. Wait for
|
|
273
|
+
// either the menu item (Hub) or the dialog (legacy per-row button).
|
|
274
|
+
await (0, test_1.expect)(deleteMenuItem.or(this.dialog)).toBeVisible({
|
|
275
|
+
timeout: 30000,
|
|
276
|
+
});
|
|
277
|
+
if (await deleteMenuItem.isVisible()) {
|
|
278
|
+
await deleteMenuItem.click({ timeout: 30000 });
|
|
279
|
+
}
|
|
280
|
+
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 60000 });
|
|
281
|
+
await (0, test_1.expect)(confirmInput.first()).toBeVisible({ timeout: 60000 });
|
|
282
|
+
await confirmInput.first().fill('DELETE', { timeout: 60000 });
|
|
283
|
+
await this.dangerDeleteButton.last().click({ timeout: 60000 });
|
|
284
|
+
// When a concurrent worker already deleted this same cluster, the modal
|
|
285
|
+
// stays open with "We're having trouble deleting the cluster". Close it;
|
|
286
|
+
// the row check below still fails if the cluster was not removed.
|
|
287
|
+
const deleteError = this.dialog.getByText("We're having trouble deleting the cluster");
|
|
288
|
+
// The alert only renders once the delete request fails, so wait for the
|
|
289
|
+
// modal to either close or show it rather than probing once.
|
|
290
|
+
await (0, test_1.expect)(async () => {
|
|
291
|
+
const closed = !(await this.dialog.isVisible());
|
|
292
|
+
(0, test_1.expect)(closed || (await deleteError.isVisible())).toBe(true);
|
|
293
|
+
}).toPass({ timeout: 60000 });
|
|
294
|
+
if (await deleteError.isVisible()) {
|
|
295
|
+
await this.dialog.getByRole('button', { name: 'Cancel' }).click();
|
|
296
|
+
await this.page.reload({ waitUntil: 'domcontentloaded' });
|
|
297
|
+
await this.clustersList.getByRole('link').first().waitFor({
|
|
298
|
+
timeout: 120000,
|
|
231
299
|
});
|
|
232
300
|
}
|
|
301
|
+
await (0, test_1.expect)(this.dialog).not.toBeVisible({ timeout: 60000 });
|
|
302
|
+
// Wait until the deleted row is gone or flagged as deleting. The table
|
|
303
|
+
// is paginated, so the row count alone does not drop: the next page's
|
|
304
|
+
// rows slide in to fill the gap.
|
|
305
|
+
await (0, test_1.expect)(this.clustersList
|
|
306
|
+
.filter({ has: this.page.locator(`a[href="${clusterHref}"]`) })
|
|
307
|
+
.filter({ hasNotText: /Deleting/ })).toHaveCount(0, { timeout: 60000 });
|
|
233
308
|
}
|
|
234
|
-
await this.page.waitForTimeout(500);
|
|
235
309
|
}
|
|
236
310
|
async clickClusterTab() {
|
|
237
311
|
await Promise.race([
|
|
@@ -18,7 +18,23 @@ class TaskPanelPage {
|
|
|
18
18
|
processesInfoText;
|
|
19
19
|
constructor(page) {
|
|
20
20
|
this.page = page;
|
|
21
|
-
|
|
21
|
+
// The task-list wrapper's `title="Available tasks"` was removed on
|
|
22
|
+
// camunda/camunda `main` by #65074 ("truncate long task card labels instead
|
|
23
|
+
// of overflowing the panel"), and SaaS 8.10's chromium-v2 Tasklist has now
|
|
24
|
+
// flipped to that redesigned shell (the design-system rollout is per app
|
|
25
|
+
// and still in flight), so `getByTitle('Available tasks')` matched nothing
|
|
26
|
+
// and every openTask/completeTask scoped through it timed out while the task
|
|
27
|
+
// was plainly listed. The `<section aria-label="Tasks side panel">` that
|
|
28
|
+
// wraps the panel is present on both shells -- it is what the product's own
|
|
29
|
+
// qa/c8-orchestration-cluster-e2e-test-suite and pages/SM-8.10 now anchor on.
|
|
30
|
+
// Both are matched because the rollout is per app and not yet everywhere:
|
|
31
|
+
// a run still served the pre-#65074 shell (an older SaaS cluster, or a
|
|
32
|
+
// version that has not flipped) only exposes the title wrapper. `.first()`
|
|
33
|
+
// keeps the locator strict-mode safe on a shell that renders both.
|
|
34
|
+
this.availableTasks = page
|
|
35
|
+
.getByRole('region', { name: 'Tasks side panel' })
|
|
36
|
+
.or(page.getByTitle('Available tasks'))
|
|
37
|
+
.first();
|
|
22
38
|
// 8.10 still serves Tasklist on the Carbon shell, so filtering lives in
|
|
23
39
|
// the collapsible filter panel: the collapsed rail carries the expand
|
|
24
40
|
// control (aria-controls="task-nav-bar") and the expanded nav lists each
|
|
@@ -22,7 +22,13 @@ class TaskPanelPage {
|
|
|
22
22
|
this.page = page;
|
|
23
23
|
this.assignmentTag = page.locator(' header > div').nth(2);
|
|
24
24
|
this.assignToMeButton = page.getByRole('button', { name: 'Assign to me' });
|
|
25
|
-
|
|
25
|
+
// The task list wrapper lost its "Available tasks" title in
|
|
26
|
+
// camunda/camunda 161f4722578 ("remove duplicate tooltips"); the
|
|
27
|
+
// TasksLayoutPage <section aria-label="Tasks side panel"> is the anchor
|
|
28
|
+
// the product's own qa-suite TaskPanelPage now uses.
|
|
29
|
+
this.availableTasks = page.getByRole('region', {
|
|
30
|
+
name: 'Tasks side panel',
|
|
31
|
+
});
|
|
26
32
|
this.completeTaskButton = page.getByRole('button', { name: 'Complete Task' });
|
|
27
33
|
this.emptyTaskMessage = this.emptyTaskMessage = page.getByRole('heading', {
|
|
28
34
|
name: /Task has no variables/i,
|