@camunda/e2e-test-suite 0.0.549 → 0.0.551
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pages/SM-8.10/ModelerHomePage.js +6 -2
- package/dist/pages/SM-8.10/TaskPanelPage.js +7 -6
- package/dist/pages/SM-8.7/TaskPanelPage.js +7 -4
- package/dist/pages/SM-8.7/UtlitiesPage.js +29 -11
- package/dist/pages/SM-8.8/ModelerHomePage.d.ts +1 -0
- package/dist/pages/SM-8.8/ModelerHomePage.js +21 -4
- package/dist/pages/SM-8.8/TaskPanelPage.js +6 -5
- package/dist/pages/SM-8.9/ModelerHomePage.d.ts +1 -0
- package/dist/pages/SM-8.9/ModelerHomePage.js +21 -4
- package/dist/pages/SM-8.9/TaskPanelPage.js +7 -6
- package/package.json +1 -1
|
@@ -73,12 +73,16 @@ class ModelerHomePage {
|
|
|
73
73
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.createNewProjectButton, {
|
|
74
74
|
totalTimeout: 30000,
|
|
75
75
|
});
|
|
76
|
-
//
|
|
77
|
-
//
|
|
76
|
+
// Modals (WhatsNew, "BPMN conditional events", etc.) render lazily after
|
|
77
|
+
// page load and intercept clicks on the button underneath. Dismiss them.
|
|
78
78
|
await this.closeButton
|
|
79
79
|
.waitFor({ state: 'visible', timeout: 5000 })
|
|
80
80
|
.then(() => this.closeButton.click())
|
|
81
81
|
.catch(() => { });
|
|
82
|
+
await this.modalCloseButton
|
|
83
|
+
.waitFor({ state: 'visible', timeout: 2000 })
|
|
84
|
+
.then(() => this.modalCloseButton.click())
|
|
85
|
+
.catch(() => { });
|
|
82
86
|
await this.createNewProjectButton.click();
|
|
83
87
|
}
|
|
84
88
|
async enterNewProjectName(name) {
|
|
@@ -37,9 +37,10 @@ class TaskPanelPage {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
async openTask(name, assignButton = true) {
|
|
40
|
-
|
|
40
|
+
const maxAttempts = 10;
|
|
41
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
41
42
|
try {
|
|
42
|
-
await this.page.waitForLoadState('
|
|
43
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
43
44
|
await this.availableTasks
|
|
44
45
|
.getByText(name, { exact: true })
|
|
45
46
|
.nth(0)
|
|
@@ -52,13 +53,13 @@ class TaskPanelPage {
|
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
catch (error) {
|
|
55
|
-
if (attempt <
|
|
56
|
+
if (attempt < maxAttempts) {
|
|
56
57
|
console.warn(`Attempt ${attempt} failed. Reloading page...`);
|
|
57
58
|
await this.page.reload();
|
|
58
|
-
await this.page.waitForLoadState('
|
|
59
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
59
60
|
}
|
|
60
61
|
else {
|
|
61
|
-
throw new Error(`Failed to open task "${name}" after ${
|
|
62
|
+
throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${error}`);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
}
|
|
@@ -84,7 +85,7 @@ class TaskPanelPage {
|
|
|
84
85
|
await this.processesPageTab.click();
|
|
85
86
|
}
|
|
86
87
|
async taskCount(name, waitForStable = true) {
|
|
87
|
-
await this.page.waitForLoadState('
|
|
88
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
88
89
|
if (waitForStable) {
|
|
89
90
|
// Wait for the task list to stabilize: poll until count is unchanged for 2s
|
|
90
91
|
let previousCount = -1;
|
|
@@ -38,12 +38,14 @@ class TaskPanelPage {
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
async openTask(name, assignButton = true) {
|
|
41
|
-
|
|
41
|
+
const maxAttempts = 10;
|
|
42
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
42
43
|
try {
|
|
44
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
43
45
|
await this.availableTasks
|
|
44
46
|
.getByText(name, { exact: true })
|
|
45
47
|
.nth(0)
|
|
46
|
-
.click({ timeout: constants_1._1_SECOND_IN_MS * 4 });
|
|
48
|
+
.click({ timeout: constants_1._1_SECOND_IN_MS * 4 });
|
|
47
49
|
if (assignButton) {
|
|
48
50
|
await (0, test_1.expect)(this.assignToMeButton).toBeVisible({
|
|
49
51
|
timeout: constants_1._1_SECOND_IN_MS * 10,
|
|
@@ -52,12 +54,13 @@ class TaskPanelPage {
|
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
56
|
catch (error) {
|
|
55
|
-
if (attempt <
|
|
57
|
+
if (attempt < maxAttempts) {
|
|
56
58
|
console.warn(`Attempt ${attempt} failed. Reloading page...`);
|
|
57
59
|
await this.page.reload();
|
|
60
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
58
61
|
}
|
|
59
62
|
else {
|
|
60
|
-
throw new Error(`Failed to open task "${name}" after
|
|
63
|
+
throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${error}`);
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
}
|
|
@@ -25,33 +25,51 @@ async function createAndRunProcess(modelerHomePage, modelerCreatePage, processNa
|
|
|
25
25
|
await modelerHomePage.clickProjectBreadcrumb();
|
|
26
26
|
}
|
|
27
27
|
exports.createAndRunProcess = createAndRunProcess;
|
|
28
|
-
async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskName, taskPriority, maxRetries =
|
|
28
|
+
async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskName, taskPriority, maxRetries = 5) {
|
|
29
29
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
30
30
|
try {
|
|
31
|
-
await
|
|
31
|
+
await page.waitForLoadState('domcontentloaded');
|
|
32
32
|
await (0, sleep_1.sleep)(1000);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
// Wait for task to appear in the list before trying to open it
|
|
34
|
+
const taskLocator = taskPanelPage.availableTasks
|
|
35
|
+
.getByText(taskName, { exact: true })
|
|
36
|
+
.first();
|
|
37
|
+
try {
|
|
38
|
+
await taskLocator.waitFor({ state: 'visible', timeout: 10000 });
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new Error(`Task ${taskName} not found in available tasks`);
|
|
42
|
+
}
|
|
43
|
+
await taskPanelPage.openTask(taskName, false);
|
|
44
|
+
await (0, sleep_1.sleep)(500);
|
|
45
|
+
await (0, test_1.expect)(taskDetailsPage.detailsPanel).toBeVisible({ timeout: 30000 });
|
|
46
|
+
// Only assign if not already assigned (handles retry after partial success)
|
|
47
|
+
if (!(await taskDetailsPage.assignedToMeText.isVisible({ timeout: 5000 }))) {
|
|
48
|
+
await (0, test_1.expect)(taskDetailsPage.assignToMeButton).toBeVisible({
|
|
49
|
+
timeout: 10000,
|
|
50
|
+
});
|
|
51
|
+
await taskDetailsPage.clickAssignToMeButton();
|
|
52
|
+
}
|
|
53
|
+
await (0, sleep_1.sleep)(500);
|
|
54
|
+
await (0, test_1.expect)(taskDetailsPage.detailsPanel.getByText(taskPriority)).toBeVisible({ timeout: 30000 });
|
|
39
55
|
await taskDetailsPage.clickCompleteTaskButton();
|
|
40
56
|
await (0, test_1.expect)(page.getByText('Task completed').first()).toBeVisible({
|
|
41
57
|
timeout: 200000,
|
|
42
58
|
});
|
|
43
59
|
await (0, test_1.expect)(taskPanelPage.availableTasks.getByText(taskName, { exact: true }).first()).not.toBeVisible({ timeout: 10000 });
|
|
44
|
-
|
|
60
|
+
console.log(`Successfully completed task: ${taskName}`);
|
|
45
61
|
return;
|
|
46
62
|
}
|
|
47
63
|
catch (error) {
|
|
64
|
+
console.warn(`Attempt ${attempt + 1} failed for completing task ${taskName}:`, error instanceof Error ? error.message : error);
|
|
48
65
|
if (attempt < maxRetries - 1) {
|
|
49
66
|
await page.reload();
|
|
50
|
-
|
|
67
|
+
await page.waitForLoadState('domcontentloaded');
|
|
68
|
+
await (0, sleep_1.sleep)(1000);
|
|
51
69
|
}
|
|
52
70
|
else {
|
|
53
71
|
console.error(error);
|
|
54
|
-
throw new Error(`Assertion failed after ${maxRetries} attempts`);
|
|
72
|
+
throw new Error(`Assertion failed after ${maxRetries} attempts for task ${taskName}`);
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
}
|
|
@@ -23,6 +23,7 @@ declare class ModelerHomePage {
|
|
|
23
23
|
readonly uploadFilesButton: Locator;
|
|
24
24
|
readonly messageBanner: Locator;
|
|
25
25
|
readonly closeButton: Locator;
|
|
26
|
+
readonly modalCloseButton: Locator;
|
|
26
27
|
readonly idpTemplateOption: Locator;
|
|
27
28
|
readonly idpApplicationNameInput: Locator;
|
|
28
29
|
readonly dialog: Locator;
|
|
@@ -28,6 +28,7 @@ class ModelerHomePage {
|
|
|
28
28
|
uploadFilesButton;
|
|
29
29
|
messageBanner;
|
|
30
30
|
closeButton;
|
|
31
|
+
modalCloseButton;
|
|
31
32
|
idpTemplateOption;
|
|
32
33
|
idpApplicationNameInput;
|
|
33
34
|
dialog;
|
|
@@ -71,6 +72,7 @@ class ModelerHomePage {
|
|
|
71
72
|
this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
|
|
72
73
|
this.messageBanner = page.locator('[data-test="close-top-banner"]');
|
|
73
74
|
this.closeButton = page.getByRole('button', { name: 'Got it - Dismiss' });
|
|
75
|
+
this.modalCloseButton = page.locator('.cds--modal.is-visible .cds--modal-close');
|
|
74
76
|
this.idpTemplateOption = page
|
|
75
77
|
.locator('[data-test="create-idp-application"]')
|
|
76
78
|
.getByText('IDP Application');
|
|
@@ -85,6 +87,16 @@ class ModelerHomePage {
|
|
|
85
87
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.createNewProjectButton, {
|
|
86
88
|
totalTimeout: 30000,
|
|
87
89
|
});
|
|
90
|
+
// Modals (WhatsNew, "BPMN conditional events", etc.) render lazily after
|
|
91
|
+
// page load and intercept clicks on the button underneath. Dismiss them.
|
|
92
|
+
await this.closeButton
|
|
93
|
+
.waitFor({ state: 'visible', timeout: 5000 })
|
|
94
|
+
.then(() => this.closeButton.click())
|
|
95
|
+
.catch(() => { });
|
|
96
|
+
await this.modalCloseButton
|
|
97
|
+
.waitFor({ state: 'visible', timeout: 2000 })
|
|
98
|
+
.then(() => this.modalCloseButton.click())
|
|
99
|
+
.catch(() => { });
|
|
88
100
|
await this.createNewProjectButton.click();
|
|
89
101
|
}
|
|
90
102
|
async enterNewProjectName(name) {
|
|
@@ -177,10 +189,15 @@ class ModelerHomePage {
|
|
|
177
189
|
}
|
|
178
190
|
async clickMessageBanner() {
|
|
179
191
|
try {
|
|
180
|
-
|
|
181
|
-
this.
|
|
182
|
-
this.
|
|
183
|
-
|
|
192
|
+
const banner = this.messageBanner
|
|
193
|
+
.or(this.closeButton)
|
|
194
|
+
.or(this.modalCloseButton);
|
|
195
|
+
if (await banner.isVisible({ timeout: 2000 })) {
|
|
196
|
+
await banner.click();
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
console.log('No banner or close button found to click');
|
|
200
|
+
}
|
|
184
201
|
}
|
|
185
202
|
catch {
|
|
186
203
|
console.log('No banner or close button found to click');
|
|
@@ -37,7 +37,8 @@ class TaskPanelPage {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
async openTask(name, assignButton = true) {
|
|
40
|
-
|
|
40
|
+
const maxAttempts = 10;
|
|
41
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
41
42
|
try {
|
|
42
43
|
await this.availableTasks
|
|
43
44
|
.getByText(name, { exact: true })
|
|
@@ -51,13 +52,13 @@ class TaskPanelPage {
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
catch (error) {
|
|
54
|
-
if (attempt <
|
|
55
|
+
if (attempt < maxAttempts) {
|
|
55
56
|
console.warn(`Attempt ${attempt} failed. Reloading page...`);
|
|
56
57
|
await this.page.reload();
|
|
57
|
-
await this.page.waitForLoadState('
|
|
58
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
58
59
|
}
|
|
59
60
|
else {
|
|
60
|
-
throw new Error(`Failed to open task "${name}" after
|
|
61
|
+
throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${error}`);
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -83,7 +84,7 @@ class TaskPanelPage {
|
|
|
83
84
|
await this.processesPageTab.click();
|
|
84
85
|
}
|
|
85
86
|
async taskCount(name, waitForStable = true) {
|
|
86
|
-
await this.page.waitForLoadState('
|
|
87
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
87
88
|
if (waitForStable) {
|
|
88
89
|
// Wait for the task list to stabilize: poll until count is unchanged for 2s
|
|
89
90
|
let previousCount = -1;
|
|
@@ -23,6 +23,7 @@ declare class ModelerHomePage {
|
|
|
23
23
|
readonly uploadFilesButton: Locator;
|
|
24
24
|
readonly messageBanner: Locator;
|
|
25
25
|
readonly closeButton: Locator;
|
|
26
|
+
readonly modalCloseButton: Locator;
|
|
26
27
|
constructor(page: Page);
|
|
27
28
|
clickCreateNewProjectButton(): Promise<void>;
|
|
28
29
|
enterNewProjectName(name: string): Promise<void>;
|
|
@@ -28,6 +28,7 @@ class ModelerHomePage {
|
|
|
28
28
|
uploadFilesButton;
|
|
29
29
|
messageBanner;
|
|
30
30
|
closeButton;
|
|
31
|
+
modalCloseButton;
|
|
31
32
|
constructor(page) {
|
|
32
33
|
this.page = page;
|
|
33
34
|
this.modelerPageBanner = page
|
|
@@ -71,11 +72,22 @@ class ModelerHomePage {
|
|
|
71
72
|
this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
|
|
72
73
|
this.messageBanner = page.locator('[data-test="close-top-banner"]');
|
|
73
74
|
this.closeButton = page.getByRole('button', { name: 'Got it - Dismiss' });
|
|
75
|
+
this.modalCloseButton = page.locator('.cds--modal.is-visible .cds--modal-close');
|
|
74
76
|
}
|
|
75
77
|
async clickCreateNewProjectButton() {
|
|
76
78
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.createNewProjectButton, {
|
|
77
79
|
totalTimeout: 60000,
|
|
78
80
|
});
|
|
81
|
+
// Modals (WhatsNew, "BPMN conditional events", etc.) render lazily after
|
|
82
|
+
// page load and intercept clicks on the button underneath. Dismiss them.
|
|
83
|
+
await this.closeButton
|
|
84
|
+
.waitFor({ state: 'visible', timeout: 5000 })
|
|
85
|
+
.then(() => this.closeButton.click())
|
|
86
|
+
.catch(() => { });
|
|
87
|
+
await this.modalCloseButton
|
|
88
|
+
.waitFor({ state: 'visible', timeout: 2000 })
|
|
89
|
+
.then(() => this.modalCloseButton.click())
|
|
90
|
+
.catch(() => { });
|
|
79
91
|
await this.createNewProjectButton.click();
|
|
80
92
|
}
|
|
81
93
|
async enterNewProjectName(name) {
|
|
@@ -189,10 +201,15 @@ class ModelerHomePage {
|
|
|
189
201
|
}
|
|
190
202
|
async clickMessageBanner() {
|
|
191
203
|
try {
|
|
192
|
-
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
195
|
-
|
|
204
|
+
const banner = this.messageBanner
|
|
205
|
+
.or(this.closeButton)
|
|
206
|
+
.or(this.modalCloseButton);
|
|
207
|
+
if (await banner.isVisible({ timeout: 2000 })) {
|
|
208
|
+
await banner.click();
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.log('No banner or close button found to click');
|
|
212
|
+
}
|
|
196
213
|
}
|
|
197
214
|
catch {
|
|
198
215
|
console.log('No banner or close button found to click');
|
|
@@ -37,9 +37,10 @@ class TaskPanelPage {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
async openTask(name, assignButton = true) {
|
|
40
|
-
|
|
40
|
+
const maxAttempts = 10;
|
|
41
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
41
42
|
try {
|
|
42
|
-
await this.page.waitForLoadState('
|
|
43
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
43
44
|
await this.availableTasks
|
|
44
45
|
.getByText(name, { exact: true })
|
|
45
46
|
.nth(0)
|
|
@@ -52,13 +53,13 @@ class TaskPanelPage {
|
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
catch (error) {
|
|
55
|
-
if (attempt <
|
|
56
|
+
if (attempt < maxAttempts) {
|
|
56
57
|
console.warn(`Attempt ${attempt} failed. Reloading page...`);
|
|
57
58
|
await this.page.reload();
|
|
58
|
-
await this.page.waitForLoadState('
|
|
59
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
59
60
|
}
|
|
60
61
|
else {
|
|
61
|
-
throw new Error(`Failed to open task "${name}" after ${
|
|
62
|
+
throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${error}`);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
}
|
|
@@ -84,7 +85,7 @@ class TaskPanelPage {
|
|
|
84
85
|
await this.processesPageTab.click();
|
|
85
86
|
}
|
|
86
87
|
async taskCount(name, waitForStable = true) {
|
|
87
|
-
await this.page.waitForLoadState('
|
|
88
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
88
89
|
if (waitForStable) {
|
|
89
90
|
// Wait for the task list to stabilize: poll until count is unchanged for 2s
|
|
90
91
|
let previousCount = -1;
|