@camunda/e2e-test-suite 0.0.986 → 0.0.988
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/8.10/ModelerHomePage.d.ts +1 -0
- package/dist/pages/8.10/ModelerHomePage.js +42 -16
- package/dist/pages/SM-8.10/FormJsPage.d.ts +1 -0
- package/dist/pages/SM-8.10/FormJsPage.js +5 -0
- package/dist/pages/SM-8.10/ModelerCreatePage.js +4 -14
- package/dist/utils/modelerCluster.d.ts +9 -0
- package/dist/utils/modelerCluster.js +30 -0
- package/package.json +1 -1
|
@@ -48,6 +48,7 @@ declare class ModelerHomePage {
|
|
|
48
48
|
createCrossComponentProjectFolder(): Promise<void>;
|
|
49
49
|
clickManageButton(retries?: number): Promise<void>;
|
|
50
50
|
clickUploadFilesButton(): Promise<void>;
|
|
51
|
+
dismissBlockingDialog(): Promise<void>;
|
|
51
52
|
clickMessageBanner(): Promise<void>;
|
|
52
53
|
selectCluster(clusterName: string): Promise<void>;
|
|
53
54
|
clickIdpApplicationTemplateOption(): Promise<void>;
|
|
@@ -244,24 +244,17 @@ class ModelerHomePage {
|
|
|
244
244
|
async clickCrossComponentProjectFolder() {
|
|
245
245
|
await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.crossComponentProjectFolder, {
|
|
246
246
|
visibilityTimeout: 60000,
|
|
247
|
-
|
|
247
|
+
// Widened from 180s: dismissing the announcement dialog costs up to ~25s
|
|
248
|
+
// of settle-and-probe per attempt, which at 180s left room for barely one
|
|
249
|
+
// retry after an intercepted click had already burnt its 60s.
|
|
250
|
+
totalTimeout: 240000,
|
|
248
251
|
maxRetries: 5,
|
|
249
252
|
preAction: async () => {
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
const blockingModal = this.page.locator('.cds--modal.is-visible');
|
|
257
|
-
if ((await blockingModal.count()) > 0) {
|
|
258
|
-
await this.page.keyboard.press('Escape');
|
|
259
|
-
await (0, sleep_1.sleep)(1000);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
catch {
|
|
263
|
-
// No blocking modal to dismiss
|
|
264
|
-
}
|
|
253
|
+
// Dismiss the dialog BEFORE the banner: the Modeler home page can
|
|
254
|
+
// stack both at once, and clickMessageBanner resolves an
|
|
255
|
+
// `.or(...).first()` union in DOM order — the top banner comes first,
|
|
256
|
+
// so on its own it closes the banner and leaves the dialog open.
|
|
257
|
+
await this.dismissBlockingDialog();
|
|
265
258
|
await this.clickMessageBanner();
|
|
266
259
|
},
|
|
267
260
|
postAction: async () => {
|
|
@@ -315,6 +308,39 @@ class ModelerHomePage {
|
|
|
315
308
|
async clickUploadFilesButton() {
|
|
316
309
|
await this.uploadFilesButton.click({ timeout: 60000 });
|
|
317
310
|
}
|
|
311
|
+
// The release-announcement dialog ("New features" / "Check out our new
|
|
312
|
+
// release") renders over the projects list and swallows every click on it:
|
|
313
|
+
// Playwright reports the project link as visible, enabled and stable, then
|
|
314
|
+
// times out with the modal overlay "intercepts pointer events". Pressing
|
|
315
|
+
// Escape blindly does not help — Carbon only closes the dialog when focus is
|
|
316
|
+
// inside it, and focus sits on the body after a page load — so close it via
|
|
317
|
+
// its own controls and confirm it is gone before moving on.
|
|
318
|
+
// Anchored on the dismiss button rather than on the dialog: the Modeler home
|
|
319
|
+
// page keeps half a dozen `role="dialog"` containers mounted and hidden, so a
|
|
320
|
+
// dialog-first lookup resolves to a hidden one and reports "nothing to
|
|
321
|
+
// dismiss" while the announcement is still covering the projects list.
|
|
322
|
+
//
|
|
323
|
+
// The dialog is also mounted a beat after the projects list, so let the page
|
|
324
|
+
// settle before looking for it: probing the instant a load finishes lost that
|
|
325
|
+
// race on about half the attempts, and the dialog that appeared right after
|
|
326
|
+
// then swallowed the click.
|
|
327
|
+
async dismissBlockingDialog() {
|
|
328
|
+
await this.page
|
|
329
|
+
.waitForLoadState('networkidle', { timeout: 15000 })
|
|
330
|
+
.catch(() => false);
|
|
331
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
332
|
+
const isOpen = await this.closeButton
|
|
333
|
+
.waitFor({ state: 'visible', timeout: 10000 })
|
|
334
|
+
.then(() => true)
|
|
335
|
+
.catch(() => false);
|
|
336
|
+
if (!isOpen)
|
|
337
|
+
return;
|
|
338
|
+
await this.closeButton.click({ timeout: 5000 }).catch(() => { });
|
|
339
|
+
await this.closeButton
|
|
340
|
+
.waitFor({ state: 'hidden', timeout: 5000 })
|
|
341
|
+
.catch(() => false);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
318
344
|
async clickMessageBanner() {
|
|
319
345
|
try {
|
|
320
346
|
const button = this.messageBanner.or(this.closeButton).first();
|
|
@@ -11,6 +11,7 @@ declare class FormJsPage {
|
|
|
11
11
|
readonly uploadMultipleFilesToggle: Locator;
|
|
12
12
|
readonly documentReferenceInput: Locator;
|
|
13
13
|
readonly documentPreview: Locator;
|
|
14
|
+
readonly deployDialog: Locator;
|
|
14
15
|
readonly deployFormButton: Locator;
|
|
15
16
|
readonly deployModalSubmitButton: Locator;
|
|
16
17
|
readonly deploySuccessNotification: Locator;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FormJsPage = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
|
+
const modelerCluster_1 = require("../../utils/modelerCluster");
|
|
5
6
|
class FormJsPage {
|
|
6
7
|
page;
|
|
7
8
|
aiFormGeneratorButton;
|
|
@@ -14,6 +15,7 @@ class FormJsPage {
|
|
|
14
15
|
uploadMultipleFilesToggle;
|
|
15
16
|
documentReferenceInput;
|
|
16
17
|
documentPreview;
|
|
18
|
+
deployDialog;
|
|
17
19
|
deployFormButton;
|
|
18
20
|
deployModalSubmitButton;
|
|
19
21
|
deploySuccessNotification;
|
|
@@ -33,6 +35,7 @@ class FormJsPage {
|
|
|
33
35
|
name: 'document reference',
|
|
34
36
|
});
|
|
35
37
|
this.documentPreview = page.locator('button[data-field-type="documentPreview"]');
|
|
38
|
+
this.deployDialog = page.getByRole('dialog');
|
|
36
39
|
this.deployFormButton = page.locator('button.cds--btn--primary', {
|
|
37
40
|
hasText: 'Deploy',
|
|
38
41
|
});
|
|
@@ -78,6 +81,8 @@ class FormJsPage {
|
|
|
78
81
|
}
|
|
79
82
|
async deployForm() {
|
|
80
83
|
await this.clickDeployFormButton();
|
|
84
|
+
await (0, test_1.expect)(this.deployDialog).toBeVisible({ timeout: 30000 });
|
|
85
|
+
await (0, modelerCluster_1.selectModelerCluster)(this.deployDialog);
|
|
81
86
|
await this.clickDeployModalSubmitButton();
|
|
82
87
|
await (0, test_1.expect)(this.deploySuccessNotification).toBeVisible({ timeout: 30000 });
|
|
83
88
|
}
|
|
@@ -4,6 +4,7 @@ exports.ModelerCreatePage = void 0;
|
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
5
|
const ConnectorMarketplacePage_1 = require("./ConnectorMarketplacePage");
|
|
6
6
|
const sleep_1 = require("../../utils/sleep");
|
|
7
|
+
const modelerCluster_1 = require("../../utils/modelerCluster");
|
|
7
8
|
class ModelerCreatePage {
|
|
8
9
|
page;
|
|
9
10
|
generalPanel;
|
|
@@ -281,6 +282,8 @@ class ModelerCreatePage {
|
|
|
281
282
|
}
|
|
282
283
|
async deployProcessInstance(tenant = '') {
|
|
283
284
|
await this.clickDeployButton();
|
|
285
|
+
await (0, test_1.expect)(this.dialog).toBeVisible({ timeout: 30000 });
|
|
286
|
+
await (0, modelerCluster_1.selectModelerCluster)(this.dialog);
|
|
284
287
|
if (tenant.length > 0) {
|
|
285
288
|
await this.clickTenantIdInput();
|
|
286
289
|
await this.fillTenantIdInput(tenant);
|
|
@@ -376,20 +379,7 @@ class ModelerCreatePage {
|
|
|
376
379
|
await (0, test_1.expect)(this.dialog).toBeVisible({
|
|
377
380
|
timeout: 30000,
|
|
378
381
|
});
|
|
379
|
-
|
|
380
|
-
if (modelerClusterName) {
|
|
381
|
-
const clusterSelect = this.dialog.getByRole('combobox', {
|
|
382
|
-
name: 'Select a cluster',
|
|
383
|
-
});
|
|
384
|
-
await clusterSelect.click();
|
|
385
|
-
const escapedClusterName = modelerClusterName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
386
|
-
await this.dialog
|
|
387
|
-
.getByRole('option', {
|
|
388
|
-
name: new RegExp(`^${escapedClusterName}(?: \\(|$)`),
|
|
389
|
-
})
|
|
390
|
-
.click();
|
|
391
|
-
await (0, test_1.expect)(clusterSelect).toContainText(modelerClusterName);
|
|
392
|
-
}
|
|
382
|
+
await (0, modelerCluster_1.selectModelerCluster)(this.dialog);
|
|
393
383
|
if (variables.length > 0) {
|
|
394
384
|
await (0, test_1.expect)(this.variableInput).toBeVisible({
|
|
395
385
|
timeout: 60000,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Locator } from '@playwright/test';
|
|
2
|
+
/**
|
|
3
|
+
* Selects the cluster named by MODELER_CLUSTER_NAME in a Web Modeler deploy dialog.
|
|
4
|
+
*
|
|
5
|
+
* No-op when the variable is unset, which is every single-cluster environment. In a topology one
|
|
6
|
+
* Hub Web Modeler serves several orchestration clusters and preselects one of them, so a test that
|
|
7
|
+
* does not choose deploys somewhere other than the release under test.
|
|
8
|
+
*/
|
|
9
|
+
export declare function selectModelerCluster(dialog: Locator): Promise<void>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectModelerCluster = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
/**
|
|
6
|
+
* Selects the cluster named by MODELER_CLUSTER_NAME in a Web Modeler deploy dialog.
|
|
7
|
+
*
|
|
8
|
+
* No-op when the variable is unset, which is every single-cluster environment. In a topology one
|
|
9
|
+
* Hub Web Modeler serves several orchestration clusters and preselects one of them, so a test that
|
|
10
|
+
* does not choose deploys somewhere other than the release under test.
|
|
11
|
+
*/
|
|
12
|
+
async function selectModelerCluster(dialog) {
|
|
13
|
+
const modelerClusterName = process.env.MODELER_CLUSTER_NAME;
|
|
14
|
+
if (!modelerClusterName) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const clusterSelect = dialog.getByRole('combobox', {
|
|
18
|
+
name: 'Select a cluster',
|
|
19
|
+
});
|
|
20
|
+
await clusterSelect.click();
|
|
21
|
+
const escapedClusterName = modelerClusterName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
22
|
+
// The option label carries a trailing " (<status>)", so anchor the name and allow that suffix.
|
|
23
|
+
await dialog
|
|
24
|
+
.getByRole('option', {
|
|
25
|
+
name: new RegExp(`^${escapedClusterName}(?: \\(|$)`),
|
|
26
|
+
})
|
|
27
|
+
.click();
|
|
28
|
+
await (0, test_1.expect)(clusterSelect).toContainText(modelerClusterName);
|
|
29
|
+
}
|
|
30
|
+
exports.selectModelerCluster = selectModelerCluster;
|