@camunda/e2e-test-suite 0.0.1025 → 0.0.1027
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/Authorization.d.ts +3 -0
- package/dist/pages/SM-8.10/Authorization.js +39 -7
- package/dist/pages/SM-8.10/IdentityUsersPage.d.ts +1 -1
- package/dist/pages/SM-8.10/IdentityUsersPage.js +8 -1
- package/dist/pages/SM-8.10/OCTenantPage.js +9 -2
- package/dist/tests/SM-8.10/migration-path-user-flows.spec.js +13 -6
- package/dist/utils/assertionHelpers/findLocatorWithPagination.js +10 -1
- package/package.json +1 -1
|
@@ -8,6 +8,8 @@ declare class Authorization {
|
|
|
8
8
|
protected readonly createAuthorizationOwnerTypeOption: (name: string) => Locator;
|
|
9
9
|
protected readonly createAuthorizationOwnerComboBox: Locator;
|
|
10
10
|
protected readonly createAuthorizationOwnerOption: (name: string) => Locator;
|
|
11
|
+
protected readonly createAuthorizationOwnerSearchInput: Locator;
|
|
12
|
+
protected readonly createAuthorizationOwnerSearchOption: (name: string) => Locator;
|
|
11
13
|
protected readonly createAuthorizationResourceTypeDropdown: Locator;
|
|
12
14
|
protected readonly createAuthorizationResourceTypeOption: (name: string) => Locator;
|
|
13
15
|
protected readonly createAuthorizationResourceIdField: Locator;
|
|
@@ -19,6 +21,7 @@ declare class Authorization {
|
|
|
19
21
|
protected readonly deleteAuthorizationModalDeleteButton: Locator;
|
|
20
22
|
protected readonly tableFilter: Locator;
|
|
21
23
|
constructor(page: Page);
|
|
24
|
+
private selectAuthorizationOwner;
|
|
22
25
|
createAuthorization(authorization: {
|
|
23
26
|
ownerType: string;
|
|
24
27
|
ownerId: string;
|
|
@@ -14,6 +14,8 @@ class Authorization {
|
|
|
14
14
|
createAuthorizationOwnerTypeOption;
|
|
15
15
|
createAuthorizationOwnerComboBox;
|
|
16
16
|
createAuthorizationOwnerOption;
|
|
17
|
+
createAuthorizationOwnerSearchInput;
|
|
18
|
+
createAuthorizationOwnerSearchOption;
|
|
17
19
|
createAuthorizationResourceTypeDropdown;
|
|
18
20
|
createAuthorizationResourceTypeOption;
|
|
19
21
|
createAuthorizationResourceIdField;
|
|
@@ -51,6 +53,16 @@ class Authorization {
|
|
|
51
53
|
name,
|
|
52
54
|
exact: true,
|
|
53
55
|
});
|
|
56
|
+
// Every owner type now renders a server-backed search dropdown instead of
|
|
57
|
+
// the combobox that listed all owners up front. The dropdown is a Carbon
|
|
58
|
+
// Search inside a ListBox, so it has no combobox role; its results are
|
|
59
|
+
// list-box menu items that carry the owner ID as their title.
|
|
60
|
+
this.createAuthorizationOwnerSearchInput =
|
|
61
|
+
this.createAuthorizationModal.getByPlaceholder('Search by owner ID');
|
|
62
|
+
this.createAuthorizationOwnerSearchOption = (name) => this.createAuthorizationModal
|
|
63
|
+
.locator('.cds--list-box__menu-item')
|
|
64
|
+
.filter({ hasText: name })
|
|
65
|
+
.first();
|
|
54
66
|
this.createAuthorizationResourceTypeDropdown =
|
|
55
67
|
this.createAuthorizationModal.getByRole('combobox', {
|
|
56
68
|
name: 'Resource type',
|
|
@@ -79,18 +91,38 @@ class Authorization {
|
|
|
79
91
|
});
|
|
80
92
|
this.tableFilter = page.getByRole('searchbox', { name: 'Filter table' });
|
|
81
93
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
await this.
|
|
86
|
-
await this.
|
|
94
|
+
// Released 8.10 alpha images still render the Carbon combobox that lists
|
|
95
|
+
// every owner, so accept whichever owner field this build shows.
|
|
96
|
+
async selectAuthorizationOwner(ownerId) {
|
|
97
|
+
await (0, test_1.expect)(this.createAuthorizationOwnerSearchInput.or(this.createAuthorizationOwnerComboBox)).toBeVisible({ timeout: 30000 });
|
|
98
|
+
if (await this.createAuthorizationOwnerSearchInput.isVisible()) {
|
|
99
|
+
await this.createAuthorizationOwnerSearchInput.fill(ownerId);
|
|
100
|
+
const ownerOption = this.createAuthorizationOwnerSearchOption(ownerId);
|
|
101
|
+
// The search is debounced and served by the API, so a just-created
|
|
102
|
+
// owner can take a while to surface.
|
|
103
|
+
await (0, test_1.expect)(ownerOption).toBeVisible({ timeout: 60000 });
|
|
104
|
+
await ownerOption.click({ timeout: 30000 });
|
|
105
|
+
// Picking an owner replaces the search input with a tag holding the
|
|
106
|
+
// selection, which is how we know the choice was committed.
|
|
107
|
+
await (0, test_1.expect)(this.createAuthorizationOwnerSearchInput).toBeHidden({
|
|
108
|
+
timeout: 30000,
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
87
112
|
await this.createAuthorizationOwnerComboBox.click();
|
|
88
|
-
await (0, test_1.expect)(this.createAuthorizationOwnerOption(
|
|
113
|
+
await (0, test_1.expect)(this.createAuthorizationOwnerOption(ownerId)).toBeVisible({
|
|
89
114
|
timeout: 30000,
|
|
90
115
|
});
|
|
91
|
-
await this.createAuthorizationOwnerOption(
|
|
116
|
+
await this.createAuthorizationOwnerOption(ownerId).click({
|
|
92
117
|
timeout: 30000,
|
|
93
118
|
});
|
|
119
|
+
}
|
|
120
|
+
async createAuthorization(authorization) {
|
|
121
|
+
await this.createAuthorizationButton.click();
|
|
122
|
+
await (0, test_1.expect)(this.createAuthorizationModal).toBeVisible();
|
|
123
|
+
await this.createAuthorizationOwnerTypeCombobox.click();
|
|
124
|
+
await this.createAuthorizationOwnerTypeOption(authorization.ownerType).click();
|
|
125
|
+
await this.selectAuthorizationOwner(authorization.ownerId);
|
|
94
126
|
// The Resource type is pre-selected and disabled when the dialog is
|
|
95
127
|
// opened from a specific resource-type tab. Only pick it from the dropdown
|
|
96
128
|
// when the field is still enabled (editable).
|
|
@@ -87,6 +87,6 @@ declare class IdentityUsersPage {
|
|
|
87
87
|
createResourceAuthorization(processId: string): Promise<void>;
|
|
88
88
|
clickAssignAuthorizationButton(): Promise<void>;
|
|
89
89
|
clickAssignedRolesTab(): Promise<void>;
|
|
90
|
-
assertUserIsAssignedCorrectRole(username: string, roles: string[]): Promise<void>;
|
|
90
|
+
assertUserIsAssignedCorrectRole(username: string, roles: (string | string[])[]): Promise<void>;
|
|
91
91
|
}
|
|
92
92
|
export { IdentityUsersPage };
|
|
@@ -462,6 +462,9 @@ class IdentityUsersPage {
|
|
|
462
462
|
async clickAssignedRolesTab() {
|
|
463
463
|
await this.assignedRolesTab.click();
|
|
464
464
|
}
|
|
465
|
+
// A role entry may be a single name, or a list of interchangeable names when
|
|
466
|
+
// Management Identity ships the same permission set under more than one label
|
|
467
|
+
// (e.g. 'Hub'/'Web Modeler'); any one of the listed names satisfies the entry.
|
|
465
468
|
async assertUserIsAssignedCorrectRole(username, roles) {
|
|
466
469
|
await this.page.getByRole('cell', { name: username, exact: true }).click();
|
|
467
470
|
// Wait for the Assigned Roles tab to render before clicking it; after
|
|
@@ -469,9 +472,13 @@ class IdentityUsersPage {
|
|
|
469
472
|
await (0, test_1.expect)(this.assignedRolesTab).toBeVisible({ timeout: 30000 });
|
|
470
473
|
await this.assignedRolesTab.click();
|
|
471
474
|
for (const role of roles) {
|
|
475
|
+
const acceptedNames = Array.isArray(role) ? role : [role];
|
|
476
|
+
const roleCell = acceptedNames
|
|
477
|
+
.map((name) => this.page.getByRole('cell', { name, exact: true }))
|
|
478
|
+
.reduce((combined, cell) => combined.or(cell));
|
|
472
479
|
// Use a generous timeout: on slow/post-upgrade clusters the role table
|
|
473
480
|
// may take several seconds to populate after the tab switch.
|
|
474
|
-
await (0, test_1.expect)(
|
|
481
|
+
await (0, test_1.expect)(roleCell.first()).toBeVisible({ timeout: 60000 });
|
|
475
482
|
}
|
|
476
483
|
}
|
|
477
484
|
}
|
|
@@ -263,9 +263,15 @@ class OCTenantPage {
|
|
|
263
263
|
await this.roleIdSearchBox.click();
|
|
264
264
|
}
|
|
265
265
|
async fillRoleIdSearchBox(roleId, roleIdentifier) {
|
|
266
|
-
await this.roleIdSearchBox.fill(roleId);
|
|
267
266
|
const result = this.page.getByText(roleIdentifier).first();
|
|
268
|
-
|
|
267
|
+
// The dropdown matches against the roles fetched with an empty search
|
|
268
|
+
// filter, so clearing the box re-triggers that fetch before retyping.
|
|
269
|
+
await (0, test_1.expect)(async () => {
|
|
270
|
+
await this.roleIdSearchBox.fill('');
|
|
271
|
+
await this.page.waitForLoadState('networkidle');
|
|
272
|
+
await this.roleIdSearchBox.fill(roleId);
|
|
273
|
+
await (0, test_1.expect)(result).toBeVisible({ timeout: 15000 });
|
|
274
|
+
}).toPass({ timeout: 90000, intervals: [2000] });
|
|
269
275
|
await result.click();
|
|
270
276
|
}
|
|
271
277
|
async clickAssignRoleSubButton() {
|
|
@@ -279,6 +285,7 @@ class OCTenantPage {
|
|
|
279
285
|
return;
|
|
280
286
|
}
|
|
281
287
|
await this.clickAssignRoleButton();
|
|
288
|
+
await this.page.waitForLoadState('networkidle');
|
|
282
289
|
await this.clickRoleIdSearchBox();
|
|
283
290
|
await this.fillRoleIdSearchBox(roleId, roleIdentifier);
|
|
284
291
|
await this.clickAssignRoleSubButton();
|
|
@@ -109,14 +109,21 @@ if (process.env.IS_MIGRATION === 'true') {
|
|
|
109
109
|
});
|
|
110
110
|
});
|
|
111
111
|
(0, SM_8_10_1.test)('Assert Users Persist in Management Identity With Correct Roles @tasklistV2', async ({ managementIdentityPage, identityUsersPage, }) => {
|
|
112
|
+
// 8.10 provisions 'Hub'/'Hub Admin' *alongside* 'Web Modeler'/'Web
|
|
113
|
+
// Modeler Admin' rather than renaming them, and both name pairs grant
|
|
114
|
+
// identical permissions, so an upgraded cluster may surface the modeler
|
|
115
|
+
// access under either pair. Each nested list accepts whichever of the
|
|
116
|
+
// equivalent names that cluster persisted. See camunda-docs
|
|
117
|
+
// docs/self-managed/upgrade/components/890-to-8100.md
|
|
118
|
+
// #management-identity-roles-and-permissions.
|
|
112
119
|
await managementIdentityPage.clickUsersLink();
|
|
113
120
|
await identityUsersPage.assertUserIsAssignedCorrectRole('demo', [
|
|
114
121
|
'Default user role',
|
|
115
122
|
'ManagementIdentity',
|
|
116
123
|
'Optimize',
|
|
117
124
|
'Orchestration',
|
|
118
|
-
'Hub',
|
|
119
|
-
'Hub Admin',
|
|
125
|
+
['Hub', 'Web Modeler'],
|
|
126
|
+
['Hub Admin', 'Web Modeler Admin'],
|
|
120
127
|
]);
|
|
121
128
|
await managementIdentityPage.clickUsersLink();
|
|
122
129
|
await identityUsersPage.assertUserIsAssignedCorrectRole('bart', [
|
|
@@ -124,8 +131,8 @@ if (process.env.IS_MIGRATION === 'true') {
|
|
|
124
131
|
'ManagementIdentity',
|
|
125
132
|
'Optimize',
|
|
126
133
|
'Orchestration',
|
|
127
|
-
'Hub',
|
|
128
|
-
'Hub Admin',
|
|
134
|
+
['Hub', 'Web Modeler'],
|
|
135
|
+
['Hub Admin', 'Web Modeler Admin'],
|
|
129
136
|
]);
|
|
130
137
|
await managementIdentityPage.clickUsersLink();
|
|
131
138
|
await identityUsersPage.assertUserIsAssignedCorrectRole('lisa', [
|
|
@@ -133,8 +140,8 @@ if (process.env.IS_MIGRATION === 'true') {
|
|
|
133
140
|
'ManagementIdentity',
|
|
134
141
|
'Optimize',
|
|
135
142
|
'Orchestration',
|
|
136
|
-
'Hub',
|
|
137
|
-
'Hub Admin',
|
|
143
|
+
['Hub', 'Web Modeler'],
|
|
144
|
+
['Hub Admin', 'Web Modeler Admin'],
|
|
138
145
|
]);
|
|
139
146
|
});
|
|
140
147
|
(0, SM_8_10_1.test)('Assert Demo User Can Deploy Processes', async ({ page, modelerHomePage, navigationPage, modelerCreatePage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskDetailsPage, taskPanelPage, }) => {
|
|
@@ -6,6 +6,12 @@ async function findLocatorWithPagination(page, locator, options) {
|
|
|
6
6
|
const maxPages = 10;
|
|
7
7
|
const paginationButton = page.getByRole('button', { name: 'Next page' });
|
|
8
8
|
const backupPaginationButton = page.getByRole('button', { name: 'Load more' });
|
|
9
|
+
// The design-system DataTable the Admin UI is migrating onto labels its
|
|
10
|
+
// forward control just "Next", unlike Carbon's "Next page". Scope it to the
|
|
11
|
+
// pagination bar so an unrelated wizard "Next" can never be clicked.
|
|
12
|
+
const dataTablePaginationButton = page
|
|
13
|
+
.locator('[data-slot="data-table-pagination"]')
|
|
14
|
+
.getByRole('button', { name: 'Next', exact: true });
|
|
9
15
|
const startTime = Date.now();
|
|
10
16
|
for (let pageNum = 0; pageNum < maxPages; pageNum++) {
|
|
11
17
|
if (Date.now() - startTime > timeout) {
|
|
@@ -20,7 +26,10 @@ async function findLocatorWithPagination(page, locator, options) {
|
|
|
20
26
|
console.log(`Found locator "${locator}" on page ${pageNum + 1}`);
|
|
21
27
|
return true;
|
|
22
28
|
}
|
|
23
|
-
const nextButton = paginationButton
|
|
29
|
+
const nextButton = paginationButton
|
|
30
|
+
.or(backupPaginationButton)
|
|
31
|
+
.or(dataTablePaginationButton)
|
|
32
|
+
.last();
|
|
24
33
|
const isVisible = await nextButton
|
|
25
34
|
.isVisible({ timeout: 1000 })
|
|
26
35
|
.catch(() => false);
|