@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.
- package/dist/pages/SM-8.7/ModelerHomePage.js +8 -6
- package/dist/pages/SM-8.7/TopologyModelerHomePage.d.ts +6 -0
- package/dist/pages/SM-8.7/TopologyModelerHomePage.js +27 -0
- package/dist/pages/SM-8.9/KeycloakAdminPage.js +4 -0
- package/dist/pages/SM-8.9/KeycloakUtils.js +10 -4
- package/dist/pages/SM-8.9/NavigationPage.d.ts +1 -0
- package/dist/pages/SM-8.9/NavigationPage.js +10 -1
- package/dist/tests/SM-8.7/console-user-flows.spec.js +2 -0
- package/dist/tests/SM-8.7/optimize-user-flows.spec.js +2 -0
- package/dist/tests/SM-8.7/topology-orchestration-smoke.spec.js +2 -2
- package/package.json +1 -1
|
@@ -77,12 +77,14 @@ class ModelerHomePage {
|
|
|
77
77
|
await this.enterNewProjectName(this.defaultFolderName);
|
|
78
78
|
}
|
|
79
79
|
async clickCrossComponentProjectFolder() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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,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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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
|
|
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 () => {
|