@camunda/e2e-test-suite 0.0.1289 → 0.0.1290

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.
@@ -18,6 +18,8 @@ declare class ModelerCreatePage {
18
18
  readonly diagramBreadcrumb: Locator;
19
19
  readonly renameDiagramNameButton: Locator;
20
20
  readonly diagramNameInput: Locator;
21
+ readonly renameInput: Locator;
22
+ readonly renameSubmitButton: Locator;
21
23
  readonly variableInput: Locator;
22
24
  readonly embedFormButton: Locator;
23
25
  readonly embedButton: Locator;
@@ -71,7 +73,6 @@ declare class ModelerCreatePage {
71
73
  readonly publicAccessToggle: Locator;
72
74
  readonly publicationTab: Locator;
73
75
  readonly copyPublicLinkButton: Locator;
74
- readonly publicLinkCodeBlock: Locator;
75
76
  readonly closeButton: Locator;
76
77
  readonly rbaEnabledDeployedDialog: Locator;
77
78
  readonly viewProcessLink: Locator;
@@ -236,6 +237,7 @@ declare class ModelerCreatePage {
236
237
  expandPublicationSection(): Promise<void>;
237
238
  enablePublicAccessIfDisabled(): Promise<void>;
238
239
  clickPublicationTab(): Promise<void>;
240
+ ensureCopyPublicLinkButtonVisible(): Promise<void>;
239
241
  clickCopyPublicLinkButton(): Promise<void>;
240
242
  getPublicationLink(): Promise<string>;
241
243
  assertFormEmbedded(): Promise<void>;
@@ -30,6 +30,8 @@ class ModelerCreatePage {
30
30
  diagramBreadcrumb;
31
31
  renameDiagramNameButton;
32
32
  diagramNameInput;
33
+ renameInput;
34
+ renameSubmitButton;
33
35
  variableInput;
34
36
  embedFormButton;
35
37
  embedButton;
@@ -83,7 +85,6 @@ class ModelerCreatePage {
83
85
  publicAccessToggle;
84
86
  publicationTab;
85
87
  copyPublicLinkButton;
86
- publicLinkCodeBlock;
87
88
  closeButton;
88
89
  rbaEnabledDeployedDialog;
89
90
  viewProcessLink;
@@ -206,6 +207,8 @@ class ModelerCreatePage {
206
207
  .locator('[data-test="rename-input"]')
207
208
  .or(page.locator('[data-test="editable-input"]'))
208
209
  .first();
210
+ this.renameInput = page.locator('[data-test="rename-input"]');
211
+ this.renameSubmitButton = page.locator('[data-test="rename-submit"]');
209
212
  this.variableInput = page.locator('[id="variables-json"]');
210
213
  this.embedFormButton = page.getByRole('button', { name: 'Link form' });
211
214
  // Hub's link picker confirms with `link-target-confirm` ("Link");
@@ -318,15 +321,16 @@ class ModelerCreatePage {
318
321
  name: 'Toggle public access',
319
322
  });
320
323
  this.publicationTab = page.getByRole('tab', { name: 'Publication' });
321
- this.copyPublicLinkButton = page.getByRole('button', {
324
+ // Legacy Carbon snippet (textbox) or Hub's design-system code block; both
325
+ // wrap the link in the <code> that getPublicationLink() reads. The old
326
+ // button-only lookup found neither on Hub, so the publication link could
327
+ // not be read at all (`getByRole('button', {name: 'Copy to clipboard'})`
328
+ // ... Received: <element(s) not found>).
329
+ this.copyPublicLinkButton = page
330
+ .getByRole('textbox', {
322
331
  name: 'Copy to clipboard',
323
- });
324
- // The Publication tab's link, held by the code block's <code> rather than
325
- // by the copy button. Filtered on the scheme so it resolves only once the
326
- // tab has actually loaded a link.
327
- this.publicLinkCodeBlock = page
328
- .locator('[data-slot="code-block"] code')
329
- .filter({ hasText: /^https?:\/\// })
332
+ })
333
+ .or(page.locator('[data-slot="code-block"]'))
330
334
  .first();
331
335
  this.rbaEnabledDeployedDialog = page.getByRole('dialog', {
332
336
  name: 'Process successfully deployed',
@@ -944,11 +948,49 @@ class ModelerCreatePage {
944
948
  await (0, test_1.expect)(this.diagramNameInput).toBeVisible({ timeout: 10000 });
945
949
  }).toPass({ timeout: 60000, intervals: [1000, 2000, 5000] });
946
950
  }
951
+ // Name-agnostic on purpose. The previous version asserted the crumb still
952
+ // read "New BPMN diagram" before renaming, which only holds for a diagram
953
+ // created from the BPMN template: modelDiagramFromFile uploads a .bpmn and
954
+ // Hub names the resource after the FILE, so the assertion raced the upload
955
+ // and failed with `Received string: "Camunda_Simple_User_Task_3 actions"`.
956
+ // Open the editor if it is not already open, fill whichever control this
957
+ // shell renders, and assert the crumb ends up showing the new name.
947
958
  async enterDiagramName(name) {
948
- // Hub renames through the current crumb's actions menu into a shared
949
- // dialog; the inline editable this used to fill never mounts on its own.
950
- // "New BPMN diagram" is the server default the diagram still carries here.
951
- await (0, hubResourceRename_1.renameHubResource)(this.page, 'New BPMN diagram', name);
959
+ const maxAttempts = 3;
960
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
961
+ try {
962
+ const editorOpen = await this.diagramNameInput
963
+ .or(this.renameInput)
964
+ .first()
965
+ .waitFor({ state: 'visible', timeout: 5000 })
966
+ .then(() => true)
967
+ .catch(() => false);
968
+ if (!editorOpen) {
969
+ await this.clickEditDiagramNameButton();
970
+ }
971
+ if (await this.renameInput.isVisible().catch(() => false)) {
972
+ await this.renameInput.fill(name, { timeout: 30000 });
973
+ await (0, test_1.expect)(this.renameInput).toHaveValue(name, { timeout: 5000 });
974
+ await this.renameSubmitButton.click({ timeout: 10000 });
975
+ await (0, test_1.expect)(this.renameInput).toBeHidden({ timeout: 30000 });
976
+ }
977
+ else {
978
+ await this.diagramNameInput.fill(name, { timeout: 45000 });
979
+ await this.diagramNameInput.press('Enter', { timeout: 45000 });
980
+ }
981
+ await (0, test_1.expect)(this.diagramNameBreadcrumb(name)).toBeVisible({
982
+ timeout: 30000,
983
+ });
984
+ return;
985
+ }
986
+ catch (error) {
987
+ if (attempt === maxAttempts) {
988
+ throw error;
989
+ }
990
+ console.warn(`Diagram rename to "${name}" did not commit ` +
991
+ `(attempt ${attempt}/${maxAttempts}): ${error}`);
992
+ }
993
+ }
952
994
  }
953
995
  async clickVariableInput() {
954
996
  await this.variableInput.click({ timeout: 60000 });
@@ -1957,42 +1999,42 @@ class ModelerCreatePage {
1957
1999
  },
1958
2000
  });
1959
2001
  }
2002
+ // The Publication tab renders its link asynchronously and can come up empty
2003
+ // when the tab is opened too early; re-entering the diagram and reopening the
2004
+ // tab is what recovers it.
2005
+ async ensureCopyPublicLinkButtonVisible() {
2006
+ await this.clickPublicationTab();
2007
+ for (let attempt = 0; attempt < 3; attempt++) {
2008
+ const isVisible = await this.copyPublicLinkButton.isVisible();
2009
+ if (isVisible) {
2010
+ return;
2011
+ }
2012
+ await this.page.reload();
2013
+ await this.page.waitForLoadState('load');
2014
+ await this.clickStartEventElement();
2015
+ await this.clickPublicationTab();
2016
+ }
2017
+ await (0, test_1.expect)(this.copyPublicLinkButton).toBeVisible({ timeout: 60000 });
2018
+ }
1960
2019
  async clickCopyPublicLinkButton() {
2020
+ await this.ensureCopyPublicLinkButtonVisible();
1961
2021
  await this.copyPublicLinkButton.click({ timeout: 60000 });
1962
2022
  }
1963
2023
  async getPublicationLink() {
1964
- await this.clickPublicationTab();
1965
- // Hub renders the publication link as a design-system code block
1966
- // (<div data-slot="code-block"><pre><code>URL</code></pre>) with the copy
1967
- // action as a separate icon button, so clicking "Copy to clipboard" no
1968
- // longer puts the URL where navigator.clipboard.readText() can see it: a
1969
- // nightly trace has the <code> holding
1970
- // https://hel-1.tasklist.ultrawombat.com/<uuid>/tasklist/new/<process>
1971
- // while the test logged "Navigating to public form: " (empty) and then
1972
- // page.goto('') reloaded the app root, landing on the login screen.
1973
- // Read the URL out of the DOM, same as pages/8.9. The filter also waits
1974
- // out the tab's "Updating public process status" spinner, which renders
1975
- // before the link arrives.
1976
- const hasCodeBlock = await this.publicLinkCodeBlock
1977
- .waitFor({ state: 'visible', timeout: 60000 })
1978
- .then(() => true)
1979
- .catch(() => false);
1980
- if (hasCodeBlock) {
1981
- const link = (await this.publicLinkCodeBlock.innerText()).trim();
1982
- (0, test_1.expect)(link).toMatch(/^https?:\/\//);
1983
- console.log('Captured public link:', link);
1984
- return link;
1985
- }
1986
- await (0, test_1.expect)(this.copyPublicLinkButton).toBeVisible({ timeout: 60000 });
1987
- await this.clickCopyPublicLinkButton();
1988
- await (0, sleep_1.sleep)(1000);
1989
- const context = this.page.context();
1990
- await context.grantPermissions(['clipboard-read']);
1991
- const clipboardText = await this.page.evaluate(async () => {
1992
- return await navigator.clipboard.readText();
1993
- });
1994
- console.log('Captured public link:', clipboardText);
1995
- return clipboardText;
2024
+ await this.ensureCopyPublicLinkButtonVisible();
2025
+ const codeLocator = this.copyPublicLinkButton.locator('code');
2026
+ // The publication tab polls every 3s for active links; wait until the URL
2027
+ // is present in the DOM before reading it to avoid a race with re-renders.
2028
+ // The previous version waited for a `[data-slot="code-block"] code`
2029
+ // locator that was itself filtered on the URL, so a tab still showing its
2030
+ // "Updating public process status" spinner simply never resolved and fell
2031
+ // through to a clipboard read that Hub no longer supports.
2032
+ await (0, test_1.expect)(codeLocator).toContainText(/https?:\/\//, { timeout: 60000 });
2033
+ const linkText = await codeLocator.innerText({ timeout: 10000 });
2034
+ const link = linkText.trim();
2035
+ (0, test_1.expect)(link).toMatch(/^https?:\/\//);
2036
+ console.log('Captured public link:', link);
2037
+ return link;
1996
2038
  }
1997
2039
  async assertFormEmbedded() {
1998
2040
  await (0, test_1.expect)(this.formLinkedSuccessMessage).toBeVisible({ timeout: 15000 });
@@ -84,7 +84,7 @@ _8_8_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV1', () => {
84
84
  await appsPage.clickConsoleLink();
85
85
  await settingsPage.clickOpenSettingsButton();
86
86
  await settingsPage.clickLogoutButton();
87
- await loginPage.loginWithTestUser(testUser);
87
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, 1000);
88
88
  });
89
89
  await _8_8_1.test.step('Navigate to Web Modeler', async () => {
90
90
  await appsPage.clickCamundaApps();
@@ -120,7 +120,7 @@ _8_8_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV1', () => {
120
120
  await appsPage.clickConsoleLink();
121
121
  await settingsPage.clickOpenSettingsButton();
122
122
  await settingsPage.clickLogoutButton();
123
- await loginPage.loginWithTestUser(testUser);
123
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, 1000);
124
124
  });
125
125
  await _8_8_1.test.step('Navigate to Tasklist and Make Sure that the Two Deployed Processes Are Accessible', async () => {
126
126
  await appsPage.clickCamundaApps();
@@ -214,7 +214,7 @@ _8_8_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV1', () => {
214
214
  await settingsPage.clickLogoutButton();
215
215
  });
216
216
  await _8_8_1.test.step('Login as Test User', async () => {
217
- await loginPage.loginWithTestUser(testUser);
217
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, 1000);
218
218
  });
219
219
  await _8_8_1.test.step('Navigate to Web Modeler', async () => {
220
220
  await appsPage.clickCamundaApps();
@@ -250,7 +250,7 @@ _8_8_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV1', () => {
250
250
  await appsPage.clickConsoleLink();
251
251
  await settingsPage.clickOpenSettingsButton();
252
252
  await settingsPage.clickLogoutButton();
253
- await loginPage.loginWithTestUser(testUser);
253
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, 1000);
254
254
  });
255
255
  await _8_8_1.test.step('Navigate to Tasklist and Both Processes Are Accessible', async () => {
256
256
  await appsPage.clickCamundaApps();
@@ -427,7 +427,7 @@ _8_8_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV1', () => {
427
427
  await appsPage.clickConsoleLink();
428
428
  await settingsPage.clickOpenSettingsButton();
429
429
  await settingsPage.clickLogoutButton();
430
- await loginPage.loginWithTestUser(testUser);
430
+ await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, 1000);
431
431
  });
432
432
  await _8_8_1.test.step('Navigate to Web Modeler', async () => {
433
433
  await appsPage.clickCamundaApps();
@@ -6,9 +6,11 @@ const _setup_1 = require("../../test-setup.js");
6
6
  const UtilitiesPage_1 = require("../../pages/8.8/UtilitiesPage");
7
7
  const sleep_1 = require("../../utils/sleep");
8
8
  const LoginPage_1 = require("../../pages/8.8/LoginPage");
9
+ const WorkspaceMembersPage_1 = require("../../pages/8.8/WorkspaceMembersPage");
9
10
  const expectTextWithRetry_1 = require("../../utils/assertionHelpers/expectTextWithRetry");
10
11
  const users_1 = require("../../utils/users");
11
12
  const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
13
+ const consoleApiHelpers_1 = require("../../utils/consoleApiHelpers");
12
14
  const mainUser = (0, users_1.getTestUser)('twelfthUser');
13
15
  _8_8_1.test.describe.parallel('UTR Enabled User Flows Test @tasklistV1', () => {
14
16
  const clusterName = 'Test Cluster';
@@ -139,6 +141,24 @@ _8_8_1.test.describe.parallel('UTR Enabled User Flows Test @tasklistV1', () => {
139
141
  await ocIdentityGroupsPage.clickGroupId(groupNameMultiple);
140
142
  await ocIdentityGroupsPage.assignUserToGroup(testUser2.username);
141
143
  });
144
+ // Test user 1 is the org's Developer. Hub shows a non-admin only the
145
+ // environments assigned to a workspace they are Editor or Workspace Admin
146
+ // on (camunda-hub EnvironmentVisibilityResolver), so without this the
147
+ // Tasklist hand-off below finds no "Test Cluster" in the sidebar and
148
+ // expandHubClusterGroup times out on its toggle. Test user 2 is an org
149
+ // Admin and sees every environment already, which is why the Candidate
150
+ // User variant passes untouched.
151
+ await _8_8_1.test.step('Grant Test User 1 Editor rights on a workspace with the cluster', async () => {
152
+ await appsPage.clickCamundaApps();
153
+ await appsPage.clickModeler();
154
+ await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
155
+ timeout: 120000,
156
+ });
157
+ const workspaceMembersPage = new WorkspaceMembersPage_1.WorkspaceMembersPage(page);
158
+ await workspaceMembersPage.openManageMembers('Cross Component Test Project');
159
+ await workspaceMembersPage.setMemberRole(testUser1.username, 'Editor');
160
+ await (0, consoleApiHelpers_1.linkClusterToWorkspaceViaApi)(page, workspaceMembersPage.workspaceId(), clusterName);
161
+ });
142
162
  await _8_8_1.test.step('Navigate to Web Modeler', async () => {
143
163
  await appsPage.clickCamundaApps();
144
164
  await appsPage.clickModeler();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1289",
3
+ "version": "0.0.1290",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",