@camunda/e2e-test-suite 0.0.331 → 0.0.333

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 (37) hide show
  1. package/dist/pages/SM-8.10/IdentityTenantPage.js +2 -1
  2. package/dist/pages/SM-8.10/ModelerCreatePage.d.ts +1 -1
  3. package/dist/pages/SM-8.10/ModelerCreatePage.js +5 -1
  4. package/dist/pages/SM-8.10/OCIdentityClusterVariablesPage.js +7 -3
  5. package/dist/pages/SM-8.10/OperateProcessesPage.js +1 -1
  6. package/dist/pages/SM-8.10/PlayPage.js +3 -4
  7. package/dist/pages/SM-8.10/TaskDetailsPage.js +2 -2
  8. package/dist/pages/SM-8.10/TaskPanelPage.js +3 -1
  9. package/dist/pages/SM-8.10/UtilitiesPage.d.ts +4 -4
  10. package/dist/pages/SM-8.10/UtilitiesPage.js +42 -9
  11. package/dist/pages/SM-8.6/IdentityTenantPage.js +1 -0
  12. package/dist/pages/SM-8.7/IdentityTenantPage.js +1 -0
  13. package/dist/pages/SM-8.8/IdentityTenantPage.js +1 -0
  14. package/dist/pages/SM-8.9/IdentityTenantPage.js +2 -1
  15. package/dist/pages/SM-8.9/ModelerCreatePage.d.ts +1 -1
  16. package/dist/pages/SM-8.9/ModelerCreatePage.js +5 -1
  17. package/dist/pages/SM-8.9/OCIdentityClusterVariablesPage.js +7 -3
  18. package/dist/pages/SM-8.9/OperateProcessesPage.js +1 -1
  19. package/dist/pages/SM-8.9/PlayPage.js +3 -4
  20. package/dist/pages/SM-8.9/TaskDetailsPage.js +2 -2
  21. package/dist/pages/SM-8.9/TaskPanelPage.js +3 -1
  22. package/dist/pages/SM-8.9/UtilitiesPage.d.ts +4 -4
  23. package/dist/pages/SM-8.9/UtilitiesPage.js +42 -9
  24. package/dist/tests/SM-8.10/cluster-variables.spec.js +48 -12
  25. package/dist/tests/SM-8.10/connectors-user-flows.spec.js +7 -6
  26. package/dist/tests/SM-8.10/hto-user-flows.spec.js +7 -6
  27. package/dist/tests/SM-8.10/mt-enabled-user-flows.spec.js +8 -6
  28. package/dist/tests/SM-8.10/play.spec.js +9 -2
  29. package/dist/tests/SM-8.6/mt-enabled-user-flows.spec.js +8 -6
  30. package/dist/tests/SM-8.8/mt-enabled-user-flows.spec.js +8 -6
  31. package/dist/tests/SM-8.9/cluster-variables.spec.js +48 -12
  32. package/dist/tests/SM-8.9/connectors-user-flows.spec.js +7 -6
  33. package/dist/tests/SM-8.9/hto-user-flows.spec.js +7 -6
  34. package/dist/tests/SM-8.9/mt-enabled-user-flows.spec.js +8 -6
  35. package/dist/tests/SM-8.9/play.spec.js +9 -2
  36. package/dist/utils/apiHelpers.js +15 -5
  37. package/package.json +1 -1
@@ -167,7 +167,8 @@ class IdentityTenantPage {
167
167
  await this.clickAssignUsersButton();
168
168
  await this.clickSearchUsersInput();
169
169
  await this.fillSearchUsersInput(user);
170
- await this.page.getByText(userEmail).click();
170
+ await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({ timeout: 30000 });
171
+ await this.page.getByText(userEmail).click({ timeout: 30000 });
171
172
  await this.clickAssignUserFinalButton();
172
173
  }
173
174
  async removeUserFromTenant(tenantName) {
@@ -86,7 +86,7 @@ declare class ModelerCreatePage {
86
86
  readonly closeDetailsPanel: Locator;
87
87
  readonly openDetailsPanel: Locator;
88
88
  constructor(page: Page);
89
- deployProcessInstance(): Promise<void>;
89
+ deployProcessInstance(tenant?: string): Promise<void>;
90
90
  clickCloseModalButton(): Promise<void>;
91
91
  modelCamundaUserTaskDiagram(processName: string, processId?: string, formName?: string): Promise<void>;
92
92
  modelJobWorkerDiagram(processName: string): Promise<void>;
@@ -245,8 +245,12 @@ class ModelerCreatePage {
245
245
  this.closeDetailsPanel = page.getByTitle('Close Details Panel');
246
246
  this.openDetailsPanel = page.getByTitle('Open Details Panel');
247
247
  }
248
- async deployProcessInstance() {
248
+ async deployProcessInstance(tenant = '') {
249
249
  await this.clickDeployButton();
250
+ if (tenant.length > 0) {
251
+ await this.clickTenantIdInput();
252
+ await this.fillTenantIdInput(tenant);
253
+ }
250
254
  await this.clickDeploySubButton();
251
255
  await (0, test_1.expect)(this.page.getByText('Process successfully deployed')).toBeVisible({
252
256
  timeout: 30000,
@@ -51,9 +51,13 @@ class OCIdentityClusterVariablesPage {
51
51
  await (0, test_1.expect)(this.variableValueField).toBeVisible();
52
52
  await (0, test_1.expect)(this.monacoEditor).toBeVisible();
53
53
  await this.monacoEditor.click();
54
- await this.monacoEditorTextArea.clear();
55
- await this.monacoEditorTextArea.fill(newValue);
56
- await (0, test_1.expect)(this.saveVariableButton).toBeEnabled();
54
+ // Monaco editor doesn't respond reliably to clear()/fill() on the
55
+ // hidden textarea. Use keyboard shortcuts to select-all and replace,
56
+ // which mirrors real user interaction.
57
+ await this.monacoEditorTextArea.press('Control+a');
58
+ await this.monacoEditorTextArea.press('Delete');
59
+ await this.monacoEditorTextArea.pressSequentially(newValue, { delay: 10 });
60
+ await (0, test_1.expect)(this.saveVariableButton).toBeEnabled({ timeout: 10000 });
57
61
  await this.saveVariableButton.click();
58
62
  await (0, test_1.expect)(this.successMessage).toBeVisible();
59
63
  await (0, test_1.expect)(this.editVariableModal).toBeHidden();
@@ -144,7 +144,7 @@ class OperateProcessesPage {
144
144
  return;
145
145
  }
146
146
  const MAX_ATTEMPTS = 100;
147
- const TOTAL_TIMEOUT_MS = constants_1._1_MINUTE_IN_MS * 2;
147
+ const TOTAL_TIMEOUT_MS = constants_1._1_MINUTE_IN_MS * 4;
148
148
  let attempt = 0;
149
149
  let lastError;
150
150
  const startTime = Date.now();
@@ -68,11 +68,11 @@ class PlayPage {
68
68
  await this.completeJobButton.click();
69
69
  }
70
70
  async clickStartInstanceButton() {
71
- const maxRetries = 3;
71
+ const maxRetries = 5;
72
72
  let attempts = 0;
73
73
  while (attempts < maxRetries) {
74
74
  try {
75
- await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
75
+ await this.diagram.waitFor({ state: 'visible', timeout: 60000 });
76
76
  await this.startInstanceButton
77
77
  .or(this.startInstanceWithCachedButton)
78
78
  .first()
@@ -86,8 +86,7 @@ class PlayPage {
86
86
  catch (error) {
87
87
  if (attempts >= maxRetries - 1)
88
88
  throw error;
89
- await this.page.reload();
90
- await (0, sleep_1.sleep)(2000);
89
+ await (0, sleep_1.sleep)(5000);
91
90
  attempts++;
92
91
  }
93
92
  }
@@ -94,7 +94,7 @@ class TaskDetailsPage {
94
94
  this.detailsInfo = page.getByTestId('details-info');
95
95
  this.textInput = page.locator('[class="fjs-input"]');
96
96
  this.textInput = page.locator('[class="fjs-input"]');
97
- this.taskCompletedBanner = this.page.getByText('Task completed');
97
+ this.taskCompletedBanner = this.page.getByText('Task completed').first();
98
98
  this.assignedToMeText = page
99
99
  .getByTestId('assignee')
100
100
  .getByText('Assigned to me');
@@ -248,7 +248,7 @@ class TaskDetailsPage {
248
248
  let attempts = 0;
249
249
  while (attempts < maxAttempts) {
250
250
  try {
251
- await (0, test_1.expect)(this.page.getByText(expectedText)).toBeVisible({
251
+ await (0, test_1.expect)(this.page.getByText(expectedText).first()).toBeVisible({
252
252
  timeout: 60000,
253
253
  });
254
254
  return;
@@ -40,6 +40,7 @@ class TaskPanelPage {
40
40
  async openTask(name, assignButton = true) {
41
41
  for (let attempt = 1; attempt <= 30; attempt++) {
42
42
  try {
43
+ await this.page.waitForLoadState('networkidle');
43
44
  await this.availableTasks
44
45
  .getByText(name, { exact: true })
45
46
  .nth(0)
@@ -55,9 +56,10 @@ class TaskPanelPage {
55
56
  if (attempt < 30) {
56
57
  console.warn(`Attempt ${attempt} failed. Reloading page...`);
57
58
  await this.page.reload();
59
+ await (0, sleep_1.sleep)(2000);
58
60
  }
59
61
  else {
60
- throw new Error(`Failed to open task "${name}" after 3 attempts: ${error}`);
62
+ throw new Error(`Failed to open task "${name}" after ${attempt} attempts: ${error}`);
61
63
  }
62
64
  }
63
65
  }
@@ -15,10 +15,10 @@ import { OCIdentityMappingRulesPage } from '../SM-8.10/OCIdentityMappingRulesPag
15
15
  import { OCIdentityRolesPage } from '../SM-8.10/OCIdentityRolesPage';
16
16
  import { Serializable } from 'playwright-core/types/structs';
17
17
  export declare function deleteAllUserGroups(): Promise<void>;
18
- export declare function runMultipleProcesses(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, numberOfProcesses: number, processName: string, processId?: string): Promise<void>;
18
+ export declare function runMultipleProcesses(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, numberOfProcesses: number, processName: string, processId?: string, tenant?: string): Promise<void>;
19
19
  export declare function createUserAndAssignToRole(page: Page, navigationPage: NavigationPage, managementIdentityPage: ManagementIdentityPage, keycloakLoginPage: KeycloakLoginPage, keycloakAdminPage: KeycloakAdminPage, ocIdentityHomePage: OCIdentityHomePage, identityMappingRulesPage: OCIdentityMappingRulesPage, identityRolesPage: OCIdentityRolesPage, username: string, password: string, role?: string, testMappings?: Serializable): Promise<void>;
20
20
  export declare function assignMappingToRole(page: Page, ocIdentityHomePage: OCIdentityHomePage, ocIdentityRolesPage: OCIdentityRolesPage, role: string, mappingRuleId: string, testMappings?: Serializable): Promise<void>;
21
- export declare function createAndRunProcess(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, processId?: string): Promise<void>;
21
+ export declare function createAndRunProcess(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, processId?: string, tenant?: string): Promise<void>;
22
22
  export declare function completeTaskWithRetry(page: Page, taskPanelPage: TaskPanelPage, taskDetailsPage: TaskDetailsPage, taskName: string, taskPriority: string, maxRetries?: number): Promise<void>;
23
23
  export declare function modelRestConnector(modelerCreatePage: ModelerCreatePage, connectorSettingsPage: ConnectorSettingsPage, connectorMarketplacePage: ConnectorMarketplacePage, processName: string, url: string, auth: string, resultExpression: string, resultVariable?: string, basicAuthCredentials?: {
24
24
  username: string;
@@ -27,8 +27,8 @@ export declare function modelRestConnector(modelerCreatePage: ModelerCreatePage,
27
27
  export declare function assertLocatorVisibleWithPaginated(page: Page, locator: Locator, text: string): Promise<void>;
28
28
  export declare function assertLocatorVisibleWithRetry(page: Page, locator: Locator, text: string, timeout?: number, notVisible?: boolean, maxRetries?: number, clickLocator?: Locator): Promise<void>;
29
29
  export declare function assertPageTextWithRetry(page: Page, text: string, notVisible?: boolean, timeout?: number, maxRetries?: number): Promise<void>;
30
- export declare function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, connectorTemplatePage: ConnectorTemplatePage): Promise<void>;
30
+ export declare function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, connectorTemplatePage: ConnectorTemplatePage, tenant?: string): Promise<void>;
31
31
  export declare function findTextWithPagination(page: Page, text: string, timeout?: number, action?: (locator: Locator) => Promise<void>): Promise<boolean>;
32
32
  export declare function modelDiagramFromFile(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, fileName?: string, nrOfRenamedUserTasks?: number, taskName?: string): Promise<void>;
33
33
  export declare function expectTextWithPagination(page: Page, text: string, shouldExist?: boolean, timeout?: number): Promise<void>;
34
- export declare function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string, endpoint: string): Promise<void>;
34
+ export declare function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string, endpoint: string, tenant?: string): Promise<void>;
@@ -14,9 +14,9 @@ async function deleteAllUserGroups() {
14
14
  // await identityPage.deleteAllGroups();
15
15
  }
16
16
  exports.deleteAllUserGroups = deleteAllUserGroups;
17
- async function runMultipleProcesses(page, modelerHomePage, modelerCreatePage, numberOfProcesses, processName, processId = '') {
17
+ async function runMultipleProcesses(page, modelerHomePage, modelerCreatePage, numberOfProcesses, processName, processId = '', tenant = '') {
18
18
  for (let i = 1; i <= numberOfProcesses; i++) {
19
- await createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName + i, processId.length > 0 ? processId + i : processId);
19
+ await createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName + i, processId.length > 0 ? processId + i : processId, tenant);
20
20
  }
21
21
  }
22
22
  exports.runMultipleProcesses = runMultipleProcesses;
@@ -57,15 +57,30 @@ async function assignMappingToRole(page, ocIdentityHomePage, ocIdentityRolesPage
57
57
  await assertLocatorVisibleWithPaginated(page, ocIdentityRolesPage.mappingRuleRow(mappingRuleId).first(), `${mappingRuleId} Mapping Rule`);
58
58
  }
59
59
  exports.assignMappingToRole = assignMappingToRole;
60
- async function createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName, processId = '') {
60
+ async function createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName, processId = '', tenant = '') {
61
61
  await modelerHomePage.clickDiagramTypeDropdown();
62
62
  await modelerHomePage.clickBpmnTemplateOption();
63
63
  await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processId);
64
- await modelerCreatePage.runProcessInstance();
64
+ await modelerCreatePage.runProcessInstance('', tenant);
65
65
  await modelerHomePage.clickProjectBreadcrumb();
66
66
  }
67
67
  exports.createAndRunProcess = createAndRunProcess;
68
68
  async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskName, taskPriority, maxRetries = 7) {
69
+ // Dismiss any lingering "Task completed" toast from a previous completion
70
+ // to avoid strict mode violations and stale UI state
71
+ try {
72
+ const toastCloseButton = page
73
+ .locator('.cds--toast-notification')
74
+ .getByRole('button', { name: /close/i })
75
+ .first();
76
+ if (await toastCloseButton.isVisible({ timeout: 2000 })) {
77
+ await toastCloseButton.click();
78
+ await (0, sleep_1.sleep)(500);
79
+ }
80
+ }
81
+ catch {
82
+ // No toast to dismiss, continue
83
+ }
69
84
  for (let attempt = 0; attempt < maxRetries; attempt++) {
70
85
  try {
71
86
  await page.waitForLoadState('networkidle');
@@ -78,8 +93,12 @@ async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskN
78
93
  throw new Error(`Task ${taskName} not found in available tasks`);
79
94
  }
80
95
  await taskPanelPage.openTask(taskName, false);
81
- await (0, sleep_1.sleep)(500);
96
+ await (0, sleep_1.sleep)(1000);
82
97
  await (0, test_1.expect)(taskDetailsPage.detailsPanel).toBeVisible({ timeout: 30000 });
98
+ // Verify the correct task is loaded by checking the task name appears
99
+ // in the details-info section (the task name heading is outside the
100
+ // complementary panel, so we use detailsInfo instead of detailsPanel)
101
+ await (0, test_1.expect)(taskDetailsPage.detailsInfo.getByText(taskName)).toBeVisible({ timeout: 30000 });
83
102
  if (!(await taskDetailsPage.assignedToMeText.isVisible({ timeout: 5000 }))) {
84
103
  await taskDetailsPage.clickAssignToMeButton();
85
104
  }
@@ -92,6 +111,20 @@ async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskN
92
111
  catch (error) {
93
112
  console.warn(`Attempt ${attempt + 1} failed for completing task ${taskName}:`, error instanceof Error ? error.message : error);
94
113
  if (attempt < maxRetries - 1) {
114
+ // Dismiss any toast before reloading
115
+ try {
116
+ const toastCloseButton = page
117
+ .locator('.cds--toast-notification')
118
+ .getByRole('button', { name: /close/i })
119
+ .first();
120
+ if (await toastCloseButton.isVisible({ timeout: 1000 })) {
121
+ await toastCloseButton.click();
122
+ await (0, sleep_1.sleep)(300);
123
+ }
124
+ }
125
+ catch {
126
+ // No toast to dismiss
127
+ }
95
128
  await page.reload();
96
129
  await page.waitForLoadState('networkidle');
97
130
  await (0, sleep_1.sleep)(500);
@@ -275,7 +308,7 @@ async function assertPageTextWithRetry(page, text, notVisible, timeout = 120000,
275
308
  }
276
309
  }
277
310
  exports.assertPageTextWithRetry = assertPageTextWithRetry;
278
- async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, connectorTemplatePage) {
311
+ async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, connectorTemplatePage, tenant = '') {
279
312
  await modelerHomePage.clickCrossComponentProjectFolder();
280
313
  await modelerHomePage.clickDiagramTypeDropdown();
281
314
  await modelerHomePage.clickUploadFilesButton();
@@ -311,7 +344,7 @@ async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modeler
311
344
  await (0, sleep_1.sleep)(5000);
312
345
  await page.reload();
313
346
  await (0, sleep_1.sleep)(5000);
314
- await modelerCreatePage.runProcessInstance();
347
+ await modelerCreatePage.runProcessInstance('', tenant);
315
348
  }
316
349
  exports.modelAndRunConnectorsTimerEventDiagram = modelAndRunConnectorsTimerEventDiagram;
317
350
  async function findTextWithPagination(page, text, timeout = 30000, action) {
@@ -393,7 +426,7 @@ async function expectTextWithPagination(page, text, shouldExist = true, timeout
393
426
  }
394
427
  }
395
428
  exports.expectTextWithPagination = expectTextWithPagination;
396
- async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, zeebeUrl, zeebeClientId, zeebeClientSecret, endpoint) {
429
+ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, zeebeUrl, zeebeClientId, zeebeClientSecret, endpoint, tenant = '') {
397
430
  await modelerHomePage.clickCrossComponentProjectFolder();
398
431
  await modelerHomePage.clickDiagramTypeDropdown();
399
432
  await modelerHomePage.clickUploadFilesButton();
@@ -430,6 +463,6 @@ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modele
430
463
  await modelerCreatePage.clickCloseDetailsPanel();
431
464
  await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(9) > .djs-element > .djs-hit'), endpoint, { openPanel: true });
432
465
  await (0, sleep_1.sleep)(2000);
433
- await modelerCreatePage.runProcessInstance();
466
+ await modelerCreatePage.runProcessInstance('', tenant);
434
467
  }
435
468
  exports.modelAndRunConnectorsDocHandlingDiagram = modelAndRunConnectorsDocHandlingDiagram;
@@ -139,6 +139,7 @@ class IdentityTenantPage {
139
139
  await this.clickAssignUsersButton();
140
140
  await this.clickSearchUsersInput();
141
141
  await this.fillSearchUsersInput(user);
142
+ await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({ timeout: 30000 });
142
143
  await this.page.getByText(userEmail).click();
143
144
  await this.clickAssignUserFinalButton();
144
145
  await (0, test_1.expect)(this.page.getByText('Users assigned')).toBeVisible({
@@ -233,6 +233,7 @@ class IdentityTenantPage {
233
233
  await this.clickAssignUsersButton();
234
234
  await this.clickSearchUsersInput();
235
235
  await this.fillSearchUsersInput(user);
236
+ await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({ timeout: 30000 });
236
237
  await this.page.getByText(userEmail).click();
237
238
  await this.clickAssignUserFinalButton();
238
239
  await (0, test_1.expect)(this.page.getByText('Users assigned')).toBeVisible({
@@ -166,6 +166,7 @@ class IdentityTenantPage {
166
166
  await this.clickAssignUsersButton();
167
167
  await this.clickSearchUsersInput();
168
168
  await this.fillSearchUsersInput(user);
169
+ await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({ timeout: 30000 });
169
170
  await this.page.getByText(userEmail).click();
170
171
  await this.clickAssignUserFinalButton();
171
172
  }
@@ -167,7 +167,8 @@ class IdentityTenantPage {
167
167
  await this.clickAssignUsersButton();
168
168
  await this.clickSearchUsersInput();
169
169
  await this.fillSearchUsersInput(user);
170
- await this.page.getByText(userEmail).click();
170
+ await (0, test_1.expect)(this.page.getByText(userEmail)).toBeVisible({ timeout: 30000 });
171
+ await this.page.getByText(userEmail).click({ timeout: 30000 });
171
172
  await this.clickAssignUserFinalButton();
172
173
  }
173
174
  async removeUserFromTenant(tenantName) {
@@ -86,7 +86,7 @@ declare class ModelerCreatePage {
86
86
  readonly closeDetailsPanel: Locator;
87
87
  readonly openDetailsPanel: Locator;
88
88
  constructor(page: Page);
89
- deployProcessInstance(): Promise<void>;
89
+ deployProcessInstance(tenant?: string): Promise<void>;
90
90
  clickCloseModalButton(): Promise<void>;
91
91
  modelCamundaUserTaskDiagram(processName: string, processId?: string, formName?: string): Promise<void>;
92
92
  modelJobWorkerDiagram(processName: string): Promise<void>;
@@ -245,8 +245,12 @@ class ModelerCreatePage {
245
245
  this.closeDetailsPanel = page.getByTitle('Close Details Panel');
246
246
  this.openDetailsPanel = page.getByTitle('Open Details Panel');
247
247
  }
248
- async deployProcessInstance() {
248
+ async deployProcessInstance(tenant = '') {
249
249
  await this.clickDeployButton();
250
+ if (tenant.length > 0) {
251
+ await this.clickTenantIdInput();
252
+ await this.fillTenantIdInput(tenant);
253
+ }
250
254
  await this.clickDeploySubButton();
251
255
  await (0, test_1.expect)(this.page.getByText('Process successfully deployed')).toBeVisible({
252
256
  timeout: 30000,
@@ -51,9 +51,13 @@ class OCIdentityClusterVariablesPage {
51
51
  await (0, test_1.expect)(this.variableValueField).toBeVisible();
52
52
  await (0, test_1.expect)(this.monacoEditor).toBeVisible();
53
53
  await this.monacoEditor.click();
54
- await this.monacoEditorTextArea.clear();
55
- await this.monacoEditorTextArea.fill(newValue);
56
- await (0, test_1.expect)(this.saveVariableButton).toBeEnabled();
54
+ // Monaco editor doesn't respond reliably to clear()/fill() on the
55
+ // hidden textarea. Use keyboard shortcuts to select-all and replace,
56
+ // which mirrors real user interaction.
57
+ await this.monacoEditorTextArea.press('Control+a');
58
+ await this.monacoEditorTextArea.press('Delete');
59
+ await this.monacoEditorTextArea.pressSequentially(newValue, { delay: 10 });
60
+ await (0, test_1.expect)(this.saveVariableButton).toBeEnabled({ timeout: 10000 });
57
61
  await this.saveVariableButton.click();
58
62
  await (0, test_1.expect)(this.successMessage).toBeVisible();
59
63
  await (0, test_1.expect)(this.editVariableModal).toBeHidden();
@@ -145,7 +145,7 @@ class OperateProcessesPage {
145
145
  return;
146
146
  }
147
147
  const MAX_ATTEMPTS = 100;
148
- const TOTAL_TIMEOUT_MS = constants_1._1_MINUTE_IN_MS * 2;
148
+ const TOTAL_TIMEOUT_MS = constants_1._1_MINUTE_IN_MS * 4;
149
149
  let attempt = 0;
150
150
  let lastError;
151
151
  const startTime = Date.now();
@@ -70,11 +70,11 @@ class PlayPage {
70
70
  await this.completeJobButton.click();
71
71
  }
72
72
  async clickStartInstanceButton() {
73
- const maxRetries = 3;
73
+ const maxRetries = 5;
74
74
  let attempts = 0;
75
75
  while (attempts < maxRetries) {
76
76
  try {
77
- await this.diagram.waitFor({ state: 'visible', timeout: 30000 });
77
+ await this.diagram.waitFor({ state: 'visible', timeout: 60000 });
78
78
  await this.startInstanceButton
79
79
  .or(this.startInstanceWithCachedButton)
80
80
  .first()
@@ -88,8 +88,7 @@ class PlayPage {
88
88
  catch (error) {
89
89
  if (attempts >= maxRetries - 1)
90
90
  throw error;
91
- await this.page.reload();
92
- await (0, sleep_1.sleep)(2000);
91
+ await (0, sleep_1.sleep)(5000);
93
92
  attempts++;
94
93
  }
95
94
  }
@@ -94,7 +94,7 @@ class TaskDetailsPage {
94
94
  this.detailsInfo = page.getByTestId('details-info');
95
95
  this.textInput = page.locator('[class="fjs-input"]');
96
96
  this.textInput = page.locator('[class="fjs-input"]');
97
- this.taskCompletedBanner = this.page.getByText('Task completed');
97
+ this.taskCompletedBanner = this.page.getByText('Task completed').first();
98
98
  this.assignedToMeText = page
99
99
  .getByTestId('assignee')
100
100
  .getByText('Assigned to me');
@@ -248,7 +248,7 @@ class TaskDetailsPage {
248
248
  let attempts = 0;
249
249
  while (attempts < maxAttempts) {
250
250
  try {
251
- await (0, test_1.expect)(this.page.getByText(expectedText)).toBeVisible({
251
+ await (0, test_1.expect)(this.page.getByText(expectedText).first()).toBeVisible({
252
252
  timeout: 60000,
253
253
  });
254
254
  return;
@@ -40,6 +40,7 @@ class TaskPanelPage {
40
40
  async openTask(name, assignButton = true) {
41
41
  for (let attempt = 1; attempt <= 30; attempt++) {
42
42
  try {
43
+ await this.page.waitForLoadState('networkidle');
43
44
  await this.availableTasks
44
45
  .getByText(name, { exact: true })
45
46
  .nth(0)
@@ -55,9 +56,10 @@ class TaskPanelPage {
55
56
  if (attempt < 30) {
56
57
  console.warn(`Attempt ${attempt} failed. Reloading page...`);
57
58
  await this.page.reload();
59
+ await (0, sleep_1.sleep)(2000);
58
60
  }
59
61
  else {
60
- throw new Error(`Failed to open task "${name}" after 3 attempts: ${error}`);
62
+ throw new Error(`Failed to open task "${name}" after ${attempt} attempts: ${error}`);
61
63
  }
62
64
  }
63
65
  }
@@ -15,10 +15,10 @@ import { OCIdentityMappingRulesPage } from '../SM-8.9/OCIdentityMappingRulesPage
15
15
  import { OCIdentityRolesPage } from '../SM-8.9/OCIdentityRolesPage';
16
16
  import { Serializable } from 'playwright-core/types/structs';
17
17
  export declare function deleteAllUserGroups(): Promise<void>;
18
- export declare function runMultipleProcesses(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, numberOfProcesses: number, processName: string, processId?: string): Promise<void>;
18
+ export declare function runMultipleProcesses(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, numberOfProcesses: number, processName: string, processId?: string, tenant?: string): Promise<void>;
19
19
  export declare function createUserAndAssignToRole(page: Page, navigationPage: NavigationPage, managementIdentityPage: ManagementIdentityPage, keycloakLoginPage: KeycloakLoginPage, keycloakAdminPage: KeycloakAdminPage, ocIdentityHomePage: OCIdentityHomePage, identityMappingRulesPage: OCIdentityMappingRulesPage, identityRolesPage: OCIdentityRolesPage, username: string, password: string, role?: string, testMappings?: Serializable): Promise<void>;
20
20
  export declare function assignMappingToRole(page: Page, ocIdentityHomePage: OCIdentityHomePage, ocIdentityRolesPage: OCIdentityRolesPage, role: string, mappingRuleId: string, testMappings?: Serializable): Promise<void>;
21
- export declare function createAndRunProcess(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, processId?: string): Promise<void>;
21
+ export declare function createAndRunProcess(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, processId?: string, tenant?: string): Promise<void>;
22
22
  export declare function completeTaskWithRetry(page: Page, taskPanelPage: TaskPanelPage, taskDetailsPage: TaskDetailsPage, taskName: string, taskPriority: string, maxRetries?: number): Promise<void>;
23
23
  export declare function modelRestConnector(modelerCreatePage: ModelerCreatePage, connectorSettingsPage: ConnectorSettingsPage, connectorMarketplacePage: ConnectorMarketplacePage, processName: string, url: string, auth: string, resultExpression: string, resultVariable?: string, basicAuthCredentials?: {
24
24
  username: string;
@@ -27,8 +27,8 @@ export declare function modelRestConnector(modelerCreatePage: ModelerCreatePage,
27
27
  export declare function assertLocatorVisibleWithPaginated(page: Page, locator: Locator, text: string): Promise<void>;
28
28
  export declare function assertLocatorVisibleWithRetry(page: Page, locator: Locator, text: string, timeout?: number, notVisible?: boolean, maxRetries?: number, clickLocator?: Locator): Promise<void>;
29
29
  export declare function assertPageTextWithRetry(page: Page, text: string, notVisible?: boolean, timeout?: number, maxRetries?: number): Promise<void>;
30
- export declare function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, connectorTemplatePage: ConnectorTemplatePage): Promise<void>;
30
+ export declare function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, connectorTemplatePage: ConnectorTemplatePage, tenant?: string): Promise<void>;
31
31
  export declare function findTextWithPagination(page: Page, text: string, timeout?: number, action?: (locator: Locator) => Promise<void>): Promise<boolean>;
32
32
  export declare function modelDiagramFromFile(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, fileName?: string, nrOfRenamedUserTasks?: number, taskName?: string): Promise<void>;
33
33
  export declare function expectTextWithPagination(page: Page, text: string, shouldExist?: boolean, timeout?: number): Promise<void>;
34
- export declare function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string, endpoint: string): Promise<void>;
34
+ export declare function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string, endpoint: string, tenant?: string): Promise<void>;
@@ -14,9 +14,9 @@ async function deleteAllUserGroups() {
14
14
  // await identityPage.deleteAllGroups();
15
15
  }
16
16
  exports.deleteAllUserGroups = deleteAllUserGroups;
17
- async function runMultipleProcesses(page, modelerHomePage, modelerCreatePage, numberOfProcesses, processName, processId = '') {
17
+ async function runMultipleProcesses(page, modelerHomePage, modelerCreatePage, numberOfProcesses, processName, processId = '', tenant = '') {
18
18
  for (let i = 1; i <= numberOfProcesses; i++) {
19
- await createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName + i, processId.length > 0 ? processId + i : processId);
19
+ await createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName + i, processId.length > 0 ? processId + i : processId, tenant);
20
20
  }
21
21
  }
22
22
  exports.runMultipleProcesses = runMultipleProcesses;
@@ -57,15 +57,30 @@ async function assignMappingToRole(page, ocIdentityHomePage, ocIdentityRolesPage
57
57
  await assertLocatorVisibleWithPaginated(page, ocIdentityRolesPage.mappingRuleRow(mappingRuleId).first(), `${mappingRuleId} Mapping Rule`);
58
58
  }
59
59
  exports.assignMappingToRole = assignMappingToRole;
60
- async function createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName, processId = '') {
60
+ async function createAndRunProcess(page, modelerHomePage, modelerCreatePage, processName, processId = '', tenant = '') {
61
61
  await modelerHomePage.clickDiagramTypeDropdown();
62
62
  await modelerHomePage.clickBpmnTemplateOption();
63
63
  await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processId);
64
- await modelerCreatePage.runProcessInstance();
64
+ await modelerCreatePage.runProcessInstance('', tenant);
65
65
  await modelerHomePage.clickProjectBreadcrumb();
66
66
  }
67
67
  exports.createAndRunProcess = createAndRunProcess;
68
68
  async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskName, taskPriority, maxRetries = 7) {
69
+ // Dismiss any lingering "Task completed" toast from a previous completion
70
+ // to avoid strict mode violations and stale UI state
71
+ try {
72
+ const toastCloseButton = page
73
+ .locator('.cds--toast-notification')
74
+ .getByRole('button', { name: /close/i })
75
+ .first();
76
+ if (await toastCloseButton.isVisible({ timeout: 2000 })) {
77
+ await toastCloseButton.click();
78
+ await (0, sleep_1.sleep)(500);
79
+ }
80
+ }
81
+ catch {
82
+ // No toast to dismiss, continue
83
+ }
69
84
  for (let attempt = 0; attempt < maxRetries; attempt++) {
70
85
  try {
71
86
  await page.waitForLoadState('networkidle');
@@ -78,8 +93,12 @@ async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskN
78
93
  throw new Error(`Task ${taskName} not found in available tasks`);
79
94
  }
80
95
  await taskPanelPage.openTask(taskName, false);
81
- await (0, sleep_1.sleep)(500);
96
+ await (0, sleep_1.sleep)(1000);
82
97
  await (0, test_1.expect)(taskDetailsPage.detailsPanel).toBeVisible({ timeout: 30000 });
98
+ // Verify the correct task is loaded by checking the task name appears
99
+ // in the details-info section (the task name heading is outside the
100
+ // complementary panel, so we use detailsInfo instead of detailsPanel)
101
+ await (0, test_1.expect)(taskDetailsPage.detailsInfo.getByText(taskName)).toBeVisible({ timeout: 30000 });
83
102
  if (!(await taskDetailsPage.assignedToMeText.isVisible({ timeout: 5000 }))) {
84
103
  await taskDetailsPage.clickAssignToMeButton();
85
104
  }
@@ -92,6 +111,20 @@ async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskN
92
111
  catch (error) {
93
112
  console.warn(`Attempt ${attempt + 1} failed for completing task ${taskName}:`, error instanceof Error ? error.message : error);
94
113
  if (attempt < maxRetries - 1) {
114
+ // Dismiss any toast before reloading
115
+ try {
116
+ const toastCloseButton = page
117
+ .locator('.cds--toast-notification')
118
+ .getByRole('button', { name: /close/i })
119
+ .first();
120
+ if (await toastCloseButton.isVisible({ timeout: 1000 })) {
121
+ await toastCloseButton.click();
122
+ await (0, sleep_1.sleep)(300);
123
+ }
124
+ }
125
+ catch {
126
+ // No toast to dismiss
127
+ }
95
128
  await page.reload();
96
129
  await page.waitForLoadState('networkidle');
97
130
  await (0, sleep_1.sleep)(500);
@@ -275,7 +308,7 @@ async function assertPageTextWithRetry(page, text, notVisible, timeout = 120000,
275
308
  }
276
309
  }
277
310
  exports.assertPageTextWithRetry = assertPageTextWithRetry;
278
- async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, connectorTemplatePage) {
311
+ async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, connectorTemplatePage, tenant = '') {
279
312
  await modelerHomePage.clickCrossComponentProjectFolder();
280
313
  await modelerHomePage.clickDiagramTypeDropdown();
281
314
  await modelerHomePage.clickUploadFilesButton();
@@ -311,7 +344,7 @@ async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modeler
311
344
  await (0, sleep_1.sleep)(5000);
312
345
  await page.reload();
313
346
  await (0, sleep_1.sleep)(5000);
314
- await modelerCreatePage.runProcessInstance();
347
+ await modelerCreatePage.runProcessInstance('', tenant);
315
348
  }
316
349
  exports.modelAndRunConnectorsTimerEventDiagram = modelAndRunConnectorsTimerEventDiagram;
317
350
  async function findTextWithPagination(page, text, timeout = 30000, action) {
@@ -393,7 +426,7 @@ async function expectTextWithPagination(page, text, shouldExist = true, timeout
393
426
  }
394
427
  }
395
428
  exports.expectTextWithPagination = expectTextWithPagination;
396
- async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, zeebeUrl, zeebeClientId, zeebeClientSecret, endpoint) {
429
+ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, zeebeUrl, zeebeClientId, zeebeClientSecret, endpoint, tenant = '') {
397
430
  await modelerHomePage.clickCrossComponentProjectFolder();
398
431
  await modelerHomePage.clickDiagramTypeDropdown();
399
432
  await modelerHomePage.clickUploadFilesButton();
@@ -430,6 +463,6 @@ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modele
430
463
  await modelerCreatePage.clickCloseDetailsPanel();
431
464
  await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(9) > .djs-element > .djs-hit'), endpoint, { openPanel: true });
432
465
  await (0, sleep_1.sleep)(2000);
433
- await modelerCreatePage.runProcessInstance();
466
+ await modelerCreatePage.runProcessInstance('', tenant);
434
467
  }
435
468
  exports.modelAndRunConnectorsDocHandlingDiagram = modelAndRunConnectorsDocHandlingDiagram;