@camunda/e2e-test-suite 0.0.256 → 0.0.258
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/SM-8.10.d.ts +81 -0
- package/dist/fixtures/SM-8.10.js +184 -0
- package/dist/pages/SM-8.10/Authorization.d.ts +31 -0
- package/dist/pages/SM-8.10/Authorization.js +146 -0
- package/dist/pages/SM-8.10/ClusterDetailsPage.d.ts +8 -0
- package/dist/pages/SM-8.10/ClusterDetailsPage.js +28 -0
- package/dist/pages/SM-8.10/ClusterPage.d.ts +11 -0
- package/dist/pages/SM-8.10/ClusterPage.js +32 -0
- package/dist/pages/SM-8.10/ConnectorMarketplacePage.d.ts +16 -0
- package/dist/pages/SM-8.10/ConnectorMarketplacePage.js +52 -0
- package/dist/pages/SM-8.10/ConnectorSettingsPage.d.ts +40 -0
- package/dist/pages/SM-8.10/ConnectorSettingsPage.js +133 -0
- package/dist/pages/SM-8.10/ConnectorTemplatePage.d.ts +11 -0
- package/dist/pages/SM-8.10/ConnectorTemplatePage.js +34 -0
- package/dist/pages/SM-8.10/ConsoleHomePage.d.ts +11 -0
- package/dist/pages/SM-8.10/ConsoleHomePage.js +31 -0
- package/dist/pages/SM-8.10/ConsoleOrganizationPage.d.ts +22 -0
- package/dist/pages/SM-8.10/ConsoleOrganizationPage.js +68 -0
- package/dist/pages/SM-8.10/FormJsPage.d.ts +31 -0
- package/dist/pages/SM-8.10/FormJsPage.js +87 -0
- package/dist/pages/SM-8.10/HomePage.d.ts +20 -0
- package/dist/pages/SM-8.10/HomePage.js +49 -0
- package/dist/pages/SM-8.10/IdentityTenantPage.d.ts +52 -0
- package/dist/pages/SM-8.10/IdentityTenantPage.js +218 -0
- package/dist/pages/SM-8.10/IdentityUsersPage.d.ts +92 -0
- package/dist/pages/SM-8.10/IdentityUsersPage.js +473 -0
- package/dist/pages/SM-8.10/KeycloakAdminPage.d.ts +15 -0
- package/dist/pages/SM-8.10/KeycloakAdminPage.js +68 -0
- package/dist/pages/SM-8.10/KeycloakLoginPage.d.ts +11 -0
- package/dist/pages/SM-8.10/KeycloakLoginPage.js +25 -0
- package/dist/pages/SM-8.10/KeycloakUtils.d.ts +16 -0
- package/dist/pages/SM-8.10/KeycloakUtils.js +63 -0
- package/dist/pages/SM-8.10/LoginPage.d.ts +21 -0
- package/dist/pages/SM-8.10/LoginPage.js +100 -0
- package/dist/pages/SM-8.10/ManagementIdentityPage.d.ts +46 -0
- package/dist/pages/SM-8.10/ManagementIdentityPage.js +153 -0
- package/dist/pages/SM-8.10/ModelerCreatePage.d.ts +199 -0
- package/dist/pages/SM-8.10/ModelerCreatePage.js +1052 -0
- package/dist/pages/SM-8.10/ModelerHomePage.d.ts +44 -0
- package/dist/pages/SM-8.10/ModelerHomePage.js +179 -0
- package/dist/pages/SM-8.10/NavigationPage.d.ts +47 -0
- package/dist/pages/SM-8.10/NavigationPage.js +134 -0
- package/dist/pages/SM-8.10/OCIdentityAuthorizationsPage.d.ts +10 -0
- package/dist/pages/SM-8.10/OCIdentityAuthorizationsPage.js +35 -0
- package/dist/pages/SM-8.10/OCIdentityClusterVariablesPage.d.ts +20 -0
- package/dist/pages/SM-8.10/OCIdentityClusterVariablesPage.js +69 -0
- package/dist/pages/SM-8.10/OCIdentityGroupsPage.d.ts +39 -0
- package/dist/pages/SM-8.10/OCIdentityGroupsPage.js +154 -0
- package/dist/pages/SM-8.10/OCIdentityHomePage.d.ts +23 -0
- package/dist/pages/SM-8.10/OCIdentityHomePage.js +81 -0
- package/dist/pages/SM-8.10/OCIdentityMappingRulesPage.d.ts +23 -0
- package/dist/pages/SM-8.10/OCIdentityMappingRulesPage.js +110 -0
- package/dist/pages/SM-8.10/OCIdentityRolesPage.d.ts +55 -0
- package/dist/pages/SM-8.10/OCIdentityRolesPage.js +197 -0
- package/dist/pages/SM-8.10/OCTenantPage.d.ts +67 -0
- package/dist/pages/SM-8.10/OCTenantPage.js +280 -0
- package/dist/pages/SM-8.10/OperateHomePage.d.ts +24 -0
- package/dist/pages/SM-8.10/OperateHomePage.js +81 -0
- package/dist/pages/SM-8.10/OperateProcessInstancePage.d.ts +24 -0
- package/dist/pages/SM-8.10/OperateProcessInstancePage.js +170 -0
- package/dist/pages/SM-8.10/OperateProcessesPage.d.ts +32 -0
- package/dist/pages/SM-8.10/OperateProcessesPage.js +205 -0
- package/dist/pages/SM-8.10/OptimizeCollectionsPage.d.ts +17 -0
- package/dist/pages/SM-8.10/OptimizeCollectionsPage.js +66 -0
- package/dist/pages/SM-8.10/OptimizeDashboardPage.d.ts +14 -0
- package/dist/pages/SM-8.10/OptimizeDashboardPage.js +56 -0
- package/dist/pages/SM-8.10/OptimizeHomePage.d.ts +19 -0
- package/dist/pages/SM-8.10/OptimizeHomePage.js +64 -0
- package/dist/pages/SM-8.10/OptimizeReportPage.d.ts +50 -0
- package/dist/pages/SM-8.10/OptimizeReportPage.js +179 -0
- package/dist/pages/SM-8.10/PlayPage.d.ts +44 -0
- package/dist/pages/SM-8.10/PlayPage.js +235 -0
- package/dist/pages/SM-8.10/SettingsPage.d.ts +12 -0
- package/dist/pages/SM-8.10/SettingsPage.js +25 -0
- package/dist/pages/SM-8.10/TaskDetailsPage.d.ts +70 -0
- package/dist/pages/SM-8.10/TaskDetailsPage.js +266 -0
- package/dist/pages/SM-8.10/TaskPanelPage.d.ts +24 -0
- package/dist/pages/SM-8.10/TaskPanelPage.js +93 -0
- package/dist/pages/SM-8.10/TaskProcessesPage.d.ts +14 -0
- package/dist/pages/SM-8.10/TaskProcessesPage.js +53 -0
- package/dist/pages/SM-8.10/UtilitiesPage.d.ts +34 -0
- package/dist/pages/SM-8.10/UtilitiesPage.js +435 -0
- package/dist/pages/SM-8.10/optimizeReportUtils.d.ts +6 -0
- package/dist/pages/SM-8.10/optimizeReportUtils.js +42 -0
- package/dist/pages/SM-8.6/ModelerCreatePage.js +3 -0
- package/dist/pages/SM-8.6/PlayPage.js +2 -0
- package/dist/pages/SM-8.7/ModelerCreatePage.js +3 -0
- package/dist/pages/SM-8.7/PlayPage.d.ts +1 -0
- package/dist/pages/SM-8.7/PlayPage.js +4 -2
- package/dist/tests/SM-8.10/cluster-variables.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/cluster-variables.spec.js +190 -0
- package/dist/tests/SM-8.10/connectors-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/connectors-user-flows.spec.js +260 -0
- package/dist/tests/SM-8.10/console-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/console-user-flows.spec.js +88 -0
- package/dist/tests/SM-8.10/document-handling-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/document-handling-user-flows.spec.js +157 -0
- package/dist/tests/SM-8.10/hto-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/hto-user-flows.spec.js +408 -0
- package/dist/tests/SM-8.10/identity-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/identity-user-flows.spec.js +233 -0
- package/dist/tests/SM-8.10/license-key-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/license-key-user-flows.spec.js +523 -0
- package/dist/tests/SM-8.10/login.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/login.spec.js +24 -0
- package/dist/tests/SM-8.10/migration-path-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/migration-path-user-flows.spec.js +224 -0
- package/dist/tests/SM-8.10/mt-enabled-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/mt-enabled-user-flows.spec.js +584 -0
- package/dist/tests/SM-8.10/optimize-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/optimize-user-flows.spec.js +184 -0
- package/dist/tests/SM-8.10/play.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/play.spec.js +152 -0
- package/dist/tests/SM-8.10/rba-enabled-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/rba-enabled-user-flows.spec.js +715 -0
- package/dist/tests/SM-8.10/smoke-tests.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/smoke-tests.spec.js +163 -0
- package/dist/tests/SM-8.10/test-setup.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/test-setup.spec.js +24 -0
- package/dist/tests/SM-8.10/web-modeler-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/web-modeler-user-flows.spec.js +178 -0
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
declare class ModelerHomePage {
|
|
3
|
+
private page;
|
|
4
|
+
private defaultFolderName;
|
|
5
|
+
readonly modelerPageBanner: Locator;
|
|
6
|
+
readonly createNewProjectButton: Locator;
|
|
7
|
+
readonly projectNameInput: Locator;
|
|
8
|
+
readonly chooseBpmnTemplateButton: Locator;
|
|
9
|
+
readonly diagramTypeDropdown: Locator;
|
|
10
|
+
readonly bpmnTemplateOption: Locator;
|
|
11
|
+
readonly formTemplateOption: Locator;
|
|
12
|
+
readonly projectBreadcrumb: Locator;
|
|
13
|
+
readonly openOrganizationsButton: Locator;
|
|
14
|
+
readonly manageButton: Locator;
|
|
15
|
+
readonly crossComponentProjectFolder: Locator;
|
|
16
|
+
readonly homeBreadcrumb: Locator;
|
|
17
|
+
readonly formNameInput: Locator;
|
|
18
|
+
readonly rows: Locator;
|
|
19
|
+
readonly licenseKeyTagNonProduction: Locator;
|
|
20
|
+
readonly licenseKeyTagNonCommercial: Locator;
|
|
21
|
+
readonly licenseKeyTagProduction: Locator;
|
|
22
|
+
readonly licenseKeyTagCommercial: Locator;
|
|
23
|
+
readonly uploadFilesButton: Locator;
|
|
24
|
+
readonly messageBanner: Locator;
|
|
25
|
+
readonly closeButton: Locator;
|
|
26
|
+
constructor(page: Page);
|
|
27
|
+
clickCreateNewProjectButton(): Promise<void>;
|
|
28
|
+
enterNewProjectName(name: string): Promise<void>;
|
|
29
|
+
createCrossComponentProjectFolder(): Promise<void>;
|
|
30
|
+
clickCrossComponentProjectFolder(): Promise<void>;
|
|
31
|
+
clickProcessDiagram(name: string): Promise<void>;
|
|
32
|
+
clickHomeBreadcrumb(): Promise<void>;
|
|
33
|
+
clickChooseBpmnTemplateButton(): Promise<void>;
|
|
34
|
+
clickDiagramTypeDropdown(): Promise<void>;
|
|
35
|
+
clickBpmnTemplateOption(): Promise<void>;
|
|
36
|
+
clickFormOption(): Promise<void>;
|
|
37
|
+
enterFormName(name: string): Promise<void>;
|
|
38
|
+
clickProjectBreadcrumb(): Promise<void>;
|
|
39
|
+
clickOpenOrganizationsButton(): Promise<void>;
|
|
40
|
+
clickManageButton(): Promise<void>;
|
|
41
|
+
clickUploadFilesButton(): Promise<void>;
|
|
42
|
+
clickMessageBanner(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export { ModelerHomePage };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModelerHomePage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
const sleep_1 = require("../../utils/sleep");
|
|
6
|
+
const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
|
|
7
|
+
class ModelerHomePage {
|
|
8
|
+
page;
|
|
9
|
+
defaultFolderName = 'Cross Component Test Project';
|
|
10
|
+
modelerPageBanner;
|
|
11
|
+
createNewProjectButton;
|
|
12
|
+
projectNameInput;
|
|
13
|
+
chooseBpmnTemplateButton;
|
|
14
|
+
diagramTypeDropdown;
|
|
15
|
+
bpmnTemplateOption;
|
|
16
|
+
formTemplateOption;
|
|
17
|
+
projectBreadcrumb;
|
|
18
|
+
openOrganizationsButton;
|
|
19
|
+
manageButton;
|
|
20
|
+
crossComponentProjectFolder;
|
|
21
|
+
homeBreadcrumb;
|
|
22
|
+
formNameInput;
|
|
23
|
+
rows;
|
|
24
|
+
licenseKeyTagNonProduction;
|
|
25
|
+
licenseKeyTagNonCommercial;
|
|
26
|
+
licenseKeyTagProduction;
|
|
27
|
+
licenseKeyTagCommercial;
|
|
28
|
+
uploadFilesButton;
|
|
29
|
+
messageBanner;
|
|
30
|
+
closeButton;
|
|
31
|
+
constructor(page) {
|
|
32
|
+
this.page = page;
|
|
33
|
+
this.modelerPageBanner = page
|
|
34
|
+
.locator('a')
|
|
35
|
+
.filter({ hasText: 'Camunda logoModeler' });
|
|
36
|
+
this.createNewProjectButton = page.getByRole('button', {
|
|
37
|
+
name: 'New project',
|
|
38
|
+
});
|
|
39
|
+
this.projectNameInput = page.locator('[data-test="editable-input"]');
|
|
40
|
+
this.chooseBpmnTemplateButton = page.getByRole('button', {
|
|
41
|
+
name: 'Choose BPMN template',
|
|
42
|
+
});
|
|
43
|
+
this.diagramTypeDropdown = page.locator('[data-test="diagram-dropdown"]');
|
|
44
|
+
this.bpmnTemplateOption = page
|
|
45
|
+
.locator('[data-test="create-bpmn-diagram"]')
|
|
46
|
+
.getByText('BPMN Diagram');
|
|
47
|
+
this.formTemplateOption = page
|
|
48
|
+
.locator('[data-test="create-form"]')
|
|
49
|
+
.getByText('Form');
|
|
50
|
+
this.projectBreadcrumb = page.locator('[data-test="breadcrumb-project"]');
|
|
51
|
+
this.openOrganizationsButton = page.getByLabel('Open Organizations');
|
|
52
|
+
this.manageButton = page.getByRole('button', { name: 'Manage' });
|
|
53
|
+
this.crossComponentProjectFolder = page
|
|
54
|
+
.getByTitle(this.defaultFolderName, {
|
|
55
|
+
exact: true,
|
|
56
|
+
})
|
|
57
|
+
.first();
|
|
58
|
+
this.homeBreadcrumb = page.locator('[data-test="breadcrumb-home"]');
|
|
59
|
+
this.formNameInput = page.locator('[data-test="editable-input"]');
|
|
60
|
+
this.rows = page.getByRole('row');
|
|
61
|
+
this.licenseKeyTagNonProduction = page
|
|
62
|
+
.getByText('Non-production license')
|
|
63
|
+
.first();
|
|
64
|
+
this.licenseKeyTagNonCommercial = page.getByText('Non-commercial license');
|
|
65
|
+
this.licenseKeyTagProduction = page.getByText('Production license').first();
|
|
66
|
+
this.licenseKeyTagCommercial = page.getByText('Commercial license');
|
|
67
|
+
this.uploadFilesButton = page.getByRole('menuitem', { name: 'Upload files' });
|
|
68
|
+
this.messageBanner = page.locator('[data-test="close-top-banner"]');
|
|
69
|
+
this.closeButton = page.getByRole('button', { name: 'Got it - Dismiss' });
|
|
70
|
+
}
|
|
71
|
+
async clickCreateNewProjectButton() {
|
|
72
|
+
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.createNewProjectButton, {
|
|
73
|
+
totalTimeout: 30000,
|
|
74
|
+
});
|
|
75
|
+
await this.createNewProjectButton.click();
|
|
76
|
+
}
|
|
77
|
+
async enterNewProjectName(name) {
|
|
78
|
+
await this.projectNameInput.click({ timeout: 60000 });
|
|
79
|
+
await this.projectNameInput.fill(name);
|
|
80
|
+
await this.projectNameInput.press('Enter');
|
|
81
|
+
}
|
|
82
|
+
async createCrossComponentProjectFolder() {
|
|
83
|
+
await (0, sleep_1.sleep)(10000);
|
|
84
|
+
await this.clickMessageBanner();
|
|
85
|
+
if (await this.crossComponentProjectFolder.isVisible()) {
|
|
86
|
+
console.log('Cross Component Project folder already exists. Clicking into it');
|
|
87
|
+
await this.clickCrossComponentProjectFolder();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await this.clickCreateNewProjectButton();
|
|
91
|
+
await this.enterNewProjectName(this.defaultFolderName);
|
|
92
|
+
await (0, sleep_1.sleep)(5000);
|
|
93
|
+
}
|
|
94
|
+
async clickCrossComponentProjectFolder() {
|
|
95
|
+
let attempts = 0;
|
|
96
|
+
const maxAttempts = 3;
|
|
97
|
+
const timeout = 60000;
|
|
98
|
+
while (attempts < maxAttempts) {
|
|
99
|
+
try {
|
|
100
|
+
await this.clickMessageBanner();
|
|
101
|
+
await (0, test_1.expect)(this.crossComponentProjectFolder).toBeVisible({ timeout });
|
|
102
|
+
await this.crossComponentProjectFolder.click();
|
|
103
|
+
await this.clickMessageBanner();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
attempts++;
|
|
108
|
+
if (attempts < maxAttempts) {
|
|
109
|
+
console.log(`Attempt ${attempts} failed. Reloading page and retrying...`);
|
|
110
|
+
await this.page.reload();
|
|
111
|
+
await (0, sleep_1.sleep)(10000);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
throw new Error('Failed to click crossComponentProjectFolder after 3 attempts.');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async clickProcessDiagram(name) {
|
|
120
|
+
const process = this.rows.filter({ hasText: name }).getByTitle(name).first();
|
|
121
|
+
await (0, test_1.expect)(process).toBeVisible({ timeout: 90000 });
|
|
122
|
+
await process.click();
|
|
123
|
+
}
|
|
124
|
+
async clickHomeBreadcrumb() {
|
|
125
|
+
try {
|
|
126
|
+
await this.homeBreadcrumb.click();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
await this.page.getByText('Home', { exact: true }).first().click();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async clickChooseBpmnTemplateButton() {
|
|
133
|
+
await this.chooseBpmnTemplateButton.click();
|
|
134
|
+
}
|
|
135
|
+
async clickDiagramTypeDropdown() {
|
|
136
|
+
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.diagramTypeDropdown, {
|
|
137
|
+
postAction: async () => {
|
|
138
|
+
await this.page.reload();
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
await this.diagramTypeDropdown.click();
|
|
142
|
+
}
|
|
143
|
+
async clickBpmnTemplateOption() {
|
|
144
|
+
await (0, test_1.expect)(this.bpmnTemplateOption).toBeVisible({ timeout: 60000 });
|
|
145
|
+
await this.bpmnTemplateOption.click({ timeout: 60000 });
|
|
146
|
+
}
|
|
147
|
+
async clickFormOption() {
|
|
148
|
+
await this.formTemplateOption.click();
|
|
149
|
+
}
|
|
150
|
+
async enterFormName(name) {
|
|
151
|
+
await this.formNameInput.click({ timeout: 60000 });
|
|
152
|
+
await this.formNameInput.fill(name);
|
|
153
|
+
await this.formNameInput.press('Enter');
|
|
154
|
+
}
|
|
155
|
+
async clickProjectBreadcrumb() {
|
|
156
|
+
await this.projectBreadcrumb.click({ timeout: 60000 });
|
|
157
|
+
}
|
|
158
|
+
async clickOpenOrganizationsButton() {
|
|
159
|
+
await this.openOrganizationsButton.click({ timeout: 30000 });
|
|
160
|
+
}
|
|
161
|
+
async clickManageButton() {
|
|
162
|
+
await this.manageButton.click({ timeout: 30000 });
|
|
163
|
+
}
|
|
164
|
+
async clickUploadFilesButton() {
|
|
165
|
+
await this.uploadFilesButton.click({ timeout: 60000 });
|
|
166
|
+
}
|
|
167
|
+
async clickMessageBanner() {
|
|
168
|
+
try {
|
|
169
|
+
await Promise.race([
|
|
170
|
+
this.messageBanner.click(),
|
|
171
|
+
this.closeButton.click(),
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
console.log('No banner or close button found to click');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.ModelerHomePage = ModelerHomePage;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Locator, Page } from '@playwright/test';
|
|
2
|
+
declare class NavigationPage {
|
|
3
|
+
private page;
|
|
4
|
+
readonly modelerPageBanner: Locator;
|
|
5
|
+
readonly operatePageBanner: Locator;
|
|
6
|
+
readonly tasklistPageBanner: Locator;
|
|
7
|
+
readonly optimizePageBanner: Locator;
|
|
8
|
+
readonly identityPageBanner: Locator;
|
|
9
|
+
readonly consolePageBanner: Locator;
|
|
10
|
+
readonly keyboardPageBanner: Locator;
|
|
11
|
+
readonly managementIdentityPageBanner: Locator;
|
|
12
|
+
constructor(page: Page);
|
|
13
|
+
goTo(url: string, banner: Locator, sleepTimeout?: number, { username, password, }?: {
|
|
14
|
+
username?: string;
|
|
15
|
+
password?: string;
|
|
16
|
+
}, maxRetries?: number): Promise<void>;
|
|
17
|
+
goToModeler(sleepTimeout?: number, credentials?: {
|
|
18
|
+
username: string;
|
|
19
|
+
password: string;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
goToTasklist(sleepTimeout?: number, credentials?: {
|
|
22
|
+
username: string;
|
|
23
|
+
password: string;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
goToOperate(sleepTimeout?: number, credentials?: {
|
|
26
|
+
username: string;
|
|
27
|
+
password: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
goToOptimize(sleepTimeout?: number, credentials?: {
|
|
30
|
+
username: string;
|
|
31
|
+
password: string;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
goToKeycloak(): Promise<void>;
|
|
34
|
+
goToOCIdentity(sleepTimeout?: number, credentials?: {
|
|
35
|
+
username: string;
|
|
36
|
+
password: string;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
goToConsole(sleepTimeout?: number, credentials?: {
|
|
39
|
+
username: string;
|
|
40
|
+
password: string;
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
goToManagementIdentity(sleepTimeout?: number, credentials?: {
|
|
43
|
+
username: string;
|
|
44
|
+
password: string;
|
|
45
|
+
}): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export { NavigationPage };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NavigationPage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
const LoginPage_1 = require("./LoginPage");
|
|
6
|
+
const sleep_1 = require("../../utils/sleep");
|
|
7
|
+
const constants_1 = require("../../utils/constants");
|
|
8
|
+
const ORCHESTRATION_CONTEXT_PATH = process.env.ORCHESTRATION_CONTEXT_PATH ?? '/orchestration';
|
|
9
|
+
const MODELER_CONTEXT_PATH = process.env.MODELER_CONTEXT_PATH ?? '/modeler';
|
|
10
|
+
const OPTIMIZE_CONTEXT_PATH = process.env.OPTIMIZE_CONTEXT_PATH ?? '/optimize';
|
|
11
|
+
const CONSOLE_CONTEXT_PATH = process.env.CONSOLE_CONTEXT_PATH ?? '/console';
|
|
12
|
+
const MANAGEMENT_IDENTITY_CONTEXT_PATH = process.env.MANAGEMENT_IDENTITY_CONTEXT_PATH ?? '/identity';
|
|
13
|
+
const IDENTITY_FIRSTUSER_USERNAME = process.env.DISTRO_QA_E2E_TESTS_IDENTITY_FIRSTUSER_USERNAME || 'demo';
|
|
14
|
+
const IDENTITY_FIRSTUSER_PASSWORD = process.env.DISTRO_QA_E2E_TESTS_IDENTITY_FIRSTUSER_PASSWORD || 'demo';
|
|
15
|
+
class NavigationPage {
|
|
16
|
+
page;
|
|
17
|
+
modelerPageBanner;
|
|
18
|
+
operatePageBanner;
|
|
19
|
+
tasklistPageBanner;
|
|
20
|
+
optimizePageBanner;
|
|
21
|
+
identityPageBanner;
|
|
22
|
+
consolePageBanner;
|
|
23
|
+
keyboardPageBanner;
|
|
24
|
+
managementIdentityPageBanner;
|
|
25
|
+
constructor(page) {
|
|
26
|
+
this.page = page;
|
|
27
|
+
this.operatePageBanner = page.getByRole('link', {
|
|
28
|
+
name: 'Camunda logo Operate',
|
|
29
|
+
});
|
|
30
|
+
this.modelerPageBanner = page
|
|
31
|
+
.locator('a')
|
|
32
|
+
.filter({ hasText: 'Camunda logoModeler' });
|
|
33
|
+
this.tasklistPageBanner = page.getByRole('link', {
|
|
34
|
+
name: 'Camunda logo Tasklist',
|
|
35
|
+
});
|
|
36
|
+
this.optimizePageBanner = page.getByRole('link', {
|
|
37
|
+
name: 'Camunda logo Optimize',
|
|
38
|
+
});
|
|
39
|
+
// TODO: Drop support for Identity once we fully rename it to Admin
|
|
40
|
+
this.identityPageBanner = page.getByRole('link', {
|
|
41
|
+
name: /Camunda logo (Identity|Admin)/,
|
|
42
|
+
});
|
|
43
|
+
this.consolePageBanner = page.getByRole('link', {
|
|
44
|
+
name: 'Camunda logo Console',
|
|
45
|
+
});
|
|
46
|
+
this.managementIdentityPageBanner = page.getByRole('link', {
|
|
47
|
+
name: 'Camunda logo Management Identity',
|
|
48
|
+
});
|
|
49
|
+
this.keyboardPageBanner = page.locator('#keycloak-bg');
|
|
50
|
+
}
|
|
51
|
+
async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 3) {
|
|
52
|
+
const startTime = Date.now();
|
|
53
|
+
let timeout = constants_1._1_SECOND_IN_MS * 1;
|
|
54
|
+
if (url === '/modeler') {
|
|
55
|
+
timeout = constants_1._1_SECOND_IN_MS * 10;
|
|
56
|
+
}
|
|
57
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
58
|
+
try {
|
|
59
|
+
if (sleepTimeout) {
|
|
60
|
+
await (0, sleep_1.sleep)(sleepTimeout);
|
|
61
|
+
}
|
|
62
|
+
await this.page.goto(url, { timeout: 10000 });
|
|
63
|
+
const loginPage = new LoginPage_1.LoginPage(this.page);
|
|
64
|
+
const loginSelector = loginPage.usernameInput;
|
|
65
|
+
await (0, test_1.expect)(banner.or(loginSelector)).toBeVisible({ timeout: 15000 });
|
|
66
|
+
const isBannerVisible = await banner.isVisible();
|
|
67
|
+
if (isBannerVisible) {
|
|
68
|
+
try {
|
|
69
|
+
await (0, test_1.expect)(loginSelector).toBeVisible({ timeout: 5000 });
|
|
70
|
+
await loginPage.login(username, password);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
// The login selector did NOT appear. The banner is real. We are on the correct page.
|
|
74
|
+
// The navigation was successful, so we can just return.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
await loginPage.login(username, password);
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const now = new Date();
|
|
84
|
+
const elapsed = Date.now() - startTime;
|
|
85
|
+
if (attempt < maxRetries - 1) {
|
|
86
|
+
await (0, sleep_1.sleep)(5000);
|
|
87
|
+
if (!this.page.isClosed()) {
|
|
88
|
+
try {
|
|
89
|
+
await this.page.waitForLoadState('load', { timeout: timeout });
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const now2 = new Date();
|
|
93
|
+
const elapsed2 = Date.now() - startTime;
|
|
94
|
+
console.warn(`[${now2.toISOString()}] (+${elapsed2}ms) [NavigationPage] Load state timeout or error: ${error}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.error(`[${now.toISOString()}] (+${elapsed}ms) [NavigationPage] Login (${url}) failed after ${maxRetries} attempts`);
|
|
100
|
+
throw new Error(`Login (${url}) failed after ${maxRetries} attempts`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async goToModeler(sleepTimeout, credentials) {
|
|
106
|
+
await this.goTo(MODELER_CONTEXT_PATH, this.modelerPageBanner, sleepTimeout, credentials);
|
|
107
|
+
}
|
|
108
|
+
async goToTasklist(sleepTimeout, credentials) {
|
|
109
|
+
await this.goTo(`${ORCHESTRATION_CONTEXT_PATH}/tasklist`, this.tasklistPageBanner, sleepTimeout, credentials);
|
|
110
|
+
}
|
|
111
|
+
async goToOperate(sleepTimeout, credentials) {
|
|
112
|
+
await this.goTo(`${ORCHESTRATION_CONTEXT_PATH}/operate`, this.operatePageBanner, sleepTimeout, credentials);
|
|
113
|
+
}
|
|
114
|
+
async goToOptimize(sleepTimeout, credentials) {
|
|
115
|
+
await this.goTo(OPTIMIZE_CONTEXT_PATH, this.optimizePageBanner, sleepTimeout, credentials);
|
|
116
|
+
}
|
|
117
|
+
async goToKeycloak() {
|
|
118
|
+
const keycloakUrl = process.env.KEYCLOAK_URL
|
|
119
|
+
? `${process.env.KEYCLOAK_URL}/auth`
|
|
120
|
+
: '/auth';
|
|
121
|
+
await this.page.goto(keycloakUrl);
|
|
122
|
+
await (0, test_1.expect)(this.keyboardPageBanner).toBeVisible({ timeout: 30000 });
|
|
123
|
+
}
|
|
124
|
+
async goToOCIdentity(sleepTimeout, credentials) {
|
|
125
|
+
await this.goTo(`${ORCHESTRATION_CONTEXT_PATH}/identity`, this.identityPageBanner, sleepTimeout, credentials);
|
|
126
|
+
}
|
|
127
|
+
async goToConsole(sleepTimeout, credentials) {
|
|
128
|
+
await this.goTo(CONSOLE_CONTEXT_PATH, this.consolePageBanner, sleepTimeout, credentials);
|
|
129
|
+
}
|
|
130
|
+
async goToManagementIdentity(sleepTimeout, credentials) {
|
|
131
|
+
await this.goTo(MANAGEMENT_IDENTITY_CONTEXT_PATH, this.managementIdentityPageBanner, sleepTimeout, credentials);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.NavigationPage = NavigationPage;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Authorization } from '../SM-8.10/Authorization';
|
|
2
|
+
import { Page } from '@playwright/test';
|
|
3
|
+
declare class OCIdentityAuthorizationsPage extends Authorization {
|
|
4
|
+
constructor(page: Page);
|
|
5
|
+
clickProcessDefinitionTab(): Promise<void>;
|
|
6
|
+
clickAuthorizationTab(): Promise<void>;
|
|
7
|
+
clickComponentTab(): Promise<void>;
|
|
8
|
+
clickResourceTab(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export { OCIdentityAuthorizationsPage };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OCIdentityAuthorizationsPage = void 0;
|
|
4
|
+
const Authorization_1 = require("../SM-8.10/Authorization");
|
|
5
|
+
const test_1 = require("@playwright/test");
|
|
6
|
+
class OCIdentityAuthorizationsPage extends Authorization_1.Authorization {
|
|
7
|
+
constructor(page) {
|
|
8
|
+
super(page);
|
|
9
|
+
}
|
|
10
|
+
async clickProcessDefinitionTab() {
|
|
11
|
+
await (0, test_1.expect)(this.selectResourceTypeTab('PROCESS_DEFINITION')).toBeVisible({
|
|
12
|
+
timeout: 60000,
|
|
13
|
+
});
|
|
14
|
+
await this.selectResourceTypeTab('PROCESS_DEFINITION').click();
|
|
15
|
+
}
|
|
16
|
+
async clickAuthorizationTab() {
|
|
17
|
+
await (0, test_1.expect)(this.selectResourceTypeTab('AUTHORIZATION')).toBeVisible({
|
|
18
|
+
timeout: 60000,
|
|
19
|
+
});
|
|
20
|
+
await this.selectResourceTypeTab('AUTHORIZATION').click();
|
|
21
|
+
}
|
|
22
|
+
async clickComponentTab() {
|
|
23
|
+
await (0, test_1.expect)(this.selectResourceTypeTab('COMPONENT')).toBeVisible({
|
|
24
|
+
timeout: 60000,
|
|
25
|
+
});
|
|
26
|
+
await this.selectResourceTypeTab('COMPONENT').click();
|
|
27
|
+
}
|
|
28
|
+
async clickResourceTab() {
|
|
29
|
+
await (0, test_1.expect)(this.selectResourceTypeTab('RESOURCE')).toBeVisible({
|
|
30
|
+
timeout: 60000,
|
|
31
|
+
});
|
|
32
|
+
await this.selectResourceTypeTab('RESOURCE').click();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.OCIdentityAuthorizationsPage = OCIdentityAuthorizationsPage;
|
|
@@ -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;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
export declare class OCIdentityGroupsPage {
|
|
3
|
+
private page;
|
|
4
|
+
readonly groupsList: Locator;
|
|
5
|
+
readonly createGroupButton: Locator;
|
|
6
|
+
readonly editGroupButton: (rowName?: string) => Locator;
|
|
7
|
+
readonly deleteGroupButton: (rowName?: string) => Locator;
|
|
8
|
+
readonly createGroupModal: Locator;
|
|
9
|
+
readonly closeCreateGroupModal: Locator;
|
|
10
|
+
readonly createGroupIdField: Locator;
|
|
11
|
+
readonly createNameField: Locator;
|
|
12
|
+
readonly createDescriptionField: Locator;
|
|
13
|
+
readonly createGroupModalCancelButton: Locator;
|
|
14
|
+
readonly createGroupModalCreateButton: Locator;
|
|
15
|
+
readonly editGroupModal: Locator;
|
|
16
|
+
readonly closeEditGroupModal: Locator;
|
|
17
|
+
readonly editNameField: Locator;
|
|
18
|
+
readonly editDescriptionField: Locator;
|
|
19
|
+
readonly editGroupModalCancelButton: Locator;
|
|
20
|
+
readonly editGroupModalUpdateButton: Locator;
|
|
21
|
+
readonly deleteGroupModal: Locator;
|
|
22
|
+
readonly closeDeleteGroupModal: Locator;
|
|
23
|
+
readonly deleteGroupModalCancelButton: Locator;
|
|
24
|
+
readonly deleteGroupModalDeleteButton: Locator;
|
|
25
|
+
readonly emptyState: Locator;
|
|
26
|
+
readonly assignUserButton: Locator;
|
|
27
|
+
readonly searchBox: Locator;
|
|
28
|
+
readonly searchBoxResult: Locator;
|
|
29
|
+
readonly assignUserButtonModal: Locator;
|
|
30
|
+
readonly selectGroupRow: (name: string) => Locator;
|
|
31
|
+
readonly groupCell: (name: string) => Locator;
|
|
32
|
+
constructor(page: Page);
|
|
33
|
+
createGroup(groupId: string, groupName: string, description?: string): Promise<void>;
|
|
34
|
+
editGroup(currentName: string, newName: string, newDescription?: string): Promise<void>;
|
|
35
|
+
deleteGroup(groupName: string): Promise<void>;
|
|
36
|
+
assertGroupExists(groupName: string): Promise<void>;
|
|
37
|
+
clickGroupId(groupName: string): Promise<void>;
|
|
38
|
+
assignUserToGroup(userName: string): Promise<void>;
|
|
39
|
+
}
|