@camunda/e2e-test-suite 0.0.819 → 0.0.821
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/tests/8.10/optimize-collections-api.spec.d.ts +1 -0
- package/dist/tests/8.10/optimize-collections-api.spec.js +172 -0
- package/dist/tests/8.10/optimize-sharing-alerts-export-api.spec.d.ts +1 -0
- package/dist/tests/8.10/optimize-sharing-alerts-export-api.spec.js +305 -0
- package/dist/utils/apiHelpers.d.ts +2 -0
- package/dist/utils/apiHelpers.js +29 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,172 @@
|
|
|
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 apiHelpers_1 = require("../../utils/apiHelpers");
|
|
6
|
+
const randomName_1 = require("../../utils/randomName");
|
|
7
|
+
_8_10_1.test.describe.configure({ mode: 'parallel' });
|
|
8
|
+
_8_10_1.test.describe('API Optimize Collections Lifecycle Tests @optimize-collections-api @8.10', () => {
|
|
9
|
+
let optimizeCookie;
|
|
10
|
+
let optimizeBearerToken;
|
|
11
|
+
let baseUrl;
|
|
12
|
+
_8_10_1.test.beforeAll(async ({ browser }) => {
|
|
13
|
+
const page = await browser.newPage();
|
|
14
|
+
optimizeCookie = await (0, apiHelpers_1.getOptimizeCoockie)(page);
|
|
15
|
+
await page.close();
|
|
16
|
+
optimizeBearerToken = await (0, apiHelpers_1.authSaasAPI)(process.env.OPTIMIZE_API_TOKEN_AUDIENCE);
|
|
17
|
+
baseUrl = process.env.CAMUNDA_OPTIMIZE_BASE_URL;
|
|
18
|
+
});
|
|
19
|
+
(0, _8_10_1.test)('Create a collection and retrieve it by ID (200)', async ({ request }) => {
|
|
20
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Create');
|
|
21
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
22
|
+
name: collectionName,
|
|
23
|
+
optimizeCookie,
|
|
24
|
+
});
|
|
25
|
+
await _8_10_1.test.step('GET /api/collection/{id} returns the created collection (200)', async () => {
|
|
26
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}`, { headers: { Cookie: optimizeCookie } });
|
|
27
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
28
|
+
const body = await response.json();
|
|
29
|
+
(0, test_1.expect)(body).toHaveProperty('id', collectionId);
|
|
30
|
+
(0, test_1.expect)(body).toHaveProperty('name', collectionName);
|
|
31
|
+
});
|
|
32
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
33
|
+
headers: { Authorization: optimizeBearerToken },
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, _8_10_1.test)('Rename a collection updates its name', async ({ request }) => {
|
|
37
|
+
const originalName = await (0, randomName_1.randomNameAgregator)('Collection Original');
|
|
38
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
39
|
+
name: originalName,
|
|
40
|
+
optimizeCookie,
|
|
41
|
+
});
|
|
42
|
+
const renamedName = await (0, randomName_1.randomNameAgregator)('Collection Renamed');
|
|
43
|
+
await _8_10_1.test.step('PUT /api/collection/{id} updates the collection name', async () => {
|
|
44
|
+
const response = await request.put(`${baseUrl}/api/collection/${collectionId}`, {
|
|
45
|
+
headers: {
|
|
46
|
+
Cookie: optimizeCookie,
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
},
|
|
49
|
+
data: { name: renamedName },
|
|
50
|
+
});
|
|
51
|
+
(0, test_1.expect)([200, 204]).toContain(response.status());
|
|
52
|
+
});
|
|
53
|
+
await _8_10_1.test.step('GET /api/collection/{id} reflects the new name', async () => {
|
|
54
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}`, { headers: { Cookie: optimizeCookie } });
|
|
55
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
56
|
+
const body = await response.json();
|
|
57
|
+
(0, test_1.expect)(body).toHaveProperty('name', renamedName);
|
|
58
|
+
});
|
|
59
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
60
|
+
headers: { Authorization: optimizeBearerToken },
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
(0, _8_10_1.test)('Update collection scope adds a process definition (200)', async ({ request, }) => {
|
|
64
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Scope');
|
|
65
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
66
|
+
name: collectionName,
|
|
67
|
+
optimizeCookie,
|
|
68
|
+
});
|
|
69
|
+
const definitionKey = 'customer_onboarding_en';
|
|
70
|
+
await _8_10_1.test.step('PUT /api/collection/{id}/scope adds a process definition', async () => {
|
|
71
|
+
await (0, apiHelpers_1.updateCollectionScope)(request, {
|
|
72
|
+
optimizeCookie,
|
|
73
|
+
collectionId,
|
|
74
|
+
data: [
|
|
75
|
+
{
|
|
76
|
+
definitionKey,
|
|
77
|
+
definitionType: 'process',
|
|
78
|
+
tenants: ['<default>'],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
await _8_10_1.test.step('GET /api/collection/{id} exposes the added scope entry', async () => {
|
|
84
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}`, { headers: { Cookie: optimizeCookie } });
|
|
85
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
86
|
+
const body = await response.json();
|
|
87
|
+
const scope = body?.data?.scope;
|
|
88
|
+
(0, test_1.expect)(Array.isArray(scope)).toBeTruthy();
|
|
89
|
+
(0, test_1.expect)(scope.some((entry) => entry.definitionKey === definitionKey)).toBeTruthy();
|
|
90
|
+
});
|
|
91
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
92
|
+
headers: { Authorization: optimizeBearerToken },
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
(0, _8_10_1.test)('Delete a collection and verify it is no longer retrievable', async ({ request, }) => {
|
|
96
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Delete');
|
|
97
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
98
|
+
name: collectionName,
|
|
99
|
+
optimizeCookie,
|
|
100
|
+
});
|
|
101
|
+
let deleteSucceeded = false;
|
|
102
|
+
await _8_10_1.test.step('DELETE /api/public/collection/{id} is accepted (200; SaaS may respond 500)', async () => {
|
|
103
|
+
const response = await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, { headers: { Authorization: optimizeBearerToken } });
|
|
104
|
+
(0, test_1.expect)([200, 500]).toContain(response.status());
|
|
105
|
+
deleteSucceeded = response.status() === 200;
|
|
106
|
+
});
|
|
107
|
+
await _8_10_1.test.step('Deleted collection is no longer retrievable when delete succeeded', async () => {
|
|
108
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}`, { headers: { Cookie: optimizeCookie } });
|
|
109
|
+
const acceptableStatuses = deleteSucceeded
|
|
110
|
+
? [401, 404, 500]
|
|
111
|
+
: [200, 401, 404, 500];
|
|
112
|
+
(0, test_1.expect)(acceptableStatuses).toContain(response.status());
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
(0, _8_10_1.test)('Create collection without auth cookie returns 401', async ({ request, }) => {
|
|
116
|
+
await _8_10_1.test.step('POST /api/collection without cookie (401)', async () => {
|
|
117
|
+
const response = await request.post(`${baseUrl}/api/collection`, {
|
|
118
|
+
headers: { 'Content-Type': 'application/json' },
|
|
119
|
+
data: { name: await (0, randomName_1.randomNameAgregator)('Unauthorized Collection') },
|
|
120
|
+
});
|
|
121
|
+
await (0, apiHelpers_1.assertUnauthorizedResponseBody)(response);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
(0, _8_10_1.test)('Get collection without auth cookie returns 401', async ({ request }) => {
|
|
125
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Auth Get');
|
|
126
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
127
|
+
name: collectionName,
|
|
128
|
+
optimizeCookie,
|
|
129
|
+
});
|
|
130
|
+
await _8_10_1.test.step('GET /api/collection/{id} without cookie (401)', async () => {
|
|
131
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}`);
|
|
132
|
+
await (0, apiHelpers_1.assertUnauthorizedResponseBody)(response);
|
|
133
|
+
});
|
|
134
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
135
|
+
headers: { Authorization: optimizeBearerToken },
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
(0, _8_10_1.test)('Delete collection without token returns 401', async ({ request }) => {
|
|
139
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Auth Delete');
|
|
140
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
141
|
+
name: collectionName,
|
|
142
|
+
optimizeCookie,
|
|
143
|
+
});
|
|
144
|
+
await _8_10_1.test.step('DELETE /api/public/collection/{id} without token (401)', async () => {
|
|
145
|
+
const response = await request.delete(`${baseUrl}/api/public/collection/${collectionId}`);
|
|
146
|
+
await (0, apiHelpers_1.assertUnauthorizedResponseBody)(response);
|
|
147
|
+
});
|
|
148
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
149
|
+
headers: { Authorization: optimizeBearerToken },
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
(0, _8_10_1.test)('Delete collection with invalid token returns 401', async ({ request, }) => {
|
|
153
|
+
const collectionName = await (0, randomName_1.randomNameAgregator)('Collection Invalid Token');
|
|
154
|
+
const collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
155
|
+
name: collectionName,
|
|
156
|
+
optimizeCookie,
|
|
157
|
+
});
|
|
158
|
+
await _8_10_1.test.step('DELETE /api/public/collection/{id} with invalid token (401)', async () => {
|
|
159
|
+
const response = await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, { headers: { Authorization: 'Bearer invalid_token' } });
|
|
160
|
+
await (0, apiHelpers_1.assertUnauthorizedResponseBody)(response);
|
|
161
|
+
});
|
|
162
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
163
|
+
headers: { Authorization: optimizeBearerToken },
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
(0, _8_10_1.test)('Delete non-existent collection is rejected (404; SaaS may respond 500)', async ({ request, }) => {
|
|
167
|
+
await _8_10_1.test.step('DELETE /api/public/collection/{id} for missing collection', async () => {
|
|
168
|
+
const response = await request.delete(`${baseUrl}/api/public/collection/nonexistent-collection-id`, { headers: { Authorization: optimizeBearerToken } });
|
|
169
|
+
(0, test_1.expect)([404, 500]).toContain(response.status());
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,305 @@
|
|
|
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 apiHelpers_1 = require("../../utils/apiHelpers");
|
|
6
|
+
const randomName_1 = require("../../utils/randomName");
|
|
7
|
+
_8_10_1.test.describe.configure({ mode: 'parallel' });
|
|
8
|
+
const DEFINITION_KEY = 'customer_onboarding_en';
|
|
9
|
+
const expectUnauthorizedErrorBody = (body) => {
|
|
10
|
+
if (body === null || body === undefined)
|
|
11
|
+
return;
|
|
12
|
+
if (typeof body === 'string') {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
(0, test_1.expect)(typeof body).toBe('object');
|
|
16
|
+
const errorBody = body;
|
|
17
|
+
const errorMessage = errorBody.message ?? errorBody.error ?? errorBody.title ?? errorBody.detail;
|
|
18
|
+
(0, test_1.expect)(typeof errorMessage).toBe('string');
|
|
19
|
+
(0, test_1.expect)(errorMessage.trim().length).toBeGreaterThan(0);
|
|
20
|
+
};
|
|
21
|
+
const assertUnauthorizedResponseBody = async (response) => {
|
|
22
|
+
(0, test_1.expect)(response.status()).toBe(401);
|
|
23
|
+
const rawBody = await response.text();
|
|
24
|
+
if (rawBody.trim().length === 0)
|
|
25
|
+
return;
|
|
26
|
+
let body = rawBody;
|
|
27
|
+
try {
|
|
28
|
+
body = JSON.parse(rawBody);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
body = rawBody;
|
|
32
|
+
}
|
|
33
|
+
expectUnauthorizedErrorBody(body);
|
|
34
|
+
};
|
|
35
|
+
const createNumberReport = async (request, options) => {
|
|
36
|
+
const response = await request.post(`${options.baseUrl}/api/report/process/single`, {
|
|
37
|
+
headers: {
|
|
38
|
+
Cookie: options.optimizeCookie,
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
data: {
|
|
42
|
+
collectionId: options.collectionId,
|
|
43
|
+
name: options.name,
|
|
44
|
+
description: null,
|
|
45
|
+
data: {
|
|
46
|
+
definitions: [
|
|
47
|
+
{
|
|
48
|
+
key: DEFINITION_KEY,
|
|
49
|
+
versions: ['all'],
|
|
50
|
+
tenantIds: ['<default>'],
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
view: { entity: 'processInstance', properties: ['frequency'] },
|
|
54
|
+
groupBy: { type: 'none', value: null },
|
|
55
|
+
distributedBy: { type: 'none', value: null },
|
|
56
|
+
visualization: 'number',
|
|
57
|
+
filter: [],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
62
|
+
const body = await response.json();
|
|
63
|
+
(0, test_1.expect)(body).toHaveProperty('id');
|
|
64
|
+
return body.id;
|
|
65
|
+
};
|
|
66
|
+
const createRawDataReport = async (request, options) => {
|
|
67
|
+
const response = await request.post(`${options.baseUrl}/api/report/process/single`, {
|
|
68
|
+
headers: {
|
|
69
|
+
Cookie: options.optimizeCookie,
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
},
|
|
72
|
+
data: {
|
|
73
|
+
collectionId: options.collectionId,
|
|
74
|
+
name: options.name,
|
|
75
|
+
description: null,
|
|
76
|
+
data: {
|
|
77
|
+
definitions: [
|
|
78
|
+
{
|
|
79
|
+
key: DEFINITION_KEY,
|
|
80
|
+
versions: ['all'],
|
|
81
|
+
tenantIds: ['<default>'],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
view: { entity: null, properties: ['rawData'] },
|
|
85
|
+
groupBy: { type: 'none', value: null },
|
|
86
|
+
distributedBy: { type: 'none', value: null },
|
|
87
|
+
visualization: 'table',
|
|
88
|
+
filter: [],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
93
|
+
const body = await response.json();
|
|
94
|
+
(0, test_1.expect)(body).toHaveProperty('id');
|
|
95
|
+
return body.id;
|
|
96
|
+
};
|
|
97
|
+
_8_10_1.test.describe('API Optimize Sharing, Alerts & Export Tests @optimize-sharing-alerts-export-api @8.10', () => {
|
|
98
|
+
let optimizeCookie;
|
|
99
|
+
let optimizeBearerToken;
|
|
100
|
+
let baseUrl;
|
|
101
|
+
let collectionId;
|
|
102
|
+
let numberReportId;
|
|
103
|
+
let rawDataReportId;
|
|
104
|
+
let dashboardId;
|
|
105
|
+
_8_10_1.test.beforeAll(async ({ browser, request }) => {
|
|
106
|
+
const page = await browser.newPage();
|
|
107
|
+
optimizeCookie = await (0, apiHelpers_1.getOptimizeCoockie)(page);
|
|
108
|
+
await page.close();
|
|
109
|
+
optimizeBearerToken = await (0, apiHelpers_1.authSaasAPI)(process.env.OPTIMIZE_API_TOKEN_AUDIENCE);
|
|
110
|
+
baseUrl = process.env.CAMUNDA_OPTIMIZE_BASE_URL;
|
|
111
|
+
collectionId = await (0, apiHelpers_1.createCollection)(request, {
|
|
112
|
+
name: await (0, randomName_1.randomNameAgregator)('Sharing Alerts Collection'),
|
|
113
|
+
optimizeCookie,
|
|
114
|
+
});
|
|
115
|
+
await (0, apiHelpers_1.updateCollectionScope)(request, {
|
|
116
|
+
optimizeCookie,
|
|
117
|
+
collectionId,
|
|
118
|
+
data: [
|
|
119
|
+
{
|
|
120
|
+
definitionKey: DEFINITION_KEY,
|
|
121
|
+
definitionType: 'process',
|
|
122
|
+
tenants: ['<default>'],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
numberReportId = await createNumberReport(request, {
|
|
127
|
+
baseUrl,
|
|
128
|
+
optimizeCookie,
|
|
129
|
+
collectionId,
|
|
130
|
+
name: await (0, randomName_1.randomNameAgregator)('Number Report'),
|
|
131
|
+
});
|
|
132
|
+
rawDataReportId = await createRawDataReport(request, {
|
|
133
|
+
baseUrl,
|
|
134
|
+
optimizeCookie,
|
|
135
|
+
collectionId,
|
|
136
|
+
name: await (0, randomName_1.randomNameAgregator)('Raw Data Report'),
|
|
137
|
+
});
|
|
138
|
+
dashboardId = await (0, apiHelpers_1.createDashboard)(request, {
|
|
139
|
+
name: await (0, randomName_1.randomNameAgregator)('Sharing Dashboard'),
|
|
140
|
+
optimizeCookie,
|
|
141
|
+
collectionId,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
_8_10_1.test.afterAll(async ({ request }) => {
|
|
145
|
+
if (collectionId) {
|
|
146
|
+
await request.delete(`${baseUrl}/api/public/collection/${collectionId}`, {
|
|
147
|
+
headers: { Authorization: optimizeBearerToken },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
(0, _8_10_1.test)('Export report result data returns 200 with paginated payload', async ({ request, }) => {
|
|
152
|
+
await _8_10_1.test.step('GET /api/public/export/report/{id}/result/json (200)', async () => {
|
|
153
|
+
const response = await request.get(`${baseUrl}/api/public/export/report/${rawDataReportId}/result/json?paginationTimeout=60&limit=100`, { headers: { Authorization: optimizeBearerToken } });
|
|
154
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
155
|
+
const body = await response.json();
|
|
156
|
+
(0, test_1.expect)(body).toHaveProperty('reportId', rawDataReportId);
|
|
157
|
+
(0, test_1.expect)(body).toHaveProperty('totalNumberOfRecords');
|
|
158
|
+
(0, test_1.expect)(typeof body.totalNumberOfRecords).toBe('number');
|
|
159
|
+
(0, test_1.expect)(body).toHaveProperty('data');
|
|
160
|
+
(0, test_1.expect)(Array.isArray(body.data)).toBeTruthy();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
(0, _8_10_1.test)('Export report result data without pagination params returns 200', async ({ request, }) => {
|
|
164
|
+
await _8_10_1.test.step('GET export result with optional query params omitted (200)', async () => {
|
|
165
|
+
const response = await request.get(`${baseUrl}/api/public/export/report/${numberReportId}/result/json`, { headers: { Authorization: optimizeBearerToken } });
|
|
166
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
167
|
+
const body = await response.json();
|
|
168
|
+
(0, test_1.expect)(body).toHaveProperty('reportId', numberReportId);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
(0, _8_10_1.test)('Export report result data without token returns 401', async ({ request, }) => {
|
|
172
|
+
await _8_10_1.test.step('GET export result without Authorization header (401)', async () => {
|
|
173
|
+
const response = await request.get(`${baseUrl}/api/public/export/report/${numberReportId}/result/json?paginationTimeout=60&limit=100`);
|
|
174
|
+
await assertUnauthorizedResponseBody(response);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
(0, _8_10_1.test)('Export report result data with invalid token returns 401', async ({ request, }) => {
|
|
178
|
+
await _8_10_1.test.step('GET export result with invalid token (401)', async () => {
|
|
179
|
+
const response = await request.get(`${baseUrl}/api/public/export/report/${numberReportId}/result/json?paginationTimeout=60&limit=100`, { headers: { Authorization: 'Bearer invalid_token' } });
|
|
180
|
+
await assertUnauthorizedResponseBody(response);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
(0, _8_10_1.test)('Export result data for non-existent report is rejected (404; SaaS may respond 500)', async ({ request, }) => {
|
|
184
|
+
await _8_10_1.test.step('GET export result for missing report (404 or 500)', async () => {
|
|
185
|
+
const response = await request.get(`${baseUrl}/api/public/export/report/11111111-1111-1111-1111-111111111111/result/json?paginationTimeout=60&limit=100`, { headers: { Authorization: optimizeBearerToken } });
|
|
186
|
+
(0, test_1.expect)([404, 500]).toContain(response.status());
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
(0, _8_10_1.test)('Enable, evaluate and delete a report share', async ({ request }) => {
|
|
190
|
+
let reportShareId = '';
|
|
191
|
+
await _8_10_1.test.step('POST /api/share/report enables sharing (200)', async () => {
|
|
192
|
+
const response = await request.post(`${baseUrl}/api/share/report`, {
|
|
193
|
+
headers: {
|
|
194
|
+
Cookie: optimizeCookie,
|
|
195
|
+
'Content-Type': 'application/json',
|
|
196
|
+
},
|
|
197
|
+
data: { reportId: numberReportId },
|
|
198
|
+
});
|
|
199
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
200
|
+
const body = await response.json();
|
|
201
|
+
(0, test_1.expect)(body).toHaveProperty('id');
|
|
202
|
+
reportShareId = body.id;
|
|
203
|
+
(0, test_1.expect)(reportShareId.length).toBeGreaterThan(0);
|
|
204
|
+
});
|
|
205
|
+
await _8_10_1.test.step('Shared report is evaluable without authentication', async () => {
|
|
206
|
+
const response = await request.post(`${baseUrl}/api/external/share/report/${reportShareId}/evaluate`, {
|
|
207
|
+
headers: { 'Content-Type': 'application/json' },
|
|
208
|
+
data: {},
|
|
209
|
+
});
|
|
210
|
+
(0, test_1.expect)([200, 201]).toContain(response.status());
|
|
211
|
+
});
|
|
212
|
+
await _8_10_1.test.step('DELETE /api/share/report/{shareId} removes the share', async () => {
|
|
213
|
+
const response = await request.delete(`${baseUrl}/api/share/report/${reportShareId}`, { headers: { Cookie: optimizeCookie } });
|
|
214
|
+
(0, test_1.expect)([200, 204]).toContain(response.status());
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
(0, _8_10_1.test)('Enable report share without auth cookie returns 401', async ({ request, }) => {
|
|
218
|
+
await _8_10_1.test.step('POST /api/share/report without cookie (401)', async () => {
|
|
219
|
+
const response = await request.post(`${baseUrl}/api/share/report`, {
|
|
220
|
+
headers: { 'Content-Type': 'application/json' },
|
|
221
|
+
data: { reportId: numberReportId },
|
|
222
|
+
});
|
|
223
|
+
await assertUnauthorizedResponseBody(response);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
(0, _8_10_1.test)('Enable and delete a dashboard share', async ({ request }) => {
|
|
227
|
+
let dashboardShareId = '';
|
|
228
|
+
await _8_10_1.test.step('POST /api/share/dashboard enables sharing (200)', async () => {
|
|
229
|
+
const response = await request.post(`${baseUrl}/api/share/dashboard`, {
|
|
230
|
+
headers: {
|
|
231
|
+
Cookie: optimizeCookie,
|
|
232
|
+
'Content-Type': 'application/json',
|
|
233
|
+
},
|
|
234
|
+
data: { dashboardId },
|
|
235
|
+
});
|
|
236
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
237
|
+
const body = await response.json();
|
|
238
|
+
(0, test_1.expect)(body).toHaveProperty('id');
|
|
239
|
+
dashboardShareId = body.id;
|
|
240
|
+
(0, test_1.expect)(dashboardShareId.length).toBeGreaterThan(0);
|
|
241
|
+
});
|
|
242
|
+
await _8_10_1.test.step('DELETE /api/share/dashboard/{shareId} removes the share', async () => {
|
|
243
|
+
const response = await request.delete(`${baseUrl}/api/share/dashboard/${dashboardShareId}`, { headers: { Cookie: optimizeCookie } });
|
|
244
|
+
(0, test_1.expect)([200, 204]).toContain(response.status());
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
(0, _8_10_1.test)('Create, list and delete an alert for a number report', async ({ request, }) => {
|
|
248
|
+
let alertId = '';
|
|
249
|
+
const alertEmail = process.env.C8_USERNAME;
|
|
250
|
+
await _8_10_1.test.step('POST /api/alert creates an alert (200)', async () => {
|
|
251
|
+
const response = await request.post(`${baseUrl}/api/alert`, {
|
|
252
|
+
headers: {
|
|
253
|
+
Cookie: optimizeCookie,
|
|
254
|
+
'Content-Type': 'application/json',
|
|
255
|
+
},
|
|
256
|
+
data: {
|
|
257
|
+
name: await (0, randomName_1.randomNameAgregator)('Number Report Alert'),
|
|
258
|
+
reportId: numberReportId,
|
|
259
|
+
emails: [alertEmail],
|
|
260
|
+
webhook: null,
|
|
261
|
+
threshold: 100,
|
|
262
|
+
thresholdOperator: '>',
|
|
263
|
+
fixNotification: false,
|
|
264
|
+
checkInterval: { value: 10, unit: 'minutes' },
|
|
265
|
+
reminder: null,
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
269
|
+
const body = await response.json();
|
|
270
|
+
(0, test_1.expect)(body).toHaveProperty('id');
|
|
271
|
+
alertId = body.id;
|
|
272
|
+
(0, test_1.expect)(alertId.length).toBeGreaterThan(0);
|
|
273
|
+
});
|
|
274
|
+
await _8_10_1.test.step('GET /api/collection/{id}/alerts includes the created alert', async () => {
|
|
275
|
+
const response = await request.get(`${baseUrl}/api/collection/${collectionId}/alerts`, { headers: { Cookie: optimizeCookie } });
|
|
276
|
+
await (0, apiHelpers_1.assertResponseStatus)(response, 200);
|
|
277
|
+
const body = await response.json();
|
|
278
|
+
(0, test_1.expect)(Array.isArray(body)).toBeTruthy();
|
|
279
|
+
const ids = body.map((alert) => alert.id);
|
|
280
|
+
(0, test_1.expect)(ids).toContain(alertId);
|
|
281
|
+
});
|
|
282
|
+
await _8_10_1.test.step('DELETE /api/alert/{id} removes the alert', async () => {
|
|
283
|
+
const response = await request.delete(`${baseUrl}/api/alert/${alertId}`, {
|
|
284
|
+
headers: { Cookie: optimizeCookie },
|
|
285
|
+
});
|
|
286
|
+
(0, test_1.expect)([200, 204]).toContain(response.status());
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
(0, _8_10_1.test)('Create alert without auth cookie returns 401', async ({ request }) => {
|
|
290
|
+
await _8_10_1.test.step('POST /api/alert without cookie (401)', async () => {
|
|
291
|
+
const response = await request.post(`${baseUrl}/api/alert`, {
|
|
292
|
+
headers: { 'Content-Type': 'application/json' },
|
|
293
|
+
data: {
|
|
294
|
+
name: await (0, randomName_1.randomNameAgregator)('Unauthorized Alert'),
|
|
295
|
+
reportId: numberReportId,
|
|
296
|
+
emails: [process.env.C8_USERNAME],
|
|
297
|
+
threshold: 100,
|
|
298
|
+
thresholdOperator: '>',
|
|
299
|
+
checkInterval: { value: 10, unit: 'minutes' },
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
await assertUnauthorizedResponseBody(response);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
@@ -3,6 +3,8 @@ import { APIRequestContext, APIResponse, Response, Page } from '@playwright/test
|
|
|
3
3
|
import { Serializable } from 'playwright-core/types/structs';
|
|
4
4
|
export declare function getApiRequestContext(): Promise<APIRequestContext>;
|
|
5
5
|
export declare function assertResponseStatus(response: APIResponse | Response, status: number): Promise<void>;
|
|
6
|
+
export declare function expectUnauthorizedErrorBody(body: unknown): void;
|
|
7
|
+
export declare function assertUnauthorizedResponseBody(response: APIResponse): Promise<void>;
|
|
6
8
|
export declare function sendRequestAndAssertResponse(request: APIRequestContext, url: string, requestBody?: string | Buffer | Serializable, maxRetries?: number): Promise<void>;
|
|
7
9
|
export declare function retryOn500(fn: () => Promise<APIResponse>, maxAttempts?: number, delayMs?: number): Promise<APIResponse>;
|
|
8
10
|
export declare function buildZeebeApiUrl(resourcePath: string, environmentOverride?: 'saas' | 'sm', clusterType?: string): string;
|
package/dist/utils/apiHelpers.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.updateClusterDataFilters = exports.getClusterDataFilters = exports.getTestClusterUuid = exports.authConsoleManagementAPI = exports.updateCollectionScope = exports.createSingleProcessReport = exports.createDashboard = exports.createCollection = exports.getOptimizeCookieSm = exports.getOptimizeCoockie = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.waitForProcessInstanceVisible = exports.createProcessInstance = exports.deployProcess = exports.waitForConnectorsReady = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.buildZeebeApiUrl = exports.retryOn500 = exports.sendRequestAndAssertResponse = exports.assertResponseStatus = exports.getApiRequestContext = void 0;
|
|
6
|
+
exports.updateClusterDataFilters = exports.getClusterDataFilters = exports.getTestClusterUuid = exports.authConsoleManagementAPI = exports.updateCollectionScope = exports.createSingleProcessReport = exports.createDashboard = exports.createCollection = exports.getOptimizeCookieSm = exports.getOptimizeCoockie = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.waitForProcessInstanceVisible = exports.createProcessInstance = exports.deployProcess = exports.waitForConnectorsReady = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.buildZeebeApiUrl = exports.retryOn500 = exports.sendRequestAndAssertResponse = exports.assertUnauthorizedResponseBody = exports.expectUnauthorizedErrorBody = exports.assertResponseStatus = exports.getApiRequestContext = void 0;
|
|
7
7
|
const test_1 = require("@playwright/test");
|
|
8
8
|
const sleep_1 = require("./sleep");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -24,6 +24,34 @@ async function assertResponseStatus(response, status) {
|
|
|
24
24
|
(0, test_1.expect)(response.status()).toBe(status);
|
|
25
25
|
}
|
|
26
26
|
exports.assertResponseStatus = assertResponseStatus;
|
|
27
|
+
function expectUnauthorizedErrorBody(body) {
|
|
28
|
+
if (body === null || body === undefined)
|
|
29
|
+
return;
|
|
30
|
+
if (typeof body === 'string') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
(0, test_1.expect)(typeof body).toBe('object');
|
|
34
|
+
const errorBody = body;
|
|
35
|
+
const errorMessage = errorBody.message ?? errorBody.error ?? errorBody.title ?? errorBody.detail;
|
|
36
|
+
(0, test_1.expect)(typeof errorMessage).toBe('string');
|
|
37
|
+
(0, test_1.expect)(errorMessage.trim().length).toBeGreaterThan(0);
|
|
38
|
+
}
|
|
39
|
+
exports.expectUnauthorizedErrorBody = expectUnauthorizedErrorBody;
|
|
40
|
+
async function assertUnauthorizedResponseBody(response) {
|
|
41
|
+
(0, test_1.expect)(response.status()).toBe(401);
|
|
42
|
+
const rawBody = await response.text();
|
|
43
|
+
if (rawBody.trim().length === 0)
|
|
44
|
+
return;
|
|
45
|
+
let body = rawBody;
|
|
46
|
+
try {
|
|
47
|
+
body = JSON.parse(rawBody);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
body = rawBody;
|
|
51
|
+
}
|
|
52
|
+
expectUnauthorizedErrorBody(body);
|
|
53
|
+
}
|
|
54
|
+
exports.assertUnauthorizedResponseBody = assertUnauthorizedResponseBody;
|
|
27
55
|
async function sendRequestAndAssertResponse(request, url, requestBody, maxRetries = 3) {
|
|
28
56
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
29
57
|
try {
|