@camunda/e2e-test-suite 0.0.1183 → 0.0.1185

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.
@@ -12,6 +12,7 @@ declare class ModelerHomePage {
12
12
  readonly createWorkspaceButton: Locator;
13
13
  readonly workspaceOpenButton: Locator;
14
14
  readonly noWorkspacesHeading: Locator;
15
+ readonly noRouteMatchMessage: Locator;
15
16
  readonly workspaceWizardHeading: Locator;
16
17
  readonly workspaceNameInput: Locator;
17
18
  readonly workspaceDescriptionInput: Locator;
@@ -51,8 +52,14 @@ declare class ModelerHomePage {
51
52
  enterNewProjectName(name: string): Promise<void>;
52
53
  private createWorkspaceViaWizard;
53
54
  waitForModelerReady(timeoutMs?: number): Promise<void>;
54
- createCrossComponentProjectFolder(): Promise<void>;
55
- clickCrossComponentProjectFolder(): Promise<void>;
55
+ createCrossComponentProjectFolder(credentials?: {
56
+ username: string;
57
+ password: string;
58
+ }): Promise<void>;
59
+ clickCrossComponentProjectFolder(credentials?: {
60
+ username: string;
61
+ password: string;
62
+ }): Promise<void>;
56
63
  private ensureWorkspaceOpen;
57
64
  private gotoWorkspacesOverview;
58
65
  private createWorkspace;
@@ -39,6 +39,8 @@ class ModelerHomePage {
39
39
  createWorkspaceButton;
40
40
  workspaceOpenButton;
41
41
  noWorkspacesHeading;
42
+ // Router 404: a flag-off deployment has no `/workspaces` route.
43
+ noRouteMatchMessage;
42
44
  workspaceWizardHeading;
43
45
  workspaceNameInput;
44
46
  workspaceDescriptionInput;
@@ -205,6 +207,7 @@ class ModelerHomePage {
205
207
  this.noWorkspacesHeading = page.getByRole('heading', {
206
208
  name: /no workspaces/i,
207
209
  });
210
+ this.noRouteMatchMessage = page.getByText(/no match for the current location/i);
208
211
  // Create-workspace wizard (`/workspaces/create`). Its single primary button
209
212
  // relabels itself "Next" -> "Create workspace" as the step changes, so it is
210
213
  // located by the stable data-test hook rather than its changing name.
@@ -305,30 +308,55 @@ class ModelerHomePage {
305
308
  // deadlocks: it never appears while the modal is up, and the dismissal in
306
309
  // clickMessageBanner/clickCreateNewProjectButton only runs after this wait.
307
310
  // Dismiss the modal on each poll until the workspace element mounts.
308
- await (0, test_1.expect)(async () => {
309
- await this.clickMessageBanner();
310
- await (0, test_1.expect)(workspaceElement).toBeVisible({ timeout: 5000 });
311
- }).toPass({ timeout: timeoutMs, intervals: [1000, 2000, 5000] });
311
+ try {
312
+ await (0, test_1.expect)(async () => {
313
+ await this.clickMessageBanner();
314
+ await (0, test_1.expect)(workspaceElement).toBeVisible({ timeout: 5000 });
315
+ }).toPass({ timeout: timeoutMs, intervals: [1000, 2000, 5000] });
316
+ }
317
+ catch (error) {
318
+ // Re-label the timeout with the real cause; "element(s) not found" reads
319
+ // as a slow-loading project list. Outside the poll because toPass()
320
+ // retries thrown errors.
321
+ if (await this.noRouteMatchMessage.isVisible().catch(() => false)) {
322
+ throw new Error(`Web Modeler served a router 404 ("No match for the current location") for ${this.page.url()}. ` +
323
+ 'The route does not exist in this deployment -- e.g. /workspaces on a ' +
324
+ 'build where the Workspaces feature flag (workspacesEnabled) is off.');
325
+ }
326
+ throw error;
327
+ }
312
328
  }
313
- async createCrossComponentProjectFolder() {
329
+ // `credentials`: the identity already logged in on this page (e.g. the RBA/
330
+ // multi-tenancy test user a preceding goToModeler(undefined, credentials)
331
+ // authenticated as). Only needed if that identity is not the default
332
+ // Identity first user -- pass it through so a flag-off fallback re-navigation
333
+ // doesn't silently switch principals mid-test.
334
+ async createCrossComponentProjectFolder(credentials) {
314
335
  // Kept name: opens (creating if absent) the shared Workspace this suite puts
315
336
  // every test's Project inside, leaving the browser on the Workspace's
316
337
  // projects listing. The flag-off era created a top-level project folder here;
317
338
  // under flag-on that folder maps to a Workspace.
318
- await this.ensureWorkspaceOpen();
339
+ await this.ensureWorkspaceOpen(credentials);
319
340
  }
320
- async clickCrossComponentProjectFolder() {
341
+ async clickCrossComponentProjectFolder(credentials) {
321
342
  // Kept name: callers use this to (re-)enter the shared Workspace's projects
322
343
  // listing after leaving Modeler. Creates the Workspace if it is somehow
323
344
  // absent (e.g. a fresh cluster where the setup spec did not run first).
324
- await this.ensureWorkspaceOpen();
345
+ await this.ensureWorkspaceOpen(credentials);
325
346
  }
326
347
  // Ensures the shared "Cross Component Test Project" Workspace is open and the
327
348
  // browser is on its projects listing (`/workspaces/{wsId}/projects`), where the
328
349
  // per-test Project is later created. Retries the whole navigation+login on a
329
350
  // transient web-modeler 500 rather than a bare reload, which would drop the
330
351
  // authenticated SPA state and land on the empty login form.
331
- async ensureWorkspaceOpen() {
352
+ //
353
+ // `credentials` must be the identity already active on `page` (the caller's
354
+ // own goToModeler login), not a new one to log in as: the flag-off branch
355
+ // re-navigates mid-flow, and NavigationPage.goToModeler() defaults to the
356
+ // first Identity user when credentials are omitted, which would silently
357
+ // swap principals for RBA/multi-tenancy callers that authenticated as a
358
+ // specific test user before calling this.
359
+ async ensureWorkspaceOpen(credentials) {
332
360
  const maxAttempts = 3;
333
361
  const retryWaitMs = 5000;
334
362
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
@@ -339,13 +367,28 @@ class ModelerHomePage {
339
367
  // some builds does not auto-redirect to /workspaces. Navigating here
340
368
  // explicitly is robust whether or not the root redirect fires.
341
369
  await this.gotoWorkspacesOverview();
342
- await this.waitForModelerReady();
343
- await this.clickMessageBanner();
344
- const flagOn = await this.becameVisible(this.createWorkspaceButton.or(this.workspaceOpenButton).first(), 30000);
370
+ // Flag-off serves a router 404 here, not Home as this fallback once
371
+ // assumed. Neither the overview nor the legacy markers can render on a
372
+ // no-match page, so checking readiness first burned the full 120s and
373
+ // threw, leaving the flag-off branch below unreachable.
374
+ const routed404 = await this.becameVisible(this.noRouteMatchMessage, 5000);
375
+ // Still confirm an overview marker: waitForModelerReady() also accepts
376
+ // the legacy Home markers, so "no 404" alone is not proof of flag-on.
377
+ let flagOn = false;
378
+ if (!routed404) {
379
+ await this.waitForModelerReady();
380
+ await this.clickMessageBanner();
381
+ flagOn = await this.becameVisible(this.createWorkspaceButton.or(this.workspaceOpenButton).first(), 30000);
382
+ }
345
383
  if (!flagOn) {
346
384
  // Legacy flag-off deployment (e.g. a pre-upgrade version in a
347
- // migration flow): /workspaces is not a route, so the app served Home
348
- // instead, where the shared folder IS the top-level project.
385
+ // migration flow): the shared folder IS the top-level project. Must
386
+ // re-navigate — the legacy markers never appear on the 404 page.
387
+ // Pass through the caller's credentials so this doesn't fall back to
388
+ // the default Identity user mid-test (see the credentials note above).
389
+ await new NavigationPage_1.NavigationPage(this.page).goToModeler(undefined, credentials);
390
+ await this.waitForModelerReady();
391
+ await this.clickMessageBanner();
349
392
  await this.openOrCreateLegacyFolder();
350
393
  return;
351
394
  }
@@ -94,7 +94,7 @@ if (process.env.IS_MT === 'true') {
94
94
  });
95
95
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
96
96
  await navigationPage.goToModeler(undefined, credentials);
97
- await modelerHomePage.createCrossComponentProjectFolder();
97
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
98
98
  await modelerHomePage.clickDiagramTypeDropdown();
99
99
  await modelerHomePage.clickBpmnTemplateOption();
100
100
  });
@@ -222,7 +222,7 @@ if (process.env.IS_MT === 'true') {
222
222
  });
223
223
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
224
224
  await navigationPage.goToModeler(undefined, credentials);
225
- await modelerHomePage.createCrossComponentProjectFolder();
225
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
226
226
  await modelerHomePage.clickDiagramTypeDropdown();
227
227
  await modelerHomePage.clickBpmnTemplateOption();
228
228
  });
@@ -299,7 +299,7 @@ if (process.env.IS_MT === 'true') {
299
299
  });
300
300
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
301
301
  await navigationPage.goToModeler(undefined, credentials);
302
- await modelerHomePage.createCrossComponentProjectFolder();
302
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
303
303
  await modelerHomePage.clickDiagramTypeDropdown();
304
304
  await modelerHomePage.clickBpmnTemplateOption();
305
305
  });
@@ -107,7 +107,7 @@ if (node_process_1.default.env.IS_RBA === 'true') {
107
107
  await navigationPage.goToModeler(undefined, credentials);
108
108
  });
109
109
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
110
- await modelerHomePage.createCrossComponentProjectFolder();
110
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
111
111
  });
112
112
  await SM_8_10_1.test.step('Create Two BPMN Diagrams with User Task and Start Process Instance', async () => {
113
113
  await (0, UtilitiesPage_1.runMultipleProcesses)(page, modelerHomePage, modelerCreatePage, 2, processName, processName);
@@ -244,7 +244,7 @@ if (node_process_1.default.env.IS_RBA === 'true') {
244
244
  await navigationPage.goToModeler(undefined, credentials);
245
245
  });
246
246
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
247
- await modelerHomePage.createCrossComponentProjectFolder();
247
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
248
248
  });
249
249
  await SM_8_10_1.test.step('Create Two BPMN Diagrams with User Task and Start Process Instance', async () => {
250
250
  await (0, UtilitiesPage_1.runMultipleProcesses)(page, modelerHomePage, modelerCreatePage, 2, processName, processName);
@@ -389,7 +389,7 @@ if (node_process_1.default.env.IS_RBA === 'true') {
389
389
  await navigationPage.goToModeler(undefined, credentials);
390
390
  });
391
391
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
392
- await modelerHomePage.createCrossComponentProjectFolder();
392
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
393
393
  });
394
394
  await SM_8_10_1.test.step('Create Two BPMN Diagrams with User Task and Start Process Instance', async () => {
395
395
  await (0, UtilitiesPage_1.runMultipleProcesses)(page, modelerHomePage, modelerCreatePage, 2, processName, processName);
@@ -535,7 +535,7 @@ if (node_process_1.default.env.IS_RBA === 'true') {
535
535
  await navigationPage.goToModeler(undefined, credentials);
536
536
  });
537
537
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
538
- await modelerHomePage.createCrossComponentProjectFolder();
538
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
539
539
  });
540
540
  await SM_8_10_1.test.step('Create Two BPMN Diagrams with User Task and Start Process Instance', async () => {
541
541
  await (0, UtilitiesPage_1.runMultipleProcesses)(page, modelerHomePage, modelerCreatePage, 2, processName, processName);
@@ -659,7 +659,7 @@ if (node_process_1.default.env.IS_RBA === 'true') {
659
659
  await navigationPage.goToModeler(undefined, credentials);
660
660
  });
661
661
  await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
662
- await modelerHomePage.createCrossComponentProjectFolder();
662
+ await modelerHomePage.createCrossComponentProjectFolder(credentials);
663
663
  });
664
664
  await SM_8_10_1.test.step('Create Two BPMN Diagrams with User Task and Start Process Instance', async () => {
665
665
  await (0, UtilitiesPage_1.runMultipleProcesses)(page, modelerHomePage, modelerCreatePage, 2, processName, processName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1183",
3
+ "version": "0.0.1185",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",