@camunda/e2e-test-suite 0.0.968 → 0.0.969

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.
@@ -24,6 +24,9 @@ declare class ModelerCreatePage {
24
24
  readonly additionalActionsButton: Locator;
25
25
  readonly cancelButton: Locator;
26
26
  readonly restConnectorOption: Locator;
27
+ readonly changeElementSearchInput: Locator;
28
+ readonly changeElementTabStrip: Locator;
29
+ readonly reusableAssetsTab: Locator;
27
30
  readonly webhookMessageStartEventConnectorOption: Locator;
28
31
  readonly webhookTab: Locator;
29
32
  readonly webhookIsActiveButton: Locator;
@@ -154,6 +157,8 @@ declare class ModelerCreatePage {
154
157
  clickNewForm(): Promise<void>;
155
158
  clickDeploySubButton(): Promise<void>;
156
159
  clickCancelButton(): Promise<void>;
160
+ private waitForVisible;
161
+ revealChangeElementTemplate(option: Locator, searchTerm: string): Promise<void>;
157
162
  clickRestConnectorOption(): Promise<void>;
158
163
  clickWebhookStartEventConnectorOption(): Promise<void>;
159
164
  clickWebhookTab(): Promise<void>;
@@ -30,6 +30,9 @@ class ModelerCreatePage {
30
30
  additionalActionsButton;
31
31
  cancelButton;
32
32
  restConnectorOption;
33
+ changeElementSearchInput;
34
+ changeElementTabStrip;
35
+ reusableAssetsTab;
33
36
  webhookMessageStartEventConnectorOption;
34
37
  webhookTab;
35
38
  webhookIsActiveButton;
@@ -168,6 +171,12 @@ class ModelerCreatePage {
168
171
  this.deploySubButton = page.locator('[data-test="deploy-action"]');
169
172
  this.cancelButton = page.getByRole('button', { name: 'Cancel' });
170
173
  this.restConnectorOption = page.locator('[data-id="replace.template-io.camunda.connectors.HttpJson.v2"]');
174
+ this.changeElementSearchInput = page.locator('.djs-popup-search input');
175
+ this.changeElementTabStrip = page.locator('.djs-popup-tabs-container');
176
+ // The tab renders its label as text content, which wins over its `title`
177
+ // attribute in the accessible-name computation. Match case-insensitively:
178
+ // the label is capitalised differently across bpmn-js releases.
179
+ this.reusableAssetsTab = page.getByRole('tab', { name: /reusable assets/i });
171
180
  // bpmn-js popup entries are `li[role="option"]` inside a `role="listbox"`,
172
181
  // so getByRole('listitem') no longer matches. Their accessible name also
173
182
  // includes the entry description, and three entries share the label
@@ -683,11 +692,51 @@ class ModelerCreatePage {
683
692
  async clickCancelButton() {
684
693
  await this.cancelButton.click({ timeout: 60000 });
685
694
  }
695
+ // `waitFor` actually blocks up to the timeout; `isVisible()` would return
696
+ // immediately and report false while the popup is still rendering.
697
+ async waitForVisible(locator, timeout) {
698
+ return locator
699
+ .first()
700
+ .waitFor({ state: 'visible', timeout })
701
+ .then(() => true)
702
+ .catch(() => false);
703
+ }
704
+ // The change-element popup is now tabbed: every `replace.template-*` entry
705
+ // is assigned to the "Reusable Assets" tab, so connector templates are not
706
+ // in the DOM at all while the default "BPMN" tab is selected - which is why
707
+ // the template locators time out with `<element(s) not found>`.
708
+ // Opening that tab is version-tolerant: on an untabbed popup the strip is
709
+ // absent and this is a no-op.
710
+ // Search is the fallback, because it spans the full entry set across every
711
+ // tab. It must be typed with `pressSequentially`: the popup's search input
712
+ // is uncontrolled and its state is written by a `keyup` handler only, so
713
+ // `fill()` (which dispatches `input` alone) never applies the filter.
714
+ async revealChangeElementTemplate(option, searchTerm) {
715
+ if (await this.waitForVisible(option, 5000)) {
716
+ return;
717
+ }
718
+ if (await this.waitForVisible(this.changeElementTabStrip, 5000)) {
719
+ await this.reusableAssetsTab.click({ timeout: 30000 });
720
+ if (await this.waitForVisible(option, 15000)) {
721
+ return;
722
+ }
723
+ }
724
+ if (!(await this.waitForVisible(this.changeElementSearchInput, 5000))) {
725
+ return;
726
+ }
727
+ await this.changeElementSearchInput.click();
728
+ await this.changeElementSearchInput.fill('');
729
+ await this.changeElementSearchInput.pressSequentially(searchTerm, {
730
+ delay: 50,
731
+ });
732
+ }
686
733
  async clickRestConnectorOption() {
734
+ await this.revealChangeElementTemplate(this.restConnectorOption, 'REST');
687
735
  await (0, test_1.expect)(this.restConnectorOption).toBeVisible({ timeout: 15000 });
688
736
  await this.restConnectorOption.click();
689
737
  }
690
738
  async clickWebhookStartEventConnectorOption() {
739
+ await this.revealChangeElementTemplate(this.webhookMessageStartEventConnectorOption, 'Webhook');
691
740
  await this.webhookMessageStartEventConnectorOption.click({ timeout: 60000 });
692
741
  }
693
742
  async clickWebhookTab() {
@@ -940,6 +989,7 @@ class ModelerCreatePage {
940
989
  await this.intermediateBoundaryEvent.click({ timeout: 60000 });
941
990
  }
942
991
  async clickIntermediateWebhookConnectorOption() {
992
+ await this.revealChangeElementTemplate(this.intermediateWebhookConnectorOption, 'Webhook');
943
993
  await this.intermediateWebhookConnectorOption.click({ timeout: 60000 });
944
994
  }
945
995
  async clickCorrelationKeyProcessInput() {
@@ -121,11 +121,21 @@ class TaskDetailsPage {
121
121
  async clickUnassignButton() {
122
122
  await this.unassignButton.click();
123
123
  }
124
+ // The "Task completed" toast is a transient confirmation: Tasklist's
125
+ // notification store auto-removes it, and it is never rendered at all when
126
+ // the refreshed task list deselects the completed task before the completion
127
+ // promise resolves (the nightly trace showed exactly that — the task was
128
+ // completed, the details panel rendered "Completed by Me" plus a completion
129
+ // date, and no toast ever entered the DOM). Accept the task's own completed
130
+ // state as well: the details panel only renders "Completion date" once the
131
+ // task has one, so this confirms the completion rather than weakening the
132
+ // check. Same fix already carried by pages/8.10/TaskDetailsPage.ts.
124
133
  async clickCompleteTaskButton() {
125
134
  await this.completeTaskButton.click({ timeout: 60000 });
126
- await (0, test_1.expect)(this.page.getByText('Task completed')).toBeVisible({
127
- timeout: 60000,
128
- });
135
+ await (0, test_1.expect)(this.page
136
+ .getByText('Task completed')
137
+ .or(this.detailsPanel.getByText('Completion date'))
138
+ .first()).toBeVisible({ timeout: 60000 });
129
139
  await this.page.reload();
130
140
  }
131
141
  async clickAddVariableButton() {
@@ -132,6 +132,9 @@ _8_9_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
132
132
  await modelerCreatePage.enterDiagramName(processName);
133
133
  await (0, sleep_1.sleep)(10000);
134
134
  await modelerCreatePage.clickChangeTypeButton();
135
+ // Connector templates now sit behind the change-element popup's
136
+ // "Reusable Assets" tab, so surface the entry before asserting on it.
137
+ await modelerCreatePage.revealChangeElementTemplate(modelerCreatePage.webhookMessageStartEventConnectorOption, 'Webhook');
135
138
  await (0, test_1.expect)(modelerCreatePage.webhookMessageStartEventConnectorOption).toBeVisible({
136
139
  timeout: 30000,
137
140
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.968",
3
+ "version": "0.0.969",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",