@camunda/e2e-test-suite 0.0.1255 → 0.0.1257

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.
@@ -75,6 +75,7 @@ declare class ModelerHomePage {
75
75
  clickCreateIdpApplicationButton(): Promise<void>;
76
76
  clickCrossComponentProjectFolder(): Promise<void>;
77
77
  private waitForCrossComponentProjectFolder;
78
+ showAllWorkspaces(probeTimeout: number): Promise<void>;
78
79
  createCrossComponentProjectFolder(): Promise<void>;
79
80
  clickManageButton(retries?: number): Promise<void>;
80
81
  clickUploadFilesButton(): Promise<void>;
@@ -744,6 +744,13 @@ class ModelerHomePage {
744
744
  // so on its own it closes the banner and leaves the dialog open.
745
745
  await this.dismissBlockingDialog();
746
746
  await this.clickMessageBanner();
747
+ // postAction's reload resets Hub's scope filter to "My workspaces".
748
+ // Let a failed scope switch propagate like dismissBlockingDialog()
749
+ // and clickMessageBanner() above -- clickLocatorWithRetry's own
750
+ // preAction handling already logs and retries it; swallowing it here
751
+ // would otherwise leave the tile wait running against the wrong
752
+ // ("My workspaces") scope for its full visibilityTimeout.
753
+ await this.showAllWorkspaces(5000);
747
754
  },
748
755
  postAction: async () => {
749
756
  // The project tile only renders on the Modeler home page. A failure
@@ -770,6 +777,7 @@ class ModelerHomePage {
770
777
  // breaks every later run for that user.
771
778
  async waitForCrossComponentProjectFolder() {
772
779
  for (let attempt = 0; attempt < 2; attempt++) {
780
+ await this.showAllWorkspaces(10000);
773
781
  const found = await this.crossComponentProjectFolder
774
782
  .waitFor({ state: 'visible', timeout: 60000 })
775
783
  .then(() => true)
@@ -778,11 +786,40 @@ class ModelerHomePage {
778
786
  return true;
779
787
  if (attempt === 0) {
780
788
  await this.page.reload();
781
- await this.page.waitForLoadState('networkidle').catch(() => { });
789
+ // Bounded: Hub keeps background requests open, so an unbounded
790
+ // networkidle wait never settled and hung here for ~7 minutes until
791
+ // the test timeout (run 36372848529).
792
+ await this.page
793
+ .waitForLoadState('networkidle', { timeout: 15000 })
794
+ .catch(() => { });
782
795
  }
783
796
  }
784
797
  return false;
785
798
  }
799
+ // Since camunda-hub #28956 the Workspaces overview defaults org-elevated
800
+ // users to "My workspaces" -- only workspaces they are an explicit member
801
+ // of -- and resets to it on every load. The shared folder is created by
802
+ // whichever test user wins the race, so every other user sees "No
803
+ // workspaces match this filter" and never finds it. Widen the scope to
804
+ // "All workspaces" first. The control is absent outside Hub and for
805
+ // non-elevated users (their list is membership-scoped anyway), so a missing
806
+ // control is a no-op.
807
+ async showAllWorkspaces(probeTimeout) {
808
+ const scopeFilter = this.page.getByRole('combobox', {
809
+ name: 'Filter workspaces',
810
+ });
811
+ if (!(await this.becameVisible(scopeFilter, probeTimeout)))
812
+ return;
813
+ if ((await scopeFilter.innerText()).includes('All workspaces'))
814
+ return;
815
+ await scopeFilter.click({ timeout: 10000 });
816
+ await this.page
817
+ .getByRole('option', { name: 'All workspaces' })
818
+ .click({ timeout: 10000 });
819
+ await (0, test_1.expect)(scopeFilter).toContainText('All workspaces', {
820
+ timeout: 10000,
821
+ });
822
+ }
786
823
  // Retries the whole detect-or-create sequence, not just its individual
787
824
  // steps. Up to 27 test-user workers race to create/open this one shared
788
825
  // workspace concurrently, and a losing worker can land on a workspace-root
@@ -193,6 +193,8 @@ _8_10_1.test.describe('Cluster Setup Tests', () => {
193
193
  // than the 100% follower failure the leader-election attempt caused.
194
194
  await modelerHomePage.createCrossComponentProjectFolder();
195
195
  await modelerHomePage.clickHomeBreadcrumb();
196
+ // Hub resets the overview to "My workspaces" on every load.
197
+ await modelerHomePage.showAllWorkspaces(10000);
196
198
  await (0, test_1.expect)(modelerHomePage.crossComponentProjectFolder).toBeVisible({ timeout: 60000 });
197
199
  });
198
200
  });
@@ -6,6 +6,7 @@ const assertions_1 = require("../../../../utils/api/assertions");
6
6
  const deployments_1 = require("../../../../utils/api/deployments");
7
7
  const bpmn_1 = require("../../../../utils/api/bpmn");
8
8
  const eventually_1 = require("../../../../utils/api/eventually");
9
+ const config_1 = require("../../../../utils/api/config");
9
10
  const capabilities_1 = require("../../../../utils/api/capabilities");
10
11
  const keys_1 = require("../../../../utils/api/keys");
11
12
  api_1.test.describe('Deployments', () => {
@@ -124,11 +125,16 @@ api_1.test.describe('Resource deletion', () => {
124
125
  body: {},
125
126
  tenant: 'none',
126
127
  });
127
- // The endpoint answers 200 with a `DeleteResourceResponse` body naming
128
- // the deleted resource (and the batch operation that clears its history),
129
- // not a bare 204.
130
- const deletion = (await (0, assertions_1.assertOk)(response));
131
- (0, test_1.expect)(String(deletion.resourceKey)).toBe(key);
128
+ // From 8.9 the endpoint answers 200 with a `DeleteResourceResponse` body
129
+ // naming the deleted resource (and the batch operation that clears its
130
+ // history). 8.8 has no response body and answers a bare 204.
131
+ if ((0, config_1.atLeastVersion)('8.9')) {
132
+ const deletion = (await (0, assertions_1.assertOk)(response));
133
+ (0, test_1.expect)(String(deletion.resourceKey)).toBe(key);
134
+ }
135
+ else {
136
+ await (0, assertions_1.assertNoContent)(response);
137
+ }
132
138
  // The test is the deletion, so cleanup has nothing left to do.
133
139
  resources.forget('resource', key);
134
140
  await (0, eventually_1.eventually)(async () => {
@@ -135,7 +135,9 @@ api_1.test.describe('Groups', () => {
135
135
  (0, api_1.test)('rejects updating an absent group', async ({ api }) => {
136
136
  const response = await api.put('/groups/{groupId}', {
137
137
  params: { groupId: (0, bpmn_1.uniqueId)('absent-group') },
138
- body: { name: 'does not exist' },
138
+ // 8.8 requires `description` on update and rejects the body with 400
139
+ // before the group is looked up.
140
+ body: { name: 'does not exist', description: 'does not exist' },
139
141
  tenant: 'none',
140
142
  });
141
143
  await (0, assertions_1.assertNotFound)(response);
@@ -137,7 +137,10 @@ api_1.test.describe('Process instances', () => {
137
137
  const key = instance.processInstanceKey;
138
138
  resources.track('processInstance', key);
139
139
  await (0, eventually_1.eventually)(async () => {
140
- const response = await api.post('/process-instances/{processInstanceKey}/incidents/search', { params: { processInstanceKey: key }, body: { filter: {} } });
140
+ const response = await api.post('/process-instances/{processInstanceKey}/incidents/search',
141
+ // 8.8's per-instance incident query has no `filter` property and
142
+ // rejects one with 400, so none is sent.
143
+ { params: { processInstanceKey: key }, body: {} });
141
144
  await (0, assertions_1.assertPaginated)(response, { exactItems: 0 });
142
145
  });
143
146
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1255",
3
+ "version": "0.0.1257",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",