@camunda/e2e-test-suite 0.0.310 → 0.0.312

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.
Files changed (30) hide show
  1. package/README.md +35 -11
  2. package/dist/pages/8.10/ClusterDetailsPage.d.ts +6 -0
  3. package/dist/pages/8.10/ClusterDetailsPage.js +22 -0
  4. package/dist/pages/8.6/ClusterDetailsPage.d.ts +6 -0
  5. package/dist/pages/8.6/ClusterDetailsPage.js +22 -0
  6. package/dist/pages/8.7/ClusterDetailsPage.d.ts +6 -0
  7. package/dist/pages/8.7/ClusterDetailsPage.js +22 -0
  8. package/dist/pages/8.8/ClusterDetailsPage.d.ts +6 -0
  9. package/dist/pages/8.8/ClusterDetailsPage.js +22 -0
  10. package/dist/pages/8.8/ClusterPage.js +1 -1
  11. package/dist/pages/8.8/OperateHomePage.js +2 -2
  12. package/dist/pages/8.8/UtilitiesPage.js +1 -1
  13. package/dist/pages/8.9/ClusterDetailsPage.d.ts +6 -0
  14. package/dist/pages/8.9/ClusterDetailsPage.js +22 -0
  15. package/dist/tests/8.10/saas-migration-path-user-flows.spec.d.ts +1 -0
  16. package/dist/tests/8.10/saas-migration-path-user-flows.spec.js +176 -0
  17. package/dist/tests/8.6/smoke-tests.spec.js +8 -2
  18. package/dist/tests/8.7/saas-migration-path-user-flows.spec.d.ts +1 -0
  19. package/dist/tests/8.7/saas-migration-path-user-flows.spec.js +150 -0
  20. package/dist/tests/8.7/smoke-tests.spec.js +8 -2
  21. package/dist/tests/8.8/saas-migration-path-user-flows.spec.d.ts +1 -0
  22. package/dist/tests/8.8/saas-migration-path-user-flows.spec.js +173 -0
  23. package/dist/tests/8.8/smoke-tests.spec.js +13 -3
  24. package/dist/tests/8.8/test-setup.spec.js +2 -1
  25. package/dist/tests/8.9/saas-migration-path-user-flows.spec.d.ts +1 -0
  26. package/dist/tests/8.9/saas-migration-path-user-flows.spec.js +176 -0
  27. package/dist/tests/8.9/smoke-tests.spec.js +11 -3
  28. package/dist/tests/c8Run-8.10/api-tests-v1.spec.js +67 -70
  29. package/dist/tests/c8Run-8.9/api-tests-v1.spec.js +67 -70
  30. package/package.json +1 -1
package/README.md CHANGED
@@ -57,14 +57,35 @@ For SaaS, a test run can be manually triggered for specific minor versions and t
57
57
 
58
58
  The workflow expects the following arguments:
59
59
 
60
- | Argument | Description | Examples |
61
- |-------------------------|----------------------------------------------------|--------------------------------------------|
62
- | C8 Minor Version | Minor version on format `<major>.<minor>` |`8.9`, `8.8` |
63
- | Cluster Generation Name | The full name of the cluster generation (not UUID) | `Camunda 8.8+gen16`, `Camunda 8.9.0-alpha5`|
60
+ | Argument | Description | Examples |
61
+ | ----------------------- | -------------------------------------------------- | ------------------------------------------- |
62
+ | C8 Minor Version | Minor version on format `<major>.<minor>` | `8.9`, `8.8` |
63
+ | Cluster Generation Name | The full name of the cluster generation (not UUID) | `Camunda 8.8+gen16`, `Camunda 8.9.0-alpha5` |
64
64
 
65
65
  > [!NOTE]
66
66
  > The cluster generation name used in the workflow run must be part of the Stable, Internal Dev, QA, or Alpha channel for it to be testable. A generation can be added to a channel in the [Camunda Accounts dashboard](https://accounts.ultrawombat.com/consoleadmin/channels)
67
67
 
68
+ #### SaaS Upgrade Path Testing
69
+
70
+ To validate an upgrade between two SaaS cluster versions, use the [SaaS Upgrade Path Testing GitHub Action](https://github.com/camunda/c8-cross-component-e2e-tests/actions/workflows/saas-upgrade-path-testing.yml).
71
+
72
+ The workflow provisions a fresh organization, runs pre-upgrade smoke tests, performs the UI-driven cluster upgrade, then validates the upgraded cluster. It supports the following upgrade paths:
73
+
74
+ - 8.6 → 8.7
75
+ - 8.7 → 8.8
76
+ - 8.8 → 8.9
77
+ - 8.9 → 8.10
78
+
79
+ The workflow expects the following arguments:
80
+
81
+ | Argument | Description | Examples |
82
+ | ----------------- | -------------------------------------------------------- | ------------------------------ |
83
+ | Source Version | Minor version to upgrade **from** | `8.8`, `8.9` |
84
+ | Source Generation | Full name of the source cluster generation | `Camunda 8.8+gen16` |
85
+ | Target Version | Minor version to upgrade **to** | `8.9`, `8.10` |
86
+ | Target Generation | Full name of the target cluster generation | `Release Test QA-8.9.0-alpha5` |
87
+ | Tasklist Version | Tasklist UI mode (`v1` or `v2`); forced to `v1` for <8.8 | `v1`, `v2` |
88
+
68
89
  #### SM with Helm
69
90
 
70
91
  For SM using Helm, a test run can manually trigger by specifying any component version as an input. TThis can be done through the following workflows:
@@ -272,6 +293,7 @@ To run MCP tests locally with c8Run, you need to start both the MCP test server
272
293
  1. Start the MCP server:
273
294
 
274
295
  **macOS/Windows:**
296
+
275
297
  ```bash
276
298
  docker run -d \
277
299
  --name mcp-test-server \
@@ -280,6 +302,7 @@ To run MCP tests locally with c8Run, you need to start both the MCP test server
280
302
  ```
281
303
 
282
304
  **Linux:**
305
+
283
306
  ```bash
284
307
  docker run -d \
285
308
  --name mcp-test-server \
@@ -444,13 +467,14 @@ By following this convention, we ensure **clarity, consistency, and alignment wi
444
467
  | `all-latest` | Runs SM tests against all latest versions |
445
468
 
446
469
  ### c8Run Supported Versions, Modes and Projects
447
- | Version | Docker Allowed? | OS When Docker | OS When Non-Docker | Projects (Non-Docker) | Projects (Docker) |
448
- |---------|----------------|-----------------|--------------------|----------------------|-----------------|
449
- | 8.6 | No | | ubuntu, macOS | | |
450
- | 8.7 | Yes | ubuntu-latest only | ubuntu, macOS, windows | chromium (ES) | chromium (ES) |
451
- | 8.8 | Yes | ubuntu-latest only | ubuntu, macOS, windows | chromium-v1 (ES) + chromium-v2 (ES) | chromium-v2 (ES) |
452
- | 8.9 | No | —| | chromium-v2 (RDBMS) | |
453
- | 8.10 | No |— | — | chromium-v2 (RDBMS) | — |
470
+
471
+ | Version | Docker Allowed? | OS When Docker | OS When Non-Docker | Projects (Non-Docker) | Projects (Docker) |
472
+ | ------- | --------------- | ------------------ | ---------------------- | ----------------------------------- | ----------------- |
473
+ | 8.6 | No | | ubuntu, macOS | | |
474
+ | 8.7 | Yes | ubuntu-latest only | ubuntu, macOS, windows | chromium (ES) | chromium (ES) |
475
+ | 8.8 | Yes | ubuntu-latest only | ubuntu, macOS, windows | chromium-v1 (ES) + chromium-v2 (ES) | chromium-v2 (ES) |
476
+ | 8.9 | No | | — | chromium-v2 (RDBMS) | — |
477
+ | 8.10 | No | — | — | chromium-v2 (RDBMS) | — |
454
478
 
455
479
  ## Viewing Test Results
456
480
 
@@ -38,6 +38,9 @@ declare class ClusterDetailsPage {
38
38
  readonly authorizationsHeading: Locator;
39
39
  readonly orchestrationClusterCheckbox: Locator;
40
40
  readonly clientCredentialsLink: (clientCredentials: string) => Locator;
41
+ readonly reviewUpdateButton: Locator;
42
+ readonly updateAvailableDialog: Locator;
43
+ readonly updateButton: Locator;
41
44
  constructor(page: Page);
42
45
  clickAPITab(): Promise<void>;
43
46
  clickCreateClientButton(): Promise<void>;
@@ -77,5 +80,8 @@ declare class ClusterDetailsPage {
77
80
  fillAPIClientName(name: string): Promise<void>;
78
81
  assertAlertText(text: string, timeout?: number, maxRetries?: number): Promise<void>;
79
82
  checkOrchestrationClusterCheckbox(): Promise<void>;
83
+ clickReviewUpdateButton(): Promise<void>;
84
+ clickUpdateButton(): Promise<void>;
85
+ performClusterUpdate(): Promise<void>;
80
86
  }
81
87
  export { ClusterDetailsPage };
@@ -44,6 +44,9 @@ class ClusterDetailsPage {
44
44
  authorizationsHeading;
45
45
  orchestrationClusterCheckbox;
46
46
  clientCredentialsLink;
47
+ reviewUpdateButton;
48
+ updateAvailableDialog;
49
+ updateButton;
47
50
  constructor(page) {
48
51
  this.page = page;
49
52
  this.apiTab = page.getByRole('tab', { name: 'API' });
@@ -135,6 +138,13 @@ class ClusterDetailsPage {
135
138
  .locator('label')
136
139
  .filter({ hasText: /^Orchestration Cluster API$/ });
137
140
  this.clientCredentialsLink = (clientCredentials) => page.getByRole('cell', { name: clientCredentials });
141
+ this.reviewUpdateButton = page.getByRole('button', { name: 'Review Update' });
142
+ this.updateAvailableDialog = page
143
+ .locator('.cds--modal-container')
144
+ .filter({ hasText: 'Update available' });
145
+ this.updateButton = this.updateAvailableDialog.getByRole('button', {
146
+ name: 'Update',
147
+ });
138
148
  }
139
149
  async clickAPITab() {
140
150
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 60000 });
@@ -482,5 +492,17 @@ class ClusterDetailsPage {
482
492
  await this.orchestrationClusterCheckbox.click();
483
493
  }
484
494
  }
495
+ async clickReviewUpdateButton() {
496
+ await this.reviewUpdateButton.click({ timeout: 60000 });
497
+ }
498
+ async clickUpdateButton() {
499
+ await this.updateButton.click({ timeout: 60000 });
500
+ }
501
+ async performClusterUpdate() {
502
+ await this.clickReviewUpdateButton();
503
+ await this.page.waitForTimeout(1000);
504
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 60000 });
505
+ await this.clickUpdateButton();
506
+ }
485
507
  }
486
508
  exports.ClusterDetailsPage = ClusterDetailsPage;
@@ -36,6 +36,9 @@ declare class ClusterDetailsPage {
36
36
  readonly clientCredentialsLink: (clientCredentials: string) => Locator;
37
37
  readonly clientRow: (name: string) => Locator;
38
38
  readonly clientRowDeleteButton: (name: string) => Locator;
39
+ readonly reviewUpdateButton: Locator;
40
+ readonly updateAvailableDialog: Locator;
41
+ readonly updateButton: Locator;
39
42
  constructor(page: Page);
40
43
  clickAPITab(): Promise<void>;
41
44
  deleteAPIClientsIfExist(name?: string): Promise<void>;
@@ -65,5 +68,8 @@ declare class ClusterDetailsPage {
65
68
  disableRBA(): Promise<void>;
66
69
  assertComponentsHealth(components?: string[]): Promise<void>;
67
70
  userTaskEnabledAssertion(): Promise<void>;
71
+ clickReviewUpdateButton(): Promise<void>;
72
+ clickUpdateButton(): Promise<void>;
73
+ performClusterUpdate(): Promise<void>;
68
74
  }
69
75
  export { ClusterDetailsPage };
@@ -42,6 +42,9 @@ class ClusterDetailsPage {
42
42
  clientCredentialsLink;
43
43
  clientRow;
44
44
  clientRowDeleteButton;
45
+ reviewUpdateButton;
46
+ updateAvailableDialog;
47
+ updateButton;
45
48
  constructor(page) {
46
49
  this.page = page;
47
50
  this.apiTab = page.getByRole('tab', { name: 'API' });
@@ -128,6 +131,13 @@ class ClusterDetailsPage {
128
131
  this.clientCredentialsLink = (clientCredentials) => page.getByRole('cell', { name: clientCredentials });
129
132
  this.clientRow = (name) => this.clientsList.filter({ hasText: name });
130
133
  this.clientRowDeleteButton = (name) => this.clientRow(name).getByRole('button', { name: 'Delete' });
134
+ this.reviewUpdateButton = page.getByRole('button', { name: 'Review Update' });
135
+ this.updateAvailableDialog = page
136
+ .locator('.cds--modal-container')
137
+ .filter({ hasText: 'Update available' });
138
+ this.updateButton = this.updateAvailableDialog.getByRole('button', {
139
+ name: 'Update',
140
+ });
131
141
  }
132
142
  async clickAPITab() {
133
143
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 15000 });
@@ -415,5 +425,17 @@ class ClusterDetailsPage {
415
425
  await (0, test_1.expect)(this.userTaskRestriction.getAttribute('aria-checked')).toBe('true');
416
426
  }
417
427
  }
428
+ async clickReviewUpdateButton() {
429
+ await this.reviewUpdateButton.click({ timeout: 60000 });
430
+ }
431
+ async clickUpdateButton() {
432
+ await this.updateButton.click({ timeout: 60000 });
433
+ }
434
+ async performClusterUpdate() {
435
+ await this.clickReviewUpdateButton();
436
+ await this.page.waitForTimeout(1000);
437
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 60000 });
438
+ await this.clickUpdateButton();
439
+ }
418
440
  }
419
441
  exports.ClusterDetailsPage = ClusterDetailsPage;
@@ -42,6 +42,9 @@ declare class ClusterDetailsPage {
42
42
  readonly clientCredentialsLink: (clientCredentials: string) => Locator;
43
43
  readonly clientRow: (name: string) => Locator;
44
44
  readonly clientRowDeleteButton: (name: string) => Locator;
45
+ readonly reviewUpdateButton: Locator;
46
+ readonly updateAvailableDialog: Locator;
47
+ readonly updateButton: Locator;
45
48
  constructor(page: Page);
46
49
  clickAPITab(): Promise<void>;
47
50
  clickCreateClientButton(): Promise<void>;
@@ -81,5 +84,8 @@ declare class ClusterDetailsPage {
81
84
  checkZeebeCheckbox(): Promise<void>;
82
85
  fillAPIClientName(name: string): Promise<void>;
83
86
  clickExpandButton(): Promise<void>;
87
+ clickReviewUpdateButton(): Promise<void>;
88
+ clickUpdateButton(): Promise<void>;
89
+ performClusterUpdate(): Promise<void>;
84
90
  }
85
91
  export { ClusterDetailsPage };
@@ -48,6 +48,9 @@ class ClusterDetailsPage {
48
48
  clientCredentialsLink;
49
49
  clientRow;
50
50
  clientRowDeleteButton;
51
+ reviewUpdateButton;
52
+ updateAvailableDialog;
53
+ updateButton;
51
54
  constructor(page) {
52
55
  this.page = page;
53
56
  this.apiTab = page.getByRole('tab', { name: 'API' });
@@ -151,6 +154,13 @@ class ClusterDetailsPage {
151
154
  this.clientCredentialsLink = (clientCredentials) => page.getByRole('cell', { name: clientCredentials });
152
155
  this.clientRow = (name) => this.clientsList.filter({ hasText: name });
153
156
  this.clientRowDeleteButton = (name) => this.clientRow(name).getByRole('button', { name: 'Delete' });
157
+ this.reviewUpdateButton = page.getByRole('button', { name: 'Review Update' });
158
+ this.updateAvailableDialog = page
159
+ .locator('.cds--modal-container')
160
+ .filter({ hasText: 'Update available' });
161
+ this.updateButton = this.updateAvailableDialog.getByRole('button', {
162
+ name: 'Update',
163
+ });
154
164
  }
155
165
  async clickAPITab() {
156
166
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 60000 });
@@ -459,5 +469,17 @@ class ClusterDetailsPage {
459
469
  async clickExpandButton() {
460
470
  await this.expandButton.click({ timeout: 60000 });
461
471
  }
472
+ async clickReviewUpdateButton() {
473
+ await this.reviewUpdateButton.click({ timeout: 60000 });
474
+ }
475
+ async clickUpdateButton() {
476
+ await this.updateButton.click({ timeout: 60000 });
477
+ }
478
+ async performClusterUpdate() {
479
+ await this.clickReviewUpdateButton();
480
+ await this.page.waitForTimeout(1000);
481
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 60000 });
482
+ await this.clickUpdateButton();
483
+ }
462
484
  }
463
485
  exports.ClusterDetailsPage = ClusterDetailsPage;
@@ -40,6 +40,9 @@ declare class ClusterDetailsPage {
40
40
  readonly clientCredentialsLink: (clientCredentials: string) => Locator;
41
41
  readonly clientRow: (name: string) => Locator;
42
42
  readonly clientRowDeleteButton: (name: string) => Locator;
43
+ readonly reviewUpdateButton: Locator;
44
+ readonly updateAvailableDialog: Locator;
45
+ readonly updateButton: Locator;
43
46
  constructor(page: Page);
44
47
  clickAPITab(): Promise<void>;
45
48
  clickCreateClientButton(): Promise<void>;
@@ -79,5 +82,8 @@ declare class ClusterDetailsPage {
79
82
  fillAPIClientName(name: string): Promise<void>;
80
83
  assertAlertText(text: string, timeout?: number, maxRetries?: number): Promise<void>;
81
84
  checkOrchestrationClusterCheckbox(): Promise<void>;
85
+ clickReviewUpdateButton(): Promise<void>;
86
+ clickUpdateButton(): Promise<void>;
87
+ performClusterUpdate(): Promise<void>;
82
88
  }
83
89
  export { ClusterDetailsPage };
@@ -46,6 +46,9 @@ class ClusterDetailsPage {
46
46
  clientCredentialsLink;
47
47
  clientRow;
48
48
  clientRowDeleteButton;
49
+ reviewUpdateButton;
50
+ updateAvailableDialog;
51
+ updateButton;
49
52
  constructor(page) {
50
53
  this.page = page;
51
54
  this.apiTab = page.getByRole('tab', { name: 'API' });
@@ -131,6 +134,13 @@ class ClusterDetailsPage {
131
134
  this.clientCredentialsLink = (clientCredentials) => page.getByRole('cell', { name: clientCredentials });
132
135
  this.clientRow = (name) => this.clientsList.filter({ hasText: name });
133
136
  this.clientRowDeleteButton = (name) => this.clientRow(name).getByRole('button', { name: 'Delete' });
137
+ this.reviewUpdateButton = page.getByRole('button', { name: 'Review Update' });
138
+ this.updateAvailableDialog = page.getByRole('dialog', {
139
+ name: 'Update available',
140
+ });
141
+ this.updateButton = this.updateAvailableDialog.getByRole('button', {
142
+ name: 'Update',
143
+ });
134
144
  }
135
145
  async clickAPITab() {
136
146
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 60000 });
@@ -487,5 +497,17 @@ class ClusterDetailsPage {
487
497
  await this.orchestrationClusterCheckbox.click();
488
498
  }
489
499
  }
500
+ async clickReviewUpdateButton() {
501
+ await this.reviewUpdateButton.click({ timeout: 60000 });
502
+ }
503
+ async clickUpdateButton() {
504
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 30000 });
505
+ await this.updateButton.click({ timeout: 60000 });
506
+ }
507
+ async performClusterUpdate() {
508
+ await this.clickReviewUpdateButton();
509
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 30000 });
510
+ await this.updateButton.click({ timeout: 60000 });
511
+ }
490
512
  }
491
513
  exports.ClusterDetailsPage = ClusterDetailsPage;
@@ -308,7 +308,7 @@ class ClusterPage {
308
308
  return;
309
309
  }
310
310
  catch (error) {
311
- console.log('Version option not found in this tab, trying next tab if available...');
311
+ console.log(`Version option ${version} not found in this tab, trying next tab if available...`);
312
312
  }
313
313
  }
314
314
  }
@@ -45,8 +45,8 @@ class OperateHomePage {
45
45
  await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.processesTab);
46
46
  await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.processPageHeading, {
47
47
  preAction: async () => {
48
- await (0, test_1.expect)(this.processesTab).toBeVisible({ timeout: 10000 });
49
- await this.processesTab.click({ timeout: 10000 });
48
+ await (0, test_1.expect)(this.processesTab).toBeVisible({ timeout: 30000 });
49
+ await this.processesTab.click({ timeout: 30000 });
50
50
  },
51
51
  });
52
52
  }
@@ -36,7 +36,7 @@ async function modelRestConnector(modelerCreatePage, connectorSettingsPage, proc
36
36
  timeout: 120000,
37
37
  });
38
38
  await modelerCreatePage.enterDiagramName(processName);
39
- await (0, sleep_1.sleep)(10000);
39
+ await (0, sleep_1.sleep)(15000);
40
40
  await modelerCreatePage.clickAppendElementButton();
41
41
  await modelerCreatePage.clickAppendTaskButton();
42
42
  await modelerCreatePage.clickChangeTypeButton();
@@ -44,6 +44,9 @@ declare class ClusterDetailsPage {
44
44
  readonly mcpSupportToggle: Locator;
45
45
  readonly mcpTab: Locator;
46
46
  readonly mcpTextarea: Locator;
47
+ readonly reviewUpdateButton: Locator;
48
+ readonly updateAvailableDialog: Locator;
49
+ readonly updateButton: Locator;
47
50
  constructor(page: Page);
48
51
  clickAPITab(): Promise<void>;
49
52
  clickCreateClientButton(): Promise<void>;
@@ -54,6 +57,9 @@ declare class ClusterDetailsPage {
54
57
  clickOperateCheckbox(): Promise<void>;
55
58
  clickOptimizeCheckbox(): Promise<void>;
56
59
  clickCreateButton(): Promise<void>;
60
+ clickReviewUpdateButton(): Promise<void>;
61
+ clickUpdateButton(): Promise<void>;
62
+ performClusterUpdate(): Promise<void>;
57
63
  clickCloseModalButton(): Promise<void>;
58
64
  clickSettingsTab(): Promise<void>;
59
65
  enableAuthorizations(): Promise<void>;
@@ -49,6 +49,9 @@ class ClusterDetailsPage {
49
49
  mcpSupportToggle;
50
50
  mcpTab;
51
51
  mcpTextarea;
52
+ reviewUpdateButton;
53
+ updateAvailableDialog;
54
+ updateButton;
52
55
  constructor(page) {
53
56
  this.page = page;
54
57
  this.apiTab = page.getByRole('tab', { name: 'API' });
@@ -146,6 +149,13 @@ class ClusterDetailsPage {
146
149
  });
147
150
  this.mcpTab = page.getByRole('tab', { name: 'MCP' });
148
151
  this.mcpTextarea = page.getByLabel('MCP', { exact: true }).locator('pre');
152
+ this.reviewUpdateButton = page.getByRole('button', { name: 'Review Update' });
153
+ this.updateAvailableDialog = page
154
+ .locator('.cds--modal-container')
155
+ .filter({ hasText: 'Update available' });
156
+ this.updateButton = this.updateAvailableDialog.getByRole('button', {
157
+ name: 'Update',
158
+ });
149
159
  }
150
160
  async clickAPITab() {
151
161
  await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 60000 });
@@ -177,6 +187,18 @@ class ClusterDetailsPage {
177
187
  async clickCreateButton() {
178
188
  await this.createButton.click({ timeout: 60000 });
179
189
  }
190
+ async clickReviewUpdateButton() {
191
+ await this.reviewUpdateButton.click({ timeout: 60000 });
192
+ }
193
+ async clickUpdateButton() {
194
+ await this.updateButton.click({ timeout: 60000 });
195
+ }
196
+ async performClusterUpdate() {
197
+ await this.clickReviewUpdateButton();
198
+ await this.page.waitForTimeout(1000);
199
+ await (0, test_1.expect)(this.updateAvailableDialog).toBeVisible({ timeout: 60000 });
200
+ await this.clickUpdateButton();
201
+ }
180
202
  async clickCloseModalButton() {
181
203
  await this.closeModalButton.click({ timeout: 60000 });
182
204
  }
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * SaaS Migration Path User Flows (8.9 → 8.10)
5
+ *
6
+ * This test suite focuses on UI upgrade automation and basic validation.
7
+ * Comprehensive functionality validation is handled by smoke test comparison
8
+ * rather than custom data validation to avoid code duplication.
9
+ *
10
+ * The complete upgrade testing flow:
11
+ * 1. Pre-upgrade: Infrastructure setup + smoke test baseline capture
12
+ * 2. Upgrade UI: This file's @saasUpgrade test (UI automation)
13
+ * 3. Post-upgrade: Smoke test comparison for comprehensive validation
14
+ *
15
+ */
16
+ const _setup_1 = require("../../test-setup.js");
17
+ const _8_10_1 = require("../../fixtures/8.10");
18
+ const test_1 = require("@playwright/test");
19
+ const UtilitiesPage_1 = require("../../pages/8.10/UtilitiesPage");
20
+ const users_1 = require("../../utils/users");
21
+ // For SaaS upgrade testing, use dynamically created organization owner credentials
22
+ // For regular testing, fall back to predefined test user
23
+ const testUser = process.env.IS_MIGRATION === 'true'
24
+ ? {
25
+ username: process.env.C8_USERNAME,
26
+ password: process.env.C8_PASSWORD,
27
+ }
28
+ : (0, users_1.getTestUser)('twentyFirstUser');
29
+ _8_10_1.test.describe.configure({ mode: 'serial' });
30
+ _8_10_1.test.describe('SaaS Migration Path Tests', () => {
31
+ _8_10_1.test.beforeEach(async ({ page, loginPage }, testInfo) => {
32
+ // Skip if not in migration mode
33
+ if (process.env.IS_MIGRATION !== 'true') {
34
+ _8_10_1.test.skip(true, 'Skipping migration tests outside of migration mode');
35
+ }
36
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, (testInfo.workerIndex + 1) * 1000);
37
+ });
38
+ _8_10_1.test.afterEach(async ({ page }, testInfo) => {
39
+ await (0, _setup_1.captureScreenshot)(page, testInfo);
40
+ await (0, _setup_1.captureFailureVideo)(page, testInfo);
41
+ });
42
+ (0, _8_10_1.test)('SaaS UI Upgrade Flow Automation @saasUpgrade', async ({ page, homePage, clusterPage, clusterDetailsPage, }) => {
43
+ _8_10_1.test.slow();
44
+ await _8_10_1.test.step('Navigate to SaaS Upgrade Section', async () => {
45
+ await homePage.clickClusters();
46
+ await clusterPage.clickClusterLink('Test Cluster');
47
+ await clusterDetailsPage.performClusterUpdate();
48
+ await homePage.clickClusters();
49
+ await clusterPage.assertClusterHealthyStatusWithRetry('Test Cluster');
50
+ await (0, test_1.expect)(page.getByText(process.env.MINOR_VERSION)).toBeVisible();
51
+ });
52
+ });
53
+ (0, _8_10_1.test)('Basic Navigation After SaaS Upgrade', async ({ homePage, appsPage, modelerHomePage, operateHomePage, optimizeHomePage, taskPanelPage, ocIdentityHomePage, }) => {
54
+ const clusterName = 'Test Cluster';
55
+ await _8_10_1.test.step('Assert Web Modeler Navigation', async () => {
56
+ await appsPage.clickCamundaApps();
57
+ await appsPage.clickModeler();
58
+ await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
59
+ timeout: 120000,
60
+ });
61
+ await modelerHomePage.clickMessageBanner();
62
+ });
63
+ await _8_10_1.test.step('Assert Console Navigation', async () => {
64
+ await appsPage.clickCamundaApps();
65
+ await appsPage.clickConsoleLink();
66
+ await (0, test_1.expect)(homePage.consoleBanner).toBeVisible({
67
+ timeout: 120000,
68
+ });
69
+ });
70
+ await _8_10_1.test.step('Assert Operate Navigation', async () => {
71
+ await appsPage.clickCamundaApps();
72
+ await appsPage.clickOperate(clusterName);
73
+ await (0, test_1.expect)(operateHomePage.operateBanner).toBeVisible({
74
+ timeout: 120000,
75
+ });
76
+ });
77
+ await _8_10_1.test.step('Assert Optimize Navigation', async () => {
78
+ await appsPage.clickCamundaApps();
79
+ await appsPage.clickOptimize(clusterName);
80
+ await (0, test_1.expect)(optimizeHomePage.optimizeBanner).toBeVisible({
81
+ timeout: 120000,
82
+ });
83
+ });
84
+ await _8_10_1.test.step('Assert Tasklist Navigation', async () => {
85
+ await appsPage.clickCamundaApps();
86
+ await appsPage.clickTasklist(clusterName);
87
+ await (0, test_1.expect)(taskPanelPage.taskListPageBanner).toBeVisible({
88
+ timeout: 120000,
89
+ });
90
+ });
91
+ await _8_10_1.test.step('Assert Admin Navigation', async () => {
92
+ await appsPage.clickCamundaApps();
93
+ await appsPage.clickAdmin(clusterName);
94
+ await (0, test_1.expect)(ocIdentityHomePage.adminBanner).toBeVisible({
95
+ timeout: 120000,
96
+ });
97
+ });
98
+ });
99
+ (0, _8_10_1.test)('Assert Process Instances Persist After SaaS Upgrade', async ({ page, appsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, optimizeHomePage, optimizeReportPage, taskPanelPage, }) => {
100
+ _8_10_1.test.slow();
101
+ // Use the same fixed names that were created in the pre-upgrade smoke tests
102
+ const processName = 'Zeebe_User_Task_ProcessUpgradeTest';
103
+ const reportName = 'UpgradeTestReport';
104
+ const clusterName = 'Test Cluster';
105
+ await _8_10_1.test.step('View Process Instance in Operate', async () => {
106
+ await appsPage.clickCamundaApps();
107
+ await appsPage.clickOperate(clusterName);
108
+ await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({
109
+ timeout: 120000,
110
+ });
111
+ await operateHomePage.clickProcessesTab();
112
+ await operateProcessesPage.clickProcessCompletedCheckbox();
113
+ await operateProcessesPage.clickProcessInstanceLink(processName);
114
+ await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
115
+ });
116
+ await _8_10_1.test.step('View Process Instance in Tasklist', async () => {
117
+ await appsPage.clickCamundaApps();
118
+ await appsPage.clickTasklist(clusterName);
119
+ await taskPanelPage.filterBy('Completed');
120
+ await (0, test_1.expect)(page.getByRole('heading', { name: 'completed' })).toBeVisible({
121
+ timeout: 45000,
122
+ });
123
+ await (0, test_1.expect)(page.getByText(processName)).toBeVisible({ timeout: 60000 });
124
+ });
125
+ await _8_10_1.test.step('View Report in Optimize', async () => {
126
+ await appsPage.clickCamundaApps();
127
+ await appsPage.clickOptimize(clusterName);
128
+ await optimizeHomePage.clickCollectionsLink();
129
+ // Look for the specific report created during pre-upgrade smoke tests
130
+ await (0, test_1.expect)(page.getByText(reportName)).toBeVisible({
131
+ timeout: 60000,
132
+ });
133
+ await page.getByText(reportName).click();
134
+ await optimizeReportPage.waitUntilLocatorIsVisible(optimizeReportPage.oneUserTaskInstance, page);
135
+ await (0, test_1.expect)(optimizeReportPage.oneUserTaskInstance).toBeVisible({
136
+ timeout: 90000,
137
+ });
138
+ });
139
+ });
140
+ (0, _8_10_1.test)('Assert SaaS Organization Data Persists After Upgrade', async ({ page, appsPage, }) => {
141
+ await _8_10_1.test.step('Verify Organization Settings Persist', async () => {
142
+ await appsPage.clickCamundaApps();
143
+ await appsPage.clickConsoleLink();
144
+ await page.getByRole('button', { name: 'Organization Settings' }).click();
145
+ // Verify organization name and settings
146
+ await (0, test_1.expect)(page.getByTestId('organization-name')).toBeVisible();
147
+ await (0, test_1.expect)(page.getByTestId('organization-members')).toBeVisible();
148
+ });
149
+ await _8_10_1.test.step('Verify User Roles and Permissions Persist', async () => {
150
+ await page.getByRole('tab', { name: 'Members' }).click();
151
+ // Verify existing users still have correct roles
152
+ await (0, test_1.expect)(page.getByText('Owner')).toBeVisible();
153
+ await (0, test_1.expect)(page.getByText('Developer')).toBeVisible();
154
+ await (0, test_1.expect)(page.getByText('Modeler')).toBeVisible();
155
+ });
156
+ });
157
+ (0, _8_10_1.test)('Assert Connectors Still Function After SaaS Upgrade @tasklistV2', async ({ operateHomePage, appsPage, operateProcessesPage, operateProcessInstancePage, }) => {
158
+ _8_10_1.test.slow();
159
+ // Use the same fixed name that was created in the pre-upgrade smoke tests
160
+ const processName = 'REST_Connector_Basic_Auth_ProcessUpgradeTest';
161
+ const clusterName = 'Test Cluster';
162
+ await _8_10_1.test.step('View Connector Process Instance in Operate', async () => {
163
+ await appsPage.clickCamundaApps();
164
+ await appsPage.clickOperate(clusterName);
165
+ await operateHomePage.clickProcessesTab();
166
+ await operateProcessesPage.clickProcessCompletedCheckbox();
167
+ await operateProcessesPage.clickProcessInstanceLink(processName);
168
+ await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
169
+ await (0, test_1.expect)(operateProcessInstancePage.variablesList).toBeVisible({
170
+ timeout: 60000,
171
+ });
172
+ await (0, test_1.expect)(operateProcessInstancePage.connectorResultVariableName('message')).toBeVisible({ timeout: 60000 });
173
+ await (0, test_1.expect)(operateProcessInstancePage.messageVariable.getByText('"Message from Mock!"')).toBeVisible({ timeout: 60000 });
174
+ });
175
+ });
176
+ });
@@ -20,6 +20,8 @@ _8_6_1.test.describe.configure({ mode: 'parallel' });
20
20
  _8_6_1.test.describe('Smoke Tests', () => {
21
21
  _8_6_1.test.skip(process.env.IS_AG === 'true', 'Skipping Smoke Tests due to console breaking changes');
22
22
  const clusterName = 'Test Cluster';
23
+ // Use fixed names for upgrade testing validation, random names for regular testing
24
+ const useFixedNames = process.env.UPGRADE_BASELINE === 'true';
23
25
  _8_6_1.test.beforeEach(async ({ page, loginPage }, testInfo) => {
24
26
  await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, (testInfo.workerIndex + 1) * 1000);
25
27
  });
@@ -29,11 +31,15 @@ _8_6_1.test.describe('Smoke Tests', () => {
29
31
  });
30
32
  (0, _8_6_1.test)('Most Common Flow User Flow With All Apps', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
31
33
  _8_6_1.test.slow();
32
- const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
34
+ const randomString = useFixedNames
35
+ ? 'UpgradeTest'
36
+ : await (0, _setup_1.generateRandomStringAsync)(3);
33
37
  const formName = 'New form' + randomString;
34
38
  const processName = 'Zeebe_User_Task_Process' + randomString;
35
39
  const userTaskName = 'zeebeUserTaskWithForm' + randomString;
36
- const reportName = await (0, _setup_1.generateRandomStringAsync)(5);
40
+ const reportName = useFixedNames
41
+ ? 'UpgradeTestReport'
42
+ : await (0, _setup_1.generateRandomStringAsync)(5);
37
43
  await _8_6_1.test.step('Navigate to Web Modeler', async () => {
38
44
  await (0, test_1.expect)(homePage.camundaComponentsButton).toBeVisible({
39
45
  timeout: 30000,