@camunda/e2e-test-suite 0.0.856 → 0.0.858

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.
@@ -223,7 +223,7 @@ class ModelerCreatePage {
223
223
  this.copyPublicLinkButton = page.getByRole('button', {
224
224
  name: 'Copy to clipboard',
225
225
  });
226
- this.closeButton = page.getByRole('button', { name: 'Close' });
226
+ this.closeButton = page.getByRole('button', { name: 'Close', exact: true });
227
227
  this.rbaEnabledDeployedDialog = page.getByRole('dialog', {
228
228
  name: 'Process successfully deployed',
229
229
  });
@@ -101,19 +101,36 @@ class ModelerHomePage {
101
101
  // is not yet in edit mode as fill() runs, leaving the project named
102
102
  // "New project". Re-enter until the field reflects the requested name.
103
103
  //
104
- // Once the rename commits, the editable input unmounts and the title
105
- // renders as a static heading (`[title="<name>"]`) instead. A retry that
106
- // still assumes `[data-test="editable-input"]` is clickable then hangs on
107
- // an element that will never reappear, even though the rename already
108
- // succeeded. Treat the static title becoming visible as success.
104
+ // Once the rename commits, the editable input unmounts and the name
105
+ // renders as static text: on the projects list as a `[title="<name>"]`
106
+ // link, and on the project detail page (where this inline rename runs) as
107
+ // the breadcrumb project button's text. Matching only `[title]` missed the
108
+ // detail-page case, so after a successful rename the retry kept clicking a
109
+ // `[data-test="editable-input"]` that had already unmounted and hung for
110
+ // the full click timeout. Treat either committed-name rendering as success,
111
+ // and wait for it after Enter — the breadcrumb briefly shows "Loading..."
112
+ // until the change is persisted.
113
+ const committedProjectName = this.page
114
+ .getByTitle(name, { exact: true })
115
+ .or(this.page
116
+ .locator('[data-test="breadcrumb-project-menu"]')
117
+ .filter({ hasText: name }));
109
118
  await (0, test_1.expect)(async () => {
110
- if (await this.page.getByTitle(name, { exact: true }).isVisible()) {
119
+ if (await committedProjectName.first().isVisible()) {
111
120
  return;
112
121
  }
113
- await this.projectNameInput.click({ timeout: 60000 });
122
+ await this.projectNameInput.click({ timeout: 15000 });
114
123
  await this.projectNameInput.fill(name);
115
- await this.projectNameInput.press('Enter');
124
+ // Confirm the value actually landed in the edit field before committing;
125
+ // if fill() ran before edit mode was active the input stays empty/default
126
+ // and this fails, so toPass retries with a fresh click.
116
127
  await (0, test_1.expect)(this.projectNameInput).toHaveValue(name, { timeout: 5000 });
128
+ await this.projectNameInput.press('Enter');
129
+ await (0, sleep_1.sleep)(1000);
130
+ // Reload so the check reflects the PERSISTED server state, not the
131
+ // optimistic client render that can silently revert to "New project".
132
+ await this.page.reload();
133
+ await (0, test_1.expect)(committedProjectName.first()).toBeVisible({ timeout: 15000 });
117
134
  }).toPass({ timeout: 120000 });
118
135
  }
119
136
  async enterIdpApplicationName(name) {
@@ -129,8 +129,7 @@ _8_10_1.test.describe('User Roles User Flow', () => {
129
129
  await modelerCreatePage.clickCloseButton();
130
130
  });
131
131
  });
132
- //Skipped due to bug 46344: https://github.com/camunda/camunda/issues/46344
133
- _8_10_1.test.skip('Analyst Role User Flow', async ({ page, modelerHomePage, appsPage, homePage, clusterPage, clusterDetailsPage, browser, consoleOrganizationsPage, settingsPage, operateHomePage, ocIdentityHomePage, taskPanelPage, optimizeHomePage, modelerCreatePage, }) => {
132
+ (0, _8_10_1.test)('Analyst Role User Flow', async ({ page, modelerHomePage, appsPage, homePage, clusterPage, clusterDetailsPage, browser, consoleOrganizationsPage, settingsPage, operateHomePage, ocIdentityHomePage, taskPanelPage, optimizeHomePage, modelerCreatePage, }) => {
134
133
  _8_10_1.test.slow();
135
134
  const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
136
135
  const processName = 'User Roles User Flow' + randomString;
@@ -221,8 +220,7 @@ _8_10_1.test.describe('User Roles User Flow', () => {
221
220
  await modelerCreatePage.clickCloseButton();
222
221
  });
223
222
  });
224
- //Skipped due to bug 46344: https://github.com/camunda/camunda/issues/46344
225
- _8_10_1.test.skip('Admin Role User Flow', async ({ page, modelerHomePage, appsPage, homePage, clusterPage, clusterDetailsPage, browser, consoleOrganizationsPage, settingsPage, operateHomePage, ocIdentityHomePage, taskPanelPage, optimizeHomePage, modelerCreatePage, }) => {
223
+ (0, _8_10_1.test)('Admin Role User Flow', async ({ page, modelerHomePage, appsPage, homePage, clusterPage, clusterDetailsPage, browser, consoleOrganizationsPage, settingsPage, operateHomePage, ocIdentityHomePage, taskPanelPage, optimizeHomePage, modelerCreatePage, }) => {
226
224
  _8_10_1.test.slow();
227
225
  const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
228
226
  const processName = 'User Roles User Flow' + randomString;
@@ -6,9 +6,8 @@ const TaskPanelPage_1 = require("../../pages/8.10/TaskPanelPage");
6
6
  const TaskDetailsPage_1 = require("../../pages/8.10/TaskDetailsPage");
7
7
  const AppsPage_1 = require("../../pages/8.10/AppsPage");
8
8
  const OperateProcessInstancePage_1 = require("../../pages/8.10/OperateProcessInstancePage");
9
- // TODO: Re-enable Optimize imports when bug is fixed
10
- // import {OptimizeHomePage} from '../../pages/8.10/OptimizeHomePage';
11
- // import {OptimizeDashboardPage} from '../../pages/8.10/OptimizeDashboardPage';
9
+ const OptimizeHomePage_1 = require("../../pages/8.10/OptimizeHomePage");
10
+ const OptimizeDashboardPage_1 = require("../../pages/8.10/OptimizeDashboardPage");
12
11
  const fileUpload_1 = require("../../utils/fileUpload");
13
12
  const _setup_1 = require("../../test-setup.js");
14
13
  const UtilitiesPage_1 = require("../../pages/8.10/UtilitiesPage");
@@ -408,9 +407,13 @@ _8_10_1.test.describe('Web Modeler User Flow Tests', () => {
408
407
  });
409
408
  (0, _8_10_1.test)('Conditional Events - Deploy, verify in Operate and verify process in Optimize dashboard @tasklistV2', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, }) => {
410
409
  _8_10_1.test.slow();
411
- const bpmnFileName = 'Conditional_Events_All.bpmn';
412
- // TODO: Uncomment when Optimize tests are re-enabled
413
- // const processName = 'Conditional Events Auto-Run';
410
+ const suffix = await (0, _setup_1.generateRandomStringAsync)(5);
411
+ const diagramName = `Conditional_Events_All_${suffix}`;
412
+ const bpmnFileName = `${diagramName}.bpmn`;
413
+ const processName = `Conditional Events Auto-Run ${suffix}`;
414
+ const bpmnContent = (0, fileUpload_1.readResourceFile)('Conditional_Events_All.bpmn')
415
+ .replaceAll('conditional-events-auto-process', `conditional-events-auto-process-${suffix}`)
416
+ .replace('Conditional Events Auto-Run Demo', processName);
414
417
  await _8_10_1.test.step('Navigate to Web Modeler', async () => {
415
418
  await (0, test_1.expect)(homePage.camundaComponentsButton).toBeVisible({
416
419
  timeout: 120000,
@@ -425,11 +428,14 @@ _8_10_1.test.describe('Web Modeler User Flow Tests', () => {
425
428
  await modelerHomePage.clickCrossComponentProjectFolder();
426
429
  await modelerHomePage.clickDiagramTypeDropdown();
427
430
  await modelerHomePage.clickUploadFilesButton();
428
- await (0, fileUpload_1.uploadFile)(page, bpmnFileName);
431
+ await (0, fileUpload_1.uploadFileContent)(page, {
432
+ name: bpmnFileName,
433
+ buffer: Buffer.from(bpmnContent),
434
+ });
429
435
  });
430
436
  await _8_10_1.test.step('Open uploaded BPMN diagram', async () => {
431
437
  await (0, sleep_1.sleep)(5000);
432
- await modelerHomePage.clickProcessDiagram(bpmnFileName.replace('.bpmn', ''));
438
+ await modelerHomePage.clickProcessDiagram(diagramName);
433
439
  });
434
440
  await _8_10_1.test.step('Deploy and run process with variable', async () => {
435
441
  const variables = '{"myVar": 8}';
@@ -442,23 +448,20 @@ _8_10_1.test.describe('Web Modeler User Flow Tests', () => {
442
448
  await modelerCreatePage.clickViewProcessInstanceLink();
443
449
  const operateTabPromise = page.waitForEvent('popup', { timeout: 60000 });
444
450
  const operateTab = await operateTabPromise;
445
- // TODO: Uncomment when Optimize tests are re-enabled
446
- // const operateTabAppsPage = new AppsPage(operateTab);
447
451
  const operateProcessInstancePage = new OperateProcessInstancePage_1.OperateProcessInstancePage(operateTab);
448
452
  await operateProcessInstancePage.closePopOverIfVisible();
449
453
  await operateProcessInstancePage.assertProcessCompleteStatusWithRetry(60000, 15);
450
454
  await operateProcessInstancePage.assertProcessVariableContainsText('myVar', '8');
451
- //Skipped due to bug 46344: https://github.com/camunda/camunda/issues/46344
452
- // await test.step('Navigate to Optimize and verify process in dashboard', async () => {
453
- // const operateTabAppsPage = new AppsPage(operateTab);
454
- // await operateTabAppsPage.clickCamundaApps();
455
- // await operateTabAppsPage.clickOptimize(clusterName);
456
- // const optimizeHomePage = new OptimizeHomePage(operateTab);
457
- // const optimizeDashboardPage = new OptimizeDashboardPage(operateTab);
458
- // await optimizeHomePage.clickDashboardLink();
459
- // await sleep(60000);
460
- // await optimizeDashboardPage.processLinkAssertion(processName, 5);
461
- // });
455
+ await _8_10_1.test.step('Navigate to Optimize and verify process in dashboard', async () => {
456
+ const operateTabAppsPage = new AppsPage_1.AppsPage(operateTab);
457
+ await operateTabAppsPage.clickCamundaApps();
458
+ await operateTabAppsPage.clickOptimize(clusterName);
459
+ const optimizeHomePage = new OptimizeHomePage_1.OptimizeHomePage(operateTab);
460
+ const optimizeDashboardPage = new OptimizeDashboardPage_1.OptimizeDashboardPage(operateTab);
461
+ await optimizeHomePage.clickDashboardLink();
462
+ await (0, sleep_1.sleep)(60000);
463
+ await optimizeDashboardPage.processLinkAssertion(processName, 5);
464
+ });
462
465
  });
463
466
  });
464
467
  });
@@ -1,4 +1,10 @@
1
+ /// <reference types="node" />
1
2
  import { Page } from '@playwright/test';
3
+ type InMemoryFile = {
4
+ name: string;
5
+ mimeType?: string;
6
+ buffer: Buffer;
7
+ };
2
8
  /**
3
9
  * Uploads a file to the file input in the provided page.
4
10
  * @param page The Playwright page object.
@@ -6,3 +12,18 @@ import { Page } from '@playwright/test';
6
12
  * @throws Will throw an error if the file doesn't exist.
7
13
  */
8
14
  export declare function uploadFile(page: Page, fileNames: string | string[]): Promise<void>;
15
+ /**
16
+ * Uploads in-memory file content to the file input in the provided page.
17
+ * Use this to upload generated content (e.g. a fixture rewritten with a
18
+ * unique process id/name) without writing a temporary file to disk.
19
+ * @param page The Playwright page object.
20
+ * @param files The file(s) to upload, each with a name and buffer.
21
+ */
22
+ export declare function uploadFileContent(page: Page, files: InMemoryFile | InMemoryFile[]): Promise<void>;
23
+ /**
24
+ * Reads a fixture from the resources directory as a UTF-8 string.
25
+ * @param fileName The file name relative to the resources directory.
26
+ * @throws Will throw an error if the file doesn't exist.
27
+ */
28
+ export declare function readResourceFile(fileName: string): string;
29
+ export {};
@@ -3,9 +3,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.uploadFile = void 0;
6
+ exports.readResourceFile = exports.uploadFileContent = exports.uploadFile = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
+ async function setInputFilesWithFallback(page, files) {
10
+ const isPathList = files.every((file) => typeof file === 'string');
11
+ const payload = isPathList
12
+ ? files
13
+ : files.map((file) => ({
14
+ name: file.name,
15
+ mimeType: file.mimeType ?? 'application/xml',
16
+ buffer: file.buffer,
17
+ }));
18
+ try {
19
+ await page.locator('input[type="file"]').setInputFiles(payload);
20
+ }
21
+ catch {
22
+ try {
23
+ await page.getByLabel('Upload files').setInputFiles(payload);
24
+ }
25
+ catch {
26
+ await page.getByLabel('Upload documents').setInputFiles(payload);
27
+ }
28
+ }
29
+ }
9
30
  /**
10
31
  * Uploads a file to the file input in the provided page.
11
32
  * @param page The Playwright page object.
@@ -20,19 +41,32 @@ async function uploadFile(page, fileNames) {
20
41
  }
21
42
  });
22
43
  console.log('Uploading files:', filePaths);
23
- try {
24
- const fileInput = await page.locator('input[type="file"]');
25
- await fileInput.setInputFiles(filePaths);
26
- }
27
- catch {
28
- try {
29
- const fileInput = await page.getByLabel('Upload files');
30
- await fileInput.setInputFiles(filePaths);
31
- }
32
- catch {
33
- const fileInput = await page.getByLabel('Upload documents');
34
- await fileInput.setInputFiles(filePaths);
35
- }
36
- }
44
+ await setInputFilesWithFallback(page, filePaths);
37
45
  }
38
46
  exports.uploadFile = uploadFile;
47
+ /**
48
+ * Uploads in-memory file content to the file input in the provided page.
49
+ * Use this to upload generated content (e.g. a fixture rewritten with a
50
+ * unique process id/name) without writing a temporary file to disk.
51
+ * @param page The Playwright page object.
52
+ * @param files The file(s) to upload, each with a name and buffer.
53
+ */
54
+ async function uploadFileContent(page, files) {
55
+ const inMemoryFiles = Array.isArray(files) ? files : [files];
56
+ console.log('Uploading in-memory files:', inMemoryFiles.map((file) => file.name));
57
+ await setInputFilesWithFallback(page, inMemoryFiles);
58
+ }
59
+ exports.uploadFileContent = uploadFileContent;
60
+ /**
61
+ * Reads a fixture from the resources directory as a UTF-8 string.
62
+ * @param fileName The file name relative to the resources directory.
63
+ * @throws Will throw an error if the file doesn't exist.
64
+ */
65
+ function readResourceFile(fileName) {
66
+ const filePath = path_1.default.resolve(__dirname, '../resources', fileName);
67
+ if (!fs_1.default.existsSync(filePath)) {
68
+ throw new Error(`File not found: ${filePath}`);
69
+ }
70
+ return fs_1.default.readFileSync(filePath, 'utf-8');
71
+ }
72
+ exports.readResourceFile = readResourceFile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.856",
3
+ "version": "0.0.858",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",