@camunda/e2e-test-suite 0.0.587 → 0.0.589

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.
@@ -3,6 +3,6 @@ declare class ClusterDetailsPage {
3
3
  private page;
4
4
  readonly customPropertiesHeading: Locator;
5
5
  constructor(page: Page);
6
- assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string): Promise<void>;
6
+ assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string | RegExp): Promise<void>;
7
7
  }
8
8
  export { ClusterDetailsPage };
@@ -3,6 +3,6 @@ declare class ClusterDetailsPage {
3
3
  private page;
4
4
  readonly customPropertiesHeading: Locator;
5
5
  constructor(page: Page);
6
- assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string): Promise<void>;
6
+ assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string | RegExp): Promise<void>;
7
7
  }
8
8
  export { ClusterDetailsPage };
@@ -101,13 +101,40 @@ class Authorization {
101
101
  }
102
102
  await this.createAuthorizationSubmitButton.click();
103
103
  await (0, test_1.expect)(this.createAuthorizationModal).not.toBeVisible();
104
- await this.selectResourceTypeTab(authorization.resourceType).click();
105
- const item = this.page.getByRole('row').filter({
106
- hasText: `${authorization.ownerId}${authorization.resourceId}`,
107
- });
108
- await this.tableFilter.click();
109
- await this.tableFilter.fill(authorization.resourceType);
110
- await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(this.page, item, authorization.resourceType, 5000, false, 10, this.selectResourceTypeTab(authorization.resourceType));
104
+ // Match the created authorization row by chaining filters on owner ID and
105
+ // resource ID. A single concatenated `hasText` does not match because
106
+ // Playwright whitespace-normalizes cell text and the rendered table
107
+ // separates adjacent cells with whitespace (e.g. tab characters).
108
+ const item = this.page
109
+ .getByRole('row')
110
+ .filter({ hasText: authorization.ownerId })
111
+ .filter({ hasText: authorization.resourceId });
112
+ // Retry to handle eventual consistency after the submit. We cannot use the
113
+ // shared `assertLocatorVisibleWithRetry` helper here because the row may
114
+ // be on a later pagination page (Carbon DataTable does not render rows
115
+ // outside the current page), so we have to narrow the visible result set
116
+ // by typing the owner ID into the table search input (placeholder reads
117
+ // "Search by owner ID"). The filter input is cleared on every reload so we
118
+ // re-apply it on each attempt.
119
+ const maxAttempts = 10;
120
+ let lastError;
121
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
122
+ try {
123
+ await this.selectResourceTypeTab(authorization.resourceType).click();
124
+ await this.tableFilter.click();
125
+ await this.tableFilter.fill(authorization.ownerId);
126
+ await (0, test_1.expect)(item).toBeVisible({ timeout: 5000 });
127
+ return;
128
+ }
129
+ catch (error) {
130
+ lastError = error;
131
+ console.warn(`Attempt ${attempt + 1}/${maxAttempts} failed asserting ${authorization.resourceType} authorization row (${authorization.ownerId} / ${authorization.resourceId}). Retrying...`);
132
+ if (attempt < maxAttempts - 1) {
133
+ await this.page.reload();
134
+ }
135
+ }
136
+ }
137
+ throw new Error(`Authorization row not visible after ${maxAttempts} attempts: ${authorization.ownerId} / ${authorization.resourceId} (${authorization.resourceType}). Last error: ${lastError}`);
111
138
  }
112
139
  async deleteAuthorization(resourceId, resourceType) {
113
140
  await this.deleteAuthorizationButton(resourceId).click();
@@ -3,6 +3,6 @@ declare class ClusterDetailsPage {
3
3
  private page;
4
4
  readonly customPropertiesHeading: Locator;
5
5
  constructor(page: Page);
6
- assertCustomPropertyLink(linkTitle: string, linkName: string, expectedHref: string): Promise<void>;
6
+ assertCustomPropertyLink(linkTitle: string, linkName: string, expectedHref: string | RegExp): Promise<void>;
7
7
  }
8
8
  export { ClusterDetailsPage };
@@ -21,23 +21,21 @@ class ClusterDetailsPage {
21
21
  timeout: 10000,
22
22
  });
23
23
  await (0, test_1.expect)(linkElement).toBeEnabled();
24
- // Intercept the navigation to capture the URL being requested
25
- await this.page.context().route(expectedHref, (route) => {
26
- // We captured the correct URL request - that's what we wanted to test
27
- route.fulfill({
28
- status: 200,
29
- contentType: 'text/html',
30
- body: '<html><body>Navigation test passed</body></html>',
31
- });
32
- });
33
- // Also handle potential redirects by intercepting with wildcard patterns
34
- await this.page.context().route(expectedHref + '/**', (route) => {
35
- route.fulfill({
36
- status: 200,
37
- contentType: 'text/html',
38
- body: '<html><body>Navigation test passed</body></html>',
39
- });
24
+ // Intercept the navigation to avoid hitting external sites.
25
+ // When a RegExp is passed (e.g. to match both www and non-www variants),
26
+ // use it directly so both redirect and non-redirect paths are caught.
27
+ const fulfill = (route) => route.fulfill({
28
+ status: 200,
29
+ contentType: 'text/html',
30
+ body: '<html><body>Navigation test passed</body></html>',
40
31
  });
32
+ if (expectedHref instanceof RegExp) {
33
+ await this.page.context().route(expectedHref, fulfill);
34
+ }
35
+ else {
36
+ await this.page.context().route(expectedHref, fulfill);
37
+ await this.page.context().route(expectedHref + '/**', fulfill);
38
+ }
41
39
  // Ensure the link is in viewport and click it
42
40
  await linkElement.scrollIntoViewIfNeeded();
43
41
  // Click and verify a new page opens with the correct URL
@@ -50,8 +48,12 @@ class ClusterDetailsPage {
50
48
  ]);
51
49
  // Verify the navigation attempt went to the correct URL (handle trailing slashes)
52
50
  const actualUrl = newPage.url().replace(/\/$/, '');
53
- const expectedUrl = expectedHref.replace(/\/$/, '');
54
- (0, test_1.expect)(actualUrl).toBe(expectedUrl);
51
+ if (expectedHref instanceof RegExp) {
52
+ (0, test_1.expect)(actualUrl).toMatch(expectedHref);
53
+ }
54
+ else {
55
+ (0, test_1.expect)(actualUrl).toBe(expectedHref.replace(/\/$/, ''));
56
+ }
55
57
  await newPage.close();
56
58
  }
57
59
  }
@@ -135,6 +135,10 @@ class OCIdentityRolesPage {
135
135
  async deleteRole(name, options) {
136
136
  const { throwError = true } = options || {};
137
137
  try {
138
+ // The role may be on a later pagination page of the Carbon DataTable
139
+ // (off-page rows are not rendered in the DOM), so paginate to it before
140
+ // attempting to click the Delete button on its row.
141
+ await (0, expectLocatorWithPagination_1.expectLocatorWithPagination)(this.page, this.rolesList.getByRole('cell', { name }).first());
138
142
  await this.deleteRoleButton(name).click();
139
143
  await (0, test_1.expect)(this.deleteRoleModal).toBeVisible();
140
144
  await this.deleteRoleModalDeleteButton.click();
@@ -3,6 +3,6 @@ declare class ClusterDetailsPage {
3
3
  private page;
4
4
  readonly customPropertiesHeading: Locator;
5
5
  constructor(page: Page);
6
- assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string): Promise<void>;
6
+ assertCustomPropertyIsNavigated(linkTitle: string, linkName: string, link: string | RegExp): Promise<void>;
7
7
  }
8
8
  export { ClusterDetailsPage };
@@ -38,7 +38,7 @@ SM_8_10_1.test.describe('Console User Flow Tests', () => {
38
38
  await (0, test_1.expect)(page.getByText(customPropertyDescription)).toBeVisible({
39
39
  timeout: 60000,
40
40
  });
41
- await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', 'https://www.camunda.com');
41
+ await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', /^https:\/\/(www\.)?camunda\.com\/?$/);
42
42
  await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 2', 'Camunda Docs', 'https://docs.camunda.io');
43
43
  });
44
44
  });
@@ -46,7 +46,7 @@ SM_8_7_1.test.describe.parallel('Console User Flow Tests', () => {
46
46
  await (0, test_1.expect)(page.getByText(customPropertyDescription)).toBeVisible({
47
47
  timeout: 60000,
48
48
  });
49
- await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', 'https://www.camunda.com');
49
+ await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', /^https:\/\/(www\.)?camunda\.com\/?$/);
50
50
  await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 2', 'Camunda Docs', 'https://docs.camunda.io');
51
51
  });
52
52
  });
@@ -31,7 +31,7 @@ SM_8_8_1.test.describe('Console User Flow Tests', () => {
31
31
  {
32
32
  linkTitle: 'Link 1',
33
33
  linkName: 'Camunda',
34
- expectedHref: 'https://www.camunda.com',
34
+ expectedHref: /^https:\/\/(www\.)?camunda\.com\/?$/,
35
35
  },
36
36
  {
37
37
  linkTitle: 'Link 2',
@@ -38,7 +38,7 @@ SM_8_9_1.test.describe('Console User Flow Tests', () => {
38
38
  await (0, test_1.expect)(page.getByText(customPropertyDescription)).toBeVisible({
39
39
  timeout: 60000,
40
40
  });
41
- await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', 'https://www.camunda.com');
41
+ await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 1', 'Camunda', /^https:\/\/(www\.)?camunda\.com\/?$/);
42
42
  await clusterDetailsPage.assertCustomPropertyIsNavigated('Link 2', 'Camunda Docs', 'https://docs.camunda.io');
43
43
  });
44
44
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.587",
3
+ "version": "0.0.589",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",