@camunda/e2e-test-suite 0.0.885 → 0.0.887

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.
@@ -90,8 +90,12 @@ class ClusterDetailsPage {
90
90
  this.rbaDisableButton = page.getByRole('button', { name: 'Disable' });
91
91
  this.dialog = page.getByRole('dialog');
92
92
  this.deleteButton = page.getByRole('button', { name: 'Delete' });
93
- this.deleteSubButton = page.getByRole('button', {
94
- name: 'danger Delete',
93
+ // The danger button in Console's confirmation modals is now named just
94
+ // "Delete" (it used to expose "danger Delete"), so scope to the open
95
+ // dialog to keep it distinct from the per-row Delete buttons behind it.
96
+ this.deleteSubButton = this.dialog.getByRole('button', {
97
+ name: 'Delete',
98
+ exact: true,
95
99
  });
96
100
  this.createClientCredentialsDialog = page.getByRole('dialog', {
97
101
  name: 'Create new client credentials',
@@ -40,9 +40,10 @@ class ClusterSecretsPage {
40
40
  name: 'Delete',
41
41
  exact: true,
42
42
  });
43
- this.deleteConnectorSecretSubButton = page.getByRole('button', {
44
- name: 'danger Delete',
45
- });
43
+ // See ClusterDetailsPage: the modal's danger button is now named "Delete".
44
+ this.deleteConnectorSecretSubButton = page
45
+ .getByRole('dialog')
46
+ .getByRole('button', { name: 'Delete', exact: true });
46
47
  this.dialog = page.getByRole('dialog');
47
48
  this.importButton = page.getByRole('button', { name: 'Import', exact: true });
48
49
  this.fromFileButton = page.getByText('from File', { exact: true });
@@ -31,6 +31,7 @@ declare class ModelerCreatePage {
31
31
  readonly createTask: Locator;
32
32
  readonly createEndEvent: Locator;
33
33
  readonly canvas: Locator;
34
+ readonly zoomOutButton: Locator;
34
35
  readonly endEventCanvas: Locator;
35
36
  readonly connectToOtherElementButton: Locator;
36
37
  readonly firstPlacedElement: Locator;
@@ -162,6 +163,8 @@ declare class ModelerCreatePage {
162
163
  clickDeploySubButtonWithRetry(clusterName: string): Promise<void>;
163
164
  clickCreateTask(): Promise<void>;
164
165
  clickCreateEndEvent(): Promise<void>;
166
+ fitElementIntoCanvas(element: Locator, margin?: number, maxZoomOutSteps?: number): Promise<void>;
167
+ clickShapeBelowContextPad(element: Locator): Promise<void>;
165
168
  clickCanvas(): Promise<void>;
166
169
  clickEndEventCanvas(): Promise<void>;
167
170
  clickConnectToOtherElementButton(): Promise<void>;
@@ -37,6 +37,7 @@ class ModelerCreatePage {
37
37
  createTask;
38
38
  createEndEvent;
39
39
  canvas;
40
+ zoomOutButton;
40
41
  endEventCanvas;
41
42
  connectToOtherElementButton;
42
43
  firstPlacedElement;
@@ -121,7 +122,11 @@ class ModelerCreatePage {
121
122
  name: 'Change element',
122
123
  exact: true,
123
124
  });
124
- this.userTaskOption = page.getByRole('option', { name: 'User task' });
125
+ // The popup also lists the project's deployed resources
126
+ // (`data-id="resources-replace-bpmnProcess-N"`) labelled with the diagram
127
+ // name, so a role+name match on 'User task' is ambiguous as soon as a
128
+ // diagram is called e.g. "Optimize Job Worker User Task Diagram".
129
+ this.userTaskOption = page.locator('.djs-popup-results [data-id="replace-with-user-task"]');
125
130
  this.priorityInput = page.getByRole('textbox', { name: 'priority' });
126
131
  this.appendEndEventButton = page.getByRole('button', {
127
132
  name: 'Append end event',
@@ -157,10 +162,13 @@ class ModelerCreatePage {
157
162
  this.deploySubButton = page.locator('[data-test="deploy-action"]');
158
163
  this.cancelButton = page.getByRole('button', { name: 'Cancel' });
159
164
  this.restConnectorOption = page.locator('[data-id="replace.template-io.camunda.connectors.HttpJson.v2"]');
160
- this.webhookMessageStartEventConnectorOption = page.getByRole('listitem', {
161
- name: 'Webhook Message Start Event Connector',
162
- exact: true,
163
- });
165
+ // bpmn-js popup entries are `li[role="option"]` inside a `role="listbox"`,
166
+ // so getByRole('listitem') no longer matches. Their accessible name also
167
+ // includes the entry description, and three entries share the label
168
+ // ("GitHub …", "Slack …", plain "Webhook …"), so name matching is
169
+ // ambiguous. Anchor on the entry's data-id — the same selector the hub's
170
+ // own e2e suite uses (`.djs-popup-results [data-id="<entryId>"]`).
171
+ this.webhookMessageStartEventConnectorOption = page.locator('.djs-popup-results [data-id="replace.template-io.camunda.connectors.webhook.WebhookConnectorStartMessage.v1"]');
164
172
  this.webhookTab = page.getByRole('tab', { name: 'Webhook' });
165
173
  this.webhookIsActiveButton = page.getByRole('button', {
166
174
  name: 'Webhook is active in Test',
@@ -172,7 +180,8 @@ class ModelerCreatePage {
172
180
  .first();
173
181
  this.createTask = page.getByTitle('Create task');
174
182
  this.createEndEvent = page.getByTitle('Create end event');
175
- this.canvas = page.locator('rect').nth(1);
183
+ this.canvas = page.locator('.djs-container');
184
+ this.zoomOutButton = page.locator('[data-test="zoom-out"]');
176
185
  this.endEventCanvas = page.locator('[class="bjs-container"]');
177
186
  this.connectToOtherElementButton = page.getByRole('button', {
178
187
  name: 'Connect to other element',
@@ -195,9 +204,7 @@ class ModelerCreatePage {
195
204
  this.intermediateBoundaryEvent = page.getByRole('button', {
196
205
  name: 'Append intermediate/boundary',
197
206
  });
198
- this.intermediateWebhookConnectorOption = page.getByRole('listitem', {
199
- name: 'Webhook Intermediate Event',
200
- });
207
+ this.intermediateWebhookConnectorOption = page.locator('.djs-popup-results [data-id="replace.template-io.camunda.connectors.webhook.WebhookConnectorIntermediate.v1"]');
201
208
  this.correlationKeyPayloadInput = page.getByLabel('Correlation key (payload)');
202
209
  this.correlationKeyProcessInput = page.getByLabel('Correlation key (process)');
203
210
  this.form = page.locator('[class="fjs-container"]');
@@ -239,7 +246,7 @@ class ModelerCreatePage {
239
246
  this.secondPlacedGateway = page
240
247
  .locator('[data-element-id*="Gateway"]')
241
248
  .last();
242
- this.serviceTaskOption = page.getByRole('option', { name: 'Service task' });
249
+ this.serviceTaskOption = page.locator('.djs-popup-results [data-id="replace-with-service-task"]');
243
250
  this.taskDefinitionPanel = page.locator('[data-group-id="group-taskDefinition"]');
244
251
  this.jobTypeInput = page.getByRole('textbox', { name: /job type/i });
245
252
  this.playTab = page.getByRole('tab', {
@@ -281,10 +288,7 @@ class ModelerCreatePage {
281
288
  .getByText('zeebeClientId');
282
289
  this.variableAssignmentValueTextboxThirdVariable = page.locator('#bio-properties-panel-StartEvent_1-output-2-source div');
283
290
  this.connectorsDocHandlingStartEventElement = page.locator('g:nth-child(5) > .djs-element > .djs-hit');
284
- this.timerEventOption = page.getByRole('listitem', {
285
- name: 'Timer intermediate catch event',
286
- exact: true,
287
- });
291
+ this.timerEventOption = page.locator('.djs-popup-results [data-id="replace-with-timer-intermediate-catch"]');
288
292
  this.timerEventSettings = page.getByText(/^Timer$/).first();
289
293
  this.timerType = page.getByLabel('Type');
290
294
  this.timerValue = page.getByLabel('Value');
@@ -719,8 +723,45 @@ class ModelerCreatePage {
719
723
  async clickCreateEndEvent() {
720
724
  await this.createEndEvent.click({ timeout: 60000 });
721
725
  }
726
+ // The canvas does not scroll with the DOM, so an element the diagram has
727
+ // pushed past the canvas edge cannot be clicked at all — the hit test returns
728
+ // the canvas container (or the panel toggle bar beside it). Zoom out until
729
+ // the element and one element-width of margin fit inside the canvas.
730
+ async fitElementIntoCanvas(element, margin = 120, maxZoomOutSteps = 3) {
731
+ for (let step = 0; step < maxZoomOutSteps; step++) {
732
+ const canvasBox = await this.canvas.boundingBox();
733
+ const elementBox = await element.boundingBox();
734
+ if (canvasBox === null || elementBox === null) {
735
+ return;
736
+ }
737
+ const elementRightEdge = elementBox.x + elementBox.width + margin;
738
+ if (elementRightEdge <= canvasBox.x + canvasBox.width) {
739
+ return;
740
+ }
741
+ await this.zoomOutButton.click({ timeout: 30000 });
742
+ }
743
+ }
744
+ // A context pad is a fixed-size strip anchored to the top-right of its
745
+ // element, so once the diagram is zoomed out it can reach across the gap and
746
+ // cover the top of the next shape. Click the bottom edge of the target, below
747
+ // the strip, so a neighbour's open pad cannot swallow the click.
748
+ async clickShapeBelowContextPad(element) {
749
+ const box = await element.boundingBox();
750
+ if (box === null) {
751
+ await element.click({ timeout: 60000 });
752
+ return;
753
+ }
754
+ await element.click({
755
+ timeout: 60000,
756
+ position: { x: box.width / 2, y: box.height - 2 },
757
+ });
758
+ }
722
759
  async clickCanvas() {
723
- await this.canvas.click({ timeout: 60000 });
760
+ // Clicking the canvas centre lands on a shape (or an open create pad) as
761
+ // soon as the diagram has more than a couple of elements, and the click is
762
+ // then intercepted instead of clearing the selection. Click the empty
763
+ // gutter above the diagram and right of the palette instead.
764
+ await this.canvas.click({ timeout: 60000, position: { x: 150, y: 25 } });
724
765
  }
725
766
  async clickEndEventCanvas() {
726
767
  await this.endEventCanvas.click({ timeout: 60000 });
@@ -965,16 +1006,22 @@ class ModelerCreatePage {
965
1006
  }
966
1007
  async clickSecondPlacedGateway(userTaskId = '') {
967
1008
  try {
968
- await this.secondPlacedGateway.click({ timeout: 60000 });
1009
+ await this.clickShapeBelowContextPad(this.secondPlacedGateway);
969
1010
  }
970
1011
  catch (error) {
971
1012
  await this.page.reload();
972
1013
  await (0, sleep_1.sleep)(10000);
1014
+ // The reload resets the canvas viewbox to the origin, discarding the
1015
+ // auto-scroll that kept the right-most gateway on screen.
1016
+ await this.fitElementIntoCanvas(this.secondPlacedGateway);
1017
+ // Clear any selection the reload restored, so its context pad is closed
1018
+ // before the gateway is clicked.
1019
+ await this.clickCanvas();
973
1020
  if (userTaskId != '') {
974
1021
  await this.clickUserTask(userTaskId);
975
1022
  await this.clickConnectToOtherElementButton();
976
1023
  }
977
- await this.secondPlacedGateway.click({ timeout: 60000 });
1024
+ await this.clickShapeBelowContextPad(this.secondPlacedGateway);
978
1025
  }
979
1026
  }
980
1027
  async addParallelUserTasks(numberOfTasks, taskName) {
@@ -1021,6 +1068,7 @@ class ModelerCreatePage {
1021
1068
  await this.clickCanvas();
1022
1069
  await (0, sleep_1.sleep)(1000);
1023
1070
  }
1071
+ await this.fitElementIntoCanvas(this.secondPlacedGateway);
1024
1072
  await this.clickSecondPlacedGateway();
1025
1073
  }
1026
1074
  async clickServiceTaskOption() {
@@ -102,7 +102,7 @@ class ModelerCreatePage {
102
102
  this.elemendIdInput = page.getByLabel('ID', { exact: true });
103
103
  this.startEventElement = page.locator('.djs-hit').first();
104
104
  this.appendPreButton = page.locator('.djs-create-pad-icon > svg').first();
105
- this.appendTaskButton = page.getByTitle('Append task');
105
+ this.appendTaskButton = page.locator('.djs-create-pad-entry[title="Append task"], .djs-create-pad-entry[aria-label="Append task"]');
106
106
  this.changeTypeButton = page.getByRole('button', {
107
107
  name: 'Change element',
108
108
  exact: true,
@@ -112,7 +112,7 @@ class ModelerCreatePage {
112
112
  .locator('span')
113
113
  .first();
114
114
  this.serviceTaskOption = page.getByRole('listitem', { name: 'Service Task' });
115
- this.appendEndEventButton = page.getByTitle('Append end event');
115
+ this.appendEndEventButton = page.locator('.djs-create-pad-entry[title="Append end event"], .djs-create-pad-entry[aria-label="Append end event"]');
116
116
  this.appendGatewayButton = page.getByTitle('append gateway');
117
117
  this.parallelGatewayOption = page.getByText('parallel gateway');
118
118
  this.dialog = page.getByRole('dialog');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.885",
3
+ "version": "0.0.887",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",