@camunda/e2e-test-suite 0.0.1262 → 0.0.1264

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.
@@ -77,12 +77,14 @@ class ModelerHomePage {
77
77
  await this.enterNewProjectName(this.defaultFolderName);
78
78
  }
79
79
  async clickCrossComponentProjectFolder() {
80
- await this.page
81
- .getByTitle(this.defaultFolderName, {
82
- exact: true,
83
- })
84
- .first()
85
- .click({ timeout: 4000 });
80
+ // Coming back to the Modeler home page mid-flow re-fetches and re-renders
81
+ // the project list, so the tile is not on screen the moment navigation
82
+ // resolves. A bare 4s click raced that render; wait for the tile first,
83
+ // the way every other version of this page object already does.
84
+ await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.crossComponentProjectFolder, {
85
+ visibilityTimeout: 30000,
86
+ });
87
+ await this.crossComponentProjectFolder.click({ timeout: 30000 });
86
88
  }
87
89
  async clickProcessDiagram(name) {
88
90
  const process = this.rows.filter({ hasText: name }).getByTitle(name).first();
@@ -0,0 +1,6 @@
1
+ import { Page } from '@playwright/test';
2
+ import { ModelerHomePage } from '../SM-8.10/ModelerHomePage';
3
+ declare class TopologyModelerHomePage extends ModelerHomePage {
4
+ constructor(page: Page);
5
+ }
6
+ export { TopologyModelerHomePage };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TopologyModelerHomePage = void 0;
4
+ const ModelerHomePage_1 = require("../SM-8.10/ModelerHomePage");
5
+ // The topology golden path runs against a mixed-version Hub: an 8.7 chart with
6
+ // the Web Modeler image built from the branch under test. That legacy Modeler
7
+ // has no Workspaces feature, and its Koa server serves an allowlist of client
8
+ // routes only, so a full-page load of the unrouted `/modeler/workspaces` falls
9
+ // through to a hard server 404 whose StaticPages/ErrorPage renders "Not Found".
10
+ // The shared SM-8.10 page object's flag-off detection matches only the Design
11
+ // System SPA's in-app router 404 ("no match for the current location"), so on
12
+ // 8.7 it never recognises the route as absent and its legacy fallback never
13
+ // engages. Widen the signal to also match the legacy hard 404 so
14
+ // ensureWorkspaceOpen falls through to the projects flow on this deployment.
15
+ // Scoped to SM-8.7: the shared object is left untouched for the passing 8.8/8.10
16
+ // consumers (see camunda/c8-cross-component-e2e-tests#3687 for the same fix in
17
+ // the shared object for the SM-8.8 topology spec).
18
+ class TopologyModelerHomePage extends ModelerHomePage_1.ModelerHomePage {
19
+ constructor(page) {
20
+ super(page);
21
+ this.noRouteMatchMessage = page
22
+ .getByText(/no match for the current location/i)
23
+ .or(page.getByText('Not Found', { exact: true }))
24
+ .first();
25
+ }
26
+ }
27
+ exports.TopologyModelerHomePage = TopologyModelerHomePage;
@@ -16,7 +16,11 @@ class KeycloakAdminPage {
16
16
  async switchToCamundaPlatform() {
17
17
  const realmSelector = this.page.getByTestId('nav-item-realms');
18
18
  await realmSelector.click();
19
+ // The realm dropdown is rendered by the admin console after an async
20
+ // realm lookup, so a bare click races Playwright's default 10s action
21
+ // timeout on a loaded cluster. Wait for it explicitly instead.
19
22
  const searchField = this.page.getByTestId('selectRealminput');
23
+ await (0, test_1.expect)(searchField).toBeVisible({ timeout: 30000 });
20
24
  await searchField.click();
21
25
  await this.page
22
26
  .getByPlaceholder('Search')
@@ -45,10 +45,16 @@ async function loginToKeycloakAdmin(navigationPage, keycloakLoginPage, keycloakA
45
45
  for (let attempt = 0; attempt < maxRetries; attempt++) {
46
46
  try {
47
47
  await navigationPage.goToKeycloak();
48
- await keycloakLoginPage.toBeVisible();
49
- await keycloakLoginPage.fillUsername((0, exports.keycloakAdminCredentials)().username);
50
- await keycloakLoginPage.fillPassword((0, exports.keycloakAdminCredentials)().password);
51
- await keycloakLoginPage.clickLogin();
48
+ // A failed attempt can still have authenticated: the submit click lands
49
+ // but its navigation outruns the action timeout, so the attempt throws
50
+ // while Keycloak keeps the master-realm session. Keycloak then serves
51
+ // the admin console straight away, and re-filling a login form that is
52
+ // no longer rendered makes every remaining attempt fail.
53
+ if (await keycloakLoginPage.keycloakBanner.isVisible()) {
54
+ await keycloakLoginPage.fillUsername((0, exports.keycloakAdminCredentials)().username);
55
+ await keycloakLoginPage.fillPassword((0, exports.keycloakAdminCredentials)().password);
56
+ await keycloakLoginPage.clickLogin();
57
+ }
52
58
  await keycloakAdminPage.toBeVisible();
53
59
  return;
54
60
  }
@@ -8,6 +8,7 @@ declare class NavigationPage {
8
8
  readonly identityPageBanner: Locator;
9
9
  readonly consolePageBanner: Locator;
10
10
  readonly keyboardPageBanner: Locator;
11
+ readonly keycloakAdminPageBanner: Locator;
11
12
  readonly managementIdentityPageBanner: Locator;
12
13
  constructor(page: Page);
13
14
  private isRetriableNavigationNetworkError;
@@ -48,6 +48,7 @@ class NavigationPage {
48
48
  identityPageBanner;
49
49
  consolePageBanner;
50
50
  keyboardPageBanner;
51
+ keycloakAdminPageBanner;
51
52
  managementIdentityPageBanner;
52
53
  constructor(page) {
53
54
  this.page = page;
@@ -76,6 +77,7 @@ class NavigationPage {
76
77
  .filter({ hasText: /^Camunda logo\s*Management Identity$/ })
77
78
  .first();
78
79
  this.keyboardPageBanner = page.locator('#keycloak-bg');
80
+ this.keycloakAdminPageBanner = page.locator('#kc-main-content-page-container');
79
81
  }
80
82
  isRetriableNavigationNetworkError(error) {
81
83
  const message = error instanceof Error ? error.message : String(error);
@@ -215,12 +217,19 @@ class NavigationPage {
215
217
  async goToModelerWithoutAccess({ username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}) {
216
218
  await this.goToWithoutAccess(MODELER_CONTEXT_PATH, username, password);
217
219
  }
220
+ // Resolves once Keycloak has settled on either its login form or, when the
221
+ // master-realm SSO session is still valid, the admin console it serves
222
+ // instead. Asserting the login form alone makes every retry of an already
223
+ // authenticated session time out on a form Keycloak will never render.
218
224
  async goToKeycloak() {
219
225
  const keycloakUrl = process.env.KEYCLOAK_URL
220
226
  ? `${process.env.KEYCLOAK_URL}/auth`
221
227
  : '/auth';
222
228
  await this.page.goto(keycloakUrl);
223
- await (0, test_1.expect)(this.keyboardPageBanner).toBeVisible({ timeout: 60000 });
229
+ await test_1.expect
230
+ .poll(async () => (await this.keyboardPageBanner.isVisible()) ||
231
+ (await this.keycloakAdminPageBanner.isVisible()), { timeout: 60000 })
232
+ .toBe(true);
224
233
  }
225
234
  async goToOCIdentity(sleepTimeout, credentials) {
226
235
  await this.goTo(`${NORMALIZED_ORCHESTRATION_CONTEXT_PATH}/identity`, this.identityPageBanner, sleepTimeout, credentials);
@@ -19,6 +19,7 @@ SM_8_7_1.test.describe.parallel('Console User Flow Tests', () => {
19
19
  (0, loggingUtils_1.cleanupTestLogging)();
20
20
  });
21
21
  (0, SM_8_7_1.test)('Custom Tags', async ({ consoleHomePage, clusterPage, navigationPage, context, }) => {
22
+ SM_8_7_1.test.slow();
22
23
  await SM_8_7_1.test.step('Navigate to Clusters', async () => {
23
24
  await context.clearCookies();
24
25
  await navigationPage.goToConsole();
@@ -33,6 +34,7 @@ SM_8_7_1.test.describe.parallel('Console User Flow Tests', () => {
33
34
  });
34
35
  });
35
36
  (0, SM_8_7_1.test)('Custom Properties', async ({ consoleHomePage, clusterPage, clusterDetailsPage, page, navigationPage, context, }) => {
37
+ SM_8_7_1.test.slow();
36
38
  await SM_8_7_1.test.step('Navigate to Cluster Details', async () => {
37
39
  await context.clearCookies();
38
40
  await navigationPage.goToConsole();
@@ -23,6 +23,7 @@ SM_8_7_1.test.describe.parallel('Optimize User Flow Tests', () => {
23
23
  (0, loggingUtils_1.cleanupTestLogging)();
24
24
  });
25
25
  (0, SM_8_7_1.test)('Process Import Flow', async ({ page, context, operateHomePage, modelerHomePage, navigationPage, modelerCreatePage, operateProcessesPage, operateProcessInstancePage, optimizeHomePage, optimizeDashboardPage, }) => {
26
+ SM_8_7_1.test.slow();
26
27
  const processName = 'Optimize_Job_Worker_User_Task_Flow' +
27
28
  (await (0, _setup_1.generateRandomStringAsync)(3));
28
29
  await SM_8_7_1.test.step('Open Cross Component Test Project and Create a BPMN Diagram Template', async () => {
@@ -122,6 +123,7 @@ SM_8_7_1.test.describe.parallel('Optimize User Flow Tests', () => {
122
123
  });
123
124
  });
124
125
  (0, SM_8_7_1.test)('New Instances Updated Flow', async ({ page, context, modelerHomePage, navigationPage, modelerCreatePage, operateHomePage, operateProcessesPage, operateProcessInstancePage, optimizeHomePage, optimizeCollectionsPage, optimizeReportPage, }) => {
126
+ SM_8_7_1.test.slow();
125
127
  const reportName = await (0, _setup_1.generateRandomStringAsync)(5);
126
128
  const processName = 'Optimize_Job_Worker_User_Task_Flow_Updated' +
127
129
  (await (0, _setup_1.generateRandomStringAsync)(3));
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const test_1 = require("@playwright/test");
4
4
  const SM_8_7_1 = require("../../fixtures/SM-8.7");
5
5
  const ModelerCreatePage_1 = require("../../pages/SM-8.10/ModelerCreatePage");
6
- const ModelerHomePage_1 = require("../../pages/SM-8.10/ModelerHomePage");
7
6
  const NavigationPage_1 = require("../../pages/SM-8.10/NavigationPage");
8
7
  const KeycloakUtils_1 = require("../../pages/SM-8.7/KeycloakUtils");
8
+ const TopologyModelerHomePage_1 = require("../../pages/SM-8.7/TopologyModelerHomePage");
9
9
  const UtlitiesPage_1 = require("../../pages/SM-8.7/UtlitiesPage");
10
10
  const _setup_1 = require("../../test-setup.js");
11
11
  const env_1 = require("../../utils/env");
@@ -17,7 +17,7 @@ SM_8_7_1.test.afterEach(async ({ page }, testInfo) => {
17
17
  SM_8_7_1.test.slow();
18
18
  const processName = `Topology_Orchestration_${await (0, _setup_1.generateRandomStringAsync)(5)}`;
19
19
  const hubNavigationPage = new NavigationPage_1.NavigationPage(page);
20
- const modelerHomePage = new ModelerHomePage_1.ModelerHomePage(page);
20
+ const modelerHomePage = new TopologyModelerHomePage_1.TopologyModelerHomePage(page);
21
21
  const modelerCreatePage = new ModelerCreatePage_1.ModelerCreatePage(page);
22
22
  (0, KeycloakUtils_1.setAdminUserCredentials)(navigationPage);
23
23
  await SM_8_7_1.test.step('Create and start a process in Web Modeler', async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1262",
3
+ "version": "0.0.1264",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",