@camunda/e2e-test-suite 0.0.684 → 0.0.686

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.
@@ -1,4 +1,6 @@
1
1
  import { Page, Locator } from '@playwright/test';
2
+ import { LoginPage } from './LoginPage';
3
+ import { AppsPage } from './AppsPage';
2
4
  declare class ModelerHomePage {
3
5
  private defaultFolderName;
4
6
  private page;
@@ -51,5 +53,19 @@ declare class ModelerHomePage {
51
53
  clickUploadFilesButton(): Promise<void>;
52
54
  clickMessageBanner(): Promise<void>;
53
55
  assertFormBreadcrumbVisible(formName: string): Promise<void>;
56
+ /**
57
+ * Handles navigation after clicking an invitation link in email.
58
+ * The invitation link may auto-authenticate the second user and land them in
59
+ * the correct org's Modeler. If the Modeler banner is visible, navigate to
60
+ * the Modeler home within the same org context — clearing cookies and
61
+ * re-logging in via the app switcher lands in the user's personal org where
62
+ * the shared project is not listed.
63
+ * If auto-authentication did not occur (page ended up on Auth0), falls back
64
+ * to the explicit login path.
65
+ */
66
+ navigateAfterInvitationLink(loginPage: LoginPage, appsPage: AppsPage, credentials: {
67
+ username: string;
68
+ password: string;
69
+ }): Promise<void>;
54
70
  }
55
71
  export { ModelerHomePage };
@@ -4,6 +4,7 @@ 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");
7
8
  class ModelerHomePage {
8
9
  defaultFolderName = 'Cross Component Test Project';
9
10
  page;
@@ -273,5 +274,36 @@ class ModelerHomePage {
273
274
  timeout: 120000,
274
275
  });
275
276
  }
277
+ /**
278
+ * Handles navigation after clicking an invitation link in email.
279
+ * The invitation link may auto-authenticate the second user and land them in
280
+ * the correct org's Modeler. If the Modeler banner is visible, navigate to
281
+ * the Modeler home within the same org context — clearing cookies and
282
+ * re-logging in via the app switcher lands in the user's personal org where
283
+ * the shared project is not listed.
284
+ * If auto-authentication did not occur (page ended up on Auth0), falls back
285
+ * to the explicit login path.
286
+ */
287
+ async navigateAfterInvitationLink(loginPage, appsPage, credentials) {
288
+ const autoAuthenticated = await this.modelerPageBanner
289
+ .waitFor({ state: 'visible', timeout: 15000 })
290
+ .then(() => true)
291
+ .catch(() => false);
292
+ if (autoAuthenticated) {
293
+ try {
294
+ await this.clickHomeBreadcrumb();
295
+ }
296
+ catch {
297
+ // Already on the Modeler home page
298
+ }
299
+ }
300
+ else {
301
+ await this.page.context().clearCookies();
302
+ await (0, UtilitiesPage_1.loginWithRetry)(this.page, loginPage, credentials, 1000, 3, true);
303
+ await appsPage.clickCamundaApps();
304
+ await appsPage.clickModeler();
305
+ }
306
+ await (0, test_1.expect)(this.modelerPageBanner).toBeVisible({ timeout: 120000 });
307
+ }
276
308
  }
277
309
  exports.ModelerHomePage = ModelerHomePage;
@@ -14,6 +14,7 @@ declare class IdentityHomePage {
14
14
  constructor(page: Page);
15
15
  private selectAllCheckboxes;
16
16
  private hasWritePermission;
17
+ private confirmWritePermissionAssigned;
17
18
  private assignPermissions;
18
19
  assignPermissionToTasklistAPI(): Promise<void>;
19
20
  assignPermissionToOperateAPI(): Promise<void>;
@@ -51,18 +51,40 @@ class IdentityHomePage {
51
51
  return this.page
52
52
  .getByRole('cell')
53
53
  .filter({ hasText: /^write/ })
54
- .isVisible();
54
+ .first()
55
+ .isVisible()
56
+ .catch(() => false);
57
+ }
58
+ // The Identity backend persists the assigned permission even when the Add
59
+ // request returns a transient 404 and the dialog fails to close on its own.
60
+ // The permission then shows up in the table after a short propagation delay,
61
+ // so confirm against the table state (across reloads) rather than relying on
62
+ // the dialog closing.
63
+ async confirmWritePermissionAssigned() {
64
+ for (let i = 0; i < 4; i++) {
65
+ await this.dialog
66
+ .waitFor({ state: 'hidden', timeout: 5000 })
67
+ .catch(() => undefined);
68
+ await this.page.reload();
69
+ await (0, sleep_1.sleep)(2000);
70
+ await this.accessToAPIsTab.click();
71
+ await (0, sleep_1.sleep)(2000);
72
+ if (await this.hasWritePermission()) {
73
+ return true;
74
+ }
75
+ }
76
+ return false;
55
77
  }
56
78
  async assignPermissions(appCell, apiName) {
57
79
  await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, appCell);
58
80
  await appCell.click();
59
81
  await this.accessToAPIsTab.click();
60
82
  await (0, sleep_1.sleep)(2000);
61
- if (await this.hasWritePermission()) {
62
- console.log(`Permissions already assigned to ${apiName}`);
63
- return;
64
- }
65
83
  for (let attempt = 1; attempt <= 3; attempt++) {
84
+ if (await this.hasWritePermission()) {
85
+ console.log(`Permissions already assigned to ${apiName}`);
86
+ return;
87
+ }
66
88
  await this.assignPermissionsButton.click();
67
89
  await this.selectOptionFromDropdown(apiName);
68
90
  await (0, test_1.expect)(this.dialog).toBeVisible();
@@ -73,18 +95,14 @@ class IdentityHomePage {
73
95
  await (0, sleep_1.sleep)(1000);
74
96
  await (0, test_1.expect)(this.addButton).toBeVisible();
75
97
  await this.addButton.click();
76
- try {
77
- await this.dialog.waitFor({ state: 'hidden', timeout: 5000 });
78
- await (0, sleep_1.sleep)(3000);
98
+ if (await this.confirmWritePermissionAssigned()) {
99
+ console.log(`Permissions assigned to ${apiName}`);
79
100
  return;
80
101
  }
81
- catch {
82
- console.log(`Add failed for ${apiName} on attempt ${attempt}, reloading...`);
83
- await this.page.reload();
84
- await (0, sleep_1.sleep)(2000);
85
- await this.accessToAPIsTab.click();
86
- await (0, sleep_1.sleep)(2000);
87
- }
102
+ console.log(`Add not confirmed for ${apiName} on attempt ${attempt}, retrying...`);
103
+ }
104
+ if (await this.hasWritePermission()) {
105
+ return;
88
106
  }
89
107
  throw new Error(`Failed to assign permissions for ${apiName} after 3 attempts`);
90
108
  }
@@ -515,37 +515,9 @@ _8_7_1.test.describe('Web Modeler User Flow Tests', () => {
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
517
  await (0, sleep_1.sleep)(60000);
518
- // The invitation link auto-authenticates the second user and lands
519
- // them in the correct org's Modeler. If the Modeler banner is visible
520
- // after the invitation, navigate to the Modeler home within the same
521
- // org context — clearing cookies and re-logging in via the app
522
- // switcher lands in the user's personal org where the shared project
523
- // is not listed.
524
- // If the invitation did not auto-authenticate (page ended up on Auth0),
525
- // fall back to the explicit login path.
526
- const autoAuthenticated = await modelerHomePage.modelerPageBanner
527
- .waitFor({ state: 'visible', timeout: 15000 })
528
- .then(() => true)
529
- .catch(() => false);
530
- if (autoAuthenticated) {
531
- try {
532
- await modelerHomePage.clickHomeBreadcrumb();
533
- }
534
- catch {
535
- // Already on the Modeler home page
536
- }
537
- }
538
- else {
539
- await page.context().clearCookies();
540
- await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, {
541
- username: emailAddress,
542
- password: password,
543
- }, 1000, 3, true);
544
- await appsPage.clickCamundaApps();
545
- await appsPage.clickModeler();
546
- }
547
- await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
548
- timeout: 120000,
518
+ await modelerHomePage.navigateAfterInvitationLink(loginPage, appsPage, {
519
+ username: emailAddress,
520
+ password: password,
549
521
  });
550
522
  await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(modelerHomePage, modelerHomePage.crossComponentProjectFolder, 'Cross Component Test Project', 90000, 20);
551
523
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.684",
3
+ "version": "0.0.686",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",