@camunda/e2e-test-suite 0.0.1014 → 0.0.1016

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,6 +1,7 @@
1
1
  import { Page, Locator } from '@playwright/test';
2
2
  declare class FormJsPage {
3
3
  private page;
4
+ private processApplicationPage;
4
5
  readonly aiFormGeneratorButton: Locator;
5
6
  readonly formRequestInput: Locator;
6
7
  readonly generateFormButton: Locator;
@@ -31,6 +32,7 @@ declare class FormJsPage {
31
32
  selectCluster(clusterName: string): Promise<void>;
32
33
  clickDeployButton(): Promise<void>;
33
34
  clickDeploySubButton(): Promise<void>;
35
+ selectOnlyThisResource(): Promise<void>;
34
36
  deployForm(clusterName: string): Promise<void>;
35
37
  }
36
38
  export { FormJsPage };
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FormJsPage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const sleep_1 = require("../../utils/sleep");
6
+ const ProcessApplicationPage_1 = require("./ProcessApplicationPage");
6
7
  class FormJsPage {
7
8
  page;
9
+ processApplicationPage;
8
10
  aiFormGeneratorButton;
9
11
  formRequestInput;
10
12
  generateFormButton;
@@ -23,6 +25,7 @@ class FormJsPage {
23
25
  deploySuccessNotification;
24
26
  constructor(page) {
25
27
  this.page = page;
28
+ this.processApplicationPage = new ProcessApplicationPage_1.ProcessApplicationPage(page);
26
29
  this.aiFormGeneratorButton = page.getByRole('button', {
27
30
  name: 'AI Form Generator',
28
31
  });
@@ -44,9 +47,12 @@ class FormJsPage {
44
47
  this.deployButton = page
45
48
  .locator('[data-test="action-bar"]')
46
49
  .getByRole('button', { name: 'Deploy', exact: true });
50
+ // Inside a process application hub titles this modal for the application
51
+ // rather than for the form, so 'Deploy form' never matches and the dialog
52
+ // reads as absent. pages/SM-8.10 filters on 'Deploy' for the same reason.
47
53
  this.dialog = page
48
54
  .locator('.cds--modal-container[role="dialog"]')
49
- .filter({ hasText: 'Deploy form' });
55
+ .filter({ hasText: 'Deploy' });
50
56
  this.deploySubButton = this.dialog.getByRole('button', {
51
57
  name: 'Deploy',
52
58
  exact: true,
@@ -99,6 +105,46 @@ class FormJsPage {
99
105
  async selectCluster(clusterName) {
100
106
  await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 30000 });
101
107
  const healthCheckTimeout = 30000;
108
+ // Inside a process application the deploy dialog renders
109
+ // ProcessAppClusterSelection, not the per-deploy ClusterSelection toggle
110
+ // list: it shows only clusters assigned to one of the application's stages
111
+ // and auto-selects the first, so there is no label to click. Confirm the
112
+ // intended cluster is the one on offer instead.
113
+ //
114
+ // The unconfigured case is called out explicitly: without this the symptom
115
+ // is the cluster toggle never appearing, retried until the test times out,
116
+ // which says nothing about the actual cause.
117
+ const notConfigured = this.dialog.getByText('Clusters not configured for stages');
118
+ if (await notConfigured.isVisible().catch(() => false)) {
119
+ throw new Error(`Process application has no cluster assigned to any stage, so "${clusterName}" cannot be deployed to. ` +
120
+ 'ProcessApplicationPage.ensureStageCluster() should have bound it before the deploy dialog was opened.');
121
+ }
122
+ const legacyClusterToggle = this.dialog.locator('label').filter({
123
+ hasText: new RegExp(`^${clusterName}`),
124
+ });
125
+ const isLegacyDialog = await legacyClusterToggle
126
+ .first()
127
+ .isVisible()
128
+ .catch(() => false);
129
+ if (!isLegacyDialog) {
130
+ const offered = await this.dialog
131
+ .getByText(clusterName, { exact: false })
132
+ .first()
133
+ .waitFor({ state: 'visible', timeout: 30000 })
134
+ .then(() => true)
135
+ .catch(() => false);
136
+ if (!offered) {
137
+ // Forget the binding before failing. The dialog lists exactly the
138
+ // clusters this application's stages point at, so a missing cluster
139
+ // means the binding did not take -- and no amount of reopening the
140
+ // dialog will make it appear. Clearing the record lets the caller's
141
+ // next attempt rebind instead of re-checking an unchanged dialog.
142
+ this.processApplicationPage.forgetStageCluster();
143
+ throw new Error(`The deploy dialog does not offer "${clusterName}": its stage ` +
144
+ 'binding did not take. It will be rebound on the next attempt.');
145
+ }
146
+ return;
147
+ }
102
148
  const healthyRegex = new RegExp(`${clusterName}[\\s\\S]*?HealthydevManage`);
103
149
  const cluster = this.dialog.locator(`[title="${clusterName}"]`);
104
150
  await (0, test_1.expect)(cluster).toBeVisible({ timeout: 30000 });
@@ -117,12 +163,39 @@ class FormJsPage {
117
163
  async clickDeploySubButton() {
118
164
  await this.deploySubButton.click({ timeout: 60000 });
119
165
  }
166
+ // Since camunda/camunda-hub#25831 a form lives inside a process application,
167
+ // and Hub then scopes Deploy to the WHOLE application by default -- it calls
168
+ // deployProcessApplication, not deployFile, so the "Form deployed!" toast
169
+ // never fires (hub's own form-deploy-action.spec.sm.tsx asserts exactly that
170
+ // default). Narrowing the scope keeps this a form-deploy test instead of
171
+ // silently turning it into a process-application deploy. The combobox only
172
+ // exists inside a container, hence the boolean probe.
173
+ async selectOnlyThisResource() {
174
+ const scopeSelect = this.dialog.getByRole('combobox', {
175
+ name: 'Resources to deploy',
176
+ });
177
+ const hasScopeSelect = await scopeSelect
178
+ .waitFor({ state: 'visible', timeout: 10000 })
179
+ .then(() => true)
180
+ .catch(() => false);
181
+ if (!hasScopeSelect) {
182
+ return;
183
+ }
184
+ await scopeSelect.click();
185
+ await this.dialog
186
+ .getByRole('option', { name: 'Only this resource' })
187
+ .or(this.dialog.getByText('Only this resource', { exact: true }))
188
+ .first()
189
+ .click({ timeout: 30000 });
190
+ }
120
191
  async deployForm(clusterName) {
192
+ await this.processApplicationPage.ensureStageCluster(clusterName);
121
193
  await this.clickDeployButton();
122
194
  await (0, test_1.expect)(this.dialog).toBeVisible({
123
195
  timeout: 30000,
124
196
  });
125
197
  await this.selectCluster(clusterName);
198
+ await this.selectOnlyThisResource();
126
199
  await this.clickDeploySubButton();
127
200
  await (0, test_1.expect)(this.deploySuccessNotification).toBeVisible({ timeout: 30000 });
128
201
  await (0, test_1.expect)(this.deploySuccessNotification).not.toBeVisible({
@@ -1,6 +1,7 @@
1
1
  import { Page, Locator } from '@playwright/test';
2
2
  declare class ModelerCreatePage {
3
3
  private page;
4
+ private processApplicationPage;
4
5
  readonly generalPanel: Locator;
5
6
  private deployDiagramDialog;
6
7
  readonly processIdInput: Locator;
@@ -216,7 +217,7 @@ declare class ModelerCreatePage {
216
217
  private suppressTestModeAnnouncement;
217
218
  switchToPlay(): Promise<void>;
218
219
  completePlayConfiguration(clusterName: string): Promise<void>;
219
- selectCluster(clusterName: string): Promise<void>;
220
+ selectCluster(clusterName: string, healthCheckTimeout?: number): Promise<void>;
220
221
  embedForm(formName: string): Promise<void>;
221
222
  fillStartEventVariablesForDocHandling(zeebeUrl: string, zeebeClientId: string, zeebeClientSecret: string): Promise<void>;
222
223
  fillZeebeClientId(clientId: string): Promise<void>;
@@ -4,8 +4,10 @@ exports.ModelerCreatePage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const sleep_1 = require("../../utils/sleep");
6
6
  const ConnectorMarketplacePage_1 = require("./ConnectorMarketplacePage");
7
+ const ProcessApplicationPage_1 = require("./ProcessApplicationPage");
7
8
  class ModelerCreatePage {
8
9
  page;
10
+ processApplicationPage;
9
11
  generalPanel;
10
12
  deployDiagramDialog;
11
13
  processIdInput;
@@ -109,6 +111,7 @@ class ModelerCreatePage {
109
111
  diagramNameBreadcrumb;
110
112
  constructor(page) {
111
113
  this.page = page;
114
+ this.processApplicationPage = new ProcessApplicationPage_1.ProcessApplicationPage(page);
112
115
  this.generalPanel = page.locator('[data-group-id="group-general"]');
113
116
  this.processIdInput = page.getByLabel('ID', { exact: true });
114
117
  this.startEventElement = page.locator('.djs-hit').first();
@@ -220,8 +223,12 @@ class ModelerCreatePage {
220
223
  this.rbaEnabledDeployedDialog = page.getByRole('dialog', {
221
224
  name: 'Process successfully deployed',
222
225
  });
226
+ // Since camunda/camunda-hub#25831 a diagram deploys as part of its process
227
+ // application and hub titles the modal for the application, not for the
228
+ // single resource, so an exact 'Deploy diagram' name no longer matches.
229
+ // Match on the verb -- pages/SM-8.10 already leaves this unfiltered.
223
230
  this.deployDiagramDialog = page.getByRole('dialog', {
224
- name: 'Deploy diagram',
231
+ name: /^Deploy/,
225
232
  });
226
233
  this.appendGatewayButton = page.getByRole('button', {
227
234
  name: 'Append gateway',
@@ -472,6 +479,7 @@ class ModelerCreatePage {
472
479
  await this.deployMenuItem.click({ timeout: 60000 });
473
480
  }
474
481
  async deployDiagram(clusterName) {
482
+ await this.processApplicationPage.ensureStageCluster(clusterName);
475
483
  await this.clickDeployButtonWithRetry();
476
484
  await (0, test_1.expect)(this.deployDiagramDialog).toBeVisible({
477
485
  timeout: 30000,
@@ -521,24 +529,29 @@ class ModelerCreatePage {
521
529
  await this.deployAndRunSubButton.click({ timeout: 30000 });
522
530
  }
523
531
  async runProcessInstance(clusterName, variables = '', formVariables = {}, textToVisible = '') {
532
+ await this.processApplicationPage.ensureStageCluster(clusterName);
524
533
  await this.clickDeployAndRunMainButton();
525
- await (0, test_1.expect)(this.dialog).toBeVisible({
526
- timeout: 30000,
527
- });
528
- //Select the correct cluster if multiple exist
529
- const clusterLabel = this.dialog
530
- .locator('label')
531
- .filter({ hasText: new RegExp(`^${clusterName}`) });
532
- await (0, test_1.expect)(clusterLabel).toBeVisible({ timeout: 30000 });
533
- await clusterLabel.click();
534
- await (0, test_1.expect)(clusterLabel.getByRole('switch')).toBeChecked({
535
- timeout: 30000,
536
- });
537
- //Check healthy status of the selected cluster
538
- const regex = new RegExp(`${clusterName}.*?HealthydevManage`);
539
- await (0, test_1.expect)(this.dialog).toHaveText(regex, {
540
- timeout: 120000,
541
- });
534
+ // Routed through selectCluster so this path gets the same
535
+ // legacy-toggle-vs-ProcessAppClusterSelection branch as every other deploy:
536
+ // inside a process application there is no cluster toggle to click. Keeps
537
+ // this path's own 120s health wait rather than selectCluster's 30s default.
538
+ try {
539
+ await this.selectCluster(clusterName, 120000);
540
+ }
541
+ catch (error) {
542
+ // selectCluster clears the stage binding when the dialog does not offer
543
+ // the cluster, so ensureStageCluster rebinds here and reports that it
544
+ // navigated. Any other failure leaves the binding in place, it returns
545
+ // false, and the original error stands -- there is nothing to redo.
546
+ // Unlike the 8.8+ flows this one has no surrounding retry loop, hence
547
+ // the one explicit second attempt.
548
+ const rebound = await this.processApplicationPage.ensureStageCluster(clusterName);
549
+ if (!rebound) {
550
+ throw error;
551
+ }
552
+ await this.clickDeployAndRunMainButton();
553
+ await this.selectCluster(clusterName, 120000);
554
+ }
542
555
  if (variables.length > 0) {
543
556
  await (0, test_1.expect)(this.variableInput).toBeVisible({
544
557
  timeout: 60000,
@@ -633,8 +646,45 @@ class ModelerCreatePage {
633
646
  }
634
647
  }
635
648
  }
649
+ // Opening the breadcrumb menu leaves the pointer on the breadcrumb button,
650
+ // and hub renders that button's truncated-name tooltip on top of the menu,
651
+ // where it swallows the click on "Rename" -- playwright reports
652
+ // `<div role="tooltip">…</div> intercepts pointer events`. Since
653
+ // camunda/camunda-hub#25831 the breadcrumb carries an extra
654
+ // process-application crumb, so the name truncates, and the tooltip renders,
655
+ // as the rule rather than the exception. Park the pointer away from the
656
+ // breadcrumb and let the tooltip unmount before clicking; reopen the menu if
657
+ // a previous attempt closed it.
636
658
  async clickEditDiagramNameButton() {
637
- await this.renameDiagramNameButton.click({ timeout: 60000 });
659
+ const openTooltip = this.page.locator('[role="tooltip"][aria-hidden="false"]');
660
+ await (0, test_1.expect)(async () => {
661
+ const menuOpen = await this.renameDiagramNameButton
662
+ .isVisible()
663
+ .catch(() => false);
664
+ if (!menuOpen) {
665
+ await this.clickDiagramBreadcrumb();
666
+ }
667
+ // Park the pointer so the breadcrumb's own tooltip gets a chance to
668
+ // unmount -- best effort, because it is not reliably hover-driven, and
669
+ // requiring it to go turned an interceptable click into a hard failure.
670
+ await this.page.mouse.move(0, 0);
671
+ await openTooltip
672
+ .first()
673
+ .waitFor({ state: 'hidden', timeout: 2000 })
674
+ .catch(() => false);
675
+ try {
676
+ await this.renameDiagramNameButton.click({ timeout: 10000 });
677
+ }
678
+ catch {
679
+ // The tooltip renders over the menu and swallows the click (playwright
680
+ // reports `<div role="tooltip">…</div> intercepts pointer events`).
681
+ // Dispatching on the element bypasses hit-testing, which no amount of
682
+ // waiting achieves when the tooltip never unmounts. Not a swallowed
683
+ // failure: the assertion below is what decides whether this worked.
684
+ await this.renameDiagramNameButton.dispatchEvent('click');
685
+ }
686
+ await (0, test_1.expect)(this.diagramNameInput).toBeVisible({ timeout: 10000 });
687
+ }).toPass({ timeout: 60000, intervals: [1000, 2000, 5000] });
638
688
  }
639
689
  async enterDiagramName(name) {
640
690
  // The inline name field stays in the DOM after the rename action closes,
@@ -1137,6 +1187,16 @@ class ModelerCreatePage {
1137
1187
  await this.playTab.click();
1138
1188
  }
1139
1189
  async completePlayConfiguration(clusterName) {
1190
+ // Play is a tab on the diagram page, not its own URL, so the stage-cluster
1191
+ // detour's goto() lands back on the Modeler tab and every Play locator
1192
+ // below would then look for a panel that is no longer rendered. Re-enter
1193
+ // Play when the detour actually navigated. Binding cannot simply move
1194
+ // before switchToPlay(): this is the first point in the flow that knows
1195
+ // which cluster the test plays on.
1196
+ const reboundStageCluster = await this.processApplicationPage.ensureStageCluster(clusterName);
1197
+ if (reboundStageCluster) {
1198
+ await this.switchToPlay();
1199
+ }
1140
1200
  const timeout = 30000;
1141
1201
  // New flow (8.10+): "Setup environment" panel with three steps:
1142
1202
  // 1. Connect cluster → "Configure environment" modal → select cluster → Save
@@ -1160,17 +1220,37 @@ class ModelerCreatePage {
1160
1220
  name: /^Configure (test case|scenario)$/,
1161
1221
  }))
1162
1222
  .first();
1163
- // Wait up to 15s for EITHER the new-flow setup panel OR the legacy Continue
1164
- // button to appear.
1165
- const setupOrContinue = setupDeployButton.or(this.continueToPlayButton);
1166
- const panelAppeared = await setupOrContinue
1167
- .first()
1168
- .isVisible({ timeout: 15000 })
1169
- .catch(() => false);
1170
- if (!panelAppeared) {
1223
+ // Play settles into exactly ONE of three states, and which one is not
1224
+ // knowable up front, so race them instead of timing out on each in turn:
1225
+ // the setup overlay, the legacy Continue button, or the configure-test
1226
+ // panel (meaning setup is already done for this diagram).
1227
+ //
1228
+ // Waiting only for the first two and reading "neither" as "already ready"
1229
+ // was wrong once the diagram moved inside a process application.
1230
+ // ConfigurationOverlay renders null until isDeploymentStateValidated, and
1231
+ // it sets that flag synchronously ONLY when processApplicationId is
1232
+ // undefined -- exactly what a project-root diagram used to give it. With
1233
+ // the diagram in a process application the id is defined, so the overlay
1234
+ // must first await checkExistingDeployment(). The old 15s probe raced that
1235
+ // async call, concluded "already ready" and returned while the overlay was
1236
+ // still about to appear. ConfigureTestPanel returns null for as long as the
1237
+ // overlay is up, so the Start button never existed and
1238
+ // clickStartInstanceButton burned its entire retry budget looking for it.
1239
+ const configurationOverlay = this.page.locator('[data-test="play-configuration-overlay"]');
1240
+ const configureTestPanel = this.page.getByTestId('configure-test-panel');
1241
+ await (0, test_1.expect)(configurationOverlay
1242
+ .or(this.continueToPlayButton)
1243
+ .or(configureTestPanel)
1244
+ .first()).toBeVisible({ timeout: 90000 });
1245
+ if (await configureTestPanel.isVisible()) {
1246
+ // Already past setup for this diagram -- nothing to drive.
1171
1247
  return;
1172
1248
  }
1173
- const isNewFlow = await setupDeployButton.isVisible().catch(() => false);
1249
+ // Keyed on the overlay itself, not on its Deploy button: when
1250
+ // checkExistingDeployment finds a deployment the overlay opens with the
1251
+ // deploy step already complete, so there is no Deploy button to see and
1252
+ // keying on it would fall through to the legacy Continue flow.
1253
+ const isNewFlow = await configurationOverlay.isVisible();
1174
1254
  if (isNewFlow) {
1175
1255
  // Step 1: connect cluster if not yet connected (modal with cluster dropdown)
1176
1256
  const connectClusterButton = this.page.getByRole('button', {
@@ -1209,13 +1289,33 @@ class ModelerCreatePage {
1209
1289
  .getByRole('button', { name: 'Save' })
1210
1290
  .click({ timeout });
1211
1291
  }
1212
- // Step 2: deploy — wait for enabled; button stays disabled until the cluster
1213
- // connection is confirmed by the backend after the Save in step 1.
1214
- await (0, test_1.expect)(setupDeployButton).toBeEnabled({ timeout: 60000 });
1215
- await setupDeployButton.click({ timeout });
1216
- await (0, test_1.expect)(this.page.getByText('Process has been successfully deployed')).toBeVisible({ timeout: 90000 });
1217
- // Step 3: configure scenario
1218
- await configureScenarioButton.click({ timeout });
1292
+ // Step 2: deploy, unless the overlay already opened with the
1293
+ // deploy step complete. checkExistingDeployment only runs when
1294
+ // processApplicationId is defined, which it now is, so re-entering
1295
+ // Play on an already-deployed process application legitimately
1296
+ // has nothing to deploy and renders no Deploy button at all.
1297
+ const alreadyDeployed = await configureScenarioButton
1298
+ .isVisible({ timeout: 3000 })
1299
+ .catch(() => false);
1300
+ if (!alreadyDeployed) {
1301
+ // Step 2: deploy — wait for enabled; button stays disabled until the cluster
1302
+ // connection is confirmed by the backend after the Save in step 1.
1303
+ await (0, test_1.expect)(setupDeployButton).toBeEnabled({ timeout: 60000 });
1304
+ await setupDeployButton.click({ timeout });
1305
+ await (0, test_1.expect)(this.page.getByText('Process has been successfully deployed')).toBeVisible({ timeout: 90000 });
1306
+ }
1307
+ // Step 3: leave the overlay, and confirm we actually left it. The
1308
+ // button only calls hideConfigurationOverlay(); the overlay's own
1309
+ // cluster-change effect can then fire resetDeployment and bring it
1310
+ // straight back, and ConfigureTestPanel stays null while it is up.
1311
+ // Assert the panel really rendered, and re-drive the click if the
1312
+ // overlay returned.
1313
+ await (0, test_1.expect)(async () => {
1314
+ if (await configurationOverlay.isVisible()) {
1315
+ await configureScenarioButton.click({ timeout });
1316
+ }
1317
+ await (0, test_1.expect)(configureTestPanel).toBeVisible({ timeout: 15000 });
1318
+ }).toPass({ timeout: 90000 });
1219
1319
  return;
1220
1320
  }
1221
1321
  // Legacy flow: select cluster via dialog, then click Continue.
@@ -1238,9 +1338,48 @@ class ModelerCreatePage {
1238
1338
  }
1239
1339
  }
1240
1340
  }
1241
- async selectCluster(clusterName) {
1341
+ async selectCluster(clusterName, healthCheckTimeout = 30000) {
1242
1342
  await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 30000 });
1243
- const healthCheckTimeout = 30000;
1343
+ // Inside a process application the deploy dialog renders
1344
+ // ProcessAppClusterSelection, not the per-deploy ClusterSelection toggle
1345
+ // list: it shows only clusters assigned to one of the application's stages
1346
+ // and auto-selects the first, so there is no label to click. Confirm the
1347
+ // intended cluster is the one on offer instead.
1348
+ //
1349
+ // The unconfigured case is called out explicitly: without this the symptom
1350
+ // is the cluster toggle never appearing, retried until the test times out,
1351
+ // which says nothing about the actual cause.
1352
+ const notConfigured = this.dialog.getByText('Clusters not configured for stages');
1353
+ if (await notConfigured.isVisible().catch(() => false)) {
1354
+ throw new Error(`Process application has no cluster assigned to any stage, so "${clusterName}" cannot be deployed to. ` +
1355
+ 'ProcessApplicationPage.ensureStageCluster() should have bound it before the deploy dialog was opened.');
1356
+ }
1357
+ const legacyClusterToggle = this.dialog.locator('label').filter({
1358
+ hasText: new RegExp(`^${clusterName}`),
1359
+ });
1360
+ const isLegacyDialog = await legacyClusterToggle
1361
+ .first()
1362
+ .isVisible()
1363
+ .catch(() => false);
1364
+ if (!isLegacyDialog) {
1365
+ const offered = await this.dialog
1366
+ .getByText(clusterName, { exact: false })
1367
+ .first()
1368
+ .waitFor({ state: 'visible', timeout: 30000 })
1369
+ .then(() => true)
1370
+ .catch(() => false);
1371
+ if (!offered) {
1372
+ // Forget the binding before failing. The dialog lists exactly the
1373
+ // clusters this application's stages point at, so a missing cluster
1374
+ // means the binding did not take -- and no amount of reopening the
1375
+ // dialog will make it appear. Clearing the record lets the caller's
1376
+ // next attempt rebind instead of re-checking an unchanged dialog.
1377
+ this.processApplicationPage.forgetStageCluster();
1378
+ throw new Error(`The deploy dialog does not offer "${clusterName}": its stage ` +
1379
+ 'binding did not take. It will be rebound on the next attempt.');
1380
+ }
1381
+ return;
1382
+ }
1244
1383
  const healthyRegex = new RegExp(`${clusterName}.*?HealthydevManage`);
1245
1384
  const clusterLabel = this.dialog
1246
1385
  .locator('label')
@@ -3,6 +3,9 @@ import { LoginPage } from './LoginPage';
3
3
  declare class ModelerHomePage {
4
4
  private defaultFolderName;
5
5
  private page;
6
+ private processApplicationPage;
7
+ private processApplicationUrl?;
8
+ private processApplicationName?;
6
9
  readonly modelerPageBanner: Locator;
7
10
  readonly createNewProjectButton: Locator;
8
11
  readonly projectNameInput: Locator;
@@ -15,6 +18,7 @@ declare class ModelerHomePage {
15
18
  readonly idpApplicationNameInput: Locator;
16
19
  readonly createIdpApplicationButton: Locator;
17
20
  readonly projectBreadcrumb: Locator;
21
+ readonly workspaceBreadcrumb: Locator;
18
22
  readonly openOrganizationsButton: Locator;
19
23
  readonly optionsButton: Locator;
20
24
  readonly manageButton: Locator;
@@ -41,12 +45,20 @@ declare class ModelerHomePage {
41
45
  getProjectNames(name: string): Promise<string[]>;
42
46
  clickProcessDiagram(name: string): Promise<void>;
43
47
  clickDiagramTypeDropdown(): Promise<void>;
48
+ clickWorkspaceDiagramTypeDropdown(): Promise<void>;
44
49
  clickBpmnTemplateOption(): Promise<void>;
45
50
  clickIdpApplicationTemplateOption(): Promise<void>;
46
51
  clickFormOption(): Promise<void>;
47
52
  enterFormName(name: string): Promise<void>;
48
53
  openFormRenameEditor(): Promise<void>;
49
54
  clickProjectBreadcrumb(): Promise<void>;
55
+ clickWorkspaceBreadcrumb(): Promise<void>;
56
+ enterResourceContainer(name?: string): Promise<void>;
57
+ private clickCreateProcessApplication;
58
+ private ensureInResourceContainer;
59
+ returnToResourceContainer(): Promise<void>;
60
+ startBlankBpmnDiagram(): Promise<void>;
61
+ private becameVisible;
50
62
  clickHomeBreadcrumb(): Promise<void>;
51
63
  clickOpenOrganizationsButton(): Promise<void>;
52
64
  clickCrossComponentProjectFolder(): Promise<void>;