@camunda/e2e-test-suite 0.0.753 → 0.0.755
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/8.7/ModelerHomePage.d.ts +16 -9
- package/dist/pages/8.7/ModelerHomePage.js +33 -24
- package/dist/pages/8.7/UtilitiesPage.d.ts +1 -0
- package/dist/pages/8.7/UtilitiesPage.js +11 -1
- package/dist/tests/8.7/rba-enabled-user-flows.spec.js +25 -0
- package/dist/tests/8.7/web-modeler-user-flows.spec.js +8 -3
- package/package.json +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Page, Locator } from '@playwright/test';
|
|
2
2
|
import { LoginPage } from './LoginPage';
|
|
3
|
-
import { AppsPage } from './AppsPage';
|
|
4
3
|
declare class ModelerHomePage {
|
|
5
4
|
private defaultFolderName;
|
|
6
5
|
private page;
|
|
@@ -55,15 +54,23 @@ declare class ModelerHomePage {
|
|
|
55
54
|
assertFormBreadcrumbVisible(formName: string): Promise<void>;
|
|
56
55
|
/**
|
|
57
56
|
* Handles navigation after clicking an invitation link in email.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* the
|
|
61
|
-
*
|
|
62
|
-
* the shared project is
|
|
63
|
-
*
|
|
64
|
-
*
|
|
57
|
+
*
|
|
58
|
+
* The invited user follows the link while logged out, so the invitation flow
|
|
59
|
+
* presents the Auth0 login. Completing the login ON the invitation flow lets
|
|
60
|
+
* SaaS accept the invite and land the user directly in the SHARED org's
|
|
61
|
+
* Modeler, where the shared project is listed.
|
|
62
|
+
*
|
|
63
|
+
* We deliberately do NOT clear cookies and re-login via the app switcher:
|
|
64
|
+
* that path authenticates into the user's PERSONAL org, where the shared
|
|
65
|
+
* project does not exist and the folder can never appear — the previous
|
|
66
|
+
* fallback raced a 15s window and, whenever the (normal) login + invite-accept
|
|
67
|
+
* redirect chain took longer, dropped into that personal-org path and hung.
|
|
68
|
+
*
|
|
69
|
+
* If the link auto-authenticated (the banner is already up), no login is
|
|
70
|
+
* needed. The redirect chain routinely takes longer than a few seconds, so
|
|
71
|
+
* wait generously for the banner instead of racing a short window.
|
|
65
72
|
*/
|
|
66
|
-
navigateAfterInvitationLink(loginPage: LoginPage,
|
|
73
|
+
navigateAfterInvitationLink(loginPage: LoginPage, credentials: {
|
|
67
74
|
username: string;
|
|
68
75
|
password: string;
|
|
69
76
|
}): Promise<void>;
|
|
@@ -4,7 +4,6 @@ exports.ModelerHomePage = void 0;
|
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const sleep_1 = require("../../utils/sleep");
|
|
6
6
|
const clickLocatorWithRetry_1 = require("../../utils/assertionHelpers/clickLocatorWithRetry");
|
|
7
|
-
const UtilitiesPage_1 = require("./UtilitiesPage");
|
|
8
7
|
class ModelerHomePage {
|
|
9
8
|
defaultFolderName = 'Cross Component Test Project';
|
|
10
9
|
page;
|
|
@@ -276,34 +275,44 @@ class ModelerHomePage {
|
|
|
276
275
|
}
|
|
277
276
|
/**
|
|
278
277
|
* Handles navigation after clicking an invitation link in email.
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
* the
|
|
282
|
-
*
|
|
283
|
-
* the shared project is
|
|
284
|
-
*
|
|
285
|
-
*
|
|
278
|
+
*
|
|
279
|
+
* The invited user follows the link while logged out, so the invitation flow
|
|
280
|
+
* presents the Auth0 login. Completing the login ON the invitation flow lets
|
|
281
|
+
* SaaS accept the invite and land the user directly in the SHARED org's
|
|
282
|
+
* Modeler, where the shared project is listed.
|
|
283
|
+
*
|
|
284
|
+
* We deliberately do NOT clear cookies and re-login via the app switcher:
|
|
285
|
+
* that path authenticates into the user's PERSONAL org, where the shared
|
|
286
|
+
* project does not exist and the folder can never appear — the previous
|
|
287
|
+
* fallback raced a 15s window and, whenever the (normal) login + invite-accept
|
|
288
|
+
* redirect chain took longer, dropped into that personal-org path and hung.
|
|
289
|
+
*
|
|
290
|
+
* If the link auto-authenticated (the banner is already up), no login is
|
|
291
|
+
* needed. The redirect chain routinely takes longer than a few seconds, so
|
|
292
|
+
* wait generously for the banner instead of racing a short window.
|
|
286
293
|
*/
|
|
287
|
-
async navigateAfterInvitationLink(loginPage,
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
async navigateAfterInvitationLink(loginPage, credentials) {
|
|
295
|
+
// If the invitation flow shows the Auth0 login, authenticate in place so
|
|
296
|
+
// the invite is accepted in the shared-org context. If it doesn't appear,
|
|
297
|
+
// the link already auto-authenticated us and we skip straight to the banner.
|
|
298
|
+
const onLogin = await loginPage.usernameInput
|
|
299
|
+
.waitFor({ state: 'visible', timeout: 60000 })
|
|
290
300
|
.then(() => true)
|
|
291
301
|
.catch(() => false);
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// Already on the Modeler home page
|
|
298
|
-
}
|
|
302
|
+
if (onLogin) {
|
|
303
|
+
await loginPage.fillUsername(credentials.username);
|
|
304
|
+
await loginPage.clickContinueButton();
|
|
305
|
+
await loginPage.fillPassword(credentials.password);
|
|
306
|
+
await loginPage.clickLoginButton();
|
|
299
307
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
await
|
|
303
|
-
|
|
304
|
-
|
|
308
|
+
await (0, test_1.expect)(this.modelerPageBanner).toBeVisible({ timeout: 180000 });
|
|
309
|
+
try {
|
|
310
|
+
await this.clickHomeBreadcrumb();
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
// Already on the Modeler home page
|
|
305
314
|
}
|
|
306
|
-
await (0, test_1.expect)(this.modelerPageBanner).toBeVisible({ timeout:
|
|
315
|
+
await (0, test_1.expect)(this.modelerPageBanner).toBeVisible({ timeout: 30000 });
|
|
307
316
|
}
|
|
308
317
|
}
|
|
309
318
|
exports.ModelerHomePage = ModelerHomePage;
|
|
@@ -29,6 +29,7 @@ export declare function runMultipleProcesses(clusterName: string, page: Page, mo
|
|
|
29
29
|
numberOfProcesses?: number;
|
|
30
30
|
processName?: string;
|
|
31
31
|
uploadFromFile?: string;
|
|
32
|
+
settleBetween?: (processId: string) => Promise<void>;
|
|
32
33
|
}): Promise<void>;
|
|
33
34
|
export declare function runProcess(clusterName: string, page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, processId?: string, uploadFromFile?: string): Promise<void>;
|
|
34
35
|
export declare function modelDiagramFromFile(page: Page, modelerHomePage: ModelerHomePage, modelerCreatePage: ModelerCreatePage, processName: string, fileName?: string, nrOfRenamedUserTasks?: number, taskName?: string): Promise<void>;
|
|
@@ -219,10 +219,20 @@ async function completeTaskWithRetry(taskPanelPage, taskDetailsPage, taskName, t
|
|
|
219
219
|
}
|
|
220
220
|
exports.completeTaskWithRetry = completeTaskWithRetry;
|
|
221
221
|
async function runMultipleProcesses(clusterName, page, modelerHomePage, modelerCreatePage, options) {
|
|
222
|
-
const { processName = 'Camunda_User_Task', numberOfProcesses = 2, uploadFromFile = '', } = options || {};
|
|
222
|
+
const { processName = 'Camunda_User_Task', numberOfProcesses = 2, uploadFromFile = '', settleBetween, } = options || {};
|
|
223
223
|
for (let i = 1; i <= numberOfProcesses; i++) {
|
|
224
224
|
await runProcess(clusterName, page, modelerHomePage, modelerCreatePage, processName + i, processName + i, uploadFromFile);
|
|
225
225
|
await modelerHomePage.clickProjectBreadcrumb();
|
|
226
|
+
// When RBA is enabled, deploying a process auto-provisions a resource
|
|
227
|
+
// authorization for the deployer keyed on the process definition id. The
|
|
228
|
+
// identity service writes that grant with a read-modify-write, so deploying
|
|
229
|
+
// the next process before this grant lands clobbers it (lost update) and it
|
|
230
|
+
// is permanently missing. When a settleBetween hook is supplied, wait for
|
|
231
|
+
// the just-deployed grant to be durably provisioned before the next deploy —
|
|
232
|
+
// a deterministic wait, not a fixed sleep.
|
|
233
|
+
if (settleBetween && i < numberOfProcesses) {
|
|
234
|
+
await settleBetween(processName + i);
|
|
235
|
+
}
|
|
226
236
|
}
|
|
227
237
|
}
|
|
228
238
|
exports.runMultipleProcesses = runMultipleProcesses;
|
|
@@ -236,6 +236,31 @@ _8_7_1.test.describe('RBA Enabled User Flows Test', () => {
|
|
|
236
236
|
await (0, UtilitiesPage_1.runMultipleProcesses)(clusterName, page, modelerHomePage, modelerCreatePage, {
|
|
237
237
|
processName: processName,
|
|
238
238
|
uploadFromFile: 'Camunda_Simple_User_Task_1',
|
|
239
|
+
// RBA is enabled before this deploy, so each process start
|
|
240
|
+
// auto-provisions the deployer's resource authorization via a
|
|
241
|
+
// read-modify-write. Deploying the second process before the first
|
|
242
|
+
// grant lands clobbers it (lost update), permanently dropping one of
|
|
243
|
+
// the two process ids — which no downstream wait can recover (see
|
|
244
|
+
// authorizedResourcesAssertion). Before deploying the next process,
|
|
245
|
+
// wait for the just-deployed grant to appear in Console, then return
|
|
246
|
+
// to the project. Deterministic, unlike a fixed sleep.
|
|
247
|
+
settleBetween: async (processId) => {
|
|
248
|
+
await appsPage.clickCamundaApps();
|
|
249
|
+
await appsPage.clickConsoleLink();
|
|
250
|
+
await homePage.clickOrganization();
|
|
251
|
+
await consoleOrganizationsPage.clickUsersTab();
|
|
252
|
+
await consoleOrganizationsPage.clickMainUser(mainUser.username);
|
|
253
|
+
await consoleOrganizationsPage.clickAuthorizations();
|
|
254
|
+
await consoleOrganizationsPage.authorizedResourcesAssertion([
|
|
255
|
+
processId,
|
|
256
|
+
]);
|
|
257
|
+
await appsPage.clickCamundaApps();
|
|
258
|
+
await appsPage.clickModeler();
|
|
259
|
+
await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
|
|
260
|
+
timeout: 120000,
|
|
261
|
+
});
|
|
262
|
+
await modelerHomePage.clickCrossComponentProjectFolder();
|
|
263
|
+
},
|
|
239
264
|
});
|
|
240
265
|
await (0, sleep_1.sleep)(60000);
|
|
241
266
|
});
|
|
@@ -514,12 +514,17 @@ _8_7_1.test.describe('Web Modeler User Flow Tests', () => {
|
|
|
514
514
|
});
|
|
515
515
|
await _8_7_1.test.step('Log in with Second User and Navigate to Cross Component Test project as Collaborator', async () => {
|
|
516
516
|
await (0, UtilitiesPage_1.clickInvitationLinkInEmail)(page, id);
|
|
517
|
-
await (
|
|
518
|
-
await modelerHomePage.navigateAfterInvitationLink(loginPage, appsPage, {
|
|
517
|
+
await modelerHomePage.navigateAfterInvitationLink(loginPage, {
|
|
519
518
|
username: emailAddress,
|
|
520
519
|
password: password,
|
|
521
520
|
});
|
|
522
|
-
|
|
521
|
+
// navigateAfterInvitationLink lands the invited user in the SHARED org's
|
|
522
|
+
// Modeler home (it logs in on the invitation flow rather than
|
|
523
|
+
// re-authenticating into the personal org), so the shared project is
|
|
524
|
+
// present. Assert its visibility directly — no session-breaking reload.
|
|
525
|
+
await (0, test_1.expect)(modelerHomePage.crossComponentProjectFolder).toBeVisible({
|
|
526
|
+
timeout: 120000,
|
|
527
|
+
});
|
|
523
528
|
});
|
|
524
529
|
await _8_7_1.test.step('Log out from Second User', async () => {
|
|
525
530
|
await settingsPage.clickOpenSettingsButton();
|