@camunda/e2e-test-suite 0.0.231 → 0.0.233
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/fixtures/8.6.d.ts +2 -0
- package/dist/fixtures/8.6.js +4 -0
- package/dist/fixtures/8.9.d.ts +2 -0
- package/dist/fixtures/8.9.js +4 -0
- package/dist/pages/8.6/ClientCredentialsDetailsPage.d.ts +12 -0
- package/dist/pages/8.6/ClientCredentialsDetailsPage.js +36 -0
- package/dist/pages/8.6/ClusterDetailsPage.d.ts +8 -1
- package/dist/pages/8.6/ClusterDetailsPage.js +60 -1
- package/dist/pages/8.9/OCIdentityClusterVariablesPage.d.ts +20 -0
- package/dist/pages/8.9/OCIdentityClusterVariablesPage.js +69 -0
- package/dist/pages/8.9/OCIdentityHomePage.d.ts +2 -0
- package/dist/pages/8.9/OCIdentityHomePage.js +15 -0
- package/dist/tests/8.6/console-user-flows.spec.js +1 -15
- package/dist/tests/8.6/operate-access-flow.spec.d.ts +1 -0
- package/dist/tests/8.6/operate-access-flow.spec.js +57 -0
- package/dist/tests/8.9/cluster-variables.spec.js +170 -40
- package/dist/utils/apiHelpers.d.ts +10 -1
- package/dist/utils/apiHelpers.js +58 -25
- package/package.json +1 -1
package/dist/fixtures/8.6.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { ModelerUserInvitePage } from '../pages/8.6/ModelerUserInvitePage';
|
|
|
26
26
|
import { SignUpPage } from '../pages/8.6/SignUpPage';
|
|
27
27
|
import { PlayPage } from '../pages/8.6/PlayPage';
|
|
28
28
|
import { ConnectorTemplatePage } from '../pages/8.6/ConnectorTemplatePage';
|
|
29
|
+
import { ClientCredentialsDetailsPage } from '../pages/8.6/ClientCredentialsDetailsPage';
|
|
29
30
|
type PlaywrightFixtures = {
|
|
30
31
|
makeAxeBuilder: () => AxeBuilder;
|
|
31
32
|
loginPage: LoginPage;
|
|
@@ -55,6 +56,7 @@ type PlaywrightFixtures = {
|
|
|
55
56
|
signUpPage: SignUpPage;
|
|
56
57
|
playPage: PlayPage;
|
|
57
58
|
connectorTemplatePage: ConnectorTemplatePage;
|
|
59
|
+
clientCredentialsDetailsPage: ClientCredentialsDetailsPage;
|
|
58
60
|
overrideTrackingScripts: void;
|
|
59
61
|
};
|
|
60
62
|
declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & PlaywrightFixtures, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
|
package/dist/fixtures/8.6.js
CHANGED
|
@@ -33,6 +33,7 @@ const ModelerUserInvitePage_1 = require("../pages/8.6/ModelerUserInvitePage");
|
|
|
33
33
|
const SignUpPage_1 = require("../pages/8.6/SignUpPage");
|
|
34
34
|
const PlayPage_1 = require("../pages/8.6/PlayPage");
|
|
35
35
|
const ConnectorTemplatePage_1 = require("../pages/8.6/ConnectorTemplatePage");
|
|
36
|
+
const ClientCredentialsDetailsPage_1 = require("../pages/8.6/ClientCredentialsDetailsPage");
|
|
36
37
|
const test = test_1.test.extend({
|
|
37
38
|
makeAxeBuilder: async ({ page }, use) => {
|
|
38
39
|
const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
|
|
@@ -125,6 +126,9 @@ const test = test_1.test.extend({
|
|
|
125
126
|
connectorTemplatePage: async ({ page }, use) => {
|
|
126
127
|
await use(new ConnectorTemplatePage_1.ConnectorTemplatePage(page));
|
|
127
128
|
},
|
|
129
|
+
clientCredentialsDetailsPage: async ({ page }, use) => {
|
|
130
|
+
await use(new ClientCredentialsDetailsPage_1.ClientCredentialsDetailsPage(page));
|
|
131
|
+
},
|
|
128
132
|
overrideTrackingScripts: [
|
|
129
133
|
async ({ context }, use) => {
|
|
130
134
|
await context.route('https://cmp.osano.com/16CVvwSNKHi9t1grQ/9403708a-488b-4f3b-aea6-613825dec79f/osano.js', (route) => route.fulfill({
|
package/dist/fixtures/8.9.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ import { OCIdentityHomePage } from '../pages/8.9/OCIdentityHomePage';
|
|
|
32
32
|
import { OCIdentityMappingRulesPage } from '../pages/8.9/OCIdentityMappingRulesPage';
|
|
33
33
|
import { OCIdentityRolesPage } from '../pages/8.9/OCIdentityRolesPage';
|
|
34
34
|
import { OCIdentityAuthorizationsPage } from '../pages/8.9/OCIdentityAuthorizationsPage';
|
|
35
|
+
import { OCIdentityClusterVariablesPage } from '../pages/8.9/OCIdentityClusterVariablesPage';
|
|
35
36
|
import { ClientCredentialsDetailsPage } from '../pages/8.9/ClientCredentialsDetailsPage';
|
|
36
37
|
type PlaywrightFixtures = {
|
|
37
38
|
makeAxeBuilder: () => AxeBuilder;
|
|
@@ -68,6 +69,7 @@ type PlaywrightFixtures = {
|
|
|
68
69
|
ocIdentityMappingRulesPage: OCIdentityMappingRulesPage;
|
|
69
70
|
ocIdentityRolesPage: OCIdentityRolesPage;
|
|
70
71
|
ocIdentityAuthorizationsPage: OCIdentityAuthorizationsPage;
|
|
72
|
+
ocIdentityClusterVariablesPage: OCIdentityClusterVariablesPage;
|
|
71
73
|
clientCredentialsDetailsPage: ClientCredentialsDetailsPage;
|
|
72
74
|
overrideTrackingScripts: void;
|
|
73
75
|
};
|
package/dist/fixtures/8.9.js
CHANGED
|
@@ -39,6 +39,7 @@ const OCIdentityHomePage_1 = require("../pages/8.9/OCIdentityHomePage");
|
|
|
39
39
|
const OCIdentityMappingRulesPage_1 = require("../pages/8.9/OCIdentityMappingRulesPage");
|
|
40
40
|
const OCIdentityRolesPage_1 = require("../pages/8.9/OCIdentityRolesPage");
|
|
41
41
|
const OCIdentityAuthorizationsPage_1 = require("../pages/8.9/OCIdentityAuthorizationsPage");
|
|
42
|
+
const OCIdentityClusterVariablesPage_1 = require("../pages/8.9/OCIdentityClusterVariablesPage");
|
|
42
43
|
const ClientCredentialsDetailsPage_1 = require("../pages/8.9/ClientCredentialsDetailsPage");
|
|
43
44
|
const test = test_1.test.extend({
|
|
44
45
|
makeAxeBuilder: async ({ page }, use) => {
|
|
@@ -151,6 +152,9 @@ const test = test_1.test.extend({
|
|
|
151
152
|
ocIdentityGroupsPage: async ({ page }, use) => {
|
|
152
153
|
await use(new OCIdentityGroupsPage_1.OCIdentityGroupsPage(page));
|
|
153
154
|
},
|
|
155
|
+
ocIdentityClusterVariablesPage: async ({ page }, use) => {
|
|
156
|
+
await use(new OCIdentityClusterVariablesPage_1.OCIdentityClusterVariablesPage(page));
|
|
157
|
+
},
|
|
154
158
|
clientCredentialsDetailsPage: async ({ page }, use) => {
|
|
155
159
|
await use(new ClientCredentialsDetailsPage_1.ClientCredentialsDetailsPage(page));
|
|
156
160
|
},
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
declare class ClientCredentialsDetailsPage {
|
|
3
|
+
private page;
|
|
4
|
+
readonly operateUrlRow: Locator;
|
|
5
|
+
readonly operateUrlValue: Locator;
|
|
6
|
+
readonly clientNameHeading: (clientName: string) => Locator;
|
|
7
|
+
constructor(page: Page);
|
|
8
|
+
isOpen(clientName: string): Promise<void>;
|
|
9
|
+
getOperateUrl(): Promise<string>;
|
|
10
|
+
goBack(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export { ClientCredentialsDetailsPage };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClientCredentialsDetailsPage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
class ClientCredentialsDetailsPage {
|
|
6
|
+
page;
|
|
7
|
+
operateUrlRow;
|
|
8
|
+
operateUrlValue;
|
|
9
|
+
clientNameHeading;
|
|
10
|
+
constructor(page) {
|
|
11
|
+
this.page = page;
|
|
12
|
+
this.operateUrlRow = page.getByRole('cell', { name: 'Operate URL' });
|
|
13
|
+
this.operateUrlValue = this.operateUrlRow.getByRole('textbox');
|
|
14
|
+
this.clientNameHeading = (clientName) => page.getByRole('heading', { name: clientName });
|
|
15
|
+
}
|
|
16
|
+
async isOpen(clientName) {
|
|
17
|
+
await (0, test_1.expect)(this.clientNameHeading(clientName)).toBeVisible({
|
|
18
|
+
timeout: 30000,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async getOperateUrl() {
|
|
22
|
+
if (await this.operateUrlValue.isVisible({ timeout: 10000 }).catch(() => false)) {
|
|
23
|
+
return await this.operateUrlValue.inputValue();
|
|
24
|
+
}
|
|
25
|
+
const text = await this.page.innerText('body');
|
|
26
|
+
const match = text.match(/Operate URL\s*([\w:/.-]+\/?)/i);
|
|
27
|
+
if (!match || !match[1]) {
|
|
28
|
+
throw new Error('Operate URL not found in client credentials page');
|
|
29
|
+
}
|
|
30
|
+
return match[1];
|
|
31
|
+
}
|
|
32
|
+
async goBack() {
|
|
33
|
+
await this.page.goBack();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.ClientCredentialsDetailsPage = ClientCredentialsDetailsPage;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
import { ClientCredentialsDetailsPage } from '../8.6/ClientCredentialsDetailsPage';
|
|
2
3
|
declare class ClusterDetailsPage {
|
|
3
4
|
private page;
|
|
4
5
|
readonly apiTab: Locator;
|
|
@@ -32,9 +33,12 @@ declare class ClusterDetailsPage {
|
|
|
32
33
|
readonly createAlertButton: Locator;
|
|
33
34
|
readonly rbaHeading: Locator;
|
|
34
35
|
readonly rbaEnabledMessage: Locator;
|
|
36
|
+
readonly clientCredentialsLink: (clientCredentials: string) => Locator;
|
|
37
|
+
readonly clientRow: (name: string) => Locator;
|
|
38
|
+
readonly clientRowDeleteButton: (name: string) => Locator;
|
|
35
39
|
constructor(page: Page);
|
|
36
40
|
clickAPITab(): Promise<void>;
|
|
37
|
-
deleteAPIClientsIfExist(): Promise<void>;
|
|
41
|
+
deleteAPIClientsIfExist(name?: string): Promise<void>;
|
|
38
42
|
clickAlertsTab(): Promise<void>;
|
|
39
43
|
clickCreateFirstAlertButton(): Promise<void>;
|
|
40
44
|
clickCreateNewAlertButton(): Promise<void>;
|
|
@@ -43,6 +47,7 @@ declare class ClusterDetailsPage {
|
|
|
43
47
|
clickCreateAlertButton(): Promise<void>;
|
|
44
48
|
deleteAlerts(): Promise<void>;
|
|
45
49
|
private doDelete;
|
|
50
|
+
clickCreateClientButton(): Promise<void>;
|
|
46
51
|
clickCreateFirstClientButton(): Promise<void>;
|
|
47
52
|
reload(): Promise<void>;
|
|
48
53
|
clickClientNameTextbox(): Promise<void>;
|
|
@@ -54,6 +59,8 @@ declare class ClusterDetailsPage {
|
|
|
54
59
|
clickCreateButton(): Promise<void>;
|
|
55
60
|
clickCloseModalButton(): Promise<void>;
|
|
56
61
|
clickSettingsTab(): Promise<void>;
|
|
62
|
+
createAPIClient(name: string): Promise<void>;
|
|
63
|
+
searchAndClickClientCredentialsLink(name: string): Promise<ClientCredentialsDetailsPage>;
|
|
57
64
|
enableRBA(): Promise<void>;
|
|
58
65
|
disableRBA(): Promise<void>;
|
|
59
66
|
assertComponentsHealth(components?: string[]): Promise<void>;
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ClusterDetailsPage = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const sleep_1 = require("../../utils/sleep");
|
|
6
|
+
const ClientCredentialsDetailsPage_1 = require("../8.6/ClientCredentialsDetailsPage");
|
|
7
|
+
const clickLocatorWithRetry_1 = require("../../utils/assertionHelpers/clickLocatorWithRetry");
|
|
6
8
|
class ClusterDetailsPage {
|
|
7
9
|
page;
|
|
8
10
|
apiTab;
|
|
@@ -36,6 +38,9 @@ class ClusterDetailsPage {
|
|
|
36
38
|
createAlertButton;
|
|
37
39
|
rbaHeading;
|
|
38
40
|
rbaEnabledMessage;
|
|
41
|
+
clientCredentialsLink;
|
|
42
|
+
clientRow;
|
|
43
|
+
clientRowDeleteButton;
|
|
39
44
|
constructor(page) {
|
|
40
45
|
this.page = page;
|
|
41
46
|
this.apiTab = page.getByRole('tab', { name: 'API' });
|
|
@@ -107,12 +112,33 @@ class ClusterDetailsPage {
|
|
|
107
112
|
name: 'Resource-based authorizations',
|
|
108
113
|
});
|
|
109
114
|
this.clientsList = page.getByRole('row').filter({ hasNotText: 'Scopes' });
|
|
115
|
+
this.clientCredentialsLink = (clientCredentials) => page.getByRole('cell', { name: clientCredentials });
|
|
116
|
+
this.clientRow = (name) => this.clientsList.filter({ hasText: name });
|
|
117
|
+
this.clientRowDeleteButton = (name) => this.clientRow(name).getByRole('button', { name: 'Delete' });
|
|
110
118
|
}
|
|
111
119
|
async clickAPITab() {
|
|
112
120
|
await (0, test_1.expect)(this.apiTab).toBeVisible({ timeout: 15000 });
|
|
113
121
|
await this.apiTab.click({ timeout: 15000 });
|
|
114
122
|
}
|
|
115
|
-
async deleteAPIClientsIfExist() {
|
|
123
|
+
async deleteAPIClientsIfExist(name) {
|
|
124
|
+
if (name) {
|
|
125
|
+
const row = this.clientRow(name);
|
|
126
|
+
const deleteButton = this.clientRowDeleteButton(name);
|
|
127
|
+
try {
|
|
128
|
+
await (0, test_1.expect)(deleteButton).toBeVisible({ timeout: 10000 });
|
|
129
|
+
await deleteButton.click();
|
|
130
|
+
await (0, test_1.expect)(this.dialog).toBeVisible();
|
|
131
|
+
await this.deleteSubButton.click();
|
|
132
|
+
await (0, test_1.expect)(this.page.getByText('Deleting...')).not.toBeVisible({
|
|
133
|
+
timeout: 10000,
|
|
134
|
+
});
|
|
135
|
+
await (0, test_1.expect)(row).not.toBeVisible();
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.warn(`No client row found for ${name} or deletion failed: ${error}`);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
116
142
|
await this.doDelete(this.dialog, 'API clients');
|
|
117
143
|
}
|
|
118
144
|
async clickAlertsTab() {
|
|
@@ -189,6 +215,9 @@ class ClusterDetailsPage {
|
|
|
189
215
|
console.error(`Error during ${text} deletion: `, error);
|
|
190
216
|
}
|
|
191
217
|
}
|
|
218
|
+
async clickCreateClientButton() {
|
|
219
|
+
await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.createFirstClientButton.or(this.createClientButton));
|
|
220
|
+
}
|
|
192
221
|
async clickCreateFirstClientButton() {
|
|
193
222
|
const maxRetries = 3;
|
|
194
223
|
for (let retries = 0; retries < maxRetries; retries++) {
|
|
@@ -252,6 +281,36 @@ class ClusterDetailsPage {
|
|
|
252
281
|
await this.settingsTab.click({ timeout: 120000 });
|
|
253
282
|
}
|
|
254
283
|
}
|
|
284
|
+
async createAPIClient(name) {
|
|
285
|
+
await this.clickCreateClientButton();
|
|
286
|
+
await (0, test_1.expect)(this.createClientCredentialsDialog).toBeVisible({
|
|
287
|
+
timeout: 60000,
|
|
288
|
+
});
|
|
289
|
+
await this.clickClientNameTextbox();
|
|
290
|
+
await this.fillClientNameTextbox(name);
|
|
291
|
+
await this.clickTasklistCheckbox();
|
|
292
|
+
await this.clickOperateCheckbox();
|
|
293
|
+
await this.clickOptimizeCheckbox();
|
|
294
|
+
await this.clickSecretsCheckbox();
|
|
295
|
+
await this.clickCreateButton();
|
|
296
|
+
await (0, test_1.expect)(this.clientCredentialsDialog).toBeVisible({
|
|
297
|
+
timeout: 20000,
|
|
298
|
+
});
|
|
299
|
+
await (0, test_1.expect)(this.clientCredentialsDialog
|
|
300
|
+
.getByText('The Client Secret will not be shown again.')
|
|
301
|
+
.first()).toBeVisible({
|
|
302
|
+
timeout: 60000,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
async searchAndClickClientCredentialsLink(name) {
|
|
306
|
+
await (0, test_1.expect)(this.clientsList.first()).toBeVisible({ timeout: 60000 });
|
|
307
|
+
const clientLink = this.clientCredentialsLink(name);
|
|
308
|
+
await (0, test_1.expect)(clientLink).toBeVisible({ timeout: 30000 });
|
|
309
|
+
await clientLink.click();
|
|
310
|
+
const clientCredentialsDetailsPage = new ClientCredentialsDetailsPage_1.ClientCredentialsDetailsPage(this.page);
|
|
311
|
+
await clientCredentialsDetailsPage.isOpen(name);
|
|
312
|
+
return clientCredentialsDetailsPage;
|
|
313
|
+
}
|
|
255
314
|
async enableRBA() {
|
|
256
315
|
await (0, test_1.expect)(this.rbaHeading).toBeVisible({ timeout: 60000 });
|
|
257
316
|
// Locate all elements with class .cds--toggle__text
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
export declare class OCIdentityClusterVariablesPage {
|
|
3
|
+
private page;
|
|
4
|
+
readonly variablesList: Locator;
|
|
5
|
+
readonly editVariableButton: (variableName: string) => Locator;
|
|
6
|
+
readonly editVariableModal: Locator;
|
|
7
|
+
readonly variableValueField: Locator;
|
|
8
|
+
readonly saveVariableButton: Locator;
|
|
9
|
+
readonly closeEditVariableModal: Locator;
|
|
10
|
+
readonly cancelButton: Locator;
|
|
11
|
+
readonly variableRow: (variableName: string) => Locator;
|
|
12
|
+
readonly monacoEditor: Locator;
|
|
13
|
+
readonly monacoEditorTextArea: Locator;
|
|
14
|
+
readonly successMessage: Locator;
|
|
15
|
+
readonly editMenuItem: Locator;
|
|
16
|
+
constructor(page: Page);
|
|
17
|
+
editVariable(variableName: string, newValue: string): Promise<void>;
|
|
18
|
+
assertVariableExists(variableName: string): Promise<void>;
|
|
19
|
+
assertVariableValue(variableName: string, expectedValue: string): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OCIdentityClusterVariablesPage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
class OCIdentityClusterVariablesPage {
|
|
6
|
+
page;
|
|
7
|
+
variablesList;
|
|
8
|
+
editVariableButton;
|
|
9
|
+
editVariableModal;
|
|
10
|
+
variableValueField;
|
|
11
|
+
saveVariableButton;
|
|
12
|
+
closeEditVariableModal;
|
|
13
|
+
cancelButton;
|
|
14
|
+
variableRow;
|
|
15
|
+
monacoEditor;
|
|
16
|
+
monacoEditorTextArea;
|
|
17
|
+
successMessage;
|
|
18
|
+
editMenuItem;
|
|
19
|
+
constructor(page) {
|
|
20
|
+
this.page = page;
|
|
21
|
+
this.variablesList = page.locator('table.cds--data-table');
|
|
22
|
+
this.variableRow = (variableName) => this.variablesList
|
|
23
|
+
.locator('tbody')
|
|
24
|
+
.getByRole('row')
|
|
25
|
+
.filter({ hasText: variableName });
|
|
26
|
+
this.editVariableButton = (variableName) => this.variableRow(variableName).getByRole('button', { name: 'Options' });
|
|
27
|
+
this.editVariableModal = page.getByRole('dialog', {
|
|
28
|
+
name: /Edit.*variable/i,
|
|
29
|
+
});
|
|
30
|
+
this.variableValueField = this.editVariableModal.getByRole('textbox', {
|
|
31
|
+
name: 'Editor content',
|
|
32
|
+
});
|
|
33
|
+
this.saveVariableButton = this.editVariableModal.locator('.cds--modal-footer button.cds--btn--primary');
|
|
34
|
+
this.closeEditVariableModal = this.editVariableModal.getByRole('button', {
|
|
35
|
+
name: 'Close',
|
|
36
|
+
});
|
|
37
|
+
this.cancelButton = this.editVariableModal.getByRole('button', {
|
|
38
|
+
name: 'Cancel',
|
|
39
|
+
});
|
|
40
|
+
this.monacoEditor = this.editVariableModal.locator('.monaco-editor');
|
|
41
|
+
this.monacoEditorTextArea = this.monacoEditor.locator('textarea.inputarea');
|
|
42
|
+
this.successMessage = this.page.getByText('Cluster variable updated');
|
|
43
|
+
this.editMenuItem = this.page
|
|
44
|
+
.locator('button[role="menuitem"]')
|
|
45
|
+
.filter({ hasText: /^Edit$/ });
|
|
46
|
+
}
|
|
47
|
+
async editVariable(variableName, newValue) {
|
|
48
|
+
await this.editVariableButton(variableName).click();
|
|
49
|
+
await (0, test_1.expect)(this.editMenuItem).toBeVisible();
|
|
50
|
+
await this.editMenuItem.click();
|
|
51
|
+
await (0, test_1.expect)(this.variableValueField).toBeVisible();
|
|
52
|
+
await (0, test_1.expect)(this.monacoEditor).toBeVisible();
|
|
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();
|
|
57
|
+
await this.saveVariableButton.click();
|
|
58
|
+
await (0, test_1.expect)(this.successMessage).toBeVisible();
|
|
59
|
+
await (0, test_1.expect)(this.editVariableModal).toBeHidden();
|
|
60
|
+
}
|
|
61
|
+
async assertVariableExists(variableName) {
|
|
62
|
+
await (0, test_1.expect)(this.variableRow(variableName)).toBeVisible();
|
|
63
|
+
}
|
|
64
|
+
async assertVariableValue(variableName, expectedValue) {
|
|
65
|
+
const row = this.variableRow(variableName);
|
|
66
|
+
await (0, test_1.expect)(row).toContainText(expectedValue);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.OCIdentityClusterVariablesPage = OCIdentityClusterVariablesPage;
|
|
@@ -5,6 +5,7 @@ declare class OCIdentityHomePage {
|
|
|
5
5
|
readonly adminBanner: Locator;
|
|
6
6
|
readonly rolesTab: Locator;
|
|
7
7
|
readonly authorizationsTab: Locator;
|
|
8
|
+
readonly clusterVariablesTab: Locator;
|
|
8
9
|
readonly licenseKeyTagNonProduction: Locator;
|
|
9
10
|
readonly licenseKeyTagNonCommercial: Locator;
|
|
10
11
|
readonly licenseKeyTagProduction: Locator;
|
|
@@ -14,5 +15,6 @@ declare class OCIdentityHomePage {
|
|
|
14
15
|
clickAuthorizationsTab(): Promise<void>;
|
|
15
16
|
clickRolesTab(): Promise<void>;
|
|
16
17
|
clickGroupsTab(): Promise<void>;
|
|
18
|
+
clickClusterVariablesTab(): Promise<void>;
|
|
17
19
|
}
|
|
18
20
|
export { OCIdentityHomePage };
|
|
@@ -8,6 +8,7 @@ class OCIdentityHomePage {
|
|
|
8
8
|
adminBanner;
|
|
9
9
|
rolesTab;
|
|
10
10
|
authorizationsTab;
|
|
11
|
+
clusterVariablesTab;
|
|
11
12
|
licenseKeyTagNonProduction;
|
|
12
13
|
licenseKeyTagNonCommercial;
|
|
13
14
|
licenseKeyTagProduction;
|
|
@@ -33,6 +34,16 @@ class OCIdentityHomePage {
|
|
|
33
34
|
.getByLabel('Admin')
|
|
34
35
|
.locator('a')
|
|
35
36
|
.filter({ hasText: /^Authorizations$/ });
|
|
37
|
+
this.clusterVariablesTab = page
|
|
38
|
+
.getByRole('banner')
|
|
39
|
+
.getByLabel('Admin')
|
|
40
|
+
.locator('a')
|
|
41
|
+
.filter({ hasText: /Cluster variables/i })
|
|
42
|
+
.or(page
|
|
43
|
+
.getByRole('banner')
|
|
44
|
+
.getByLabel('Admin')
|
|
45
|
+
.locator('a')
|
|
46
|
+
.filter({ hasText: /Variables/i }));
|
|
36
47
|
this.licenseKeyTagNonProduction = page
|
|
37
48
|
.getByText('Non-production license')
|
|
38
49
|
.first();
|
|
@@ -53,5 +64,9 @@ class OCIdentityHomePage {
|
|
|
53
64
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.groupsTab);
|
|
54
65
|
await this.groupsTab.click({ timeout: 30000 });
|
|
55
66
|
}
|
|
67
|
+
async clickClusterVariablesTab() {
|
|
68
|
+
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.clusterVariablesTab);
|
|
69
|
+
await this.clusterVariablesTab.click({ timeout: 30000 });
|
|
70
|
+
}
|
|
56
71
|
}
|
|
57
72
|
exports.OCIdentityHomePage = OCIdentityHomePage;
|
|
@@ -30,21 +30,7 @@ _8_6_1.test.describe('Console User Flow Tests', () => {
|
|
|
30
30
|
await clusterPage.clickClusterLink(defaultClusterName);
|
|
31
31
|
await clusterDetailsPage.clickAPITab();
|
|
32
32
|
await clusterDetailsPage.deleteAPIClientsIfExist();
|
|
33
|
-
await clusterDetailsPage.
|
|
34
|
-
await (0, test_1.expect)(clusterDetailsPage.createClientCredentialsDialog).toBeVisible({ timeout: 60000 });
|
|
35
|
-
await clusterDetailsPage.clickClientNameTextbox();
|
|
36
|
-
await clusterDetailsPage.fillClientNameTextbox(clientName);
|
|
37
|
-
await clusterDetailsPage.clickTasklistCheckbox();
|
|
38
|
-
await clusterDetailsPage.clickOperateCheckbox();
|
|
39
|
-
await clusterDetailsPage.clickOptimizeCheckbox();
|
|
40
|
-
await clusterDetailsPage.clickSecretsCheckbox();
|
|
41
|
-
await clusterDetailsPage.clickCreateButton();
|
|
42
|
-
await (0, test_1.expect)(clusterDetailsPage.clientCredentialsDialog).toBeVisible({
|
|
43
|
-
timeout: 20000,
|
|
44
|
-
});
|
|
45
|
-
await (0, test_1.expect)(clusterDetailsPage.clientCredentialsDialog
|
|
46
|
-
.getByText('The Client Secret will not be shown again.')
|
|
47
|
-
.first()).toBeVisible({ timeout: 60000 });
|
|
33
|
+
await clusterDetailsPage.createAPIClient(clientName);
|
|
48
34
|
await clusterDetailsPage.clickCloseModalButton();
|
|
49
35
|
await (0, test_1.expect)(clusterDetailsPage.clientsList.filter({ hasText: clientName })).toContainText('Zeebe, Tasklist, Operate, Optimize, and Secrets');
|
|
50
36
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const _8_6_1 = require("../../fixtures/8.6");
|
|
5
|
+
const UtilitiesPage_1 = require("../../pages/8.6/UtilitiesPage");
|
|
6
|
+
const _setup_1 = require("../../test-setup.js");
|
|
7
|
+
const users_1 = require("../../utils/users");
|
|
8
|
+
const urlHelpers_1 = require("../../utils/urlHelpers");
|
|
9
|
+
const testUser = (0, users_1.getTestUser)('twentySecondUser');
|
|
10
|
+
// This test covers the manual scenario: create a new API client via UI, copy the Operate URL, and verify the Operate endpoint denies unauthenticated access.
|
|
11
|
+
_8_6_1.test.describe.configure({ mode: 'parallel' });
|
|
12
|
+
_8_6_1.test.describe('Operate access requires authentication', () => {
|
|
13
|
+
let clientName;
|
|
14
|
+
const clusterName = 'Test Cluster';
|
|
15
|
+
_8_6_1.test.beforeEach(async ({ page, loginPage }, testInfo) => {
|
|
16
|
+
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, (testInfo.workerIndex + 1) * 1000);
|
|
17
|
+
});
|
|
18
|
+
_8_6_1.test.afterEach(async ({ page, homePage, clusterPage, clusterDetailsPage }, testInfo) => {
|
|
19
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
20
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
21
|
+
if (clientName) {
|
|
22
|
+
await homePage.clickClusters();
|
|
23
|
+
await clusterPage.clickClusterLink(clusterName);
|
|
24
|
+
await clusterDetailsPage.clickAPITab();
|
|
25
|
+
await clusterDetailsPage.deleteAPIClientsIfExist(clientName);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
(0, _8_6_1.test)('check that POST /v1/process-definitions/search without credentials returns 403 Forbidden with JSON body', async ({ homePage, clusterPage, clusterDetailsPage, clientCredentialsDetailsPage, request, }) => {
|
|
29
|
+
clientName = `operate-deny-${await (0, _setup_1.generateRandomStringAsync)(5)}`;
|
|
30
|
+
await _8_6_1.test.step('Add API Client to Cluster', async () => {
|
|
31
|
+
await homePage.clickClusters();
|
|
32
|
+
await clusterPage.clickClusterLink(clusterName);
|
|
33
|
+
await clusterDetailsPage.clickAPITab();
|
|
34
|
+
await clusterDetailsPage.createAPIClient(clientName);
|
|
35
|
+
await clusterDetailsPage.clickCloseModalButton();
|
|
36
|
+
await (0, test_1.expect)(clusterDetailsPage.clientsList.filter({ hasText: clientName })).toBeVisible({ timeout: 6000 });
|
|
37
|
+
});
|
|
38
|
+
let operateUrl = '';
|
|
39
|
+
await _8_6_1.test.step('Capture Operate URL from client credentials page and close it', async () => {
|
|
40
|
+
await clusterDetailsPage.searchAndClickClientCredentialsLink(clientName);
|
|
41
|
+
operateUrl = await clientCredentialsDetailsPage.getOperateUrl();
|
|
42
|
+
(0, test_1.expect)(operateUrl).toMatch(/^https?:\/\//);
|
|
43
|
+
await clientCredentialsDetailsPage.goBack();
|
|
44
|
+
await clusterDetailsPage.clickAPITab();
|
|
45
|
+
});
|
|
46
|
+
await _8_6_1.test.step('POST search endpoint without auth should be rejected', async () => {
|
|
47
|
+
const sanitizedOperateUrl = (0, urlHelpers_1.sanitizeUrl)(operateUrl);
|
|
48
|
+
const response = await request.post(`${sanitizedOperateUrl}/v1/process-definitions/search`, {
|
|
49
|
+
data: { filter: {}, size: 10 },
|
|
50
|
+
});
|
|
51
|
+
(0, test_1.expect)(response.status()).toBe(403);
|
|
52
|
+
const body = await response.json();
|
|
53
|
+
(0, test_1.expect)(body.status).toBe(403);
|
|
54
|
+
(0, test_1.expect)(body.error).toBe('Forbidden');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -6,16 +6,91 @@ const _setup_1 = require("../../test-setup.js");
|
|
|
6
6
|
const apiHelpers_1 = require("../../utils/apiHelpers");
|
|
7
7
|
const sleep_1 = require("../../utils/sleep");
|
|
8
8
|
const users_1 = require("../../utils/users");
|
|
9
|
+
const randomName_1 = require("../../utils/randomName");
|
|
10
|
+
const CLUSTER_VAR_NAMES = {
|
|
11
|
+
ORIGINAL_JSON: 'ORIGINAL_API_INFO',
|
|
12
|
+
UPDATABLE_JSON: 'UPDATABLE_API_INFO',
|
|
13
|
+
ORIGINAL_STRING: 'ORIGINAL_APP_VERSION',
|
|
14
|
+
UPDATABLE_STRING: 'UPDATABLE_APP_VERSION',
|
|
15
|
+
};
|
|
16
|
+
function getConfigByType(type) {
|
|
17
|
+
const configs = {
|
|
18
|
+
JSON: {
|
|
19
|
+
processName: 'Cluster Variable Original JSON',
|
|
20
|
+
processNameUpdatable: 'Cluster Variable Updatable JSON',
|
|
21
|
+
taskName: 'Preview JSON cluster variables',
|
|
22
|
+
originalVariableName: CLUSTER_VAR_NAMES.ORIGINAL_JSON,
|
|
23
|
+
updatableVariableName: CLUSTER_VAR_NAMES.UPDATABLE_JSON,
|
|
24
|
+
originalValue: originalJsonClusterVariableValue,
|
|
25
|
+
operateVariableName: 'URL',
|
|
26
|
+
randomValuePrefix: 'https://updated.api.com',
|
|
27
|
+
},
|
|
28
|
+
String: {
|
|
29
|
+
processName: 'Cluster Variable Original String',
|
|
30
|
+
processNameUpdatable: 'Cluster Variable Updatable String',
|
|
31
|
+
taskName: 'Preview String cluster variable',
|
|
32
|
+
originalVariableName: CLUSTER_VAR_NAMES.ORIGINAL_STRING,
|
|
33
|
+
updatableVariableName: CLUSTER_VAR_NAMES.UPDATABLE_STRING,
|
|
34
|
+
originalValue: originalStringClusterVariableValue,
|
|
35
|
+
operateVariableName: 'APP_VERSION_VALUE',
|
|
36
|
+
randomValuePrefix: 'v3.0.0-updated',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
return configs[type];
|
|
40
|
+
}
|
|
9
41
|
const testUser = (0, users_1.getTestUser)('sixteenthUser');
|
|
10
42
|
let authToken;
|
|
11
|
-
let
|
|
43
|
+
let originalJsonClusterVariableValue;
|
|
44
|
+
let originalStringClusterVariableValue;
|
|
45
|
+
let jsonProcessKeyDisplay;
|
|
46
|
+
let jsonProcessKeyUpdate;
|
|
47
|
+
let stringProcessKeyDisplay;
|
|
48
|
+
let stringProcessKeyUpdate;
|
|
12
49
|
_8_9_1.test.describe.configure({ mode: 'parallel' });
|
|
13
50
|
_8_9_1.test.describe('Cluster Variables User Flows', () => {
|
|
14
51
|
const clusterName = 'Test Cluster';
|
|
15
52
|
_8_9_1.test.beforeAll(async () => {
|
|
16
53
|
authToken = await (0, apiHelpers_1.authSaasAPI)();
|
|
17
|
-
await
|
|
18
|
-
|
|
54
|
+
await Promise.all([
|
|
55
|
+
(0, apiHelpers_1.createJsonClusterVariable)(authToken, 'saas', CLUSTER_VAR_NAMES.ORIGINAL_JSON, process.env.CLUSTER_VARIABLE_JSON_VALUE),
|
|
56
|
+
(0, apiHelpers_1.createJsonClusterVariable)(authToken, 'saas', CLUSTER_VAR_NAMES.UPDATABLE_JSON, process.env.CLUSTER_VARIABLE_JSON_VALUE),
|
|
57
|
+
(0, apiHelpers_1.createStringClusterVariable)(authToken, 'saas', CLUSTER_VAR_NAMES.ORIGINAL_STRING, process.env.CLUSTER_VARIABLE_STRING_VALUE),
|
|
58
|
+
(0, apiHelpers_1.createStringClusterVariable)(authToken, 'saas', CLUSTER_VAR_NAMES.UPDATABLE_STRING, process.env.CLUSTER_VARIABLE_STRING_VALUE),
|
|
59
|
+
]);
|
|
60
|
+
originalJsonClusterVariableValue = JSON.parse(process.env.CLUSTER_VARIABLE_JSON_VALUE);
|
|
61
|
+
originalStringClusterVariableValue =
|
|
62
|
+
process.env.CLUSTER_VARIABLE_STRING_VALUE;
|
|
63
|
+
const deployments = [
|
|
64
|
+
{
|
|
65
|
+
path: './resources/cluster_variables/cluster_variable_json_readonly.bpmn',
|
|
66
|
+
assignTo: 'jsonProcessKeyDisplay',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
path: './resources/cluster_variables/cluster_variable_json_mutable.bpmn',
|
|
70
|
+
assignTo: 'jsonProcessKeyUpdate',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
path: './resources/cluster_variables/cluster_variable_json_form.form',
|
|
74
|
+
assignTo: null,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
path: './resources/cluster_variables/cluster_variable_string_readonly.bpmn',
|
|
78
|
+
assignTo: 'stringProcessKeyDisplay',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
path: './resources/cluster_variables/cluster_variable_string_mutable.bpmn',
|
|
82
|
+
assignTo: 'stringProcessKeyUpdate',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
path: './resources/cluster_variables/cluster_variable_string_form.form',
|
|
86
|
+
assignTo: null,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
const deploymentResults = await Promise.all(deployments.map((d) => (0, apiHelpers_1.deployProcess)(d.path, authToken)));
|
|
90
|
+
jsonProcessKeyDisplay = deploymentResults[0];
|
|
91
|
+
jsonProcessKeyUpdate = deploymentResults[1];
|
|
92
|
+
stringProcessKeyDisplay = deploymentResults[3];
|
|
93
|
+
stringProcessKeyUpdate = deploymentResults[4];
|
|
19
94
|
});
|
|
20
95
|
_8_9_1.test.beforeEach(async ({ page, appsPage, loginPage }, testInfo) => {
|
|
21
96
|
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, (testInfo.workerIndex + 1) * 1000);
|
|
@@ -27,44 +102,99 @@ _8_9_1.test.describe('Cluster Variables User Flows', () => {
|
|
|
27
102
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
28
103
|
});
|
|
29
104
|
_8_9_1.test.describe('Global cluster variable', () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
(
|
|
34
|
-
(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
105
|
+
const testConfigs = [
|
|
106
|
+
{
|
|
107
|
+
type: 'JSON',
|
|
108
|
+
processKeyDisplay: () => jsonProcessKeyDisplay,
|
|
109
|
+
processKeyUpdate: () => jsonProcessKeyUpdate,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: 'String',
|
|
113
|
+
processKeyDisplay: () => stringProcessKeyDisplay,
|
|
114
|
+
processKeyUpdate: () => stringProcessKeyUpdate,
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
for (const config of testConfigs) {
|
|
118
|
+
(0, _8_9_1.test)(`User views ${config.type} cluster variable in Tasklist from readonly process and completes task`, async ({ appsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, }) => {
|
|
119
|
+
_8_9_1.test.slow();
|
|
120
|
+
const derived = getConfigByType(config.type);
|
|
121
|
+
const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyDisplay()), authToken);
|
|
122
|
+
await _8_9_1.test.step('User can access the process on operate', async () => {
|
|
123
|
+
await operateHomePage.clickProcessesTab();
|
|
124
|
+
await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
|
|
125
|
+
await operateProcessesPage.clickProcessInstanceLink(derived.processName);
|
|
126
|
+
await operateProcessInstancePage.assertActiveTokenIsPresent();
|
|
127
|
+
});
|
|
128
|
+
await _8_9_1.test.step(`User can view the process with ${config.type} cluster variable on tasklist`, async () => {
|
|
129
|
+
await appsPage.clickCamundaApps();
|
|
130
|
+
await appsPage.clickTasklist(clusterName);
|
|
131
|
+
await (0, sleep_1.sleep)(5000);
|
|
132
|
+
await taskPanelPage.openTask(derived.taskName);
|
|
133
|
+
await taskDetailsPage.clickAssignToMeButton();
|
|
134
|
+
});
|
|
135
|
+
await _8_9_1.test.step(`User can view the value of ${config.type} cluster variable and complete the task`, async () => {
|
|
136
|
+
if (config.type === 'JSON') {
|
|
137
|
+
for (const value of Object.values(derived.originalValue)) {
|
|
138
|
+
await taskDetailsPage.assertTextIsPresent(String(value));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
await taskDetailsPage.assertTextIsPresent(String(derived.originalValue));
|
|
143
|
+
}
|
|
144
|
+
await taskDetailsPage.clickCompleteTaskButton();
|
|
145
|
+
});
|
|
146
|
+
await _8_9_1.test.step('User can assert the process is completed on Operate', async () => {
|
|
147
|
+
await appsPage.clickCamundaApps();
|
|
148
|
+
await appsPage.clickOperate(clusterName);
|
|
149
|
+
await operateHomePage.clickProcessesTab();
|
|
150
|
+
await operateProcessesPage.clickProcessCompletedCheckbox();
|
|
151
|
+
await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
|
|
152
|
+
await operateProcessesPage.clickProcessInstanceLink(derived.processName);
|
|
153
|
+
await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
|
|
154
|
+
});
|
|
45
155
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
await
|
|
156
|
+
}
|
|
157
|
+
for (const config of testConfigs) {
|
|
158
|
+
(0, _8_9_1.test)(`User updates ${config.type} cluster variable in Admin UI and verifies changes in Operate`, async ({ appsPage, ocIdentityHomePage, ocIdentityClusterVariablesPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
159
|
+
_8_9_1.test.slow();
|
|
160
|
+
const derived = getConfigByType(config.type);
|
|
161
|
+
const randomRawValue = await (0, randomName_1.randomNameAgregator)(derived.randomValuePrefix);
|
|
162
|
+
const newValue = config.type === 'JSON'
|
|
163
|
+
? JSON.stringify({
|
|
164
|
+
endpoint: randomRawValue,
|
|
165
|
+
timeout_ms: '5000',
|
|
166
|
+
array: ['updated_item1', 'updated_item2'],
|
|
167
|
+
})
|
|
168
|
+
: JSON.stringify(randomRawValue);
|
|
169
|
+
await _8_9_1.test.step('User navigates to Admin UI', async () => {
|
|
170
|
+
await appsPage.clickCamundaApps();
|
|
171
|
+
await appsPage.clickAdmin(clusterName);
|
|
172
|
+
});
|
|
173
|
+
await _8_9_1.test.step('User navigates to Cluster Variables tab', async () => {
|
|
174
|
+
await ocIdentityHomePage.clickClusterVariablesTab();
|
|
175
|
+
});
|
|
176
|
+
await _8_9_1.test.step(`User verifies ${config.type} cluster variable exists`, async () => {
|
|
177
|
+
await ocIdentityClusterVariablesPage.assertVariableExists(derived.updatableVariableName);
|
|
178
|
+
});
|
|
179
|
+
await _8_9_1.test.step(`User updates the ${config.type} cluster variable value`, async () => {
|
|
180
|
+
await ocIdentityClusterVariablesPage.editVariable(derived.updatableVariableName, newValue);
|
|
181
|
+
});
|
|
182
|
+
await _8_9_1.test.step(`User creates a process instance with the updated ${config.type} cluster variable`, async () => {
|
|
183
|
+
const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyUpdate()), authToken);
|
|
184
|
+
await _8_9_1.test.step('User navigates to the process instance on Operate', async () => {
|
|
185
|
+
await appsPage.clickCamundaApps();
|
|
186
|
+
await appsPage.clickOperate(clusterName);
|
|
187
|
+
await operateHomePage.clickProcessesTab();
|
|
188
|
+
await operateProcessesPage.clickProcessCompletedCheckbox();
|
|
189
|
+
await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
|
|
190
|
+
await operateProcessesPage.clickProcessInstanceLink(derived.processNameUpdatable);
|
|
191
|
+
await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
|
|
192
|
+
});
|
|
193
|
+
await _8_9_1.test.step(`User verifies the updated ${config.type} cluster variable value is present in process variables`, async () => {
|
|
194
|
+
await operateProcessInstancePage.assertProcessVariableContainsText(derived.operateVariableName, randomRawValue);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
52
197
|
});
|
|
53
|
-
|
|
54
|
-
for (const [, value] of Object.entries(jsonClusterVariableValue)) {
|
|
55
|
-
await taskDetailsPage.assertTextIsPresent(String(value));
|
|
56
|
-
}
|
|
57
|
-
await taskDetailsPage.clickCompleteTaskButton();
|
|
58
|
-
});
|
|
59
|
-
await _8_9_1.test.step('User can assert the process is completed on Operate', async () => {
|
|
60
|
-
await appsPage.clickCamundaApps();
|
|
61
|
-
await appsPage.clickOperate(clusterName);
|
|
62
|
-
await operateHomePage.clickProcessesTab();
|
|
63
|
-
await operateProcessesPage.clickProcessCompletedCheckbox();
|
|
64
|
-
await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
|
|
65
|
-
await operateProcessesPage.clickProcessInstanceLink(`Cluster Variable Global scope - API INFO`);
|
|
66
|
-
await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
|
|
67
|
-
});
|
|
68
|
-
});
|
|
198
|
+
}
|
|
69
199
|
});
|
|
70
200
|
});
|
|
@@ -13,7 +13,16 @@ export declare function authC8runAPI(name: string, password: string): Promise<vo
|
|
|
13
13
|
export declare function validateMcpServerHealth(serverUrl?: string): Promise<APIResponse>;
|
|
14
14
|
export declare function deployProcess(filePath: string, authToken?: string, environment?: 'saas' | 'sm'): Promise<number | null>;
|
|
15
15
|
export declare function createProcessInstance(processDefinitionKey: string, authToken?: string, environment?: 'saas' | 'sm'): Promise<string>;
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function createJsonClusterVariable(authToken?: string, environment?: 'saas' | 'sm', customVariableName?: string, customVariableValue?: string): Promise<void>;
|
|
17
|
+
export declare function createStringClusterVariable(authToken?: string, environment?: 'saas' | 'sm', customVariableName?: string, customVariableValue?: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated This function will be removed when SM-8.9 cluster variables test is updated.
|
|
20
|
+
* Use createJsonClusterVariable() for JSON variables or
|
|
21
|
+
* createStringClusterVariable() for String variables instead.
|
|
22
|
+
*
|
|
23
|
+
* Maintained for backward compatibility with tests/SM-8.9/cluster-variables.spec.ts
|
|
24
|
+
*/
|
|
25
|
+
export declare function createGlobalClusterVariable(authToken: string, environment?: 'saas' | 'sm'): Promise<Record<string, unknown>>;
|
|
17
26
|
interface ReportDefinition {
|
|
18
27
|
key: string;
|
|
19
28
|
filter?: unknown[];
|
package/dist/utils/apiHelpers.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.updateCollectionScope = exports.createSingleProcessReport = exports.createDashboard = exports.createCollection = exports.getOptimizeCoockie = exports.createGlobalClusterVariable = exports.createProcessInstance = exports.deployProcess = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.sendRequestAndAssertResponse = exports.assertResponseStatus = void 0;
|
|
6
|
+
exports.updateCollectionScope = exports.createSingleProcessReport = exports.createDashboard = exports.createCollection = exports.getOptimizeCoockie = exports.createGlobalClusterVariable = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.createProcessInstance = exports.deployProcess = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.sendRequestAndAssertResponse = exports.assertResponseStatus = void 0;
|
|
7
7
|
const test_1 = require("@playwright/test");
|
|
8
8
|
const sleep_1 = require("./sleep");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -242,32 +242,65 @@ async function createProcessInstance(processDefinitionKey, authToken, environmen
|
|
|
242
242
|
return String(processInstanceKey);
|
|
243
243
|
}
|
|
244
244
|
exports.createProcessInstance = createProcessInstance;
|
|
245
|
-
async function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
245
|
+
async function createClusterVariableInternal(authToken, environment, variableName, variableValue, variableType) {
|
|
246
|
+
try {
|
|
247
|
+
apiRequestContext = await getApiRequestContext();
|
|
248
|
+
const url = buildZeebeApiUrl('/v2/cluster-variables/global', environment);
|
|
249
|
+
const response = await apiRequestContext.post(url, {
|
|
250
|
+
headers: {
|
|
251
|
+
Authorization: authToken,
|
|
252
|
+
},
|
|
253
|
+
data: {
|
|
254
|
+
name: variableName,
|
|
255
|
+
value: variableValue,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
const status = response.status();
|
|
259
|
+
if (status === 200 || status === 201 || status === 204) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// Handle "already exists" as a benign condition
|
|
263
|
+
if (status === 409) {
|
|
264
|
+
console.warn(`${variableType} cluster variable "${variableName}" already exists (HTTP 409).`);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const bodyText = await response.text();
|
|
268
|
+
throw new Error(`Failed to create ${variableType} cluster variable "${variableName}": HTTP ${status} - ${bodyText}`);
|
|
261
269
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
270
|
+
catch (error) {
|
|
271
|
+
if (error instanceof Error && error.message.includes('Failed to create')) {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
// Wrap unexpected errors with context
|
|
275
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
276
|
+
throw new Error(`Unexpected error creating ${variableType} cluster variable "${variableName}": ${errorMessage}`);
|
|
267
277
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
278
|
+
}
|
|
279
|
+
async function createJsonClusterVariable(authToken, environment = 'saas', customVariableName, customVariableValue) {
|
|
280
|
+
const variableName = customVariableName ?? String(process.env.CLUSTER_VARIABLE_NAME);
|
|
281
|
+
const variableValue = customVariableValue
|
|
282
|
+
? JSON.parse(customVariableValue)
|
|
283
|
+
: JSON.parse(process.env.CLUSTER_VARIABLE_JSON);
|
|
284
|
+
await createClusterVariableInternal(authToken ?? '', environment, variableName, variableValue, 'JSON');
|
|
285
|
+
}
|
|
286
|
+
exports.createJsonClusterVariable = createJsonClusterVariable;
|
|
287
|
+
async function createStringClusterVariable(authToken, environment = 'saas', customVariableName, customVariableValue) {
|
|
288
|
+
const variableName = customVariableName ?? String(process.env.CLUSTER_VARIABLE_STRING_NAME);
|
|
289
|
+
const variableValue = customVariableValue ?? process.env.CLUSTER_VARIABLE_STRING_VALUE;
|
|
290
|
+
await createClusterVariableInternal(authToken ?? '', environment, variableName, variableValue, 'String');
|
|
291
|
+
}
|
|
292
|
+
exports.createStringClusterVariable = createStringClusterVariable;
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated This function will be removed when SM-8.9 cluster variables test is updated.
|
|
295
|
+
* Use createJsonClusterVariable() for JSON variables or
|
|
296
|
+
* createStringClusterVariable() for String variables instead.
|
|
297
|
+
*
|
|
298
|
+
* Maintained for backward compatibility with tests/SM-8.9/cluster-variables.spec.ts
|
|
299
|
+
*/
|
|
300
|
+
async function createGlobalClusterVariable(authToken, environment = 'saas') {
|
|
301
|
+
const variableValue = process.env.CLUSTER_VARIABLE_JSON_VALUE;
|
|
302
|
+
await createJsonClusterVariable(authToken, environment, 'ORIGINAL_API_INFO', variableValue);
|
|
303
|
+
return JSON.parse(variableValue);
|
|
271
304
|
}
|
|
272
305
|
exports.createGlobalClusterVariable = createGlobalClusterVariable;
|
|
273
306
|
async function getOptimizeCoockie(page) {
|