@camunda/e2e-test-suite 0.0.1028 → 0.0.1030

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.
@@ -194,7 +194,26 @@ class FormJsPage {
194
194
  await (0, test_1.expect)(this.dialog).toBeVisible({
195
195
  timeout: 30000,
196
196
  });
197
- await this.selectCluster(clusterName);
197
+ // Same recovery as ModelerCreatePage.runProcessInstance: selectCluster
198
+ // clears the stage binding when the dialog does not offer the cluster, so
199
+ // ensureStageCluster rebinds here and reports that it navigated. Any other
200
+ // failure leaves the binding in place, it returns false, and the original
201
+ // error stands. This path has no surrounding retry loop, hence the one
202
+ // explicit second attempt.
203
+ try {
204
+ await this.selectCluster(clusterName);
205
+ }
206
+ catch (error) {
207
+ const rebound = await this.processApplicationPage.ensureStageCluster(clusterName);
208
+ if (!rebound) {
209
+ throw error;
210
+ }
211
+ await this.clickDeployButton();
212
+ await (0, test_1.expect)(this.dialog).toBeVisible({
213
+ timeout: 30000,
214
+ });
215
+ await this.selectCluster(clusterName);
216
+ }
198
217
  await this.selectOnlyThisResource();
199
218
  await this.clickDeploySubButton();
200
219
  await (0, test_1.expect)(this.deploySuccessNotification).toBeVisible({ timeout: 30000 });
@@ -98,7 +98,10 @@ class ModelerHomePage {
98
98
  this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
99
99
  this.dialog = page.getByRole('dialog');
100
100
  this.messageBanner = page.locator('[data-test="close-top-banner"]');
101
- this.closeButton = page.getByRole('button', { name: 'Got it - Dismiss' });
101
+ // Matched on the shared "Got it" prefix so it covers both announcement
102
+ // dialogs hub currently ships: the release notes one ("Got it - Dismiss")
103
+ // and the process-application restructure one ("Got it").
104
+ this.closeButton = page.getByRole('button', { name: 'Got it' });
102
105
  this.optionsButton = page.getByRole('button', { name: 'Options' });
103
106
  this.formNameBreadcrumb = (formName) => page.locator('button[data-test="breadcrumb-form"]', {
104
107
  hasText: formName,
@@ -106,16 +109,31 @@ class ModelerHomePage {
106
109
  this.formBreadcrumbButton = page.locator('button[data-test="breadcrumb-form"]');
107
110
  this.renameFormMenuItem = page.locator('[data-test="rename-form"]');
108
111
  }
112
+ // The release-announcement dialog ("Check out our new release") re-mounts
113
+ // after the projects list re-renders, so one dismissal pass is not enough.
114
+ // Repeat while a pass still finds something to dismiss; a pass that finds
115
+ // nothing returns immediately, so the cost is unchanged when no overlay is up.
109
116
  async dismissOverlays() {
110
- for (const locator of [
111
- this.closeButton,
112
- this.page.getByRole('button', { name: 'Close' }).first(),
113
- this.messageBanner,
114
- ]) {
115
- await locator
116
- .waitFor({ state: 'visible', timeout: 3000 })
117
- .then(() => locator.click())
118
- .catch(() => { });
117
+ for (let pass = 0; pass < 3; pass++) {
118
+ let dismissed = false;
119
+ for (const locator of [
120
+ this.closeButton,
121
+ this.page.getByRole('button', { name: 'Close' }).first(),
122
+ this.messageBanner,
123
+ ]) {
124
+ const visible = await locator
125
+ .waitFor({ state: 'visible', timeout: 3000 })
126
+ .then(() => true)
127
+ .catch(() => false);
128
+ if (!visible) {
129
+ continue;
130
+ }
131
+ await locator.click({ timeout: 10000 }).catch(() => { });
132
+ dismissed = true;
133
+ }
134
+ if (!dismissed) {
135
+ return;
136
+ }
119
137
  }
120
138
  }
121
139
  async clickCreateNewProjectButton() {
@@ -127,10 +145,39 @@ class ModelerHomePage {
127
145
  visibilityTimeout: 10000,
128
146
  });
129
147
  }
148
+ // The rename runs on a freshly created project, which is exactly when an
149
+ // announcement dialog mounts on top of it: it takes focus, the inline editor
150
+ // unmounts, and a single click on `[data-test="editable-input"]` then waits
151
+ // out its whole timeout on an element that never comes back — leaving the
152
+ // project named "New project". Dismiss overlays and re-enter the name until
153
+ // it commits.
154
+ //
155
+ // The committed name renders differently per page: the project page puts it
156
+ // in the breadcrumb menu button, and only the projects list carries a
157
+ // `[title="<name>"]` link. Accept either, and once the rename has been
158
+ // submitted treat the editor unmounting as done — hub keeps rendering the
159
+ // pre-rename fetch until a reload, which the caller's Home-page assertion
160
+ // already performs.
130
161
  async enterNewProjectName(name) {
131
- await this.projectNameInput.click({ timeout: 60000 });
132
- await this.projectNameInput.fill(name);
133
- await this.projectNameInput.press('Enter');
162
+ const committedName = this.page
163
+ .locator('[data-test="breadcrumb-project-menu"]', { hasText: name })
164
+ .or(this.page.getByTitle(name, { exact: true }))
165
+ .first();
166
+ let submitted = false;
167
+ await (0, test_1.expect)(async () => {
168
+ if (await committedName.isVisible()) {
169
+ return;
170
+ }
171
+ if (submitted && !(await this.projectNameInput.isVisible())) {
172
+ return;
173
+ }
174
+ await this.dismissOverlays();
175
+ await this.projectNameInput.click({ timeout: 15000 });
176
+ await this.projectNameInput.fill(name);
177
+ submitted = true;
178
+ await this.projectNameInput.press('Enter');
179
+ await (0, test_1.expect)(committedName).toBeVisible({ timeout: 10000 });
180
+ }).toPass({ timeout: 120000 });
134
181
  }
135
182
  async enterIdpApplicationName(name) {
136
183
  await this.idpApplicationNameInput.click({ timeout: 60000 });
@@ -378,12 +425,17 @@ class ModelerHomePage {
378
425
  await this.page.getByText('Home', { exact: true }).first().click();
379
426
  }
380
427
  }
428
+ // An announcement dialog covering the Modeler header makes every click on the
429
+ // org button bounce off the modal layer ("intercepts pointer events") until
430
+ // the timeout, so dismiss overlays before each attempt.
381
431
  async clickOpenOrganizationsButton() {
382
- await (0, sleep_1.sleep)(5000);
383
- await (0, test_1.expect)(this.openOrganizationsButton).toBeVisible({
384
- timeout: 10000,
432
+ await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.openOrganizationsButton, {
433
+ preAction: async () => {
434
+ await this.dismissOverlays();
435
+ },
436
+ totalTimeout: 120000,
437
+ visibilityTimeout: 30000,
385
438
  });
386
- await this.openOrganizationsButton.click({ timeout: 30000 });
387
439
  }
388
440
  async clickCrossComponentProjectFolder() {
389
441
  await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.crossComponentProjectFolder, {
@@ -160,6 +160,19 @@ class ProcessApplicationPage {
160
160
  .filter({ hasNotText: 'Select a development cluster' })
161
161
  .first();
162
162
  await option.click({ timeout: 30000 });
163
+ // The field defaults to the first cluster alphabetically and re-mounts as
164
+ // the cluster list settles, so an option click can be dropped and Save
165
+ // then persists that default. Nothing downstream re-reads the binding --
166
+ // ensureStageCluster records the requested cluster as fact -- so the
167
+ // symptom surfaces much later, as a deploy dialog offering a cluster the
168
+ // test never asked for. Confirm the field carries the chosen cluster
169
+ // before saving; ensureStageCluster's retry re-navigates and binds again
170
+ // when it does not.
171
+ if (clusterName) {
172
+ await (0, test_1.expect)(this.developmentClusterSelect).toContainText(clusterName, {
173
+ timeout: 15000,
174
+ });
175
+ }
163
176
  await this.defineStagesSaveButton.click({ timeout: 30000 });
164
177
  await (0, test_1.expect)(this.defineStagesDialog).toBeHidden({ timeout: 60000 });
165
178
  }
@@ -204,7 +204,8 @@ _8_9_1.test.describe('Optimize User Flow Tests', () => {
204
204
  await (0, test_1.expect)(newOperateTab.getByText('Displaying data from 1 instance.')).toBeVisible({ timeout: 90000 });
205
205
  });
206
206
  });
207
- (0, _8_9_1.test)('Process Import Flow @tasklistV1', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, }) => {
207
+ // Skipped due to bug #60153: https://github.com/camunda/camunda/issues/60153
208
+ _8_9_1.test.skip('Process Import Flow @tasklistV1', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, }) => {
208
209
  _8_9_1.test.slow();
209
210
  const processName = 'Process Import Flow' + (await (0, _setup_1.generateRandomStringAsync)(6));
210
211
  await _8_9_1.test.step('Navigate to Web Modeler', async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1028",
3
+ "version": "0.0.1030",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",