@camunda/e2e-test-suite 0.0.1250 → 0.0.1251
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/BrowseAllConnectorMarketplacePage.d.ts +17 -0
- package/dist/pages/BrowseAllConnectorMarketplacePage.js +145 -0
- package/dist/pages/SM-8.10/ClusterDetailsPage.d.ts +1 -1
- package/dist/pages/SM-8.10/ClusterDetailsPage.js +13 -6
- package/dist/pages/SM-8.10/ClusterPage.js +3 -1
- package/dist/pages/SM-8.10/ConnectorMarketplacePage.d.ts +2 -0
- package/dist/pages/SM-8.10/ConnectorMarketplacePage.js +16 -1
- package/dist/pages/SM-8.10/ModelerCreatePage.d.ts +4 -1
- package/dist/pages/SM-8.10/ModelerCreatePage.js +78 -51
- package/dist/pages/SM-8.10/ModelerHomePage.d.ts +2 -1
- package/dist/pages/SM-8.10/ModelerHomePage.js +24 -0
- package/dist/pages/SM-8.10/OperateHomePage.js +8 -1
- package/dist/pages/SM-8.10/OptimizeHomePage.js +13 -4
- package/dist/pages/SM-8.10/ProcessApplicationPage.d.ts +10 -5
- package/dist/pages/SM-8.10/ProcessApplicationPage.js +163 -68
- package/dist/pages/SM-8.10/UtilitiesPage.js +6 -6
- package/dist/pages/SM-8.7/NavigationPage.js +2 -1
- package/dist/tests/8.10/connectors-user-flows.spec.js +4 -2
- package/dist/tests/8.10/saas-migration-path-user-flows.spec.js +2 -1
- package/dist/tests/8.10/smoke-tests.spec.js +2 -1
- package/dist/tests/8.7/connectors-user-flows.spec.js +8 -4
- package/dist/tests/8.7/saas-migration-path-user-flows.spec.js +2 -1
- package/dist/tests/8.7/smoke-tests.spec.js +2 -1
- package/dist/tests/8.8/connectors-user-flows.spec.js +4 -2
- package/dist/tests/8.8/saas-migration-path-user-flows.spec.js +2 -1
- package/dist/tests/8.8/smoke-tests.spec.js +2 -1
- package/dist/tests/8.9/connectors-user-flows.spec.js +4 -2
- package/dist/tests/8.9/saas-migration-path-user-flows.spec.js +2 -1
- package/dist/tests/8.9/smoke-tests.spec.js +2 -1
- package/dist/tests/SM-8.10/cluster-management-user-flows.spec.js +13 -6
- package/dist/tests/SM-8.10/connectors-user-flows.spec.js +2 -1
- package/dist/tests/SM-8.10/hub-web-modeler-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/hub-web-modeler-smoke.spec.js +24 -0
- package/dist/tests/SM-8.10/mt-enabled-user-flows.spec.js +3 -1
- package/dist/tests/SM-8.10/topology-orchestration-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.10/topology-orchestration-smoke.spec.js +58 -0
- package/dist/tests/SM-8.7/topology-orchestration-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.7/topology-orchestration-smoke.spec.js +62 -0
- package/dist/tests/SM-8.8/topology-orchestration-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.8/topology-orchestration-smoke.spec.js +58 -0
- package/dist/tests/SM-8.9/topology-orchestration-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.9/topology-orchestration-smoke.spec.js +58 -0
- package/dist/tests/c8Run-8.7/connectors-user-flows.spec.js +6 -3
- package/dist/tests/c8Run-8.8/connectors-user-flows.spec.js +6 -3
- package/dist/tests/c8Run-8.9/connectors-user-flows.spec.js +6 -3
- package/dist/utils/modelerCluster.d.ts +4 -6
- package/dist/utils/modelerCluster.js +55 -32
- package/package.json +1 -1
- package/playwright.config.ts +18 -5
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const SM_8_10_1 = require("../../fixtures/SM-8.10");
|
|
4
|
+
const _setup_1 = require("../../test-setup.js");
|
|
5
|
+
SM_8_10_1.test.describe('Hub and Web Modeler smoke tests', () => {
|
|
6
|
+
SM_8_10_1.test.afterEach(async ({ page }, testInfo) => {
|
|
7
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
8
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
9
|
+
});
|
|
10
|
+
(0, SM_8_10_1.test)('Deploy and start a process on the selected cluster', async ({ navigationPage, modelerHomePage, modelerCreatePage, }) => {
|
|
11
|
+
const suffix = await (0, _setup_1.generateRandomStringAsync)(5);
|
|
12
|
+
const processName = `Hub_Web_Modeler_Smoke_${suffix}`;
|
|
13
|
+
await SM_8_10_1.test.step('Open Web Modeler and create a BPMN diagram', async () => {
|
|
14
|
+
await navigationPage.goToModeler();
|
|
15
|
+
await modelerHomePage.createCrossComponentProjectFolder();
|
|
16
|
+
await modelerHomePage.clickDiagramTypeDropdown();
|
|
17
|
+
await modelerHomePage.clickBpmnTemplateOption();
|
|
18
|
+
await modelerCreatePage.modelJobWorkerDiagram(processName);
|
|
19
|
+
});
|
|
20
|
+
await SM_8_10_1.test.step('Deploy and start the process on the selected cluster', async () => {
|
|
21
|
+
await modelerCreatePage.runProcessInstance();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -223,6 +223,7 @@ if (process.env.IS_MT === 'true') {
|
|
|
223
223
|
await SM_8_10_1.test.step('Open Cross Component Test Project', async () => {
|
|
224
224
|
await navigationPage.goToModeler(undefined, credentials);
|
|
225
225
|
await modelerHomePage.createCrossComponentProjectFolder(credentials);
|
|
226
|
+
await modelerHomePage.assignWorkspaceEnvironmentAsOrgAdmin(browser);
|
|
226
227
|
await modelerHomePage.clickDiagramTypeDropdown();
|
|
227
228
|
await modelerHomePage.clickBpmnTemplateOption();
|
|
228
229
|
});
|
|
@@ -392,7 +393,8 @@ if (process.env.IS_MT === 'true') {
|
|
|
392
393
|
});
|
|
393
394
|
}
|
|
394
395
|
});
|
|
395
|
-
|
|
396
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
397
|
+
SM_8_10_1.test.skip('User Can Be Assigned To Multiple Tenants @tasklistV2', async ({ page, modelerHomePage, modelerCreatePage, operateProcessInstancePage, operateProcessesPage, operateHomePage, navigationPage, managementIdentityTenantPage, connectorSettingsPage, connectorMarketplacePage, ocIdentityHomePage, ocTenantPage, managementIdentityPage, }) => {
|
|
396
398
|
SM_8_10_1.test.slow();
|
|
397
399
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
398
400
|
const processName1 = 'Multiple_Tenant_Flow_1' + randomString;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const SM_8_10_1 = require("../../fixtures/SM-8.10");
|
|
5
|
+
const ModelerCreatePage_1 = require("../../pages/SM-8.10/ModelerCreatePage");
|
|
6
|
+
const ModelerHomePage_1 = require("../../pages/SM-8.10/ModelerHomePage");
|
|
7
|
+
const NavigationPage_1 = require("../../pages/SM-8.10/NavigationPage");
|
|
8
|
+
const UtilitiesPage_1 = require("../../pages/SM-8.10/UtilitiesPage");
|
|
9
|
+
const _setup_1 = require("../../test-setup.js");
|
|
10
|
+
SM_8_10_1.test.afterEach(async ({ page }, testInfo) => {
|
|
11
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
12
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
13
|
+
});
|
|
14
|
+
(0, SM_8_10_1.test)('Topology orchestration golden path @tasklistV2', async ({ navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, optimizeHomePage, page, request, }) => {
|
|
15
|
+
SM_8_10_1.test.slow();
|
|
16
|
+
const processName = `Topology_Orchestration_${await (0, _setup_1.generateRandomStringAsync)(5)}`;
|
|
17
|
+
const hubNavigationPage = new NavigationPage_1.NavigationPage(page);
|
|
18
|
+
const modelerHomePage = new ModelerHomePage_1.ModelerHomePage(page);
|
|
19
|
+
const modelerCreatePage = new ModelerCreatePage_1.ModelerCreatePage(page);
|
|
20
|
+
await SM_8_10_1.test.step('Create and start a process in Web Modeler', async () => {
|
|
21
|
+
await hubNavigationPage.goToModeler();
|
|
22
|
+
await modelerHomePage.createCrossComponentProjectFolder();
|
|
23
|
+
await modelerHomePage.clickDiagramTypeDropdown();
|
|
24
|
+
await modelerHomePage.clickBpmnTemplateOption();
|
|
25
|
+
await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processName);
|
|
26
|
+
await modelerCreatePage.runProcessInstance();
|
|
27
|
+
});
|
|
28
|
+
await SM_8_10_1.test.step('Assert the process instance is active in Operate', async () => {
|
|
29
|
+
await navigationPage.goToOperate();
|
|
30
|
+
await operateHomePage.clickProcessesTab();
|
|
31
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'active');
|
|
32
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrActiveIconVisible();
|
|
33
|
+
(0, test_1.expect)(result).toBe('active');
|
|
34
|
+
});
|
|
35
|
+
await SM_8_10_1.test.step('Complete the user task in Tasklist', async () => {
|
|
36
|
+
await navigationPage.goToTasklist();
|
|
37
|
+
await (0, UtilitiesPage_1.completeTaskWithRetry)(page, taskPanelPage, taskDetailsPage, processName, 'medium');
|
|
38
|
+
});
|
|
39
|
+
await SM_8_10_1.test.step('Assert the process instance is completed in Operate', async () => {
|
|
40
|
+
await navigationPage.goToOperate();
|
|
41
|
+
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 120000 });
|
|
42
|
+
await operateHomePage.clickProcessesTab();
|
|
43
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'completed');
|
|
44
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrCompletedIconVisible();
|
|
45
|
+
(0, test_1.expect)(result).toBe('completed');
|
|
46
|
+
});
|
|
47
|
+
if (process.env.IS_OPTIMIZE !== 'false') {
|
|
48
|
+
await SM_8_10_1.test.step('Assert the process is imported in Optimize', async () => {
|
|
49
|
+
await navigationPage.goToOptimize();
|
|
50
|
+
await optimizeHomePage.assertProcessHasBeenImported(processName);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await SM_8_10_1.test.step('Check Connectors readiness', async () => {
|
|
54
|
+
const response = await request.get('/connectors/actuator/health/readiness');
|
|
55
|
+
(0, test_1.expect)(response.status()).toBe(200);
|
|
56
|
+
(0, test_1.expect)(await response.json()).toMatchObject({ status: 'UP' });
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const SM_8_7_1 = require("../../fixtures/SM-8.7");
|
|
5
|
+
const ModelerCreatePage_1 = require("../../pages/SM-8.10/ModelerCreatePage");
|
|
6
|
+
const ModelerHomePage_1 = require("../../pages/SM-8.10/ModelerHomePage");
|
|
7
|
+
const NavigationPage_1 = require("../../pages/SM-8.10/NavigationPage");
|
|
8
|
+
const KeycloakUtils_1 = require("../../pages/SM-8.7/KeycloakUtils");
|
|
9
|
+
const UtlitiesPage_1 = require("../../pages/SM-8.7/UtlitiesPage");
|
|
10
|
+
const _setup_1 = require("../../test-setup.js");
|
|
11
|
+
const env_1 = require("../../utils/env");
|
|
12
|
+
SM_8_7_1.test.afterEach(async ({ page }, testInfo) => {
|
|
13
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
14
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
15
|
+
});
|
|
16
|
+
(0, SM_8_7_1.test)('Topology orchestration golden path', async ({ navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, optimizeHomePage, page, request, }) => {
|
|
17
|
+
SM_8_7_1.test.slow();
|
|
18
|
+
const processName = `Topology_Orchestration_${await (0, _setup_1.generateRandomStringAsync)(5)}`;
|
|
19
|
+
const hubNavigationPage = new NavigationPage_1.NavigationPage(page);
|
|
20
|
+
const modelerHomePage = new ModelerHomePage_1.ModelerHomePage(page);
|
|
21
|
+
const modelerCreatePage = new ModelerCreatePage_1.ModelerCreatePage(page);
|
|
22
|
+
(0, KeycloakUtils_1.setAdminUserCredentials)(navigationPage);
|
|
23
|
+
await SM_8_7_1.test.step('Create and start a process in Web Modeler', async () => {
|
|
24
|
+
await hubNavigationPage.goToModeler();
|
|
25
|
+
await modelerHomePage.clickCreateNewProjectButton();
|
|
26
|
+
await modelerHomePage.createCrossComponentProjectFolder();
|
|
27
|
+
await modelerHomePage.clickDiagramTypeDropdown();
|
|
28
|
+
await modelerHomePage.clickBpmnTemplateOption();
|
|
29
|
+
await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processName);
|
|
30
|
+
await modelerCreatePage.runProcessInstance();
|
|
31
|
+
});
|
|
32
|
+
await SM_8_7_1.test.step('Assert the process instance is active in Operate', async () => {
|
|
33
|
+
await navigationPage.goToOperate();
|
|
34
|
+
await operateHomePage.clickProcessesTab();
|
|
35
|
+
await operateProcessesPage.clickProcessInstanceLink(processName);
|
|
36
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrActiveIconVisible();
|
|
37
|
+
(0, test_1.expect)(result).toBe('active');
|
|
38
|
+
});
|
|
39
|
+
await SM_8_7_1.test.step('Complete the user task in Tasklist', async () => {
|
|
40
|
+
await navigationPage.goToTasklist();
|
|
41
|
+
await (0, UtlitiesPage_1.completeTaskWithRetry)(page, taskPanelPage, taskDetailsPage, processName, 'medium');
|
|
42
|
+
});
|
|
43
|
+
await SM_8_7_1.test.step('Assert the process instance is completed in Operate', async () => {
|
|
44
|
+
await navigationPage.goToOperate();
|
|
45
|
+
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 120000 });
|
|
46
|
+
await operateHomePage.clickProcessesTab();
|
|
47
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'completed');
|
|
48
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrCompletedIconVisible();
|
|
49
|
+
(0, test_1.expect)(result).toBe('completed');
|
|
50
|
+
});
|
|
51
|
+
if (process.env.IS_OPTIMIZE !== 'false' && !env_1.isOpenSearch) {
|
|
52
|
+
await SM_8_7_1.test.step('Assert the process is imported in Optimize', async () => {
|
|
53
|
+
await navigationPage.goToOptimize();
|
|
54
|
+
await optimizeHomePage.assertProcessHasBeenImported(processName);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
await SM_8_7_1.test.step('Check Connectors readiness', async () => {
|
|
58
|
+
const response = await request.get('/connectors/actuator/health/readiness');
|
|
59
|
+
(0, test_1.expect)(response.status()).toBe(200);
|
|
60
|
+
(0, test_1.expect)(await response.json()).toMatchObject({ status: 'UP' });
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const SM_8_8_1 = require("../../fixtures/SM-8.8");
|
|
5
|
+
const ModelerCreatePage_1 = require("../../pages/SM-8.10/ModelerCreatePage");
|
|
6
|
+
const ModelerHomePage_1 = require("../../pages/SM-8.10/ModelerHomePage");
|
|
7
|
+
const NavigationPage_1 = require("../../pages/SM-8.10/NavigationPage");
|
|
8
|
+
const UtilitiesPage_1 = require("../../pages/SM-8.8/UtilitiesPage");
|
|
9
|
+
const _setup_1 = require("../../test-setup.js");
|
|
10
|
+
SM_8_8_1.test.afterEach(async ({ page }, testInfo) => {
|
|
11
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
12
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
13
|
+
});
|
|
14
|
+
(0, SM_8_8_1.test)('Topology orchestration golden path @tasklistV2', async ({ navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, optimizeHomePage, page, request, }) => {
|
|
15
|
+
SM_8_8_1.test.slow();
|
|
16
|
+
const processName = `Topology_Orchestration_${await (0, _setup_1.generateRandomStringAsync)(5)}`;
|
|
17
|
+
const hubNavigationPage = new NavigationPage_1.NavigationPage(page);
|
|
18
|
+
const modelerHomePage = new ModelerHomePage_1.ModelerHomePage(page);
|
|
19
|
+
const modelerCreatePage = new ModelerCreatePage_1.ModelerCreatePage(page);
|
|
20
|
+
await SM_8_8_1.test.step('Create and start a process in Web Modeler', async () => {
|
|
21
|
+
await hubNavigationPage.goToModeler();
|
|
22
|
+
await modelerHomePage.createCrossComponentProjectFolder();
|
|
23
|
+
await modelerHomePage.clickDiagramTypeDropdown();
|
|
24
|
+
await modelerHomePage.clickBpmnTemplateOption();
|
|
25
|
+
await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processName);
|
|
26
|
+
await modelerCreatePage.runProcessInstance();
|
|
27
|
+
});
|
|
28
|
+
await SM_8_8_1.test.step('Assert the process instance is active in Operate', async () => {
|
|
29
|
+
await navigationPage.goToOperate();
|
|
30
|
+
await operateHomePage.clickProcessesTab();
|
|
31
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'active');
|
|
32
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrActiveIconVisible();
|
|
33
|
+
(0, test_1.expect)(result).toBe('active');
|
|
34
|
+
});
|
|
35
|
+
await SM_8_8_1.test.step('Complete the user task in Tasklist', async () => {
|
|
36
|
+
await navigationPage.goToTasklist();
|
|
37
|
+
await (0, UtilitiesPage_1.completeTaskWithRetry)(page, taskPanelPage, taskDetailsPage, processName, 'medium');
|
|
38
|
+
});
|
|
39
|
+
await SM_8_8_1.test.step('Assert the process instance is completed in Operate', async () => {
|
|
40
|
+
await navigationPage.goToOperate();
|
|
41
|
+
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 120000 });
|
|
42
|
+
await operateHomePage.clickProcessesTab();
|
|
43
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'completed');
|
|
44
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrCompletedIconVisible();
|
|
45
|
+
(0, test_1.expect)(result).toBe('completed');
|
|
46
|
+
});
|
|
47
|
+
if (process.env.IS_OPTIMIZE !== 'false') {
|
|
48
|
+
await SM_8_8_1.test.step('Assert the process is imported in Optimize', async () => {
|
|
49
|
+
await navigationPage.goToOptimize();
|
|
50
|
+
await optimizeHomePage.assertProcessHasBeenImported(processName);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await SM_8_8_1.test.step('Check Connectors readiness', async () => {
|
|
54
|
+
const response = await request.get('/connectors/actuator/health/readiness');
|
|
55
|
+
(0, test_1.expect)(response.status()).toBe(200);
|
|
56
|
+
(0, test_1.expect)(await response.json()).toMatchObject({ status: 'UP' });
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const SM_8_9_1 = require("../../fixtures/SM-8.9");
|
|
5
|
+
const ModelerCreatePage_1 = require("../../pages/SM-8.10/ModelerCreatePage");
|
|
6
|
+
const ModelerHomePage_1 = require("../../pages/SM-8.10/ModelerHomePage");
|
|
7
|
+
const NavigationPage_1 = require("../../pages/SM-8.10/NavigationPage");
|
|
8
|
+
const UtilitiesPage_1 = require("../../pages/SM-8.9/UtilitiesPage");
|
|
9
|
+
const _setup_1 = require("../../test-setup.js");
|
|
10
|
+
SM_8_9_1.test.afterEach(async ({ page }, testInfo) => {
|
|
11
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
12
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
13
|
+
});
|
|
14
|
+
(0, SM_8_9_1.test)('Topology orchestration golden path @tasklistV2', async ({ navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, optimizeHomePage, page, request, }) => {
|
|
15
|
+
SM_8_9_1.test.slow();
|
|
16
|
+
const processName = `Topology_Orchestration_${await (0, _setup_1.generateRandomStringAsync)(5)}`;
|
|
17
|
+
const hubNavigationPage = new NavigationPage_1.NavigationPage(page);
|
|
18
|
+
const modelerHomePage = new ModelerHomePage_1.ModelerHomePage(page);
|
|
19
|
+
const modelerCreatePage = new ModelerCreatePage_1.ModelerCreatePage(page);
|
|
20
|
+
await SM_8_9_1.test.step('Create and start a process in Web Modeler', async () => {
|
|
21
|
+
await hubNavigationPage.goToModeler();
|
|
22
|
+
await modelerHomePage.createCrossComponentProjectFolder();
|
|
23
|
+
await modelerHomePage.clickDiagramTypeDropdown();
|
|
24
|
+
await modelerHomePage.clickBpmnTemplateOption();
|
|
25
|
+
await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processName);
|
|
26
|
+
await modelerCreatePage.runProcessInstance();
|
|
27
|
+
});
|
|
28
|
+
await SM_8_9_1.test.step('Assert the process instance is active in Operate', async () => {
|
|
29
|
+
await navigationPage.goToOperate();
|
|
30
|
+
await operateHomePage.clickProcessesTab();
|
|
31
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'active');
|
|
32
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrActiveIconVisible();
|
|
33
|
+
(0, test_1.expect)(result).toBe('active');
|
|
34
|
+
});
|
|
35
|
+
await SM_8_9_1.test.step('Complete the user task in Tasklist', async () => {
|
|
36
|
+
await navigationPage.goToTasklist();
|
|
37
|
+
await (0, UtilitiesPage_1.completeTaskWithRetry)(page, taskPanelPage, taskDetailsPage, processName, 'medium');
|
|
38
|
+
});
|
|
39
|
+
await SM_8_9_1.test.step('Assert the process instance is completed in Operate', async () => {
|
|
40
|
+
await navigationPage.goToOperate();
|
|
41
|
+
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 120000 });
|
|
42
|
+
await operateHomePage.clickProcessesTab();
|
|
43
|
+
await operateProcessesPage.clickProcessInstanceLink(processName, 'completed');
|
|
44
|
+
const result = await operateProcessInstancePage.assertEitherIncidentOrCompletedIconVisible();
|
|
45
|
+
(0, test_1.expect)(result).toBe('completed');
|
|
46
|
+
});
|
|
47
|
+
if (process.env.IS_OPTIMIZE !== 'false') {
|
|
48
|
+
await SM_8_9_1.test.step('Assert the process is imported in Optimize', async () => {
|
|
49
|
+
await navigationPage.goToOptimize();
|
|
50
|
+
await optimizeHomePage.assertProcessHasBeenImported(processName);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await SM_8_9_1.test.step('Check Connectors readiness', async () => {
|
|
54
|
+
const response = await request.get('/connectors/actuator/health/readiness');
|
|
55
|
+
(0, test_1.expect)(response.status()).toBe(200);
|
|
56
|
+
(0, test_1.expect)(await response.json()).toMatchObject({ status: 'UP' });
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -32,7 +32,8 @@ c8Run_8_7_1.test.describe('Connectors User Flow Tests', () => {
|
|
|
32
32
|
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
33
33
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
34
34
|
});
|
|
35
|
-
|
|
35
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
36
|
+
c8Run_8_7_1.test.skip('REST Connector No Auth User Flow', async ({ operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
36
37
|
await c8Run_8_7_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
37
38
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
38
39
|
await operateHomePage.clickProcessesTab();
|
|
@@ -47,7 +48,8 @@ c8Run_8_7_1.test.describe('Connectors User Flow Tests', () => {
|
|
|
47
48
|
});
|
|
48
49
|
});
|
|
49
50
|
});
|
|
50
|
-
|
|
51
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
52
|
+
c8Run_8_7_1.test.skip('REST Connector Basic Auth User Flow', async ({ operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
51
53
|
await c8Run_8_7_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
52
54
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
53
55
|
await operateHomePage.clickProcessesTab();
|
|
@@ -62,7 +64,8 @@ c8Run_8_7_1.test.describe('Connectors User Flow Tests', () => {
|
|
|
62
64
|
});
|
|
63
65
|
});
|
|
64
66
|
});
|
|
65
|
-
|
|
67
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
68
|
+
c8Run_8_7_1.test.skip('REST Connector Bearer Token Auth User Flow', async ({ operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
66
69
|
await c8Run_8_7_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
67
70
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
68
71
|
await operateHomePage.clickProcessesTab();
|
|
@@ -33,7 +33,8 @@ c8Run_8_8_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
33
33
|
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
34
34
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
35
35
|
});
|
|
36
|
-
|
|
36
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
37
|
+
c8Run_8_8_1.test.skip('REST Connector No Auth User Flow', async ({ page, operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
37
38
|
await c8Run_8_8_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
38
39
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
39
40
|
await operateHomePage.clickProcessesTab();
|
|
@@ -44,7 +45,8 @@ c8Run_8_8_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
44
45
|
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(page, operateProcessInstancePage.statusVariable.getByText('"Awesome!"'), 'Status variable text');
|
|
45
46
|
});
|
|
46
47
|
});
|
|
47
|
-
|
|
48
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
49
|
+
c8Run_8_8_1.test.skip('REST Connector Basic Auth User Flow', async ({ page, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
48
50
|
await c8Run_8_8_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
49
51
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
50
52
|
await operateHomePage.clickProcessesTab();
|
|
@@ -55,7 +57,8 @@ c8Run_8_8_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
55
57
|
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(page, operateProcessInstancePage.messageVariable.getByText('"Awesome!"'), 'Status variable text');
|
|
56
58
|
});
|
|
57
59
|
});
|
|
58
|
-
|
|
60
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
61
|
+
c8Run_8_8_1.test.skip('REST Connector Bearer Token Auth User Flow', async ({ operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
59
62
|
await c8Run_8_8_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
60
63
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
61
64
|
await operateHomePage.clickProcessesTab();
|
|
@@ -43,7 +43,8 @@ c8Run_8_9_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
43
43
|
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
44
44
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
45
45
|
});
|
|
46
|
-
|
|
46
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
47
|
+
c8Run_8_9_1.test.skip('REST Connector No Auth User Flow', async ({ page, operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
47
48
|
await c8Run_8_9_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
48
49
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
49
50
|
await operateHomePage.clickProcessesTab();
|
|
@@ -54,7 +55,8 @@ c8Run_8_9_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
54
55
|
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(page, operateProcessInstancePage.statusVariable.getByText('"Awesome!"'), 'Status variable text');
|
|
55
56
|
});
|
|
56
57
|
});
|
|
57
|
-
|
|
58
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
59
|
+
c8Run_8_9_1.test.skip('REST Connector Basic Auth User Flow', async ({ page, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
58
60
|
await c8Run_8_9_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
59
61
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
60
62
|
await operateHomePage.clickProcessesTab();
|
|
@@ -65,7 +67,8 @@ c8Run_8_9_1.test.describe('Connectors User Flow Tests @tasklistV2', () => {
|
|
|
65
67
|
await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(page, operateProcessInstancePage.messageVariable.getByText('"Awesome!"'), 'Status variable text');
|
|
66
68
|
});
|
|
67
69
|
});
|
|
68
|
-
|
|
70
|
+
// Skipped due to bug #3673: https://github.com/camunda/c8-cross-component-e2e-tests/issues/3673
|
|
71
|
+
c8Run_8_9_1.test.skip('REST Connector Bearer Token Auth User Flow', async ({ operateHomePage, operateProcessInstancePage, operateProcessesPage, }) => {
|
|
69
72
|
await c8Run_8_9_1.test.step('View Process Instance in Operate, assert it completes and assert result expression', async () => {
|
|
70
73
|
await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
|
|
71
74
|
await operateHomePage.clickProcessesTab();
|
|
@@ -9,11 +9,9 @@ import { Locator } from '@playwright/test';
|
|
|
9
9
|
* Two dialog generations are in the field:
|
|
10
10
|
*
|
|
11
11
|
* - The legacy one offers a per-deploy cluster combobox labelled "Select a cluster".
|
|
12
|
-
* - Hub's
|
|
13
|
-
*
|
|
14
|
-
* and arrives with the
|
|
15
|
-
*
|
|
16
|
-
* Hence keying the trigger on its id rather than its accessible name: the id says what the
|
|
17
|
-
* control is for and has survived the rename, the label is prose and did not.
|
|
12
|
+
* - Hub's environment-based one (camunda-hub#29210 "Environments phase1") offers a radio list under
|
|
13
|
+
* the "environment-selection-heading" heading, one row per Environment assigned to the deploy's
|
|
14
|
+
* workspace (`[data-test="environment-row-*"]`), and arrives with the first Environment
|
|
15
|
+
* preselected.
|
|
18
16
|
*/
|
|
19
17
|
export declare function selectModelerCluster(dialog: Locator): Promise<void>;
|
|
@@ -12,12 +12,10 @@ const test_1 = require("@playwright/test");
|
|
|
12
12
|
* Two dialog generations are in the field:
|
|
13
13
|
*
|
|
14
14
|
* - The legacy one offers a per-deploy cluster combobox labelled "Select a cluster".
|
|
15
|
-
* - Hub's
|
|
16
|
-
*
|
|
17
|
-
* and arrives with the
|
|
18
|
-
*
|
|
19
|
-
* Hence keying the trigger on its id rather than its accessible name: the id says what the
|
|
20
|
-
* control is for and has survived the rename, the label is prose and did not.
|
|
15
|
+
* - Hub's environment-based one (camunda-hub#29210 "Environments phase1") offers a radio list under
|
|
16
|
+
* the "environment-selection-heading" heading, one row per Environment assigned to the deploy's
|
|
17
|
+
* workspace (`[data-test="environment-row-*"]`), and arrives with the first Environment
|
|
18
|
+
* preselected.
|
|
21
19
|
*/
|
|
22
20
|
async function selectModelerCluster(dialog) {
|
|
23
21
|
const modelerClusterName = process.env.MODELER_CLUSTER_NAME;
|
|
@@ -25,49 +23,74 @@ async function selectModelerCluster(dialog) {
|
|
|
25
23
|
return;
|
|
26
24
|
}
|
|
27
25
|
const page = dialog.page();
|
|
28
|
-
const stageSelect = dialog.locator('#cluster-selection-dropdown');
|
|
29
26
|
const legacySelect = dialog.getByRole('combobox', {
|
|
30
27
|
name: 'Select a cluster',
|
|
31
28
|
});
|
|
29
|
+
const environmentHeading = dialog.locator('#environment-selection-heading');
|
|
32
30
|
// Wait on the union so whichever generation this dialog is settles the wait, instead of paying a
|
|
33
31
|
// full timeout probing the other one first.
|
|
34
|
-
const appeared = await
|
|
35
|
-
.or(
|
|
32
|
+
const appeared = await legacySelect
|
|
33
|
+
.or(environmentHeading)
|
|
36
34
|
.first()
|
|
37
35
|
.waitFor({ state: 'visible', timeout: 30000 })
|
|
38
36
|
.then(() => true)
|
|
39
37
|
.catch(() => false);
|
|
40
38
|
if (!appeared) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
'
|
|
43
|
-
'
|
|
39
|
+
throw new Error('The deploy dialog offers no cluster/environment selector: neither a "Select a cluster" ' +
|
|
40
|
+
'combobox (legacy dialog) nor #environment-selection-heading (environment-based dialog) ' +
|
|
41
|
+
'became visible.');
|
|
42
|
+
}
|
|
43
|
+
if (await environmentHeading.isVisible().catch(() => false)) {
|
|
44
|
+
await selectDeployEnvironment(dialog, modelerClusterName);
|
|
45
|
+
return;
|
|
44
46
|
}
|
|
45
|
-
const
|
|
46
|
-
? stageSelect
|
|
47
|
-
: legacySelect;
|
|
48
|
-
// The stage dialog arrives with the bound cluster already selected, so the usual outcome is that
|
|
49
|
-
// nothing is clicked at all. That is not just a saved click: the option list unmounts on the
|
|
50
|
-
// click that lands, so every open is a chance to lose that race.
|
|
51
|
-
const selected = (await clusterSelect.textContent()) ?? '';
|
|
47
|
+
const selected = (await legacySelect.textContent()) ?? '';
|
|
52
48
|
if (!selected.includes(modelerClusterName)) {
|
|
53
|
-
await
|
|
49
|
+
await legacySelect.click();
|
|
54
50
|
const escapedClusterName = modelerClusterName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
// boundary. A legacy option is just "<cluster> (<status>)". Anchoring the start therefore
|
|
59
|
-
// matches neither reliably; the trailing " (" is what keeps the match honest, and is enough
|
|
60
|
-
// on its own to tell "Orch" from "Orchestration A".
|
|
61
|
-
const optionName = new RegExp(`${escapedClusterName}(?:\\s*\\(|$)`);
|
|
62
|
-
// The stage select is a Radix UI Select: its listbox is portalled to document.body, OUTSIDE
|
|
63
|
-
// the dialog element, so a dialog-scoped option query never resolves even while the option is
|
|
64
|
-
// visible on screen. Query at page scope; the trigger above stays dialog-scoped because it
|
|
65
|
-
// renders inside the dialog.
|
|
51
|
+
// An option's accessible name is "<cluster> (<status>)" -- anchor the start so "Orch" cannot
|
|
52
|
+
// match "Orchestration A".
|
|
53
|
+
const optionName = new RegExp(`^${escapedClusterName}(?:\\s*\\(|$)`);
|
|
66
54
|
await page
|
|
67
55
|
.getByRole('option', { name: optionName })
|
|
68
56
|
.first()
|
|
69
57
|
.click({ timeout: 30000 });
|
|
70
58
|
}
|
|
71
|
-
await (0, test_1.expect)(
|
|
59
|
+
await (0, test_1.expect)(legacySelect).toContainText(modelerClusterName);
|
|
72
60
|
}
|
|
73
61
|
exports.selectModelerCluster = selectModelerCluster;
|
|
62
|
+
/**
|
|
63
|
+
* Picks a row in the environment-based deploy dialog (camunda-hub#29210). Each row is
|
|
64
|
+
* `[data-test="environment-row-<id>"]`, one per Environment assigned to the deploy's workspace, and
|
|
65
|
+
* the dialog preselects the first one -- so with no cluster name to match, the preselection is left
|
|
66
|
+
* alone.
|
|
67
|
+
*
|
|
68
|
+
* This suite's single-cluster topology gives each cluster exactly one Environment, whose row shows
|
|
69
|
+
* no separate cluster subtext -- so the row's only visible identifying text is the Environment's
|
|
70
|
+
* own name, matched here on the assumption that it is named after its cluster (true for how this
|
|
71
|
+
* suite's clusters are registered). A row that does carry a distinct cluster subtext also matches,
|
|
72
|
+
* since `hasText` scans the whole row.
|
|
73
|
+
*/
|
|
74
|
+
async function selectDeployEnvironment(dialog, clusterName) {
|
|
75
|
+
const rows = dialog.locator('[data-test^="environment-row-"]');
|
|
76
|
+
await (0, test_1.expect)(rows.first()).toBeVisible({ timeout: 30000 });
|
|
77
|
+
const target = rows.filter({ hasText: clusterName }).first();
|
|
78
|
+
const targetAppeared = await target
|
|
79
|
+
.waitFor({ state: 'visible', timeout: 30000 })
|
|
80
|
+
.then(() => true)
|
|
81
|
+
.catch(() => false);
|
|
82
|
+
if (!targetAppeared) {
|
|
83
|
+
throw new Error(`No Environment backed by cluster "${clusterName}" is assigned to this deploy's workspace -- ` +
|
|
84
|
+
"none of the deploy dialog's environment rows matched that name. Assign it via the " +
|
|
85
|
+
"workspace's Environments settings tab first (see ProcessApplicationPage.ensureStageCluster).");
|
|
86
|
+
}
|
|
87
|
+
const alreadySelected = await target
|
|
88
|
+
.getByRole('radio', { checked: true })
|
|
89
|
+
.isVisible()
|
|
90
|
+
.catch(() => false);
|
|
91
|
+
if (alreadySelected) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
await target.getByRole('radio').click({ timeout: 30000 });
|
|
95
|
+
await (0, test_1.expect)(target).toContainText(clusterName);
|
|
96
|
+
}
|
package/package.json
CHANGED
package/playwright.config.ts
CHANGED
|
@@ -254,6 +254,9 @@ const dependencies = (project: string) => {
|
|
|
254
254
|
return [`${project}-setup`];
|
|
255
255
|
};
|
|
256
256
|
|
|
257
|
+
const regularTestIgnore =
|
|
258
|
+
/(?:test-setup|hub-web-modeler-smoke|topology-orchestration-smoke)\.spec\.[jt]s$/;
|
|
259
|
+
|
|
257
260
|
export default defineConfig({
|
|
258
261
|
testDir: process.env.MINOR_VERSION
|
|
259
262
|
? `./tests/${process.env.MINOR_VERSION}/`
|
|
@@ -293,13 +296,23 @@ export default defineConfig({
|
|
|
293
296
|
testMatch: changedFolders.includes('chromium')
|
|
294
297
|
? changedFolders.map((folder) => `**/${folder}/*.spec.ts`)
|
|
295
298
|
: undefined,
|
|
296
|
-
testIgnore:
|
|
299
|
+
testIgnore: regularTestIgnore,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: 'hub-web-modeler',
|
|
303
|
+
use: devices['Desktop Chrome'],
|
|
304
|
+
testMatch: /hub-web-modeler-smoke\.spec\.[jt]s$/,
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: 'topology-orchestration',
|
|
308
|
+
use: devices['Desktop Chrome'],
|
|
309
|
+
testMatch: /topology-orchestration-smoke\.spec\.[jt]s$/,
|
|
297
310
|
},
|
|
298
311
|
{
|
|
299
312
|
name: 'firefox',
|
|
300
313
|
use: devices['Desktop Firefox'],
|
|
301
314
|
dependencies: dependencies('firefox'),
|
|
302
|
-
testIgnore:
|
|
315
|
+
testIgnore: regularTestIgnore,
|
|
303
316
|
},
|
|
304
317
|
{
|
|
305
318
|
name: 'msedge',
|
|
@@ -309,7 +322,7 @@ export default defineConfig({
|
|
|
309
322
|
channel: 'msedge',
|
|
310
323
|
},
|
|
311
324
|
dependencies: dependencies('msedge'),
|
|
312
|
-
testIgnore:
|
|
325
|
+
testIgnore: regularTestIgnore,
|
|
313
326
|
},
|
|
314
327
|
{
|
|
315
328
|
name: 'chromium-setup',
|
|
@@ -340,7 +353,7 @@ export default defineConfig({
|
|
|
340
353
|
},
|
|
341
354
|
},
|
|
342
355
|
dependencies: ['chromium-v1-setup'],
|
|
343
|
-
testIgnore:
|
|
356
|
+
testIgnore: regularTestIgnore,
|
|
344
357
|
grep: /^(?!.*@tasklistV2).*$/,
|
|
345
358
|
},
|
|
346
359
|
|
|
@@ -353,7 +366,7 @@ export default defineConfig({
|
|
|
353
366
|
},
|
|
354
367
|
},
|
|
355
368
|
dependencies: ['chromium-v2-setup'],
|
|
356
|
-
testIgnore:
|
|
369
|
+
testIgnore: regularTestIgnore,
|
|
357
370
|
grep: /^(?!.*@tasklistV1).*$/,
|
|
358
371
|
},
|
|
359
372
|
|