@camunda/e2e-test-suite 0.0.413 → 0.0.415
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/OCIdentityClusterVariablesPage.d.ts +2 -0
- package/dist/pages/SM-8.10/OCIdentityClusterVariablesPage.js +33 -5
- package/dist/pages/SM-8.10/OperateProcessInstancePage.d.ts +3 -0
- package/dist/pages/SM-8.10/OperateProcessInstancePage.js +30 -6
- package/dist/pages/SM-8.10/OperateProcessesPage.js +31 -0
- package/dist/tests/SM-8.10/smoke-tests.spec.js +3 -6
- package/package.json +1 -1
|
@@ -11,8 +11,10 @@ export declare class OCIdentityClusterVariablesPage {
|
|
|
11
11
|
readonly variableRow: (variableName: string) => Locator;
|
|
12
12
|
readonly monacoEditor: Locator;
|
|
13
13
|
readonly monacoEditorTextArea: Locator;
|
|
14
|
+
readonly monacoSuggestWidget: Locator;
|
|
14
15
|
readonly successMessage: Locator;
|
|
15
16
|
readonly editMenuItem: Locator;
|
|
17
|
+
readonly editModalHeading: Locator;
|
|
16
18
|
constructor(page: Page);
|
|
17
19
|
editVariable(variableName: string, newValue: string): Promise<void>;
|
|
18
20
|
assertVariableExists(variableName: string): Promise<void>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OCIdentityClusterVariablesPage = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
|
+
const sleep_1 = require("../../utils/sleep");
|
|
5
6
|
class OCIdentityClusterVariablesPage {
|
|
6
7
|
page;
|
|
7
8
|
variablesList;
|
|
@@ -14,8 +15,10 @@ class OCIdentityClusterVariablesPage {
|
|
|
14
15
|
variableRow;
|
|
15
16
|
monacoEditor;
|
|
16
17
|
monacoEditorTextArea;
|
|
18
|
+
monacoSuggestWidget;
|
|
17
19
|
successMessage;
|
|
18
20
|
editMenuItem;
|
|
21
|
+
editModalHeading;
|
|
19
22
|
constructor(page) {
|
|
20
23
|
this.page = page;
|
|
21
24
|
this.variablesList = page.locator('table.cds--data-table');
|
|
@@ -39,7 +42,10 @@ class OCIdentityClusterVariablesPage {
|
|
|
39
42
|
});
|
|
40
43
|
this.monacoEditor = this.editVariableModal.locator('.monaco-editor');
|
|
41
44
|
this.monacoEditorTextArea = this.monacoEditor.locator('textarea.inputarea');
|
|
45
|
+
this.monacoSuggestWidget = this.monacoEditor.locator('.editor-widget.suggest-widget');
|
|
42
46
|
this.successMessage = this.page.getByText('Cluster variable updated');
|
|
47
|
+
this.editModalHeading =
|
|
48
|
+
this.editVariableModal.locator('.cds--modal-header');
|
|
43
49
|
this.editMenuItem = this.page
|
|
44
50
|
.locator('button[role="menuitem"]')
|
|
45
51
|
.filter({ hasText: /^Edit$/ });
|
|
@@ -50,14 +56,36 @@ class OCIdentityClusterVariablesPage {
|
|
|
50
56
|
await this.editMenuItem.click();
|
|
51
57
|
await (0, test_1.expect)(this.variableValueField).toBeVisible();
|
|
52
58
|
await (0, test_1.expect)(this.monacoEditor).toBeVisible();
|
|
53
|
-
await this.monacoEditor.click();
|
|
54
59
|
// Monaco editor doesn't respond reliably to clear()/fill() on the
|
|
55
60
|
// hidden textarea. Use keyboard shortcuts to select-all and replace,
|
|
56
61
|
// which mirrors real user interaction.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
// Retry the clear-type-enable cycle because Monaco auto-completion of
|
|
63
|
+
// brackets / quotes can corrupt JSON input on the first attempt.
|
|
64
|
+
const MAX_TYPE_ATTEMPTS = 3;
|
|
65
|
+
for (let attempt = 1; attempt <= MAX_TYPE_ATTEMPTS; attempt++) {
|
|
66
|
+
await this.monacoEditor.click();
|
|
67
|
+
await this.monacoEditorTextArea.press('Control+a');
|
|
68
|
+
await this.monacoEditorTextArea.press('Delete');
|
|
69
|
+
// Let Monaco settle after clearing content
|
|
70
|
+
await (0, sleep_1.sleep)(500);
|
|
71
|
+
await this.monacoEditorTextArea.pressSequentially(newValue, { delay: 20 });
|
|
72
|
+
// Dismiss any auto-complete popup by clicking the modal heading.
|
|
73
|
+
// Do NOT use press('Escape') on the textarea — when no autocomplete
|
|
74
|
+
// is showing, the Escape event propagates to the Carbon modal and
|
|
75
|
+
// closes the entire dialog.
|
|
76
|
+
await this.editModalHeading.click();
|
|
77
|
+
// Let Monaco settle and validate the new content
|
|
78
|
+
await (0, sleep_1.sleep)(500);
|
|
79
|
+
try {
|
|
80
|
+
await (0, test_1.expect)(this.saveVariableButton).toBeEnabled({ timeout: 10000 });
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
if (attempt === MAX_TYPE_ATTEMPTS) {
|
|
85
|
+
throw new Error(`Save button did not become enabled after ${MAX_TYPE_ATTEMPTS} typing attempts`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
61
89
|
await this.saveVariableButton.click();
|
|
62
90
|
await (0, test_1.expect)(this.successMessage).toBeVisible();
|
|
63
91
|
await (0, test_1.expect)(this.editVariableModal).toBeHidden();
|
|
@@ -6,6 +6,8 @@ declare class OperateProcessInstancePage {
|
|
|
6
6
|
readonly diagramSpinner: Locator;
|
|
7
7
|
readonly activeIcon: Locator;
|
|
8
8
|
readonly incidentIcon: Locator;
|
|
9
|
+
readonly variablesList: Locator;
|
|
10
|
+
readonly messageVariable: Locator;
|
|
9
11
|
constructor(page: Page);
|
|
10
12
|
connectorResultVariableName(name: string): Promise<Locator>;
|
|
11
13
|
connectorResultVariableValue(variableName: string): Promise<Locator>;
|
|
@@ -19,6 +21,7 @@ declare class OperateProcessInstancePage {
|
|
|
19
21
|
assertEitherIncidentOrCompletedIconVisible(): Promise<string>;
|
|
20
22
|
assertProcessCompleteStatusWithRetry(timeout?: number, maxRetries?: number): Promise<void>;
|
|
21
23
|
assertProcessVariableContainsText(variableName: string, text: string): Promise<void>;
|
|
24
|
+
assertResultVariableVisibleWithRetry(variableName: string): Promise<void>;
|
|
22
25
|
assertActiveTokenIsPresent(): Promise<void>;
|
|
23
26
|
}
|
|
24
27
|
export { OperateProcessInstancePage };
|
|
@@ -10,6 +10,8 @@ class OperateProcessInstancePage {
|
|
|
10
10
|
diagramSpinner;
|
|
11
11
|
activeIcon;
|
|
12
12
|
incidentIcon;
|
|
13
|
+
variablesList;
|
|
14
|
+
messageVariable;
|
|
13
15
|
constructor(page) {
|
|
14
16
|
this.page = page;
|
|
15
17
|
this.diagram = page.getByTestId('diagram');
|
|
@@ -23,6 +25,8 @@ class OperateProcessInstancePage {
|
|
|
23
25
|
this.incidentIcon = page
|
|
24
26
|
.getByTestId('instance-header')
|
|
25
27
|
.getByTestId('INCIDENT-icon');
|
|
28
|
+
this.variablesList = page.getByTestId('variables-list');
|
|
29
|
+
this.messageVariable = page.getByTestId('variable-message');
|
|
26
30
|
}
|
|
27
31
|
async connectorResultVariableName(name) {
|
|
28
32
|
return await this.page.getByTestId(name);
|
|
@@ -150,18 +154,38 @@ class OperateProcessInstancePage {
|
|
|
150
154
|
}
|
|
151
155
|
async assertProcessVariableContainsText(variableName, text) {
|
|
152
156
|
const maxRetries = 3;
|
|
153
|
-
for (let
|
|
157
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
154
158
|
try {
|
|
155
|
-
await (0, test_1.expect)(this.page.getByTestId(`variable-${variableName}`)).toContainText(text, { timeout:
|
|
159
|
+
await (0, test_1.expect)(this.page.getByTestId(`variable-${variableName}`)).toContainText(text, { timeout: 8000 });
|
|
156
160
|
return;
|
|
157
161
|
}
|
|
158
162
|
catch (error) {
|
|
159
|
-
console.log(`
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
console.log(`assertProcessVariableContainsText attempt ${attempt + 1}/${maxRetries} failed: ${error}`);
|
|
164
|
+
if (attempt < maxRetries - 1) {
|
|
165
|
+
await this.page.reload({ timeout: 10000 }).catch(() => { });
|
|
166
|
+
await (0, sleep_1.sleep)(2000);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`Failed to assert variable ${variableName} contains "${text}" after ${maxRetries} attempts.`);
|
|
171
|
+
}
|
|
172
|
+
async assertResultVariableVisibleWithRetry(variableName) {
|
|
173
|
+
const maxRetries = 3;
|
|
174
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
175
|
+
try {
|
|
176
|
+
await (0, test_1.expect)(this.variablesList).toBeVisible({ timeout: 8000 });
|
|
177
|
+
await (0, test_1.expect)(this.page.getByTestId(`variable-${variableName}`)).toBeVisible({ timeout: 8000 });
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.log(`assertResultVariableVisibleWithRetry attempt ${attempt + 1}/${maxRetries} failed: ${error}`);
|
|
182
|
+
if (attempt < maxRetries - 1) {
|
|
183
|
+
await this.page.reload({ timeout: 10000 }).catch(() => { });
|
|
184
|
+
await (0, sleep_1.sleep)(2000);
|
|
185
|
+
}
|
|
162
186
|
}
|
|
163
187
|
}
|
|
164
|
-
throw new Error(`Failed to assert variable ${variableName} after ${maxRetries} attempts.`);
|
|
188
|
+
throw new Error(`Failed to assert variable ${variableName} visible after ${maxRetries} attempts.`);
|
|
165
189
|
}
|
|
166
190
|
async assertActiveTokenIsPresent() {
|
|
167
191
|
await (0, test_1.expect)(this.activeIcon).toBeVisible({ timeout: 60000 });
|
|
@@ -154,6 +154,9 @@ class OperateProcessesPage {
|
|
|
154
154
|
else {
|
|
155
155
|
await this.toggleCompletedCheckbox();
|
|
156
156
|
}
|
|
157
|
+
// Capture URL after filters are applied so we can navigate back here
|
|
158
|
+
// if a reload redirects away from Operate.
|
|
159
|
+
const operateUrl = this.page.url();
|
|
157
160
|
while (Date.now() - startTime < TOTAL_TIMEOUT_MS &&
|
|
158
161
|
attempt < MAX_ATTEMPTS) {
|
|
159
162
|
attempt++;
|
|
@@ -167,6 +170,34 @@ class OperateProcessesPage {
|
|
|
167
170
|
lastError = err instanceof Error ? err.message : err;
|
|
168
171
|
await this.page.reload();
|
|
169
172
|
await this.page.waitForLoadState('networkidle');
|
|
173
|
+
// After reload, the page may redirect away from Operate (e.g. to
|
|
174
|
+
// Tasklist). Navigate back to the original Operate URL if that
|
|
175
|
+
// happens.
|
|
176
|
+
if (!this.page.url().includes('/operate')) {
|
|
177
|
+
await this.page.goto(operateUrl);
|
|
178
|
+
await this.page.waitForLoadState('networkidle');
|
|
179
|
+
}
|
|
180
|
+
// Re-apply checkbox filter lost after reload
|
|
181
|
+
if (type === 'active') {
|
|
182
|
+
await this.toggleActiveCheckboxOn();
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
await this.toggleCompletedCheckbox();
|
|
186
|
+
}
|
|
187
|
+
// Re-fill Process Instance Key filter if it was previously applied
|
|
188
|
+
// but its value was cleared by the reload.
|
|
189
|
+
try {
|
|
190
|
+
const isFilterVisible = await this.processInstanceKeyTextBox.isVisible();
|
|
191
|
+
if (isFilterVisible) {
|
|
192
|
+
const currentValue = await this.processInstanceKeyTextBox.inputValue();
|
|
193
|
+
if (!currentValue) {
|
|
194
|
+
await this.processInstanceKeyTextBox.fill(processName);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Filter input not available, skip
|
|
200
|
+
}
|
|
170
201
|
await (0, sleep_1.sleep)(2000);
|
|
171
202
|
}
|
|
172
203
|
}
|
|
@@ -129,7 +129,7 @@ SM_8_10_1.test.describe.parallel('Smoke Tests', () => {
|
|
|
129
129
|
});
|
|
130
130
|
console.log(`[${testInfo.title}] Test end: timeout = ${testInfo.timeout}`);
|
|
131
131
|
});
|
|
132
|
-
(0, SM_8_10_1.test)('Most Common REST Connector User Flow @tasklistV2', async ({
|
|
132
|
+
(0, SM_8_10_1.test)('Most Common REST Connector User Flow @tasklistV2', async ({ context, operateHomePage, modelerHomePage, modelerCreatePage, connectorSettingsPage, navigationPage, operateProcessesPage, operateProcessInstancePage, connectorMarketplacePage, }, testInfo) => {
|
|
133
133
|
// Skipped only for AG to unblock until failure is investigated
|
|
134
134
|
SM_8_10_1.test.skip(process.env.IS_AG === 'true', 'Skipping Most Common REST Connector User Flow for AG unblock while failure is investigated');
|
|
135
135
|
console.log(`[${testInfo.title}] Test start: timeout = ${testInfo.timeout}`);
|
|
@@ -152,11 +152,8 @@ SM_8_10_1.test.describe.parallel('Smoke Tests', () => {
|
|
|
152
152
|
await operateProcessesPage.clickProcessInstanceLink(processName, 'completed');
|
|
153
153
|
const result = await operateProcessInstancePage.assertEitherIncidentOrCompletedIconVisible();
|
|
154
154
|
(0, test_1.expect)(result).toBe('completed');
|
|
155
|
-
await
|
|
156
|
-
|
|
157
|
-
});
|
|
158
|
-
(0, test_1.expect)((await operateProcessInstancePage.connectorResultVariableName('message')).isVisible()).toBeTruthy();
|
|
159
|
-
await (0, test_1.expect)(page.getByTestId('variable-message').getByText('"Message from Mock!"')).toBeVisible({ timeout: 60000 });
|
|
155
|
+
await operateProcessInstancePage.assertResultVariableVisibleWithRetry('message');
|
|
156
|
+
await operateProcessInstancePage.assertProcessVariableContainsText('message', '"Message from Mock!"');
|
|
160
157
|
});
|
|
161
158
|
console.log(`[${testInfo.title}] Test end: timeout = ${testInfo.timeout}`);
|
|
162
159
|
});
|