@camunda/e2e-test-suite 0.0.723 → 0.0.724

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,7 +3,10 @@ declare class ConnectorMarketplacePage {
3
3
  private page;
4
4
  readonly searchForConnectorTextbox: Locator;
5
5
  readonly downloadToProjectButton: Locator;
6
+ readonly snackbar: Locator;
6
7
  readonly replaceResourceButton: Locator;
8
+ readonly addToProjectButton: Locator;
9
+ readonly cancelButton: Locator;
7
10
  readonly closeButton: Locator;
8
11
  constructor(page: Page);
9
12
  clickSearchForConnectorTextbox(): Promise<void>;
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectorMarketplacePage = void 0;
4
- const test_1 = require("@playwright/test");
5
4
  class ConnectorMarketplacePage {
6
5
  page;
7
6
  searchForConnectorTextbox;
8
7
  downloadToProjectButton;
8
+ snackbar;
9
9
  replaceResourceButton;
10
+ addToProjectButton;
11
+ cancelButton;
10
12
  closeButton;
11
13
  constructor(page) {
12
14
  this.page = page;
@@ -14,9 +16,14 @@ class ConnectorMarketplacePage {
14
16
  this.downloadToProjectButton = page
15
17
  .getByRole('button', { name: 'Download to project' })
16
18
  .first();
19
+ this.snackbar = page.locator('[data-test="snackbar"]');
17
20
  this.replaceResourceButton = page.getByRole('button', {
18
21
  name: 'Replace resource',
19
22
  });
23
+ this.addToProjectButton = page.getByRole('button', {
24
+ name: 'Add to project',
25
+ });
26
+ this.cancelButton = page.getByRole('button', { name: 'Cancel' });
20
27
  this.closeButton = page.getByRole('button', { name: 'Close' });
21
28
  }
22
29
  async clickSearchForConnectorTextbox() {
@@ -36,12 +43,38 @@ class ConnectorMarketplacePage {
36
43
  }
37
44
  async downloadConnectorToProject() {
38
45
  await this.clickDownloadToProjectButton();
39
- try {
40
- await (0, test_1.expect)(this.replaceResourceButton).toBeVisible();
41
- await this.clickReplaceResourceButton();
46
+ let imported = false;
47
+ // A fresh download shows "Add to project"; an already-present resource
48
+ // shows "Replace resource". Pick whichever the ImportModal rendered —
49
+ // the old code only handled "Replace resource", so a first-time download
50
+ // (the SaaS nightly always runs in a fresh project) was never confirmed
51
+ // and the connector never reached the diagram.
52
+ if (await this.addToProjectButton
53
+ .isVisible({ timeout: 20000 })
54
+ .catch(() => false)) {
55
+ await this.addToProjectButton.click({ timeout: 10000 });
56
+ imported = true;
57
+ }
58
+ else if (await this.replaceResourceButton
59
+ .isVisible({ timeout: 5000 })
60
+ .catch(() => false)) {
61
+ await this.replaceResourceButton.click({ timeout: 10000 });
62
+ imported = true;
63
+ }
64
+ else if (await this.cancelButton.isVisible({ timeout: 3000 }).catch(() => false)) {
65
+ await this.cancelButton.click({ timeout: 10000 });
42
66
  }
43
- catch (e) {
44
- return;
67
+ // After a successful import, wait for the snackbar (confirms the connector
68
+ // template was received by the modeler) then close the marketplace panel so
69
+ // the diagram canvas is unblocked before the caller tries to select the
70
+ // newly installed connector.
71
+ if (imported) {
72
+ await this.snackbar
73
+ .waitFor({ state: 'visible', timeout: 60000 })
74
+ .catch(() => { });
75
+ if (await this.closeButton.isVisible({ timeout: 5000 }).catch(() => false)) {
76
+ await this.closeButton.click({ timeout: 10000 });
77
+ }
45
78
  }
46
79
  }
47
80
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModelerCreatePage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const sleep_1 = require("../../utils/sleep");
6
+ const ConnectorMarketplacePage_1 = require("./ConnectorMarketplacePage");
6
7
  class ModelerCreatePage {
7
8
  page;
8
9
  generalPanel;
@@ -707,55 +708,44 @@ class ModelerCreatePage {
707
708
  }
708
709
  async clickPublicHolidayConnectorOption() {
709
710
  const maxRetries = 4;
710
- const setupModelerState = async () => {
711
- // Navigate back from marketplace (full-page nav in 8.7) if needed
712
- const onModeler = await this.page
713
- .locator('[data-test="modeler"]')
714
- .waitFor({ state: 'visible', timeout: 5000 })
715
- .then(() => true)
716
- .catch(() => false);
717
- if (!onModeler) {
718
- await this.page.keyboard.press('Escape');
719
- await this.page.waitForTimeout(2000);
720
- const afterEscape = await this.page
721
- .locator('[data-test="modeler"]')
722
- .waitFor({ state: 'visible', timeout: 3000 })
723
- .then(() => true)
724
- .catch(() => false);
725
- if (!afterEscape) {
726
- await this.page.goBack();
727
- await this.page.waitForTimeout(5000);
728
- }
729
- await this.page.reload();
730
- await this.page.waitForTimeout(5000);
731
- }
732
- await this.clickCanvas();
733
- await this.secondElement.click({ timeout: 60000 });
734
- await this.clickChangeTypeButton();
735
- // Wait for change-type panel to be fully loaded before clicking connector
736
- await (0, test_1.expect)(this.marketPlaceButton).toBeVisible({ timeout: 60000 });
737
- };
738
711
  for (let retries = 0; retries < maxRetries; retries++) {
739
712
  try {
740
- await setupModelerState();
741
- await this.publicHolidayConnectorOption.click({ timeout: 120000 });
713
+ if (retries === 2) {
714
+ // Re-download connector on second retry in case the first download
715
+ // failed to confirm the import.
716
+ await this.clickMarketPlaceButton();
717
+ const connectorMarketplacePage = new ConnectorMarketplacePage_1.ConnectorMarketplacePage(this.page);
718
+ await connectorMarketplacePage.clickSearchForConnectorTextbox();
719
+ await connectorMarketplacePage.fillSearchForConnectorTextbox('Worldwide Public Holiday');
720
+ await (0, sleep_1.sleep)(10000);
721
+ await connectorMarketplacePage.downloadConnectorToProject();
722
+ }
723
+ // Always open the change-type popup before trying to click the option
724
+ await this.clickCanvas();
725
+ await this.secondElement.click({ timeout: 60000 });
726
+ await this.clickChangeTypeButton();
727
+ await (0, test_1.expect)(this.marketPlaceButton).toBeVisible({ timeout: 60000 });
728
+ // Filter the virtualized change-element popup so the option scrolls
729
+ // into view — `getByText` alone never matches an off-screen entry.
730
+ const changeElementSearch = this.page.locator('.djs-popup-search input');
731
+ if (await changeElementSearch
732
+ .isVisible({ timeout: 5000 })
733
+ .catch(() => false)) {
734
+ await changeElementSearch.pressSequentially('Worldwide Public Holiday', { delay: 50 });
735
+ }
736
+ await this.publicHolidayConnectorOption.waitFor({
737
+ state: 'visible',
738
+ timeout: 60000,
739
+ });
740
+ await this.publicHolidayConnectorOption.click({ timeout: 30000 });
742
741
  return;
743
742
  }
744
743
  catch (error) {
745
744
  console.error(`Click attempt ${retries + 1} failed: ${error}`);
746
745
  if (retries >= maxRetries - 1)
747
746
  break;
748
- const onModeler = await this.page
749
- .locator('[data-test="modeler"]')
750
- .waitFor({ state: 'visible', timeout: 3000 })
751
- .then(() => true)
752
- .catch(() => false);
753
- if (!onModeler) {
754
- await this.page.goBack();
755
- await this.page.waitForTimeout(3000);
756
- }
757
747
  await this.page.reload();
758
- await this.page.waitForTimeout(5000);
748
+ await new Promise((resolve) => setTimeout(resolve, 10000));
759
749
  }
760
750
  }
761
751
  throw new Error(`Failed to click the public holiday connector after ${maxRetries} attempts.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.723",
3
+ "version": "0.0.724",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",