@camunda/e2e-test-suite 0.0.1008 → 0.0.1010

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.
@@ -3,10 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModelerHomePage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
6
+ const randomName_1 = require("../../utils/randomName");
6
7
  const NavigationPage_1 = require("./NavigationPage");
8
+ const ProcessApplicationPage_1 = require("./ProcessApplicationPage");
7
9
  class ModelerHomePage {
8
10
  page;
9
11
  defaultFolderName = 'Cross Component Test Project';
12
+ // Since camunda/camunda-hub#25831 files and folders cannot sit at a
13
+ // workspace ("project" in today's UI) root -- only process applications and
14
+ // IDP applications can. The container is therefore entered lazily, at the
15
+ // point a resource is created, and remembered for the lifetime of this page
16
+ // object (one instance per test, see fixtures/SM-8.10.ts). Specs that only
17
+ // need the workspace itself never trigger the hop.
18
+ processApplicationPage;
19
+ // Load-bearing: hub renders no process-application breadcrumb on a diagram
20
+ // page at container root, so the remembered URL -- not a breadcrumb click --
21
+ // is how we get back. Hub's own Playwright suite does the same.
22
+ processApplicationUrl;
23
+ processApplicationName;
10
24
  modelerPageBanner;
11
25
  createNewProjectButton;
12
26
  projectNameInput;
@@ -19,6 +33,7 @@ class ModelerHomePage {
19
33
  bpmnTemplateOption;
20
34
  formTemplateOption;
21
35
  projectBreadcrumb;
36
+ workspaceBreadcrumb;
22
37
  openOrganizationsButton;
23
38
  manageButton;
24
39
  crossComponentProjectFolder;
@@ -35,6 +50,7 @@ class ModelerHomePage {
35
50
  modalCloseButton;
36
51
  constructor(page) {
37
52
  this.page = page;
53
+ this.processApplicationPage = new ProcessApplicationPage_1.ProcessApplicationPage(page);
38
54
  // Matches both Modeler shells -- see NavigationPage.modelerPageBanner for
39
55
  // why the Design System branch excludes the /login href.
40
56
  this.modelerPageBanner = page
@@ -58,12 +74,11 @@ class ModelerHomePage {
58
74
  name: 'Choose BPMN template',
59
75
  });
60
76
  this.diagramTypeDropdown = page.locator('[data-test="diagram-dropdown"]');
61
- this.bpmnTemplateOption = page
62
- .locator('[data-test="create-bpmn-diagram"]')
63
- .getByText('BPMN Diagram');
64
- this.formTemplateOption = page
65
- .locator('[data-test="create-form"]')
66
- .getByText('Form');
77
+ // Matched on the test id alone: hub's design-system variant of the create
78
+ // menu renders "BPMN diagram" (lowercase d), so a text filter breaks the
79
+ // day that variant ships.
80
+ this.bpmnTemplateOption = page.locator('[data-test="create-bpmn-diagram"]');
81
+ this.formTemplateOption = page.locator('[data-test="create-form"]');
67
82
  // The Design System shell drops the breadcrumb-project hook. Its context
68
83
  // breadcrumb is org / project / entity, so the project crumb is the second
69
84
  // item -- scoped to the breadcrumb nav, never a bare nth() on the page.
@@ -75,6 +90,21 @@ class ModelerHomePage {
75
90
  .getByRole('button')
76
91
  .first())
77
92
  .first();
93
+ // Kept separate from projectBreadcrumb, which now means "the container my
94
+ // resources live in". When hub's workspaces terminology flag flips,
95
+ // breadcrumb-project comes to denote the process application, so the
96
+ // workspace level needs its own name from the start. Carries the same
97
+ // Design System fallback as projectBreadcrumb: under that shell neither
98
+ // test-id hook exists, and the workspace level is the project crumb.
99
+ this.workspaceBreadcrumb = page
100
+ .locator('[data-test="breadcrumb-project"]')
101
+ .or(page.locator('[data-test="breadcrumb-workspace"]'))
102
+ .or(page
103
+ .locator('nav[aria-label="Context navigation"] [data-slot="nav-breadcrumb-item"]')
104
+ .nth(1)
105
+ .getByRole('button')
106
+ .first())
107
+ .first();
78
108
  this.openOrganizationsButton = page.getByLabel('Open Organizations');
79
109
  this.manageButton = page.getByRole('button', { name: 'Manage' });
80
110
  this.crossComponentProjectFolder = page
@@ -248,7 +278,12 @@ class ModelerHomePage {
248
278
  }
249
279
  }
250
280
  }
281
+ // Opens a resource where this test put it. Several specs leave Modeler
282
+ // entirely (to Optimize, to Operate) and come back via
283
+ // clickCrossComponentProjectFolder(), which lands at workspace root -- the
284
+ // resource is one level down, so re-enter the container first.
251
285
  async clickProcessDiagram(name) {
286
+ await this.ensureInResourceContainer();
252
287
  const process = this.rows.filter({ hasText: name }).getByTitle(name).first();
253
288
  await (0, test_1.expect)(process).toBeVisible({ timeout: 90000 });
254
289
  await process.click();
@@ -267,13 +302,19 @@ class ModelerHomePage {
267
302
  async clickChooseBpmnTemplateButton() {
268
303
  await this.chooseBpmnTemplateButton.click();
269
304
  }
305
+ // Opens the create menu inside this test's process application. The menu at
306
+ // workspace root no longer offers BPMN, Form or Upload -- those resources
307
+ // cannot live there -- so the container is entered first. Callers are
308
+ // unchanged, which is why the ~150 existing spec call sites need no edit.
270
309
  async clickDiagramTypeDropdown() {
271
- await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.diagramTypeDropdown, {
310
+ await this.enterResourceContainer();
311
+ const dropdown = this.processApplicationPage.createNewDropdown;
312
+ await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, dropdown, {
272
313
  postAction: async () => {
273
314
  await this.page.reload();
274
315
  },
275
316
  });
276
- await this.diagramTypeDropdown.click();
317
+ await dropdown.click();
277
318
  }
278
319
  async clickBpmnTemplateOption() {
279
320
  await (0, test_1.expect)(this.bpmnTemplateOption).toBeVisible({ timeout: 60000 });
@@ -286,6 +327,13 @@ class ModelerHomePage {
286
327
  // no inline editable input and renames through the breadcrumb's "More
287
328
  // actions" > "Rename" dialog.
288
329
  async enterFormName(name) {
330
+ // Wait for the form editor itself before probing rename affordances. The
331
+ // project page also renders a "More actions" button, so the or() gate below
332
+ // is satisfied while the caller's navigation is still in flight -- which
333
+ // renamed the PROJECT to the form's name instead of the form. The Carbon
334
+ // shell could not hit this: editable-input existed only inside the editor,
335
+ // so the gate implicitly waited for navigation.
336
+ await this.page.waitForURL(/\/forms\//, { timeout: 60000 });
289
337
  await this.formNameInput
290
338
  .or(this.moreActionsButton)
291
339
  .first()
@@ -309,8 +357,97 @@ class ModelerHomePage {
309
357
  await this.renameSubmitButton.click();
310
358
  await (0, test_1.expect)(this.renameInput).toBeHidden({ timeout: 10000 });
311
359
  }
360
+ // Kept under its original name because it is what ~10 call sites already
361
+ // mean: "go back to where my resources live". That is now the process
362
+ // application, not the workspace root.
312
363
  async clickProjectBreadcrumb() {
313
- await this.projectBreadcrumb.click({ timeout: 60000 });
364
+ await this.returnToResourceContainer();
365
+ }
366
+ // The workspace ("project") level itself, for the surfaces that genuinely
367
+ // live there -- collaborators, IDP applications, published element
368
+ // templates.
369
+ async clickWorkspaceBreadcrumb() {
370
+ await this.workspaceBreadcrumb.click({ timeout: 60000 });
371
+ }
372
+ // Creates, once per test, the process application that holds this test's
373
+ // resources, and leaves the browser inside it. Idempotent: called again while
374
+ // already in the container it is a no-op, so a spec that creates several
375
+ // resources in a row pays for the container once.
376
+ //
377
+ // One container per test rather than one shared with the seeded workspace:
378
+ // deploying is process-application-wide, so a shared container would let one
379
+ // spec's deploy pick up every other spec's half-modelled diagram.
380
+ async enterResourceContainer(name) {
381
+ if (this.processApplicationUrl) {
382
+ const stillInside = await this.becameVisible(this.processApplicationPage.breadcrumb, 5000);
383
+ if (!stillInside) {
384
+ await this.returnToResourceContainer();
385
+ }
386
+ return;
387
+ }
388
+ this.processApplicationName =
389
+ name ??
390
+ (await (0, randomName_1.randomNameAgregator)('Cross Component Process Application'));
391
+ console.log(`Creating process application ${this.processApplicationName} inside ${this.defaultFolderName}`);
392
+ await this.clickCreateProcessApplication();
393
+ await this.processApplicationPage.nameNewProcessApplication(this.processApplicationName);
394
+ this.processApplicationUrl = this.page.url();
395
+ }
396
+ // Which control creates a process application depends on the hub version
397
+ // under test. Since camunda/camunda-hub#25831 it is a plain primary button on
398
+ // the workspace root, and the "Create new" menu explicitly hides the item
399
+ // (hideProcessApplication) because a process application is no longer just
400
+ // another resource. Before that change the menu item was the only way in.
401
+ // Race both entry points so neither version pays a full timeout, then use
402
+ // whichever one rendered.
403
+ async clickCreateProcessApplication() {
404
+ const button = this.processApplicationPage.createProcessApplicationButton;
405
+ const rootLoaded = await this.becameVisible(button.or(this.diagramTypeDropdown).first(), 60000);
406
+ if (!rootLoaded) {
407
+ await this.page.reload();
408
+ }
409
+ // Short: the joint probe above already settled which branch rendered, and
410
+ // hub renders exactly one of them (EntityTable renders the toolbar's create
411
+ // menu OR the empty state, never both), so this only confirms which.
412
+ if (await this.becameVisible(button, 5000)) {
413
+ await this.processApplicationPage.clickCreateProcessApplicationButton();
414
+ return;
415
+ }
416
+ await this.diagramTypeDropdown.click({ timeout: 60000 });
417
+ await this.processApplicationPage.clickCreateProcessApplicationOption();
418
+ }
419
+ // Re-enters this test's container if it already has one, without creating
420
+ // one: opening an existing resource must not have the side effect of
421
+ // creating a container for a spec that never asked for it.
422
+ async ensureInResourceContainer() {
423
+ if (!this.processApplicationUrl) {
424
+ return;
425
+ }
426
+ await this.enterResourceContainer();
427
+ }
428
+ // Navigates back to this test's process application by the remembered URL
429
+ // rather than by a breadcrumb click: hub renders no process-application
430
+ // breadcrumb on a diagram page at container root, and the breadcrumb that
431
+ // does exist on the container page doubles as its rename control. Hub's own
432
+ // Playwright suite navigates back the same way.
433
+ async returnToResourceContainer() {
434
+ if (!this.processApplicationUrl) {
435
+ await this.clickWorkspaceBreadcrumb();
436
+ return;
437
+ }
438
+ await this.page.goto(this.processApplicationUrl, {
439
+ waitUntil: 'domcontentloaded',
440
+ });
441
+ await this.processApplicationPage.waitForProcessApplication();
442
+ await this.clickMessageBanner();
443
+ }
444
+ // Single seam for "give me an empty BPMN diagram in this test's container".
445
+ // A process application always ships an auto-created main process; this adds
446
+ // a new diagram rather than adopting that one, so every existing modelling
447
+ // assertion keeps its current subject.
448
+ async startBlankBpmnDiagram() {
449
+ await this.clickDiagramTypeDropdown();
450
+ await this.clickBpmnTemplateOption();
314
451
  }
315
452
  async clickOpenOrganizationsButton() {
316
453
  await this.openOrganizationsButton.click({ timeout: 30000 });
@@ -344,6 +481,14 @@ class ModelerHomePage {
344
481
  }
345
482
  }
346
483
  }
484
+ // Boolean visibility probe. waitFor rather than isVisible, which resolves
485
+ // immediately and would report a false negative on a still-rendering page.
486
+ async becameVisible(locator, timeout) {
487
+ return locator
488
+ .waitFor({ state: 'visible', timeout })
489
+ .then(() => true)
490
+ .catch(() => false);
491
+ }
347
492
  // Probe with waitFor, not isVisible: the "New features" modal renders lazily
348
493
  // after page load, and isVisible resolves immediately — Playwright ignores
349
494
  // its timeout option — so it misses an overlay that has yet to paint.
@@ -0,0 +1,23 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ declare class ProcessApplicationPage {
3
+ private page;
4
+ readonly createProcessApplicationButton: Locator;
5
+ readonly createProcessApplicationOption: Locator;
6
+ readonly creationDialog: Locator;
7
+ readonly nameInput: Locator;
8
+ readonly submitButton: Locator;
9
+ readonly cancelButton: Locator;
10
+ readonly breadcrumb: Locator;
11
+ readonly folderExplorer: Locator;
12
+ readonly titleBar: Locator;
13
+ readonly createNewDropdown: Locator;
14
+ readonly inlineNameInput: Locator;
15
+ constructor(page: Page);
16
+ private pageReady;
17
+ waitForProcessApplication(timeout?: number): Promise<void>;
18
+ clickCreateProcessApplicationButton(): Promise<void>;
19
+ clickCreateProcessApplicationOption(): Promise<void>;
20
+ nameNewProcessApplication(name: string): Promise<void>;
21
+ openByName(name: string): Promise<void>;
22
+ }
23
+ export { ProcessApplicationPage };
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProcessApplicationPage = void 0;
4
+ const test_1 = require("@playwright/test");
5
+ const submitModalWithRetry_1 = require("../../utils/assertionHelpers/submitModalWithRetry");
6
+ // Since camunda/camunda-hub#25831 a process application is a first-class
7
+ // container rather than a folder, and a workspace root ("project" in today's
8
+ // UI) holds nothing but process applications and IDP applications. Every file
9
+ // and folder this suite creates therefore has to live inside a process
10
+ // application. This page object owns that container's surface only; entering
11
+ // and leaving it is driven from ModelerHomePage so the ~150 existing spec call
12
+ // sites keep working unchanged.
13
+ class ProcessApplicationPage {
14
+ page;
15
+ // Empty workspace root: a plain primary button rendered next to the "Create
16
+ // new" menu (hub's EmptyStateActionButtons).
17
+ createProcessApplicationButton;
18
+ // Non-empty root: the item inside the "Create new" menu. Hub passes
19
+ // hideProcessApplication at workspace level, so this is the fallback rather
20
+ // than the primary path -- its own unit test asserts the item is absent
21
+ // there. Kept because the Hub PR is still moving this surface.
22
+ createProcessApplicationOption;
23
+ creationDialog;
24
+ nameInput;
25
+ submitButton;
26
+ cancelButton;
27
+ breadcrumb;
28
+ folderExplorer;
29
+ titleBar;
30
+ createNewDropdown;
31
+ inlineNameInput;
32
+ constructor(page) {
33
+ this.page = page;
34
+ // .first() defensively only: hub renders exactly one of these today, in the
35
+ // workspace-root empty state. A future second placement should not turn
36
+ // every PA-creating test into a strict-mode violation.
37
+ this.createProcessApplicationButton = page
38
+ .getByRole('button', { name: 'Create process application' })
39
+ .first();
40
+ this.createProcessApplicationOption = page.locator('[data-test="create-process-application"]');
41
+ this.creationDialog = page.getByRole('dialog', {
42
+ name: 'Create a process application',
43
+ });
44
+ // Deliberately scoped to the dialog: ModelerCreatePage owns an unscoped
45
+ // getByLabel('Name', {exact: true}) for the properties panel, which would
46
+ // resolve to two elements while the creation modal is open.
47
+ this.nameInput = this.creationDialog.getByLabel('Name', { exact: true });
48
+ this.submitButton = this.creationDialog.getByRole('button', {
49
+ name: 'Create',
50
+ exact: true,
51
+ });
52
+ this.cancelButton = this.creationDialog.getByRole('button', {
53
+ name: 'Cancel',
54
+ exact: true,
55
+ });
56
+ this.breadcrumb = page.locator('[data-test="breadcrumb-process-application-menu"]');
57
+ // The Design System shell renames this region "Resources"; the Carbon shell
58
+ // calls it "Folder explorer". Both hold the resource table and its toolbar,
59
+ // so matching either keeps createNewDropdown below correctly scoped.
60
+ this.folderExplorer = page
61
+ .getByRole('region', { name: 'Folder explorer' })
62
+ .or(page.getByRole('region', { name: 'Resources' }))
63
+ .first();
64
+ // Design System proof that we are on a process application page: the
65
+ // Carbon-era breadcrumb hook is gone under that shell, the same way
66
+ // breadcrumb-project is.
67
+ this.titleBar = page.locator('[data-test="process-application-title-bar"]');
68
+ // The process application page renders more than one diagram-dropdown
69
+ // (hub's own unit tests reach for it with getAllByTestId), so the dropdown
70
+ // has to be resolved inside the folder explorer rather than page-wide.
71
+ this.createNewDropdown = this.folderExplorer
72
+ .locator('[data-test="diagram-dropdown"]')
73
+ .first();
74
+ this.inlineNameInput = page.locator('[data-test="editable-input"]');
75
+ }
76
+ // Any one of the title bar, the resource region or the breadcrumb proves we
77
+ // are on the process application page. Three branches because the Design
78
+ // System and Carbon shells expose different subsets: only the title bar is
79
+ // present under both. .first() because several match once it has rendered.
80
+ pageReady() {
81
+ return this.titleBar.or(this.folderExplorer).or(this.breadcrumb).first();
82
+ }
83
+ async waitForProcessApplication(timeout = 90000) {
84
+ await (0, test_1.expect)(this.pageReady()).toBeVisible({ timeout });
85
+ }
86
+ async clickCreateProcessApplicationButton() {
87
+ await (0, test_1.expect)(this.createProcessApplicationButton).toBeVisible({
88
+ timeout: 60000,
89
+ });
90
+ await this.createProcessApplicationButton.click({ timeout: 60000 });
91
+ }
92
+ async clickCreateProcessApplicationOption() {
93
+ await (0, test_1.expect)(this.createProcessApplicationOption).toBeVisible({
94
+ timeout: 60000,
95
+ });
96
+ await this.createProcessApplicationOption.click({ timeout: 60000 });
97
+ }
98
+ // Hub creates a process application through a modal today. It used an inline
99
+ // editable title before, and #27593 is still moving this surface, so the
100
+ // inline path is kept as a fallback — this is the one method that has to
101
+ // change if naming moves back inline.
102
+ async nameNewProcessApplication(name) {
103
+ const isModal = await this.creationDialog
104
+ .waitFor({ state: 'visible', timeout: 15000 })
105
+ .then(() => true)
106
+ .catch(() => false);
107
+ if (isModal) {
108
+ await this.nameInput.click({ timeout: 30000 });
109
+ await this.nameInput.fill(name);
110
+ await (0, test_1.expect)(this.nameInput).toHaveValue(name, { timeout: 10000 });
111
+ await (0, submitModalWithRetry_1.submitModalWithRetry)(this.submitButton, this.creationDialog);
112
+ await this.waitForProcessApplication();
113
+ return;
114
+ }
115
+ await (0, test_1.expect)(this.inlineNameInput).toBeVisible({ timeout: 30000 });
116
+ await this.inlineNameInput.click({ timeout: 60000 });
117
+ await this.inlineNameInput.fill(name);
118
+ await this.inlineNameInput.press('Enter');
119
+ await this.waitForProcessApplication();
120
+ }
121
+ async openByName(name) {
122
+ const processApplication = this.page
123
+ .getByRole('row')
124
+ .filter({ hasText: name })
125
+ .getByTitle(name)
126
+ .first();
127
+ await (0, test_1.expect)(processApplication).toBeVisible({ timeout: 90000 });
128
+ await processApplication.click({ timeout: 60000 });
129
+ await this.waitForProcessApplication();
130
+ }
131
+ }
132
+ exports.ProcessApplicationPage = ProcessApplicationPage;
@@ -416,6 +416,14 @@ async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modeler
416
416
  timeout: 60000,
417
417
  });
418
418
  await connectorMarketplacePage.downloadConnectorToProject();
419
+ // Both lookups are container-relative: clickProjectBreadcrumb() returns to
420
+ // this test's process application, which is where the uploaded diagram
421
+ // lives. The downloaded element template is the open question -- hub
422
+ // publishes element templates to the workspace, but the marketplace
423
+ // download is initiated from inside the container, so it should land there.
424
+ // If a trace shows the template at workspace root instead, the first of
425
+ // these two calls becomes clickWorkspaceBreadcrumb() followed by
426
+ // returnToResourceContainer() before the diagram is reopened.
419
427
  await modelerHomePage.clickProjectBreadcrumb();
420
428
  await modelerHomePage.clickProcessDiagram('REST Outbound Connector');
421
429
  await connectorTemplatePage.publishConnector();
@@ -125,7 +125,7 @@ _8_10_1.test.describe('User Roles User Flow', () => {
125
125
  await modelerCreatePage.clickAppendEndEventButton();
126
126
  await (0, sleep_1.sleep)(20000);
127
127
  await modelerCreatePage.runProcessInstance(clusterName);
128
- await (0, test_1.expect)(page.getByText('The diagram failed to deploy & run')).toBeVisible({ timeout: 60000 });
128
+ await (0, test_1.expect)(page.getByText(/The (diagram|application) failed to deploy & run/)).toBeVisible({ timeout: 60000 });
129
129
  await modelerCreatePage.clickCloseButton();
130
130
  });
131
131
  });
@@ -216,7 +216,7 @@ _8_10_1.test.describe('User Roles User Flow', () => {
216
216
  await modelerCreatePage.clickAppendEndEventButton();
217
217
  await (0, sleep_1.sleep)(20000);
218
218
  await modelerCreatePage.runProcessInstance(clusterName, '', {}, '', false);
219
- await (0, test_1.expect)(page.getByText('The diagram failed to deploy & run')).toBeVisible({ timeout: 60000 });
219
+ await (0, test_1.expect)(page.getByText(/The (diagram|application) failed to deploy & run/)).toBeVisible({ timeout: 60000 });
220
220
  await modelerCreatePage.clickCloseButton();
221
221
  });
222
222
  });
@@ -312,7 +312,7 @@ _8_10_1.test.describe('User Roles User Flow', () => {
312
312
  await modelerCreatePage.clickAppendEndEventButton();
313
313
  await (0, sleep_1.sleep)(20000);
314
314
  await modelerCreatePage.runProcessInstance(clusterName);
315
- await (0, test_1.expect)(page.getByText('The diagram failed to deploy & run')).not.toBeVisible({ timeout: 60000 });
315
+ await (0, test_1.expect)(page.getByText(/The (diagram|application) failed to deploy & run/)).not.toBeVisible({ timeout: 60000 });
316
316
  await (0, test_1.expect)(modelerCreatePage.viewProcessInstanceLink).toBeVisible({
317
317
  timeout: 120000,
318
318
  });
@@ -95,7 +95,9 @@ _8_10_1.test.describe('IDP User Flow Tests', () => {
95
95
  await modelerHomePage.clickCrossComponentProjectFolder();
96
96
  });
97
97
  await _8_10_1.test.step('Add an IDP application to the project', async () => {
98
- await modelerHomePage.clickDiagramTypeDropdown();
98
+ // Workspace-level menu: an IDP application can only be created at
99
+ // workspace root, never inside a process application.
100
+ await modelerHomePage.clickWorkspaceDiagramTypeDropdown();
99
101
  await modelerHomePage.clickIdpApplicationTemplateOption();
100
102
  });
101
103
  await _8_10_1.test.step('Creates a document extraction template', async () => {
@@ -168,7 +170,9 @@ _8_10_1.test.describe('IDP User Flow Tests', () => {
168
170
  await modelerHomePage.clickCrossComponentProjectFolder();
169
171
  });
170
172
  await _8_10_1.test.step('Add an IDP application to the project', async () => {
171
- await modelerHomePage.clickDiagramTypeDropdown();
173
+ // Workspace-level menu: an IDP application can only be created at
174
+ // workspace root, never inside a process application.
175
+ await modelerHomePage.clickWorkspaceDiagramTypeDropdown();
172
176
  await modelerHomePage.clickIdpApplicationTemplateOption();
173
177
  });
174
178
  await _8_10_1.test.step('Creates a document extraction template', async () => {
@@ -249,7 +253,9 @@ _8_10_1.test.describe('IDP User Flow Tests', () => {
249
253
  await modelerHomePage.clickCrossComponentProjectFolder();
250
254
  });
251
255
  await _8_10_1.test.step('Add an IDP application to the project', async () => {
252
- await modelerHomePage.clickDiagramTypeDropdown();
256
+ // Workspace-level menu: an IDP application can only be created at
257
+ // workspace root, never inside a process application.
258
+ await modelerHomePage.clickWorkspaceDiagramTypeDropdown();
253
259
  await modelerHomePage.clickIdpApplicationTemplateOption();
254
260
  });
255
261
  await _8_10_1.test.step('Creates a classification template', async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1008",
3
+ "version": "0.0.1010",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",