@camunda/e2e-test-suite 0.0.791 → 0.0.793

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.
@@ -464,8 +464,13 @@ class IdentityUsersPage {
464
464
  }
465
465
  async assertUserIsAssignedCorrectRole(username, roles) {
466
466
  await this.page.getByRole('cell', { name: username, exact: true }).click();
467
+ // Wait for the Assigned Roles tab to render before clicking it; after
468
+ // navigating to a user row the panel can take a moment to hydrate.
469
+ await (0, test_1.expect)(this.assignedRolesTab).toBeVisible({ timeout: 30000 });
467
470
  await this.assignedRolesTab.click();
468
471
  for (const role of roles) {
472
+ // Use a generous timeout: on slow/post-upgrade clusters the role table
473
+ // may take several seconds to populate after the tab switch.
469
474
  await (0, test_1.expect)(this.page.getByRole('cell', { name: role, exact: true })).toBeVisible({ timeout: 60000 });
470
475
  }
471
476
  }
@@ -1000,6 +1000,14 @@ class ModelerCreatePage {
1000
1000
  const max = 3;
1001
1001
  for (let i = 0; i < max; i++) {
1002
1002
  try {
1003
+ // Filter the popup to surface the webhook connector. The full connector
1004
+ // list can be long and the specific entry may be below the viewport or
1005
+ // not yet populated when the popup first opens.
1006
+ if (await this.changeElementSearchInput
1007
+ .isVisible({ timeout: 3000 })
1008
+ .catch(() => false)) {
1009
+ await this.changeElementSearchInput.fill('Webhook');
1010
+ }
1003
1011
  await (0, test_1.expect)(this.intermediateWebhookConnectorOption).toBeVisible({
1004
1012
  timeout: 30000,
1005
1013
  });
@@ -1011,7 +1019,9 @@ class ModelerCreatePage {
1011
1019
  if (i === max - 1)
1012
1020
  throw err;
1013
1021
  await this.page.reload();
1014
- await this.page.waitForLoadState('networkidle');
1022
+ // domcontentloaded is more reliable than networkidle for Modeler
1023
+ // which maintains persistent background connections (SSE/WebSocket).
1024
+ await this.page.waitForLoadState('domcontentloaded');
1015
1025
  // Wait for modeler canvas to render after reload before re-selecting
1016
1026
  await (0, test_1.expect)(this.secondElement).toBeVisible({ timeout: 60000 });
1017
1027
  await this.secondElement.click({ force: true, timeout: 30000 });
@@ -27,6 +27,7 @@ declare class ModelerHomePage {
27
27
  constructor(page: Page);
28
28
  clickCreateNewProjectButton(): Promise<void>;
29
29
  enterNewProjectName(name: string): Promise<void>;
30
+ waitForModelerReady(timeoutMs?: number): Promise<void>;
30
31
  createCrossComponentProjectFolder(): Promise<void>;
31
32
  clickCrossComponentProjectFolder(): Promise<void>;
32
33
  clickProcessDiagram(name: string): Promise<void>;
@@ -95,20 +95,58 @@ class ModelerHomePage {
95
95
  await this.projectNameInput.fill(name);
96
96
  await this.projectNameInput.press('Enter');
97
97
  }
98
+ // Wait for the Modeler app shell to render, reloading on transient upstream
99
+ // errors (e.g. nginx 503 during pod restarts). Uses the banner link as a
100
+ // stable signal that the SPA has mounted successfully.
101
+ async waitForModelerReady(timeoutMs = 120000) {
102
+ const startTime = Date.now();
103
+ while (Date.now() - startTime < timeoutMs) {
104
+ if (await this.modelerPageBanner.isVisible().catch(() => false)) {
105
+ return;
106
+ }
107
+ // The Modeler upstream can return a transient 503 (nginx) while its
108
+ // pod restarts. Reload the error page until the app shell renders.
109
+ try {
110
+ await this.page.reload({ waitUntil: 'domcontentloaded' });
111
+ }
112
+ catch {
113
+ // ignore reload errors and keep polling
114
+ }
115
+ await this.page.waitForTimeout(2000);
116
+ }
117
+ throw new Error(`Modeler app shell did not render within ${timeoutMs}ms (banner not found).`);
118
+ }
98
119
  async createCrossComponentProjectFolder() {
99
- // Removed waitForLoadState('networkidle'). Modeler emits
100
- // background activity; the toBeVisible auto-wait covers
101
- // readiness deterministically.
102
- await (0, test_1.expect)(this.createNewProjectButton).toBeVisible({ timeout: 30000 });
103
- await this.clickMessageBanner();
104
- if (await this.crossComponentProjectFolder.isVisible()) {
105
- console.log('Cross Component Project folder already exists. Clicking into it');
106
- await this.clickCrossComponentProjectFolder();
107
- return;
120
+ // After a fresh user login (e.g. lisa, bart) the Modeler pod may still be
121
+ // initialising or returning transient 503s. Poll until the app shell banner
122
+ // is visible before interacting with the project list.
123
+ const maxAttempts = 3;
124
+ const retryWaitMs = 5000;
125
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
126
+ try {
127
+ await this.waitForModelerReady();
128
+ await this.clickMessageBanner();
129
+ if (await this.crossComponentProjectFolder.isVisible()) {
130
+ console.log('Cross Component Project folder already exists. Clicking into it');
131
+ await this.clickCrossComponentProjectFolder();
132
+ return;
133
+ }
134
+ await this.clickCreateNewProjectButton();
135
+ await this.enterNewProjectName(this.defaultFolderName);
136
+ await (0, test_1.expect)(this.page.getByRole('heading', { name: this.defaultFolderName })).toBeVisible({ timeout: 10000 });
137
+ return;
138
+ }
139
+ catch (error) {
140
+ if (attempt < maxAttempts - 1) {
141
+ console.log(`createCrossComponentProjectFolder attempt ${attempt + 1} failed. Reloading and retrying...`);
142
+ await this.page.reload({ waitUntil: 'domcontentloaded' });
143
+ await this.page.waitForTimeout(retryWaitMs);
144
+ }
145
+ else {
146
+ throw error;
147
+ }
148
+ }
108
149
  }
109
- await this.clickCreateNewProjectButton();
110
- await this.enterNewProjectName(this.defaultFolderName);
111
- await (0, test_1.expect)(this.page.getByRole('heading', { name: this.defaultFolderName })).toBeVisible({ timeout: 10000 });
112
150
  }
113
151
  async clickCrossComponentProjectFolder() {
114
152
  let attempts = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.791",
3
+ "version": "0.0.793",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",