@camunda/e2e-test-suite 0.0.828 → 0.0.830
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/fixtures/8.10.d.ts +2 -0
- package/dist/fixtures/8.10.js +4 -0
- package/dist/pages/8.10/OptimizeSharePage.d.ts +16 -0
- package/dist/pages/8.10/OptimizeSharePage.js +92 -0
- package/dist/tests/8.10/optimize-sharing-alerts-export-ui.spec.d.ts +1 -0
- package/dist/tests/8.10/optimize-sharing-alerts-export-ui.spec.js +181 -0
- package/package.json +1 -1
package/dist/fixtures/8.10.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { OptimizeCollectionsPage } from '../pages/8.10/OptimizeCollectionsPage';
|
|
|
15
15
|
import { OptimizeHomePage } from '../pages/8.10/OptimizeHomePage';
|
|
16
16
|
import { FormJsPage } from '../pages/8.10/FormJsPage';
|
|
17
17
|
import { OptimizeReportPage } from '../pages/8.10/OptimizeReportPage';
|
|
18
|
+
import { OptimizeSharePage } from '../pages/8.10/OptimizeSharePage';
|
|
18
19
|
import { ConsoleOrganizationPage } from '../pages/8.10/ConsoleOrganizationPage';
|
|
19
20
|
import { SettingsPage } from '../pages/8.10/SettingsPage';
|
|
20
21
|
import { ConnectorSettingsPage } from '../pages/8.10/ConnectorSettingsPage';
|
|
@@ -54,6 +55,7 @@ type PlaywrightFixtures = {
|
|
|
54
55
|
optimizeHomePage: OptimizeHomePage;
|
|
55
56
|
formJsPage: FormJsPage;
|
|
56
57
|
optimizeReportPage: OptimizeReportPage;
|
|
58
|
+
optimizeSharePage: OptimizeSharePage;
|
|
57
59
|
consoleOrganizationsPage: ConsoleOrganizationPage;
|
|
58
60
|
settingsPage: SettingsPage;
|
|
59
61
|
connectorSettingsPage: ConnectorSettingsPage;
|
package/dist/fixtures/8.10.js
CHANGED
|
@@ -22,6 +22,7 @@ const OptimizeCollectionsPage_1 = require("../pages/8.10/OptimizeCollectionsPage
|
|
|
22
22
|
const OptimizeHomePage_1 = require("../pages/8.10/OptimizeHomePage");
|
|
23
23
|
const FormJsPage_1 = require("../pages/8.10/FormJsPage");
|
|
24
24
|
const OptimizeReportPage_1 = require("../pages/8.10/OptimizeReportPage");
|
|
25
|
+
const OptimizeSharePage_1 = require("../pages/8.10/OptimizeSharePage");
|
|
25
26
|
const ConsoleOrganizationPage_1 = require("../pages/8.10/ConsoleOrganizationPage");
|
|
26
27
|
const SettingsPage_1 = require("../pages/8.10/SettingsPage");
|
|
27
28
|
const ConnectorSettingsPage_1 = require("../pages/8.10/ConnectorSettingsPage");
|
|
@@ -115,6 +116,9 @@ const test = test_1.test.extend({
|
|
|
115
116
|
optimizeReportPage: async ({ page }, use) => {
|
|
116
117
|
await use(new OptimizeReportPage_1.OptimizeReportPage(page));
|
|
117
118
|
},
|
|
119
|
+
optimizeSharePage: async ({ page }, use) => {
|
|
120
|
+
await use(new OptimizeSharePage_1.OptimizeSharePage(page));
|
|
121
|
+
},
|
|
118
122
|
consoleOrganizationsPage: async ({ page }, use) => {
|
|
119
123
|
await use(new ConsoleOrganizationPage_1.ConsoleOrganizationPage(page));
|
|
120
124
|
},
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
declare class OptimizeSharePage {
|
|
3
|
+
private page;
|
|
4
|
+
readonly shareButton: Locator;
|
|
5
|
+
readonly enableSharingToggle: Locator;
|
|
6
|
+
readonly sharingToggleLabel: Locator;
|
|
7
|
+
readonly shareLinkInput: Locator;
|
|
8
|
+
readonly downloadButton: Locator;
|
|
9
|
+
constructor(page: Page);
|
|
10
|
+
openEntityById(baseUrl: string, entityType: 'report' | 'dashboard', entityId: string): Promise<void>;
|
|
11
|
+
enableSharing(): Promise<void>;
|
|
12
|
+
assertShareLinkVisible(): Promise<void>;
|
|
13
|
+
disableSharing(): Promise<void>;
|
|
14
|
+
assertDownloadOptionAvailable(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export { OptimizeSharePage };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OptimizeSharePage = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
class OptimizeSharePage {
|
|
6
|
+
page;
|
|
7
|
+
shareButton;
|
|
8
|
+
enableSharingToggle;
|
|
9
|
+
sharingToggleLabel;
|
|
10
|
+
shareLinkInput;
|
|
11
|
+
downloadButton;
|
|
12
|
+
constructor(page) {
|
|
13
|
+
this.page = page;
|
|
14
|
+
this.shareButton = page
|
|
15
|
+
.locator('.share-button button')
|
|
16
|
+
.or(page.getByRole('button', { name: /share/i }))
|
|
17
|
+
.first();
|
|
18
|
+
this.enableSharingToggle = page
|
|
19
|
+
.locator('#sharingToggle')
|
|
20
|
+
.or(page.locator('.ShareEntity .cds--toggle__switch'))
|
|
21
|
+
.or(page.getByRole('switch'))
|
|
22
|
+
.first();
|
|
23
|
+
// Carbon's toggle overlays the <button role="switch"> with a <label> whose
|
|
24
|
+
// text/appearance intercepts pointer events, so clicking the switch button
|
|
25
|
+
// directly times out. The label (`for="sharingToggle"`) is the real click
|
|
26
|
+
// target that flips the toggle.
|
|
27
|
+
this.sharingToggleLabel = page
|
|
28
|
+
.locator('label[for="sharingToggle"]')
|
|
29
|
+
.or(page.locator('.ShareEntity .cds--toggle__label'))
|
|
30
|
+
.or(page.locator('.ShareEntity .cds--toggle__appearance'))
|
|
31
|
+
.first();
|
|
32
|
+
this.shareLinkInput = page
|
|
33
|
+
.locator('#sharingLinkText')
|
|
34
|
+
.or(page.locator('.ShareEntity input[type="text"]'))
|
|
35
|
+
.or(page.locator('input[value*="/share/"]'))
|
|
36
|
+
.first();
|
|
37
|
+
// Optimize renders the CSV export as a single icon button (DownloadButton)
|
|
38
|
+
// on raw-data reports, not a menu. Its accessible name comes from the
|
|
39
|
+
// `report.downloadCSV` label ("Download CSV").
|
|
40
|
+
this.downloadButton = page
|
|
41
|
+
.getByRole('button', { name: /download|csv/i })
|
|
42
|
+
.or(page.locator('.DownloadButton button'))
|
|
43
|
+
.or(page.locator('a.DownloadButton'))
|
|
44
|
+
.first();
|
|
45
|
+
}
|
|
46
|
+
async openEntityById(baseUrl, entityType, entityId) {
|
|
47
|
+
const url = `${baseUrl}/#/${entityType}/${entityId}`;
|
|
48
|
+
await this.page.goto(url, {
|
|
49
|
+
waitUntil: 'domcontentloaded',
|
|
50
|
+
timeout: 60000,
|
|
51
|
+
});
|
|
52
|
+
// Optimize is a HashRouter single-page app. When the browser is already on
|
|
53
|
+
// an Optimize page (e.g. the home dashboard), a hash-only navigation does
|
|
54
|
+
// not reliably trigger the router to render the target entity view. Force a
|
|
55
|
+
// full document reload at the hash route so the entity (and its
|
|
56
|
+
// always-present Share control) renders from scratch. Use waitFor (which
|
|
57
|
+
// actually polls) rather than isVisible (a one-shot check), reloading only
|
|
58
|
+
// when the Share control still hasn't rendered.
|
|
59
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
60
|
+
const shareVisible = await this.shareButton
|
|
61
|
+
.waitFor({ state: 'visible', timeout: 10000 })
|
|
62
|
+
.then(() => true)
|
|
63
|
+
.catch(() => false);
|
|
64
|
+
if (shareVisible) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
await this.page.reload({ waitUntil: 'domcontentloaded' });
|
|
68
|
+
}
|
|
69
|
+
await (0, test_1.expect)(this.shareButton).toBeVisible({ timeout: 30000 });
|
|
70
|
+
}
|
|
71
|
+
async enableSharing() {
|
|
72
|
+
await this.shareButton.click({ timeout: 30000 });
|
|
73
|
+
await (0, test_1.expect)(this.enableSharingToggle).toBeVisible({ timeout: 30000 });
|
|
74
|
+
await this.sharingToggleLabel.click({ timeout: 30000 });
|
|
75
|
+
}
|
|
76
|
+
async assertShareLinkVisible() {
|
|
77
|
+
await (0, test_1.expect)(this.shareLinkInput).toBeVisible({ timeout: 30000 });
|
|
78
|
+
// Enabling sharing triggers an async backend call that generates the public
|
|
79
|
+
// share URL; the input is briefly empty until it resolves. toHaveValue
|
|
80
|
+
// auto-retries until the value is populated, avoiding a race with a
|
|
81
|
+
// one-shot value read.
|
|
82
|
+
await (0, test_1.expect)(this.shareLinkInput).toHaveValue(/share/i, { timeout: 30000 });
|
|
83
|
+
}
|
|
84
|
+
async disableSharing() {
|
|
85
|
+
await (0, test_1.expect)(this.enableSharingToggle).toBeVisible({ timeout: 30000 });
|
|
86
|
+
await this.sharingToggleLabel.click({ timeout: 30000 });
|
|
87
|
+
}
|
|
88
|
+
async assertDownloadOptionAvailable() {
|
|
89
|
+
await (0, test_1.expect)(this.downloadButton).toBeVisible({ timeout: 30000 });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.OptimizeSharePage = OptimizeSharePage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const _8_10_1 = require("../../fixtures/8.10");
|
|
5
|
+
const _setup_1 = require("../../test-setup.js");
|
|
6
|
+
const UtilitiesPage_1 = require("../../pages/8.10/UtilitiesPage");
|
|
7
|
+
const users_1 = require("../../utils/users");
|
|
8
|
+
const apiHelpers_1 = require("../../utils/apiHelpers");
|
|
9
|
+
const randomName_1 = require("../../utils/randomName");
|
|
10
|
+
const testUser = (0, users_1.getTestUser)('mainUser');
|
|
11
|
+
const clusterName = 'Test Cluster';
|
|
12
|
+
const DEFINITION_KEY = 'customer_onboarding_en';
|
|
13
|
+
_8_10_1.test.describe.configure({ mode: 'parallel' });
|
|
14
|
+
_8_10_1.test.describe('Optimize Sharing & Export UI Tests @optimize-sharing-alerts-export-ui @8.10', () => {
|
|
15
|
+
let baseUrl;
|
|
16
|
+
let optimizeCookie;
|
|
17
|
+
let optimizeBearerToken;
|
|
18
|
+
let collectionId;
|
|
19
|
+
let reportId;
|
|
20
|
+
let csvReportId;
|
|
21
|
+
let dashboardId;
|
|
22
|
+
_8_10_1.test.beforeAll(async ({ browser, request }) => {
|
|
23
|
+
baseUrl = process.env.CAMUNDA_OPTIMIZE_BASE_URL;
|
|
24
|
+
const seedPage = await browser.newPage();
|
|
25
|
+
optimizeCookie = await (0, apiHelpers_1.getOptimizeCoockie)(seedPage);
|
|
26
|
+
await seedPage.close();
|
|
27
|
+
optimizeBearerToken = await (0, apiHelpers_1.authSaasAPI)(process.env.OPTIMIZE_API_TOKEN_AUDIENCE);
|
|
28
|
+
collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
29
|
+
name: await (0, randomName_1.randomNameAgregator)('Sharing UI Collection'),
|
|
30
|
+
optimizeCookie,
|
|
31
|
+
});
|
|
32
|
+
await (0, apiHelpers_1.updateCollectionScope)(request, {
|
|
33
|
+
optimizeCookie,
|
|
34
|
+
collectionId,
|
|
35
|
+
data: [
|
|
36
|
+
{
|
|
37
|
+
definitionKey: DEFINITION_KEY,
|
|
38
|
+
definitionType: 'process',
|
|
39
|
+
tenants: ['<default>'],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
// Build the report directly (rather than via the createSingleProcessReport
|
|
44
|
+
// helper, which sends an empty `data: {}` and nests the definition/view in
|
|
45
|
+
// `configuration`, so the fields below would be silently dropped).
|
|
46
|
+
const reportName = await (0, randomName_1.randomNameAgregator)('Sharing UI Report');
|
|
47
|
+
const reportResponse = await (0, apiHelpers_1.retryOn500)(() => request.post(`${baseUrl}/api/report/process/single`, {
|
|
48
|
+
headers: {
|
|
49
|
+
Cookie: optimizeCookie,
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
data: {
|
|
53
|
+
collectionId,
|
|
54
|
+
name: reportName,
|
|
55
|
+
data: {
|
|
56
|
+
definitions: [
|
|
57
|
+
{
|
|
58
|
+
identifier: 'definition_1',
|
|
59
|
+
key: DEFINITION_KEY,
|
|
60
|
+
versions: ['all'],
|
|
61
|
+
tenantIds: ['<default>'],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
filter: [],
|
|
65
|
+
view: { entity: 'processInstance', properties: ['frequency'] },
|
|
66
|
+
groupBy: { type: 'none', value: null },
|
|
67
|
+
distributedBy: { type: 'none', value: null },
|
|
68
|
+
visualization: 'number',
|
|
69
|
+
configuration: {},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}));
|
|
73
|
+
(0, test_1.expect)(reportResponse.status()).toBe(200);
|
|
74
|
+
reportId = (await reportResponse.json()).id;
|
|
75
|
+
dashboardId = await (0, apiHelpers_1.createDashboard)(request, {
|
|
76
|
+
name: await (0, randomName_1.randomNameAgregator)('Sharing UI Dashboard'),
|
|
77
|
+
optimizeCookie,
|
|
78
|
+
collectionId,
|
|
79
|
+
});
|
|
80
|
+
// Optimize only renders the CSV download action on raw-data reports
|
|
81
|
+
// (view.properties includes 'rawData'). Seed a dedicated raw-data report
|
|
82
|
+
// for the CSV export assertion. Wrapped in retryOn500 so a transient 5xx
|
|
83
|
+
// here doesn't fail every test in the file, matching the other setup calls.
|
|
84
|
+
const csvReportName = await (0, randomName_1.randomNameAgregator)('Sharing UI CSV Report');
|
|
85
|
+
const csvReportResponse = await (0, apiHelpers_1.retryOn500)(() => request.post(`${baseUrl}/api/report/process/single`, {
|
|
86
|
+
headers: {
|
|
87
|
+
Cookie: optimizeCookie,
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
data: {
|
|
91
|
+
collectionId,
|
|
92
|
+
name: csvReportName,
|
|
93
|
+
data: {
|
|
94
|
+
definitions: [
|
|
95
|
+
{
|
|
96
|
+
identifier: 'definition_1',
|
|
97
|
+
key: DEFINITION_KEY,
|
|
98
|
+
versions: ['all'],
|
|
99
|
+
tenantIds: ['<default>'],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
filter: [],
|
|
103
|
+
view: { entity: null, properties: ['rawData'] },
|
|
104
|
+
groupBy: { type: 'none', value: null },
|
|
105
|
+
distributedBy: { type: 'none', value: null },
|
|
106
|
+
visualization: 'table',
|
|
107
|
+
configuration: {},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
}));
|
|
111
|
+
(0, test_1.expect)(csvReportResponse.status()).toBe(200);
|
|
112
|
+
csvReportId = (await csvReportResponse.json()).id;
|
|
113
|
+
});
|
|
114
|
+
_8_10_1.test.beforeEach(async ({ page, loginPage }, testInfo) => {
|
|
115
|
+
await (0, UtilitiesPage_1.loginWithRetry)(page, loginPage, testUser, (testInfo.workerIndex + 1) * 1000);
|
|
116
|
+
});
|
|
117
|
+
_8_10_1.test.afterEach(async ({ page }, testInfo) => {
|
|
118
|
+
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
119
|
+
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
120
|
+
});
|
|
121
|
+
_8_10_1.test.afterAll(async ({ request }) => {
|
|
122
|
+
if (collectionId) {
|
|
123
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
124
|
+
headers: { Authorization: optimizeBearerToken },
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
(0, _8_10_1.test)('Enable report sharing and expose a public share link', async ({ appsPage, optimizeHomePage, optimizeSharePage, }) => {
|
|
129
|
+
await _8_10_1.test.step('Open Optimize from the Camunda apps launcher', async () => {
|
|
130
|
+
await appsPage.clickCamundaApps();
|
|
131
|
+
await appsPage.clickOptimize(clusterName);
|
|
132
|
+
await test_1.expect
|
|
133
|
+
.poll(async () => optimizeHomePage.optimizeBanner.isVisible({ timeout: 5000 }), { timeout: 120000 })
|
|
134
|
+
.toBe(true);
|
|
135
|
+
});
|
|
136
|
+
await _8_10_1.test.step('Navigate to the seeded report', async () => {
|
|
137
|
+
await optimizeSharePage.openEntityById(baseUrl, 'report', reportId);
|
|
138
|
+
});
|
|
139
|
+
await _8_10_1.test.step('Enable sharing and assert a public share link is generated', async () => {
|
|
140
|
+
await optimizeSharePage.enableSharing();
|
|
141
|
+
await optimizeSharePage.assertShareLinkVisible();
|
|
142
|
+
});
|
|
143
|
+
await _8_10_1.test.step('Disable sharing to leave the report in its original state', async () => {
|
|
144
|
+
await optimizeSharePage.disableSharing();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
(0, _8_10_1.test)('Report offers a CSV download/export action', async ({ appsPage, optimizeHomePage, optimizeSharePage, }) => {
|
|
148
|
+
await _8_10_1.test.step('Open Optimize from the Camunda apps launcher', async () => {
|
|
149
|
+
await appsPage.clickCamundaApps();
|
|
150
|
+
await appsPage.clickOptimize(clusterName);
|
|
151
|
+
await test_1.expect
|
|
152
|
+
.poll(async () => optimizeHomePage.optimizeBanner.isVisible({ timeout: 5000 }), { timeout: 120000 })
|
|
153
|
+
.toBe(true);
|
|
154
|
+
});
|
|
155
|
+
await _8_10_1.test.step('Navigate to the seeded raw-data report', async () => {
|
|
156
|
+
await optimizeSharePage.openEntityById(baseUrl, 'report', csvReportId);
|
|
157
|
+
});
|
|
158
|
+
await _8_10_1.test.step('Assert a CSV download/export action is available', async () => {
|
|
159
|
+
await optimizeSharePage.assertDownloadOptionAvailable();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
(0, _8_10_1.test)('Enable dashboard sharing and expose a public share link', async ({ appsPage, optimizeHomePage, optimizeSharePage, }) => {
|
|
163
|
+
await _8_10_1.test.step('Open Optimize from the Camunda apps launcher', async () => {
|
|
164
|
+
await appsPage.clickCamundaApps();
|
|
165
|
+
await appsPage.clickOptimize(clusterName);
|
|
166
|
+
await test_1.expect
|
|
167
|
+
.poll(async () => optimizeHomePage.optimizeBanner.isVisible({ timeout: 5000 }), { timeout: 120000 })
|
|
168
|
+
.toBe(true);
|
|
169
|
+
});
|
|
170
|
+
await _8_10_1.test.step('Navigate to the seeded dashboard', async () => {
|
|
171
|
+
await optimizeSharePage.openEntityById(baseUrl, 'dashboard', dashboardId);
|
|
172
|
+
});
|
|
173
|
+
await _8_10_1.test.step('Enable sharing and assert a public share link is generated', async () => {
|
|
174
|
+
await optimizeSharePage.enableSharing();
|
|
175
|
+
await optimizeSharePage.assertShareLinkVisible();
|
|
176
|
+
});
|
|
177
|
+
await _8_10_1.test.step('Disable sharing to leave the dashboard in its original state', async () => {
|
|
178
|
+
await optimizeSharePage.disableSharing();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|