@camunda/e2e-test-suite 0.0.960 → 0.0.962
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.
- package/dist/pages/SM-8.9/ConnectorMarketplacePage.d.ts +1 -0
- package/dist/pages/SM-8.9/ConnectorMarketplacePage.js +15 -0
- package/dist/pages/SM-8.9/ModelerCreatePage.d.ts +1 -0
- package/dist/pages/SM-8.9/ModelerCreatePage.js +11 -0
- package/dist/pages/SM-8.9/ModelerHomePage.js +8 -1
- package/dist/pages/SM-8.9/UtilitiesPage.js +27 -6
- package/dist/tests/8.9/hto-user-flows.spec.js +6 -6
- package/package.json +1 -1
|
@@ -13,6 +13,7 @@ declare class ConnectorMarketplacePage {
|
|
|
13
13
|
clickCancelButton(): Promise<void>;
|
|
14
14
|
clickReplaceResourceButton(): Promise<void>;
|
|
15
15
|
downloadConnectorToProject(): Promise<void>;
|
|
16
|
+
private waitForImportToSettle;
|
|
16
17
|
searchAndDownloadConnector(connectorName: string, maxRetries?: number): Promise<void>;
|
|
17
18
|
}
|
|
18
19
|
export { ConnectorMarketplacePage };
|
|
@@ -54,6 +54,7 @@ class ConnectorMarketplacePage {
|
|
|
54
54
|
.then(() => true)
|
|
55
55
|
.catch(() => false);
|
|
56
56
|
if (!modalOpened) {
|
|
57
|
+
await this.waitForImportToSettle();
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
60
|
if (await this.addToProjectButton.isVisible()) {
|
|
@@ -62,6 +63,20 @@ class ConnectorMarketplacePage {
|
|
|
62
63
|
else {
|
|
63
64
|
await this.replaceResourceButton.click({ timeout: 20000 });
|
|
64
65
|
}
|
|
66
|
+
await this.waitForImportToSettle(primaryButton.first());
|
|
67
|
+
}
|
|
68
|
+
// Hub writes the template into the project asynchronously after the primary
|
|
69
|
+
// button is clicked, and keeps the ImportModal mounted until that request
|
|
70
|
+
// resolves. Returning as soon as the click resolved let the caller's
|
|
71
|
+
// `page.reload()` tear the page down ~90ms later and abort the write, leaving
|
|
72
|
+
// the project's connector-template list empty.
|
|
73
|
+
async waitForImportToSettle(modalButton) {
|
|
74
|
+
if (modalButton) {
|
|
75
|
+
await modalButton
|
|
76
|
+
.waitFor({ state: 'hidden', timeout: 60000 })
|
|
77
|
+
.catch(() => { });
|
|
78
|
+
}
|
|
79
|
+
await this.page.waitForLoadState('networkidle').catch(() => { });
|
|
65
80
|
}
|
|
66
81
|
// The marketplace search backend can transiently return HTTP 504
|
|
67
82
|
// ("upstream request timeout"), which leaves the modal in an error or
|
|
@@ -191,6 +191,7 @@ declare class ModelerCreatePage {
|
|
|
191
191
|
fillZeebeRestValue(zeebeUrl: string): Promise<void>;
|
|
192
192
|
embedForm(formName: string): Promise<void>;
|
|
193
193
|
clickFirstPlaceRESTConnector(): Promise<void>;
|
|
194
|
+
isConnectorTemplateApplied(timeout?: number): Promise<boolean>;
|
|
194
195
|
setOAuthTokenEndpoint(elementToClick: Locator, endpoint: string, options?: {
|
|
195
196
|
retries?: number;
|
|
196
197
|
settleMs?: number;
|
|
@@ -1064,6 +1064,17 @@ class ModelerCreatePage {
|
|
|
1064
1064
|
async clickFirstPlaceRESTConnector() {
|
|
1065
1065
|
await this.firstPlaceRESTConnector.click({ timeout: 60000 });
|
|
1066
1066
|
}
|
|
1067
|
+
// The Authentication group is contributed by the REST connector element
|
|
1068
|
+
// template, so it exists only while that template resolves for the selected
|
|
1069
|
+
// element. When the marketplace import never reached the project the panel
|
|
1070
|
+
// renders `Template: Not found` instead and no amount of waiting produces
|
|
1071
|
+
// the group.
|
|
1072
|
+
async isConnectorTemplateApplied(timeout = 30000) {
|
|
1073
|
+
return this.authenticationPanel
|
|
1074
|
+
.waitFor({ state: 'visible', timeout })
|
|
1075
|
+
.then(() => true)
|
|
1076
|
+
.catch(() => false);
|
|
1077
|
+
}
|
|
1067
1078
|
async setOAuthTokenEndpoint(elementToClick, endpoint, options) {
|
|
1068
1079
|
const retries = options?.retries ?? 2;
|
|
1069
1080
|
const settleMs = options?.settleMs ?? 250;
|
|
@@ -206,11 +206,18 @@ class ModelerHomePage {
|
|
|
206
206
|
// restarts. Wait for the app shell before checking for the dropdown, and
|
|
207
207
|
// reload-then-wait on each retry so a 503 is ridden out rather than
|
|
208
208
|
// reasserted against the error page.
|
|
209
|
+
// `expectLocatorWithRetry` re-checks its elapsed budget before every
|
|
210
|
+
// attempt, so the 60s default `totalTimeout` was spent inside a single
|
|
211
|
+
// `waitForModelerReady` recovery and the helper gave up "after 1 attempts"
|
|
212
|
+
// -- the reload-and-wait retry never actually ran. Bound the recovery wait
|
|
213
|
+
// and widen the budget so all three attempts fit.
|
|
209
214
|
await this.waitForModelerReady();
|
|
210
215
|
await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.diagramTypeDropdown, {
|
|
216
|
+
visibilityTimeout: 15000,
|
|
217
|
+
totalTimeout: 180000,
|
|
211
218
|
postAction: async () => {
|
|
212
219
|
await this.page.reload();
|
|
213
|
-
await this.waitForModelerReady();
|
|
220
|
+
await this.waitForModelerReady(45000);
|
|
214
221
|
},
|
|
215
222
|
});
|
|
216
223
|
await this.diagramTypeDropdown.click();
|
|
@@ -428,6 +428,32 @@ async function expectTextWithPagination(page, text, shouldExist = true, timeout
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
exports.expectTextWithPagination = expectTextWithPagination;
|
|
431
|
+
// SM Web Modeler ships no bundled marketplace connectors, so the REST connector
|
|
432
|
+
// template has to be imported from the marketplace into the project before any
|
|
433
|
+
// of the OAuth steps below can find the template-provided Authentication group.
|
|
434
|
+
// The import is confirmed against the diagram itself and re-driven when it did
|
|
435
|
+
// not land, so a dropped import fails here with its own cause instead of five
|
|
436
|
+
// 60s waits on a panel that can never render.
|
|
437
|
+
async function importRestConnectorTemplate(modelerCreatePage, connectorMarketplacePage, page) {
|
|
438
|
+
const maxAttempts = 2;
|
|
439
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
440
|
+
await modelerCreatePage.clickFirstPlaceRESTConnector();
|
|
441
|
+
await modelerCreatePage.clickChangeTypeButton();
|
|
442
|
+
await modelerCreatePage.clickMarketPlaceButton();
|
|
443
|
+
await connectorMarketplacePage.searchAndDownloadConnector('REST Connector');
|
|
444
|
+
await page.reload();
|
|
445
|
+
await page.waitForLoadState('networkidle');
|
|
446
|
+
await modelerCreatePage.clickFirstPlaceRESTConnector();
|
|
447
|
+
if (await modelerCreatePage.isConnectorTemplateApplied()) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
console.warn(`REST connector template did not resolve on the diagram after import ` +
|
|
451
|
+
`attempt ${attempt}/${maxAttempts}; re-importing from the marketplace.`);
|
|
452
|
+
}
|
|
453
|
+
throw new Error(`REST connector template was not imported into the project after ` +
|
|
454
|
+
`${maxAttempts} marketplace attempts: the element still renders ` +
|
|
455
|
+
`"Template: Not found", so its Authentication group never exists.`);
|
|
456
|
+
}
|
|
431
457
|
async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, zeebeUrl, zeebeClientId, zeebeClientSecret, endpoint, tenant = '') {
|
|
432
458
|
await modelerHomePage.clickCrossComponentProjectFolder();
|
|
433
459
|
await modelerHomePage.clickDiagramTypeDropdown();
|
|
@@ -443,12 +469,7 @@ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modele
|
|
|
443
469
|
await modelerCreatePage.clickIdInput();
|
|
444
470
|
await modelerCreatePage.fillIdInput(processName);
|
|
445
471
|
await (0, sleep_1.sleep)(10000);
|
|
446
|
-
await modelerCreatePage
|
|
447
|
-
await modelerCreatePage.clickChangeTypeButton();
|
|
448
|
-
await modelerCreatePage.clickMarketPlaceButton();
|
|
449
|
-
await connectorMarketplacePage.searchAndDownloadConnector('REST Connector');
|
|
450
|
-
await page.reload();
|
|
451
|
-
await page.waitForLoadState('networkidle');
|
|
472
|
+
await importRestConnectorTemplate(modelerCreatePage, connectorMarketplacePage, page);
|
|
452
473
|
await modelerCreatePage.fillStartEventVariablesForDocHandling(zeebeUrl, zeebeClientId, zeebeClientSecret);
|
|
453
474
|
await modelerCreatePage.setOAuthTokenEndpoint(page.locator('.djs-hit').first(), endpoint);
|
|
454
475
|
await (0, sleep_1.sleep)(2000);
|
|
@@ -248,17 +248,17 @@ _8_9_1.test.describe('HTO User Flow Tests', () => {
|
|
|
248
248
|
await (0, test_1.expect)(operateHomePage.editVariableSpinner).not.toBeVisible({
|
|
249
249
|
timeout: 180000,
|
|
250
250
|
});
|
|
251
|
+
// Operate can render a stale /v2/variables/search response when two
|
|
252
|
+
// polls overlap right after the update, and then stops polling
|
|
253
|
+
// variables, so the panel stays pinned to the old value and a passive
|
|
254
|
+
// wait can never recover. Re-assert across page reloads instead.
|
|
255
|
+
await (0, UtilitiesPage_1.assertPageTextWithRetry)(page, '"updatedValue"');
|
|
251
256
|
await (0, test_1.expect)(page.getByText('"testValue"')).not.toBeVisible({
|
|
252
257
|
timeout: 60000,
|
|
253
258
|
});
|
|
254
|
-
await (0, test_1.expect)(page.getByText('"updatedValue"')).toBeVisible({
|
|
255
|
-
timeout: 90000,
|
|
256
|
-
});
|
|
257
259
|
await appsPage.clickCamundaApps();
|
|
258
260
|
await appsPage.clickTasklist(clusterName);
|
|
259
|
-
await (0,
|
|
260
|
-
timeout: 20000,
|
|
261
|
-
});
|
|
261
|
+
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(page, taskPanelPage.taskListPageBanner, 'Tasklist banner');
|
|
262
262
|
await (0, expectTextWithRetry_1.expectTextWithRetry)(page, processName);
|
|
263
263
|
await taskPanelPage.openTask(processName);
|
|
264
264
|
await (0, test_1.expect)(page.getByText('testVariable')).toBeVisible({
|