@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.
@@ -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.clickFirstPlaceRESTConnector();
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, test_1.expect)(taskPanelPage.taskListPageBanner).toBeVisible({
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({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.960",
3
+ "version": "0.0.962",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",