@camunda/e2e-test-suite 0.0.1372 → 0.0.1374

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.
@@ -33,6 +33,7 @@ declare class ClusterPage {
33
33
  readonly clusterHealthiness: (clusterName: string) => Locator;
34
34
  readonly clusterLink: (clusterName: string) => Locator;
35
35
  readonly dialog: Locator;
36
+ private createdClusterIds;
36
37
  constructor(page: Page);
37
38
  clickClusterBanner(): Promise<void>;
38
39
  deleteCluster(name: string): Promise<void>;
@@ -44,6 +45,7 @@ declare class ClusterPage {
44
45
  selectSubRegion(region: string): Promise<void>;
45
46
  private extractClusterIdFromUrl;
46
47
  private logClusterCreationInfo;
48
+ private createdClusterRow;
47
49
  clickClusterType(): Promise<void>;
48
50
  clickCreateClusterButton(): Promise<void>;
49
51
  clickClustersBreadcrumb(clusterName: string): Promise<void>;
@@ -40,6 +40,10 @@ class ClusterPage {
40
40
  clusterHealthiness;
41
41
  clusterLink;
42
42
  dialog;
43
+ // Cluster names are not unique: a concurrent or leftover same-named
44
+ // cluster (possibly being deleted) can be the first matching row. Remember
45
+ // the id of the cluster this page created so its own row is tracked.
46
+ createdClusterIds = new Map();
43
47
  constructor(page) {
44
48
  this.page = page;
45
49
  this.dialog = page.getByRole('dialog');
@@ -202,11 +206,20 @@ class ClusterPage {
202
206
  const clusterHref = await row
203
207
  .getByRole('link', { name, exact: true })
204
208
  .getAttribute('href');
205
- await rowAction.click({ timeout: 60000 });
206
- if (await deleteMenuItem.isVisible({ timeout: 5000 }).catch(() => false)) {
207
- await deleteMenuItem.click({ timeout: 30000 });
208
- }
209
- await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 60000 });
209
+ // The kebab menu animates open and the table re-renders while polling
210
+ // cluster status, detaching the menu item mid-click ("element is not
211
+ // stable"). Reopen the menu and retry until the confirm dialog shows.
212
+ await (0, test_1.expect)(async () => {
213
+ if (!(await this.dialog.isVisible())) {
214
+ if (!(await deleteMenuItem.isVisible())) {
215
+ await rowAction.click({ timeout: 10000 });
216
+ }
217
+ if (await deleteMenuItem.isVisible({ timeout: 5000 }).catch(() => false)) {
218
+ await deleteMenuItem.click({ timeout: 10000 });
219
+ }
220
+ }
221
+ await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 5000 });
222
+ }).toPass({ timeout: 90000 });
210
223
  await (0, test_1.expect)(confirmInput.first()).toBeVisible({ timeout: 60000 });
211
224
  await confirmInput.first().fill('DELETE', { timeout: 60000 });
212
225
  await this.dangerDeleteButton.last().click({ timeout: 60000 });
@@ -319,12 +332,26 @@ class ClusterPage {
319
332
  await this.page.waitForURL(/\/cluster\/[a-f0-9-]+$/, { timeout: 60000 });
320
333
  const currentUrl = this.page.url();
321
334
  const clusterId = this.extractClusterIdFromUrl(currentUrl);
335
+ if (clusterId) {
336
+ this.createdClusterIds.set(clusterName, clusterId);
337
+ }
338
+ else {
339
+ this.createdClusterIds.delete(clusterName);
340
+ }
322
341
  console.log(`🎉 Cluster "${clusterName}" created successfully with ID: ${clusterId || 'Unknown'} at ${new Date().toISOString()}`);
323
342
  }
324
343
  catch (error) {
325
344
  console.warn(`⚠️ Could not extract cluster info for "${clusterName}": ${error}`);
326
345
  }
327
346
  }
347
+ createdClusterRow(name) {
348
+ const clusterId = this.createdClusterIds.get(name);
349
+ if (!clusterId)
350
+ return this.cluster(name);
351
+ return this.clustersList
352
+ .filter({ has: this.page.locator(`a[href*="${clusterId}"]`) })
353
+ .first();
354
+ }
328
355
  async clickClusterType() {
329
356
  if (process.env.IS_PROD !== 'true') {
330
357
  await (0, test_1.expect)(this.g3DevClusterType).toBeVisible({ timeout: 60000 });
@@ -337,7 +364,7 @@ class ClusterPage {
337
364
  await this.createClusterButton.click();
338
365
  }
339
366
  async clickClustersBreadcrumb(clusterName) {
340
- const clusterRow = this.cluster(clusterName);
367
+ const clusterRow = this.createdClusterRow(clusterName);
341
368
  // Camunda Hub's clusters table renders the in-progress status as
342
369
  // "Creating…" (with an ellipsis), so an exact 'Creating' match never hits.
343
370
  const creatingStatus = clusterRow.getByText(/^Creating/);
@@ -451,13 +478,15 @@ class ClusterPage {
451
478
  }
452
479
  }
453
480
  async assertClusterHealthyStatusWithRetry(name, visibilityTimeout = 100000, totalTimeout = 600000) {
454
- await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.clusterHealthiness(name), {
481
+ const clusterRow = this.createdClusterRow(name);
482
+ const healthyStatus = clusterRow.getByText('Healthy', { exact: true });
483
+ await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, healthyStatus, {
455
484
  visibilityTimeout: visibilityTimeout,
456
485
  totalTimeout: totalTimeout,
457
486
  maxRetries: 5,
458
487
  preAction: async () => {
459
488
  await this.page.reload();
460
- await (0, test_1.expect)(this.cluster(name)).toBeVisible({ timeout: 30000 });
489
+ await (0, test_1.expect)(clusterRow).toBeVisible({ timeout: 30000 });
461
490
  },
462
491
  });
463
492
  console.log('Cluster is healthy:', name);
@@ -22,9 +22,13 @@ _8_7_1.test.describe('Console User Flow Tests', () => {
22
22
  await (0, _setup_1.captureScreenshot)(page, testInfo);
23
23
  await (0, _setup_1.captureFailureVideo)(page, testInfo);
24
24
  });
25
- (0, _8_7_1.test)('Create Cluster', async ({ homePage, clusterPage }) => {
25
+ (0, _8_7_1.test)('Create Cluster', async ({ homePage, clusterPage }, testInfo) => {
26
26
  _8_7_1.test.slow();
27
- const newClusterName = 'UI Test Cluster';
27
+ // createCluster pre-deletes every same-named cluster, so parallel repeats
28
+ // (--repeat-each) would delete each other's clusters. Suffix repeats only;
29
+ // a normal run keeps the plain name.
30
+ const repeatIndex = testInfo.repeatEachIndex;
31
+ const newClusterName = `UI Test Cluster${repeatIndex ? ` ${repeatIndex}` : ''}`;
28
32
  await _8_7_1.test.step('Navigate to clusters and create cluster', async () => {
29
33
  await homePage.clickClusters();
30
34
  await clusterPage.createCluster(newClusterName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1372",
3
+ "version": "0.0.1374",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",