@camunda/e2e-test-suite 0.0.1089 → 0.0.1091

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.
@@ -148,7 +148,22 @@ class FormJsPage {
148
148
  .isVisible()
149
149
  .catch(() => false);
150
150
  if (!isLegacyDialog) {
151
- await (0, test_1.expect)(this.dialog.getByText(clusterName, { exact: false }).first()).toBeVisible({ timeout: 30000 });
151
+ const offered = await this.dialog
152
+ .getByText(clusterName, { exact: false })
153
+ .first()
154
+ .waitFor({ state: 'visible', timeout: 30000 })
155
+ .then(() => true)
156
+ .catch(() => false);
157
+ if (!offered) {
158
+ // Forget the binding before failing. The dialog lists exactly the
159
+ // clusters this application's stages point at, so a missing cluster
160
+ // means the binding did not take -- and no amount of reopening the
161
+ // dialog will make it appear. Clearing the record lets the caller's
162
+ // next attempt rebind instead of re-checking an unchanged dialog.
163
+ this.processApplicationPage.forgetStageCluster();
164
+ throw new Error(`The deploy dialog does not offer "${clusterName}": its stage ` +
165
+ 'binding did not take. It will be rebound on the next attempt.');
166
+ }
152
167
  return;
153
168
  }
154
169
  const healthyRegex = new RegExp(`${clusterName}[\\s\\S]*?HealthydevManage`);
@@ -200,7 +215,25 @@ class FormJsPage {
200
215
  await (0, test_1.expect)(this.dialog).toBeVisible({
201
216
  timeout: 30000,
202
217
  });
203
- await this.selectCluster(clusterName);
218
+ // selectCluster clears the stage binding when the dialog does not offer the
219
+ // cluster, so ensureStageCluster rebinds here and reports that it
220
+ // navigated. Any other failure leaves the binding in place, it returns
221
+ // false, and the original error stands. This path has no surrounding retry
222
+ // loop, hence the one explicit second attempt.
223
+ try {
224
+ await this.selectCluster(clusterName);
225
+ }
226
+ catch (error) {
227
+ const rebound = await this.processApplicationPage.ensureStageCluster(clusterName);
228
+ if (!rebound) {
229
+ throw error;
230
+ }
231
+ await this.clickDeployButton();
232
+ await (0, test_1.expect)(this.dialog).toBeVisible({
233
+ timeout: 30000,
234
+ });
235
+ await this.selectCluster(clusterName);
236
+ }
204
237
  await this.selectOnlyThisResource();
205
238
  await this.clickDeploySubButton();
206
239
  await (0, test_1.expect)(this.deploySuccessNotification).toBeVisible({ timeout: 30000 });
@@ -22,6 +22,7 @@ declare class ProcessApplicationPage {
22
22
  nameNewProcessApplication(name: string): Promise<void>;
23
23
  defineDevelopmentStage(clusterName?: string): Promise<void>;
24
24
  rememberResourceContainer(url: string): void;
25
+ forgetStageCluster(): void;
25
26
  ensureStageCluster(clusterName: string): Promise<boolean>;
26
27
  private openStageDefinition;
27
28
  openByName(name: string): Promise<void>;
@@ -196,6 +196,18 @@ class ProcessApplicationPage {
196
196
  rememberResourceContainer(url) {
197
197
  resourceContainers.set(this.page, { url });
198
198
  }
199
+ // Drops the recorded development-stage binding so the next ensureStageCluster
200
+ // call binds again. Called when the deploy dialog turns out not to offer the
201
+ // cluster we believe we bound: the dialog offers exactly what the
202
+ // application's stages point at, so if the cluster is missing the binding
203
+ // did not take, and reopening the dialog can never change that. Without
204
+ // this, a caller's retries all re-check a state nothing is changing.
205
+ forgetStageCluster() {
206
+ const container = resourceContainers.get(this.page);
207
+ if (container) {
208
+ container.developmentCluster = undefined;
209
+ }
210
+ }
199
211
  // A process application deploys to the clusters bound to its stages, and
200
212
  // nothing else: inside a container DeployModal renders
201
213
  // ProcessAppClusterSelection, which lists only those and auto-selects the
@@ -21,6 +21,7 @@ declare class Authorization {
21
21
  protected readonly deleteAuthorizationModalDeleteButton: Locator;
22
22
  protected readonly tableFilter: Locator;
23
23
  constructor(page: Page);
24
+ protected selectResourceType(resourceType: string): Promise<void>;
24
25
  private selectAuthorizationOwner;
25
26
  createAuthorization(authorization: {
26
27
  ownerType: string;
@@ -98,6 +98,26 @@ class Authorization {
98
98
  .or(page.getByRole('searchbox', { name: 'Search by owner ID' }))
99
99
  .first();
100
100
  }
101
+ // The Admin's Authorizations page is migrating onto the new design-system
102
+ // shell, which replaces the per-resource-type tabs with a single
103
+ // "Authorization type" filter combobox (identity/client ListV2.tsx, gated on
104
+ // isNewDesignSystemEnabled). Select the resource type through whichever this
105
+ // build renders: click the tab, or open the combobox and pick the option.
106
+ async selectResourceType(resourceType) {
107
+ const tab = this.selectResourceTypeTab(resourceType);
108
+ const filterCombobox = this.page.getByRole('combobox', {
109
+ name: 'Authorization type',
110
+ });
111
+ await (0, test_1.expect)(tab.or(filterCombobox)).toBeVisible({ timeout: 60000 });
112
+ if (await tab.isVisible()) {
113
+ await tab.click();
114
+ return;
115
+ }
116
+ await filterCombobox.click();
117
+ await this.page
118
+ .getByRole('option', { name: resourceType, exact: true })
119
+ .click({ timeout: 30000 });
120
+ }
101
121
  // Released 8.10 alpha images still render the Carbon combobox that lists
102
122
  // every owner, so accept whichever owner field this build shows.
103
123
  async selectAuthorizationOwner(ownerId) {
@@ -2,34 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OCIdentityAuthorizationsPage = void 0;
4
4
  const Authorization_1 = require("../SM-8.10/Authorization");
5
- const test_1 = require("@playwright/test");
6
5
  class OCIdentityAuthorizationsPage extends Authorization_1.Authorization {
7
6
  constructor(page) {
8
7
  super(page);
9
8
  }
10
9
  async clickProcessDefinitionTab() {
11
- await (0, test_1.expect)(this.selectResourceTypeTab('PROCESS_DEFINITION')).toBeVisible({
12
- timeout: 60000,
13
- });
14
- await this.selectResourceTypeTab('PROCESS_DEFINITION').click();
10
+ await this.selectResourceType('PROCESS_DEFINITION');
15
11
  }
16
12
  async clickAuthorizationTab() {
17
- await (0, test_1.expect)(this.selectResourceTypeTab('AUTHORIZATION')).toBeVisible({
18
- timeout: 60000,
19
- });
20
- await this.selectResourceTypeTab('AUTHORIZATION').click();
13
+ await this.selectResourceType('AUTHORIZATION');
21
14
  }
22
15
  async clickComponentTab() {
23
- await (0, test_1.expect)(this.selectResourceTypeTab('COMPONENT')).toBeVisible({
24
- timeout: 60000,
25
- });
26
- await this.selectResourceTypeTab('COMPONENT').click();
16
+ await this.selectResourceType('COMPONENT');
27
17
  }
28
18
  async clickResourceTab() {
29
- await (0, test_1.expect)(this.selectResourceTypeTab('RESOURCE')).toBeVisible({
30
- timeout: 60000,
31
- });
32
- await this.selectResourceTypeTab('RESOURCE').click();
19
+ await this.selectResourceType('RESOURCE');
33
20
  }
34
21
  }
35
22
  exports.OCIdentityAuthorizationsPage = OCIdentityAuthorizationsPage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1089",
3
+ "version": "0.0.1091",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",