@camunda/e2e-test-suite 0.0.1149 → 0.0.1151
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.
|
@@ -9,6 +9,7 @@ declare class ConnectorMarketplacePage {
|
|
|
9
9
|
readonly replaceResourceButton: Locator;
|
|
10
10
|
readonly saveAsCopyButton: Locator;
|
|
11
11
|
readonly cancelButton: Locator;
|
|
12
|
+
readonly dialogTitle: Locator;
|
|
12
13
|
constructor(page: Page);
|
|
13
14
|
clickSearchForConnectorTextbox(): Promise<void>;
|
|
14
15
|
fillSearchForConnectorTextbox(connectorName: string): Promise<void>;
|
|
@@ -16,6 +17,8 @@ declare class ConnectorMarketplacePage {
|
|
|
16
17
|
clickSnackbar(): Promise<void>;
|
|
17
18
|
clickCloseButton(): Promise<void>;
|
|
18
19
|
clickReplaceResourceButton(): Promise<void>;
|
|
19
|
-
downloadConnectorToProject(): Promise<
|
|
20
|
+
downloadConnectorToProject(): Promise<boolean>;
|
|
21
|
+
private closeMarketplaceDialog;
|
|
22
|
+
searchAndDownloadConnector(connectorName: string): Promise<boolean>;
|
|
20
23
|
}
|
|
21
24
|
export { ConnectorMarketplacePage };
|
|
@@ -11,8 +11,13 @@ class ConnectorMarketplacePage {
|
|
|
11
11
|
replaceResourceButton;
|
|
12
12
|
saveAsCopyButton;
|
|
13
13
|
cancelButton;
|
|
14
|
+
dialogTitle;
|
|
14
15
|
constructor(page) {
|
|
15
16
|
this.page = page;
|
|
17
|
+
// Title of the marketplace dialog itself — present both while the listing
|
|
18
|
+
// renders and while it is stuck on its loading spinner, so it is the one
|
|
19
|
+
// reliable marker of "the dialog is still up".
|
|
20
|
+
this.dialogTitle = page.getByText('Browse Marketplace connectors');
|
|
16
21
|
this.searchForConnectorTextbox = page.getByPlaceholder('Search for a connector');
|
|
17
22
|
this.downloadToProjectButton = page
|
|
18
23
|
.getByRole('button', { name: 'Download to project' })
|
|
@@ -48,38 +53,65 @@ class ConnectorMarketplacePage {
|
|
|
48
53
|
}
|
|
49
54
|
async downloadConnectorToProject() {
|
|
50
55
|
await this.clickDownloadToProjectButton();
|
|
51
|
-
// After clicking "Download to project", Hub
|
|
52
|
-
// primary button depends on project state:
|
|
53
|
-
// "
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
]);
|
|
65
|
-
imported = true;
|
|
66
|
-
}
|
|
67
|
-
catch (e) {
|
|
68
|
-
if (await this.cancelButton.isVisible({ timeout: 3000 }).catch(() => false)) {
|
|
69
|
-
await this.cancelButton.click({ timeout: 10000 });
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Wait for the snackbar that confirms the template was received, then close
|
|
73
|
-
// the marketplace dialog so the change-element popup is unblocked before the
|
|
74
|
-
// caller selects the newly installed connector.
|
|
56
|
+
// After clicking "Download to project", Hub fetches the connector detail
|
|
57
|
+
// and opens an ImportModal whose primary button depends on project state:
|
|
58
|
+
// "Add to project" (new template), "Replace resource" (same template
|
|
59
|
+
// exists), or "Save as copy" (conflict). Wait once for whichever of the
|
|
60
|
+
// three Hub renders, then click that one — never race three clicks, which
|
|
61
|
+
// fires all of them at the same time and hides which button was missing.
|
|
62
|
+
const importButton = this.addToProjectButton
|
|
63
|
+
.or(this.replaceResourceButton)
|
|
64
|
+
.or(this.saveAsCopyButton);
|
|
65
|
+
const imported = await importButton
|
|
66
|
+
.waitFor({ state: 'visible', timeout: 20000 })
|
|
67
|
+
.then(() => true)
|
|
68
|
+
.catch(() => false);
|
|
75
69
|
if (imported) {
|
|
70
|
+
await importButton.click({ timeout: 20000 });
|
|
71
|
+
// The snackbar confirms Hub received the template. It auto-dismisses, so
|
|
72
|
+
// a miss is not treated as fatal here — the caller proves the template
|
|
73
|
+
// landed by finding the connector in the change-element popup.
|
|
76
74
|
await this.snackbar
|
|
77
75
|
.waitFor({ state: 'visible', timeout: 60000 })
|
|
78
|
-
.catch(() =>
|
|
79
|
-
if (await this.closeButton.isVisible({ timeout: 5000 }).catch(() => false)) {
|
|
80
|
-
await this.closeButton.click({ timeout: 10000 });
|
|
81
|
-
}
|
|
76
|
+
.catch(() => false);
|
|
82
77
|
}
|
|
78
|
+
else if (await this.cancelButton.isVisible({ timeout: 3000 }).catch(() => false)) {
|
|
79
|
+
await this.cancelButton.click({ timeout: 10000 });
|
|
80
|
+
}
|
|
81
|
+
// Always close the marketplace dialog, download or not. When Hub's
|
|
82
|
+
// connector-detail request fails (observed as a 504 on
|
|
83
|
+
// /api/external/marketplace/connectors/<id>) the dialog stays up on its
|
|
84
|
+
// loading spinner forever and swallows every click on the canvas beneath
|
|
85
|
+
// it, so leaving it open turns one failed download into a cascade of
|
|
86
|
+
// 60 s timeouts in the caller.
|
|
87
|
+
await this.closeMarketplaceDialog();
|
|
88
|
+
return imported;
|
|
89
|
+
}
|
|
90
|
+
async closeMarketplaceDialog() {
|
|
91
|
+
if (await this.closeButton.isVisible({ timeout: 5000 }).catch(() => false)) {
|
|
92
|
+
await this.closeButton.click({ timeout: 10000 });
|
|
93
|
+
}
|
|
94
|
+
if (await this.dialogTitle
|
|
95
|
+
.waitFor({ state: 'hidden', timeout: 10000 })
|
|
96
|
+
.then(() => true)
|
|
97
|
+
.catch(() => false)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// The stuck-spinner state can leave the close control unresponsive;
|
|
101
|
+
// Escape dismisses the dialog just as reliably.
|
|
102
|
+
await this.page.keyboard.press('Escape');
|
|
103
|
+
await this.dialogTitle.waitFor({ state: 'hidden', timeout: 30000 });
|
|
104
|
+
}
|
|
105
|
+
async searchAndDownloadConnector(connectorName) {
|
|
106
|
+
await this.clickSearchForConnectorTextbox();
|
|
107
|
+
await this.fillSearchForConnectorTextbox(connectorName);
|
|
108
|
+
// Wait for the searched connector's card to render before downloading, so
|
|
109
|
+
// the click cannot land on a leftover card from the unfiltered listing.
|
|
110
|
+
await this.page
|
|
111
|
+
.getByText(connectorName, { exact: true })
|
|
112
|
+
.first()
|
|
113
|
+
.waitFor({ state: 'visible', timeout: 60000 });
|
|
114
|
+
return await this.downloadConnectorToProject();
|
|
83
115
|
}
|
|
84
116
|
}
|
|
85
117
|
exports.ConnectorMarketplacePage = ConnectorMarketplacePage;
|
|
@@ -185,6 +185,7 @@ declare class ModelerCreatePage {
|
|
|
185
185
|
private openAppendCreatePad;
|
|
186
186
|
clickAppendElementButton(): Promise<void>;
|
|
187
187
|
clickMarketPlaceButton(): Promise<void>;
|
|
188
|
+
private openChangeElementPopup;
|
|
188
189
|
clickPublicHolidayConnectorOption(): Promise<void>;
|
|
189
190
|
clickPublicHolidayYearOption(): Promise<void>;
|
|
190
191
|
fillPublicHolidayYearOption(year: string): Promise<void>;
|
|
@@ -1106,24 +1106,34 @@ class ModelerCreatePage {
|
|
|
1106
1106
|
}
|
|
1107
1107
|
throw new Error(`Failed to click the button after ${maxRetries} attempts.`);
|
|
1108
1108
|
}
|
|
1109
|
+
async openChangeElementPopup() {
|
|
1110
|
+
await this.clickCanvas();
|
|
1111
|
+
await this.secondElement.click({ timeout: 60000 });
|
|
1112
|
+
await this.clickChangeTypeButton();
|
|
1113
|
+
await (0, test_1.expect)(this.marketPlaceButton).toBeVisible({ timeout: 60000 });
|
|
1114
|
+
}
|
|
1109
1115
|
async clickPublicHolidayConnectorOption() {
|
|
1110
1116
|
const maxRetries = 4;
|
|
1111
1117
|
for (let retries = 0; retries < maxRetries; retries++) {
|
|
1112
1118
|
try {
|
|
1113
|
-
|
|
1114
|
-
|
|
1119
|
+
// Always open the change-type popup before trying to click the option.
|
|
1120
|
+
// This has to come first: the marketplace button only exists inside
|
|
1121
|
+
// that popup, so the re-download recovery below can only work once the
|
|
1122
|
+
// popup is open (it used to run before this block, right after a
|
|
1123
|
+
// page.reload(), and so could never find the button).
|
|
1124
|
+
await this.openChangeElementPopup();
|
|
1125
|
+
if (retries > 0) {
|
|
1126
|
+
// The previous attempt did not find the connector in the popup, so
|
|
1127
|
+
// the marketplace download never landed — Hub's connector-detail
|
|
1128
|
+
// request can fail (a 504 on
|
|
1129
|
+
// /api/external/marketplace/connectors/<id> leaves the marketplace
|
|
1130
|
+
// dialog stuck on its spinner and no import modal opens). Re-run the
|
|
1131
|
+
// download from the now-open popup, then reopen the popup.
|
|
1115
1132
|
await this.clickMarketPlaceButton();
|
|
1116
1133
|
const connectorMarketplacePage = new ConnectorMarketplacePage_1.ConnectorMarketplacePage(this.page);
|
|
1117
|
-
await connectorMarketplacePage.
|
|
1118
|
-
await
|
|
1119
|
-
await (0, sleep_1.sleep)(10000);
|
|
1120
|
-
await connectorMarketplacePage.downloadConnectorToProject();
|
|
1134
|
+
await connectorMarketplacePage.searchAndDownloadConnector('Public Holiday Connector');
|
|
1135
|
+
await this.openChangeElementPopup();
|
|
1121
1136
|
}
|
|
1122
|
-
// Always open the change-type popup before trying to click the option
|
|
1123
|
-
await this.clickCanvas();
|
|
1124
|
-
await this.secondElement.click({ timeout: 60000 });
|
|
1125
|
-
await this.clickChangeTypeButton();
|
|
1126
|
-
await (0, test_1.expect)(this.marketPlaceButton).toBeVisible({ timeout: 60000 });
|
|
1127
1137
|
// Filter the virtualized change-element popup so the option scrolls
|
|
1128
1138
|
// into view. Search by each full connector name (the marketplace
|
|
1129
1139
|
// renamed it "Public Holiday Outbound" -> "Worldwide Public Holiday"),
|