@camunda/e2e-test-suite 0.0.255 → 0.0.257

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.
@@ -238,7 +238,10 @@ class ModelerCreatePage {
238
238
  await this.elemendIdInput.click();
239
239
  }
240
240
  async fillElementIdInput(id) {
241
+ await (0, test_1.expect)(this.elemendIdInput).toBeVisible();
241
242
  await this.elemendIdInput.fill(id);
243
+ await (0, test_1.expect)(this.elemendIdInput).toHaveValue(id);
244
+ await (0, sleep_1.sleep)(1000);
242
245
  }
243
246
  async clickStartEventElement() {
244
247
  await this.startEventElement.click({ force: true });
@@ -33,6 +33,8 @@ class PlayPage {
33
33
  });
34
34
  }
35
35
  async clickCompleteJobButton() {
36
+ await (0, test_1.expect)(this.completeJobButton).toBeVisible({ timeout: 60000 });
37
+ await (0, test_1.expect)(this.completeJobButton).toBeEnabled({ timeout: 60000 });
36
38
  await this.completeJobButton.click();
37
39
  }
38
40
  async clickStartInstanceButton() {
@@ -135,7 +135,7 @@ class ModelerCreatePage {
135
135
  this.diagramBreadcrumb = page.locator('[data-test="breadcrumb-diagram"]');
136
136
  this.renameDiagramNameButton = page.getByText('Rename');
137
137
  this.diagramNameInput = page.locator('[data-test="editable-input"]');
138
- this.variableInput = page.getByLabel('Variables');
138
+ this.variableInput = page.locator('[id="variables-json"]');
139
139
  this.embedFormButton = page.getByRole('button', { name: 'Link form' });
140
140
  this.embedButton = page.locator('[data-test="confirm-move"]');
141
141
  this.newForm = page.locator('[data-test="item-New form"]');
@@ -349,6 +349,7 @@ class ModelerCreatePage {
349
349
  await this.fillTenantIdInput(tenant);
350
350
  }
351
351
  await this.clickDeployAndRunSubButton();
352
+ await (0, test_1.expect)(this.dialog).not.toBeVisible();
352
353
  await this.instanceStartedAssertion();
353
354
  return;
354
355
  }
@@ -65,6 +65,8 @@ class PlayPage {
65
65
  });
66
66
  }
67
67
  async clickCompleteJobButton() {
68
+ await (0, test_1.expect)(this.completeJobButton).toBeVisible({ timeout: 30000 });
69
+ await (0, test_1.expect)(this.completeJobButton).toBeEnabled({ timeout: 30000 });
68
70
  await this.completeJobButton.click();
69
71
  }
70
72
  async clickStartInstanceButton() {
@@ -9,7 +9,6 @@ const loggingUtils_1 = require("../../utils/loggingUtils");
9
9
  const resetSession_1 = require("../../utils/resetSession");
10
10
  const KeycloakUtils_1 = require("../../pages/SM-8.9/KeycloakUtils");
11
11
  SM_8_9_1.test.describe.parallel('Smoke Tests', () => {
12
- SM_8_9_1.test.skip(true, 'Skipped due to Identity/admin change, will check and re-enable once the changes are in place');
13
12
  SM_8_9_1.test.beforeEach(async ({ navigationPage, managementIdentityPage, keycloakLoginPage, keycloakAdminPage, page, browser, loginPage, ocIdentityHomePage, ocIdentityRolesPage, }, testInfo) => {
14
13
  if (process.env.IS_MIGRATION === 'true') {
15
14
  await navigationPage.goToOCIdentity((testInfo.workerIndex + 1) * 1000);
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const c8Run_8_9_1 = require("../../fixtures/c8Run-8.9");
4
+ const test_1 = require("@playwright/test");
5
+ const UtilitiesPage_1 = require("../../pages/c8Run-8.9/UtilitiesPage");
6
+ const _setup_1 = require("../../test-setup.js");
7
+ const apiHelpers_1 = require("../../utils/apiHelpers");
8
+ const keycloakHelpers_1 = require("../../utils/keycloakHelpers");
9
+ const zeebeClient_1 = require("../../utils/zeebeClient");
10
+ const sleep_1 = require("../../utils/sleep");
11
+ let bearerToken;
12
+ const authMethods = [
13
+ {
14
+ name: 'Basic Auth',
15
+ processId: 'mcp_remote_client_basic_auth',
16
+ },
17
+ {
18
+ name: 'Bearer Token',
19
+ processId: 'mcp_remote_client_bearer_auth',
20
+ getVariables: () => ({ bearerToken }),
21
+ },
22
+ {
23
+ name: 'OAuth Client Credentials',
24
+ processId: 'mcp_remote_client_oauth_auth',
25
+ },
26
+ ];
27
+ c8Run_8_9_1.test.beforeAll(async () => {
28
+ if (process.env.MCP_SERVER_AVAILABLE !== 'true') {
29
+ return;
30
+ }
31
+ await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12001'); // No auth
32
+ await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12002'); // Basic auth
33
+ await (0, apiHelpers_1.validateMcpServerHealth)('http://127.0.0.1:12004'); // OAuth
34
+ await (0, keycloakHelpers_1.validateKeycloakHealth)();
35
+ bearerToken = await (0, keycloakHelpers_1.getAccessToken)();
36
+ await (0, zeebeClient_1.deploy)([
37
+ './resources/mcp_server/mcp_remote_client_basic_auth.bpmn',
38
+ './resources/mcp_server/mcp_remote_client_bearer_auth.bpmn',
39
+ './resources/mcp_server/mcp_remote_client_oauth_auth.bpmn',
40
+ ]);
41
+ });
42
+ c8Run_8_9_1.test.describe('@tasklistV2 MCP Client connector authentication tests', () => {
43
+ c8Run_8_9_1.test.skip(process.env.MCP_SERVER_AVAILABLE !== 'true', 'MCP authentication servers require Docker and are only available on Linux CI runners');
44
+ c8Run_8_9_1.test.beforeEach(async ({ page, operateLoginPage, operateHomePage }) => {
45
+ await (0, UtilitiesPage_1.navigateToApp)(page, 'operate');
46
+ await operateLoginPage.login('demo', 'demo');
47
+ await operateHomePage.operateBannerIsVisible();
48
+ });
49
+ c8Run_8_9_1.test.afterEach(async ({ page }, testInfo) => {
50
+ await (0, _setup_1.captureScreenshot)(page, testInfo);
51
+ await (0, _setup_1.captureFailureVideo)(page, testInfo);
52
+ });
53
+ for (const { name, processId, getVariables } of authMethods) {
54
+ (0, c8Run_8_9_1.test)(`As a user I can authenticate using ${name} and list tools`, async ({ operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
55
+ await (0, zeebeClient_1.createInstances)(processId, 1, 1, getVariables?.());
56
+ await (0, sleep_1.sleep)(2000);
57
+ await c8Run_8_9_1.test.step('Navigate to completed process instance', async () => {
58
+ await operateHomePage.clickProcessesTab();
59
+ await operateProcessesPage.clickProcessCompletedCheckbox();
60
+ await operateProcessesPage.clickProcessInstanceLink(processId);
61
+ await operateProcessInstancePage.completedIconAssertion();
62
+ });
63
+ await c8Run_8_9_1.test.step(`Verify ${name} successfully listed tools`, async () => {
64
+ await operateProcessInstancePage.verifyVariableJsonContent('listToolsResult', (value) => {
65
+ const data = value;
66
+ (0, test_1.expect)(data.toolDefinitions).toBeDefined();
67
+ (0, test_1.expect)(data.toolDefinitions.length).toBeGreaterThan(0);
68
+ (0, test_1.expect)(data.toolDefinitions.some((tool) => tool.name)).toBe(true);
69
+ });
70
+ });
71
+ });
72
+ }
73
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Helper functions for interacting with Keycloak OAuth2 server
3
+ */
4
+ /**
5
+ * Fetches an OAuth2 access token from Keycloak using client credentials flow
6
+ * @param realm - Keycloak realm name
7
+ * @param clientId - OAuth2 client ID
8
+ * @param clientSecret - OAuth2 client secret
9
+ * @param keycloakUrl - Base URL of Keycloak server
10
+ * @returns Access token string
11
+ */
12
+ export declare function getAccessToken(realm?: string, clientId?: string, clientSecret?: string, keycloakUrl?: string): Promise<string>;
13
+ /**
14
+ * Validates that Keycloak server is healthy and accessible
15
+ * @param keycloakUrl - Base URL of Keycloak server
16
+ */
17
+ export declare function validateKeycloakHealth(keycloakUrl?: string): Promise<void>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * Helper functions for interacting with Keycloak OAuth2 server
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateKeycloakHealth = exports.getAccessToken = void 0;
7
+ const DEFAULT_KEYCLOAK_URL = process.env.KEYCLOAK_URL || 'http://127.0.0.1:18080';
8
+ const DEFAULT_REALM = 'camunda-platform';
9
+ const DEFAULT_CLIENT_ID = 'zeebe';
10
+ const DEFAULT_CLIENT_SECRET = 'zecobe-secret';
11
+ /**
12
+ * Fetches an OAuth2 access token from Keycloak using client credentials flow
13
+ * @param realm - Keycloak realm name
14
+ * @param clientId - OAuth2 client ID
15
+ * @param clientSecret - OAuth2 client secret
16
+ * @param keycloakUrl - Base URL of Keycloak server
17
+ * @returns Access token string
18
+ */
19
+ async function getAccessToken(realm = DEFAULT_REALM, clientId = DEFAULT_CLIENT_ID, clientSecret = DEFAULT_CLIENT_SECRET, keycloakUrl = DEFAULT_KEYCLOAK_URL) {
20
+ const tokenEndpoint = `${keycloakUrl}/realms/${realm}/protocol/openid-connect/token`;
21
+ const params = new URLSearchParams();
22
+ params.append('grant_type', 'client_credentials');
23
+ params.append('client_id', clientId);
24
+ params.append('client_secret', clientSecret);
25
+ try {
26
+ const response = await fetch(tokenEndpoint, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/x-www-form-urlencoded',
30
+ },
31
+ body: params.toString(),
32
+ });
33
+ if (!response.ok) {
34
+ const errorText = await response.text();
35
+ throw new Error(`Failed to fetch access token from Keycloak: ${response.status} ${response.statusText}\n${errorText}`);
36
+ }
37
+ const data = await response.json();
38
+ if (!data.access_token) {
39
+ throw new Error('Access token not found in Keycloak response: ' + JSON.stringify(data));
40
+ }
41
+ return data.access_token;
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error) {
45
+ throw new Error(`Error fetching Keycloak access token: ${error.message}`);
46
+ }
47
+ throw error;
48
+ }
49
+ }
50
+ exports.getAccessToken = getAccessToken;
51
+ /**
52
+ * Validates that Keycloak server is healthy and accessible
53
+ * @param keycloakUrl - Base URL of Keycloak server
54
+ */
55
+ async function validateKeycloakHealth(keycloakUrl = DEFAULT_KEYCLOAK_URL) {
56
+ // Check if the camunda-platform realm is accessible instead of health endpoint
57
+ // since Keycloak 23+ may not expose health endpoints by default
58
+ const realmEndpoint = `${keycloakUrl}/realms/camunda-platform`;
59
+ try {
60
+ const response = await fetch(realmEndpoint, {
61
+ method: 'GET',
62
+ });
63
+ if (!response.ok) {
64
+ throw new Error(`Keycloak realm check failed: ${response.status} ${response.statusText}`);
65
+ }
66
+ console.log(`Keycloak server is healthy at ${keycloakUrl}`);
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error) {
70
+ throw new Error(`Keycloak server is not available at ${keycloakUrl}: ${error.message}\n` +
71
+ 'Make sure Keycloak is running with: docker run -d --name keycloak -p 18080:8080 ' +
72
+ '-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin ' +
73
+ 'quay.io/keycloak/keycloak:23.0 start-dev');
74
+ }
75
+ throw error;
76
+ }
77
+ }
78
+ exports.validateKeycloakHealth = validateKeycloakHealth;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.255",
3
+ "version": "0.0.257",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",