@centreon/js-config 23.10.65 → 24.4.0
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/cypress/component/commands.tsx +203 -158
- package/cypress/component/configuration.js +83 -54
- package/cypress/component/enableVisualTesting.ts +21 -21
- package/cypress/component/excludeNodeModulesFromCoverage.js +36 -0
- package/cypress/e2e/commands/configuration.ts +327 -1
- package/cypress/e2e/commands/monitoring.ts +56 -0
- package/cypress/e2e/commands.ts +501 -143
- package/cypress/e2e/configuration.ts +37 -14
- package/cypress/e2e/plugins.ts +31 -4
- package/cypress/e2e/tasks.ts +204 -53
- package/jest/index.js +0 -1
- package/package.json +64 -57
- package/tsconfig/lambda/node20.tsconfig.json +12 -0
- package/webpack/base/globalConfig.js +7 -2
- package/webpack/base/index.js +8 -8
package/cypress/e2e/commands.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-namespace */
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import 'cypress-wait-until';
|
|
2
4
|
|
|
3
5
|
import './commands/configuration';
|
|
4
6
|
import './commands/monitoring';
|
|
@@ -7,10 +9,53 @@ import installLogsCollector from 'cypress-terminal-report/src/installLogsCollect
|
|
|
7
9
|
|
|
8
10
|
installLogsCollector({ enableExtendedCollector: true });
|
|
9
11
|
|
|
12
|
+
const apiBase = '/centreon/api';
|
|
13
|
+
const apiActionV1 = `${apiBase}/index.php`;
|
|
10
14
|
const apiLoginV2 = '/centreon/authentication/providers/configurations/local';
|
|
11
15
|
|
|
12
16
|
const artifactIllegalCharactersMatcher = /[,\s/|<>*?:"]/g;
|
|
13
17
|
|
|
18
|
+
export enum PatternType {
|
|
19
|
+
contains = '*',
|
|
20
|
+
endsWith = '$',
|
|
21
|
+
equals = '',
|
|
22
|
+
startsWith = '^'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface GetByLabelProps {
|
|
26
|
+
label: string;
|
|
27
|
+
patternType?: PatternType;
|
|
28
|
+
tag?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Cypress.Commands.add(
|
|
32
|
+
'getByLabel',
|
|
33
|
+
({
|
|
34
|
+
tag = '',
|
|
35
|
+
patternType = PatternType.equals,
|
|
36
|
+
label
|
|
37
|
+
}: GetByLabelProps): Cypress.Chainable => {
|
|
38
|
+
return cy.get(`${tag}[aria-label${patternType}="${label}"]`);
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
interface GetByTestIdProps {
|
|
43
|
+
patternType?: PatternType;
|
|
44
|
+
tag?: string;
|
|
45
|
+
testId: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Cypress.Commands.add(
|
|
49
|
+
'getByTestId',
|
|
50
|
+
({
|
|
51
|
+
tag = '',
|
|
52
|
+
patternType = PatternType.equals,
|
|
53
|
+
testId
|
|
54
|
+
}: GetByTestIdProps): Cypress.Chainable => {
|
|
55
|
+
return cy.get(`${tag}[data-testid${patternType}="${testId}"]`);
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
14
59
|
Cypress.Commands.add('getWebVersion', (): Cypress.Chainable => {
|
|
15
60
|
return cy
|
|
16
61
|
.exec(
|
|
@@ -34,6 +79,34 @@ Cypress.Commands.add('getIframeBody', (): Cypress.Chainable => {
|
|
|
34
79
|
.then(cy.wrap);
|
|
35
80
|
});
|
|
36
81
|
|
|
82
|
+
Cypress.Commands.add(
|
|
83
|
+
'waitForElementInIframe',
|
|
84
|
+
(iframeSelector, elementSelector) => {
|
|
85
|
+
cy.waitUntil(
|
|
86
|
+
() =>
|
|
87
|
+
cy.get(iframeSelector).then(($iframe) => {
|
|
88
|
+
const iframeBody = $iframe[0].contentDocument.body;
|
|
89
|
+
if (iframeBody) {
|
|
90
|
+
const $element = Cypress.$(iframeBody).find(elementSelector);
|
|
91
|
+
|
|
92
|
+
return $element.length > 0 && $element.is(':visible');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false;
|
|
96
|
+
}),
|
|
97
|
+
{
|
|
98
|
+
errorMsg: 'The element is not visible within the iframe',
|
|
99
|
+
interval: 5000,
|
|
100
|
+
timeout: 100000
|
|
101
|
+
}
|
|
102
|
+
).then((isVisible) => {
|
|
103
|
+
if (!isVisible) {
|
|
104
|
+
throw new Error('The element is not visible');
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
|
|
37
110
|
Cypress.Commands.add(
|
|
38
111
|
'hoverRootMenuItem',
|
|
39
112
|
(rootItemNumber: number): Cypress.Chainable => {
|
|
@@ -59,7 +132,7 @@ interface NavigateToProps {
|
|
|
59
132
|
|
|
60
133
|
Cypress.Commands.add(
|
|
61
134
|
'navigateTo',
|
|
62
|
-
({ rootItemNumber, subMenu, page }): void => {
|
|
135
|
+
({ rootItemNumber, subMenu, page }: NavigateToProps): void => {
|
|
63
136
|
if (subMenu) {
|
|
64
137
|
cy.hoverRootMenuItem(rootItemNumber)
|
|
65
138
|
.contains(subMenu)
|
|
@@ -100,6 +173,24 @@ Cypress.Commands.add(
|
|
|
100
173
|
}
|
|
101
174
|
);
|
|
102
175
|
|
|
176
|
+
Cypress.Commands.add('getContainerId', (containerName: string) => {
|
|
177
|
+
cy.log(`Getting container id of ${containerName}`);
|
|
178
|
+
|
|
179
|
+
return cy.task('getContainerId', containerName);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
Cypress.Commands.add('getContainerIpAddress', (containerName: string) => {
|
|
183
|
+
cy.log(`Getting container ip address of ${containerName}`);
|
|
184
|
+
|
|
185
|
+
return cy.task('getContainerIpAddress', containerName);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
Cypress.Commands.add('getContainersLogs', () => {
|
|
189
|
+
cy.log('Getting containers logs');
|
|
190
|
+
|
|
191
|
+
return cy.task('getContainersLogs');
|
|
192
|
+
});
|
|
193
|
+
|
|
103
194
|
interface CopyFromContainerProps {
|
|
104
195
|
destination: string;
|
|
105
196
|
name?: string;
|
|
@@ -108,38 +199,54 @@ interface CopyFromContainerProps {
|
|
|
108
199
|
|
|
109
200
|
Cypress.Commands.add(
|
|
110
201
|
'copyFromContainer',
|
|
111
|
-
(
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
destination
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return cy.exec(`docker cp ${name}:${source} "${destination}"`, options);
|
|
202
|
+
({ name = 'web', source, destination }: CopyFromContainerProps) => {
|
|
203
|
+
cy.log(`Copy content from ${name}:${source} to ${destination}`);
|
|
204
|
+
|
|
205
|
+
return cy.task('copyFromContainer', {
|
|
206
|
+
destination,
|
|
207
|
+
serviceName: name,
|
|
208
|
+
source
|
|
209
|
+
});
|
|
120
210
|
}
|
|
121
211
|
);
|
|
122
212
|
|
|
213
|
+
export enum CopyToContainerContentType {
|
|
214
|
+
Directory = 'directory',
|
|
215
|
+
File = 'file'
|
|
216
|
+
}
|
|
217
|
+
|
|
123
218
|
interface CopyToContainerProps {
|
|
124
219
|
destination: string;
|
|
125
220
|
name?: string;
|
|
126
221
|
source: string;
|
|
222
|
+
type: CopyToContainerContentType;
|
|
127
223
|
}
|
|
128
224
|
|
|
129
225
|
Cypress.Commands.add(
|
|
130
226
|
'copyToContainer',
|
|
131
|
-
(
|
|
132
|
-
{
|
|
133
|
-
|
|
227
|
+
({ name = 'web', source, destination, type }: CopyToContainerProps) => {
|
|
228
|
+
cy.log(`Copy content from ${source} to ${name}:${destination}`);
|
|
229
|
+
|
|
230
|
+
return cy.task('copyToContainer', {
|
|
231
|
+
destination,
|
|
232
|
+
serviceName: name,
|
|
134
233
|
source,
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
options?: Partial<Cypress.ExecOptions>
|
|
138
|
-
) => {
|
|
139
|
-
return cy.exec(`docker cp ${source} ${name}:${destination}`, options);
|
|
234
|
+
type
|
|
235
|
+
});
|
|
140
236
|
}
|
|
141
237
|
);
|
|
142
238
|
|
|
239
|
+
Cypress.Commands.add('loginAsAdminViaApiV2', (): Cypress.Chainable => {
|
|
240
|
+
return cy.request({
|
|
241
|
+
body: {
|
|
242
|
+
login: 'admin',
|
|
243
|
+
password: 'Centreon!2021'
|
|
244
|
+
},
|
|
245
|
+
method: 'POST',
|
|
246
|
+
url: apiLoginV2
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
143
250
|
interface LoginByTypeOfUserProps {
|
|
144
251
|
jsonName?: string;
|
|
145
252
|
loginViaApi?: boolean;
|
|
@@ -178,16 +285,42 @@ Cypress.Commands.add(
|
|
|
178
285
|
.getByLabel({ label: 'Connect', tag: 'button' })
|
|
179
286
|
.click();
|
|
180
287
|
|
|
181
|
-
return cy
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
});
|
|
288
|
+
return cy.get('.MuiAlert-message').then(($snackbar) => {
|
|
289
|
+
if ($snackbar.text().includes('Login succeeded')) {
|
|
290
|
+
cy.wait('@getNavigationList');
|
|
291
|
+
cy.get('.MuiAlert-message').should('not.be.visible');
|
|
292
|
+
}
|
|
293
|
+
});
|
|
188
294
|
}
|
|
189
295
|
);
|
|
190
296
|
|
|
297
|
+
Cypress.Commands.add('logout', (): void => {
|
|
298
|
+
cy.getByLabel({ label: 'Profile' }).should('exist').click();
|
|
299
|
+
|
|
300
|
+
cy.intercept({
|
|
301
|
+
method: 'GET',
|
|
302
|
+
times: 1,
|
|
303
|
+
url: '/centreon/api/latest/authentication/logout'
|
|
304
|
+
}).as('logout');
|
|
305
|
+
|
|
306
|
+
cy.contains(/^Logout$/).click();
|
|
307
|
+
|
|
308
|
+
cy.wait('@logout').its('response.statusCode').should('eq', 302);
|
|
309
|
+
|
|
310
|
+
// https://github.com/cypress-io/cypress/issues/25841
|
|
311
|
+
cy.clearAllCookies();
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
Cypress.Commands.add('logoutViaAPI', (): Cypress.Chainable => {
|
|
315
|
+
return cy
|
|
316
|
+
.request({
|
|
317
|
+
method: 'GET',
|
|
318
|
+
url: '/centreon/authentication/logout'
|
|
319
|
+
})
|
|
320
|
+
.visit('/')
|
|
321
|
+
.getByLabel({ label: 'Alias', tag: 'input' });
|
|
322
|
+
});
|
|
323
|
+
|
|
191
324
|
Cypress.Commands.add(
|
|
192
325
|
'visitEmptyPage',
|
|
193
326
|
(): Cypress.Chainable =>
|
|
@@ -199,32 +332,91 @@ Cypress.Commands.add(
|
|
|
199
332
|
.visit('/waiting-page')
|
|
200
333
|
);
|
|
201
334
|
|
|
202
|
-
Cypress.Commands.add('waitForContainerAndSetToken', (): Cypress.Chainable => {
|
|
203
|
-
return cy.setUserTokenApiV1();
|
|
204
|
-
});
|
|
205
|
-
|
|
206
335
|
interface ExecInContainerProps {
|
|
207
|
-
command: string
|
|
336
|
+
command: string | Array<string>;
|
|
208
337
|
name: string;
|
|
209
338
|
}
|
|
210
339
|
|
|
340
|
+
interface ExecInContainerResult {
|
|
341
|
+
exitCode: number;
|
|
342
|
+
output: string;
|
|
343
|
+
}
|
|
344
|
+
|
|
211
345
|
Cypress.Commands.add(
|
|
212
346
|
'execInContainer',
|
|
213
347
|
({ command, name }: ExecInContainerProps): Cypress.Chainable => {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
348
|
+
const commands =
|
|
349
|
+
typeof command === 'string' || command instanceof String
|
|
350
|
+
? [command]
|
|
351
|
+
: command;
|
|
352
|
+
|
|
353
|
+
const results = commands.reduce(
|
|
354
|
+
(acc, runCommand) => {
|
|
355
|
+
cy.task<ExecInContainerResult>(
|
|
356
|
+
'execInContainer',
|
|
357
|
+
{ command: runCommand, name },
|
|
358
|
+
{ timeout: 600000 }
|
|
359
|
+
).then((result) => {
|
|
360
|
+
if (result.exitCode) {
|
|
361
|
+
cy.log(result.output);
|
|
362
|
+
|
|
363
|
+
// output will not be truncated
|
|
364
|
+
throw new Error(`
|
|
365
|
+
Execution of "${runCommand}" failed
|
|
366
|
+
Exit code: ${result.exitCode}
|
|
367
|
+
Output:\n${result.output}`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
acc.output = `${acc.output}${result.output}`;
|
|
371
|
+
});
|
|
225
372
|
|
|
226
|
-
return
|
|
227
|
-
}
|
|
373
|
+
return acc;
|
|
374
|
+
},
|
|
375
|
+
{ exitCode: 0, output: '' }
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
return cy.wrap(results);
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
interface RequestOnDatabaseProps {
|
|
383
|
+
database: string;
|
|
384
|
+
query: string;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
Cypress.Commands.add(
|
|
388
|
+
'requestOnDatabase',
|
|
389
|
+
({ database, query }: RequestOnDatabaseProps): Cypress.Chainable => {
|
|
390
|
+
return cy.task('requestOnDatabase', { database, query });
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
interface SetUserTokenApiV1Props {
|
|
395
|
+
login?: string;
|
|
396
|
+
password?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
Cypress.Commands.add(
|
|
400
|
+
'setUserTokenApiV1',
|
|
401
|
+
({
|
|
402
|
+
login = 'admin',
|
|
403
|
+
password = 'Centreon!2021'
|
|
404
|
+
}: SetUserTokenApiV1Props = {}): Cypress.Chainable => {
|
|
405
|
+
return cy
|
|
406
|
+
.request({
|
|
407
|
+
body: {
|
|
408
|
+
password,
|
|
409
|
+
username: login
|
|
410
|
+
},
|
|
411
|
+
headers: {
|
|
412
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
413
|
+
},
|
|
414
|
+
method: 'POST',
|
|
415
|
+
url: `${apiActionV1}?action=authenticate`
|
|
416
|
+
})
|
|
417
|
+
.then(({ body }) =>
|
|
418
|
+
window.localStorage.setItem('userTokenApiV1', body.authToken)
|
|
419
|
+
);
|
|
228
420
|
}
|
|
229
421
|
);
|
|
230
422
|
|
|
@@ -234,6 +426,7 @@ interface PortBinding {
|
|
|
234
426
|
}
|
|
235
427
|
|
|
236
428
|
interface StartContainerProps {
|
|
429
|
+
command?: string;
|
|
237
430
|
image: string;
|
|
238
431
|
name: string;
|
|
239
432
|
portBindings: Array<PortBinding>;
|
|
@@ -241,145 +434,212 @@ interface StartContainerProps {
|
|
|
241
434
|
|
|
242
435
|
Cypress.Commands.add(
|
|
243
436
|
'startContainer',
|
|
244
|
-
({
|
|
437
|
+
({
|
|
438
|
+
command,
|
|
439
|
+
name,
|
|
440
|
+
image,
|
|
441
|
+
portBindings
|
|
442
|
+
}: StartContainerProps): Cypress.Chainable => {
|
|
245
443
|
cy.log(`Starting container ${name} from image ${image}`);
|
|
246
444
|
|
|
247
445
|
return cy.task(
|
|
248
446
|
'startContainer',
|
|
249
|
-
{ image, name, portBindings },
|
|
447
|
+
{ command, image, name, portBindings },
|
|
250
448
|
{ timeout: 600000 } // 10 minutes because docker pull can be very slow
|
|
251
449
|
);
|
|
252
450
|
}
|
|
253
451
|
);
|
|
254
452
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
interface StartWebContainerProps {
|
|
263
|
-
name?: string;
|
|
264
|
-
os?: string;
|
|
453
|
+
interface StartContainersProps {
|
|
454
|
+
composeFile?: string;
|
|
455
|
+
databaseImage?: string;
|
|
456
|
+
moduleName?: string;
|
|
457
|
+
openidImage?: string;
|
|
458
|
+
profiles?: Array<string>;
|
|
459
|
+
samlImage?: string;
|
|
265
460
|
useSlim?: boolean;
|
|
266
|
-
|
|
461
|
+
webOs?: string;
|
|
462
|
+
webVersion?: string;
|
|
267
463
|
}
|
|
268
464
|
|
|
269
465
|
Cypress.Commands.add(
|
|
270
|
-
'
|
|
466
|
+
'startContainers',
|
|
271
467
|
({
|
|
272
|
-
|
|
273
|
-
|
|
468
|
+
composeFile,
|
|
469
|
+
databaseImage = Cypress.env('DATABASE_IMAGE'),
|
|
470
|
+
moduleName = 'centreon-web',
|
|
471
|
+
openidImage = `docker.centreon.com/centreon/keycloak:${Cypress.env(
|
|
472
|
+
'OPENID_IMAGE_VERSION'
|
|
473
|
+
)}`,
|
|
474
|
+
profiles = [],
|
|
475
|
+
samlImage = `docker.centreon.com/centreon/keycloak:${Cypress.env(
|
|
476
|
+
'SAML_IMAGE_VERSION'
|
|
477
|
+
)}`,
|
|
274
478
|
useSlim = true,
|
|
275
|
-
|
|
276
|
-
|
|
479
|
+
webOs = Cypress.env('WEB_IMAGE_OS'),
|
|
480
|
+
webVersion = Cypress.env('WEB_IMAGE_VERSION')
|
|
481
|
+
}: StartContainersProps = {}): Cypress.Chainable => {
|
|
482
|
+
cy.log('Starting containers ...');
|
|
483
|
+
|
|
484
|
+
let composeFilePath = composeFile;
|
|
485
|
+
if (!composeFile) {
|
|
486
|
+
const cypressDir = path.dirname(Cypress.config('configFile'));
|
|
487
|
+
composeFilePath = `${cypressDir}/../../../.github/docker/docker-compose.yml`;
|
|
488
|
+
}
|
|
489
|
+
|
|
277
490
|
const slimSuffix = useSlim ? '-slim' : '';
|
|
278
491
|
|
|
279
|
-
const
|
|
492
|
+
const webImage = `docker.centreon.com/centreon/${moduleName}${slimSuffix}-${webOs}:${webVersion}`;
|
|
280
493
|
|
|
281
494
|
return cy
|
|
282
|
-
.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
495
|
+
.task(
|
|
496
|
+
'startContainers',
|
|
497
|
+
{
|
|
498
|
+
composeFile: composeFilePath,
|
|
499
|
+
databaseImage,
|
|
500
|
+
openidImage,
|
|
501
|
+
profiles,
|
|
502
|
+
samlImage,
|
|
503
|
+
webImage
|
|
504
|
+
},
|
|
505
|
+
{ timeout: 600000 } // 10 minutes because docker pull can be very slow
|
|
506
|
+
)
|
|
287
507
|
.then(() => {
|
|
288
508
|
const baseUrl = 'http://127.0.0.1:4000';
|
|
289
509
|
|
|
290
510
|
Cypress.config('baseUrl', baseUrl);
|
|
291
511
|
|
|
292
|
-
return cy.
|
|
293
|
-
'waitOn',
|
|
294
|
-
`${baseUrl}/centreon/api/latest/platform/installation/status`
|
|
295
|
-
);
|
|
512
|
+
return cy.wrap(null);
|
|
296
513
|
})
|
|
297
514
|
.visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
|
|
298
515
|
.setUserTokenApiV1();
|
|
299
516
|
}
|
|
300
517
|
);
|
|
301
518
|
|
|
302
|
-
interface
|
|
303
|
-
name
|
|
519
|
+
interface StopContainerProps {
|
|
520
|
+
name: string;
|
|
304
521
|
}
|
|
305
522
|
|
|
306
523
|
Cypress.Commands.add(
|
|
307
|
-
'
|
|
308
|
-
({
|
|
309
|
-
|
|
310
|
-
|
|
524
|
+
'stopContainer',
|
|
525
|
+
({ name }: StopContainerProps): Cypress.Chainable => {
|
|
526
|
+
cy.log(`Stopping container ${name}`);
|
|
527
|
+
|
|
528
|
+
return cy.task('stopContainer', { name });
|
|
529
|
+
}
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
Cypress.Commands.add(
|
|
533
|
+
'getLogDirectory',
|
|
534
|
+
(): Cypress.Chainable => {
|
|
311
535
|
const logDirectory = `results/logs/${Cypress.spec.name.replace(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
536
|
+
artifactIllegalCharactersMatcher,
|
|
537
|
+
'_'
|
|
538
|
+
)}/${Cypress.currentTest.title.replace(
|
|
539
|
+
artifactIllegalCharactersMatcher,
|
|
540
|
+
'_'
|
|
541
|
+
)}`;
|
|
318
542
|
|
|
319
543
|
return cy
|
|
320
|
-
.visitEmptyPage()
|
|
321
544
|
.createDirectory(logDirectory)
|
|
322
|
-
.copyFromContainer({
|
|
323
|
-
destination: `${logDirectory}/broker`,
|
|
324
|
-
name,
|
|
325
|
-
source: '/var/log/centreon-broker'
|
|
326
|
-
})
|
|
327
|
-
.copyFromContainer({
|
|
328
|
-
destination: `${logDirectory}/engine`,
|
|
329
|
-
name,
|
|
330
|
-
source: '/var/log/centreon-engine'
|
|
331
|
-
})
|
|
332
|
-
.copyFromContainer({
|
|
333
|
-
destination: `${logDirectory}/centreon`,
|
|
334
|
-
name,
|
|
335
|
-
source: '/var/log/centreon'
|
|
336
|
-
})
|
|
337
|
-
.then(() => {
|
|
338
|
-
if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
|
|
339
|
-
return cy.copyFromContainer({
|
|
340
|
-
destination: `${logDirectory}/php`,
|
|
341
|
-
name,
|
|
342
|
-
source: '/var/log/php-fpm'
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return cy.copyFromContainer(
|
|
347
|
-
{
|
|
348
|
-
destination: `${logDirectory}/php8.1-fpm-centreon-error.log`,
|
|
349
|
-
name,
|
|
350
|
-
source: '/var/log/php8.1-fpm-centreon-error.log'
|
|
351
|
-
},
|
|
352
|
-
{ failOnNonZeroExit: false }
|
|
353
|
-
);
|
|
354
|
-
})
|
|
355
545
|
.exec(`chmod -R 755 "${logDirectory}"`)
|
|
356
|
-
.
|
|
546
|
+
.wrap(logDirectory);
|
|
357
547
|
}
|
|
358
548
|
);
|
|
359
549
|
|
|
360
|
-
interface
|
|
550
|
+
interface CopyWebContainerLogsProps {
|
|
361
551
|
name: string;
|
|
362
552
|
}
|
|
363
553
|
|
|
364
554
|
Cypress.Commands.add(
|
|
365
|
-
'
|
|
366
|
-
({ name }:
|
|
367
|
-
cy.log(`
|
|
555
|
+
'copyWebContainerLogs',
|
|
556
|
+
({ name }: CopyWebContainerLogsProps): Cypress.Chainable => {
|
|
557
|
+
cy.log(`Getting logs from container ${name} ...`);
|
|
558
|
+
|
|
559
|
+
return cy.getLogDirectory().then((logDirectory) => {
|
|
560
|
+
let sourcePhpLogs = '/var/log/php8.1-fpm-centreon-error.log';
|
|
561
|
+
let targetPhpLogs = `${logDirectory}/php8.1-fpm-centreon-error.log`;
|
|
562
|
+
let sourceApacheLogs = '/var/log/apache2';
|
|
563
|
+
let targetApacheLogs = `${logDirectory}/apache2`;
|
|
564
|
+
if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
|
|
565
|
+
sourcePhpLogs = '/var/log/php-fpm';
|
|
566
|
+
targetPhpLogs = `${logDirectory}/php`;
|
|
567
|
+
sourceApacheLogs = '/var/log/httpd';
|
|
568
|
+
targetApacheLogs = `${logDirectory}/httpd`;
|
|
569
|
+
}
|
|
368
570
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
'
|
|
374
|
-
)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
571
|
+
return cy
|
|
572
|
+
.copyFromContainer({
|
|
573
|
+
destination: `${logDirectory}/broker`,
|
|
574
|
+
name,
|
|
575
|
+
source: '/var/log/centreon-broker'
|
|
576
|
+
})
|
|
577
|
+
.copyFromContainer({
|
|
578
|
+
destination: `${logDirectory}/engine`,
|
|
579
|
+
name,
|
|
580
|
+
source: '/var/log/centreon-engine'
|
|
581
|
+
})
|
|
582
|
+
.copyFromContainer({
|
|
583
|
+
destination: `${logDirectory}/centreon`,
|
|
584
|
+
name,
|
|
585
|
+
source: '/var/log/centreon'
|
|
586
|
+
})
|
|
587
|
+
.copyFromContainer({
|
|
588
|
+
destination: `${logDirectory}/centreon-gorgone`,
|
|
589
|
+
name,
|
|
590
|
+
source: '/var/log/centreon-gorgone'
|
|
591
|
+
})
|
|
592
|
+
.copyFromContainer({
|
|
593
|
+
destination: targetPhpLogs,
|
|
594
|
+
name,
|
|
595
|
+
source: sourcePhpLogs,
|
|
596
|
+
})
|
|
597
|
+
.copyFromContainer({
|
|
598
|
+
destination: targetApacheLogs,
|
|
599
|
+
name,
|
|
600
|
+
source: sourceApacheLogs,
|
|
601
|
+
})
|
|
602
|
+
.exec(`chmod -R 755 "${logDirectory}"`);
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
Cypress.Commands.add('stopContainers', (): Cypress.Chainable => {
|
|
607
|
+
cy.log('Stopping containers ...');
|
|
608
|
+
|
|
609
|
+
const name = 'web';
|
|
610
|
+
|
|
611
|
+
return cy
|
|
612
|
+
.visitEmptyPage()
|
|
613
|
+
.getLogDirectory()
|
|
614
|
+
.then((logDirectory) => {
|
|
615
|
+
return cy
|
|
616
|
+
.getContainersLogs()
|
|
617
|
+
.then((containersLogs: Array<Array<string>>) => {
|
|
618
|
+
if (!containersLogs) {
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
Object.entries(containersLogs).forEach(([containerName, logs]) => {
|
|
623
|
+
cy.writeFile(
|
|
624
|
+
`${logDirectory}/container-${containerName}.log`,
|
|
625
|
+
logs
|
|
626
|
+
);
|
|
627
|
+
});
|
|
628
|
+
})
|
|
629
|
+
.copyWebContainerLogs({ name })
|
|
630
|
+
.exec(`chmod -R 755 "${logDirectory}"`)
|
|
631
|
+
.task(
|
|
632
|
+
'stopContainers',
|
|
633
|
+
{},
|
|
634
|
+
{ timeout: 600000 } // 10 minutes because docker pull can be very slow
|
|
635
|
+
);
|
|
380
636
|
});
|
|
637
|
+
});
|
|
381
638
|
|
|
382
|
-
|
|
639
|
+
Cypress.Commands.add(
|
|
640
|
+
'createDirectory',
|
|
641
|
+
(directoryPath: string): Cypress.Chainable => {
|
|
642
|
+
return cy.task('createDirectory', directoryPath);
|
|
383
643
|
}
|
|
384
644
|
);
|
|
385
645
|
|
|
@@ -416,6 +676,41 @@ Cypress.Commands.add(
|
|
|
416
676
|
}
|
|
417
677
|
);
|
|
418
678
|
|
|
679
|
+
Cypress.Commands.add(
|
|
680
|
+
'insertDashboardWithWidget',
|
|
681
|
+
(dashboardBody, patchBody) => {
|
|
682
|
+
cy.request({
|
|
683
|
+
body: {
|
|
684
|
+
...dashboardBody
|
|
685
|
+
},
|
|
686
|
+
method: 'POST',
|
|
687
|
+
url: '/centreon/api/latest/configuration/dashboards'
|
|
688
|
+
}).then((response) => {
|
|
689
|
+
const dashboardId = response.body.id;
|
|
690
|
+
cy.waitUntil(
|
|
691
|
+
() => {
|
|
692
|
+
return cy
|
|
693
|
+
.request({
|
|
694
|
+
method: 'GET',
|
|
695
|
+
url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
|
|
696
|
+
})
|
|
697
|
+
.then((getResponse) => {
|
|
698
|
+
return getResponse.body && getResponse.body.id === dashboardId;
|
|
699
|
+
});
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
timeout: 10000
|
|
703
|
+
}
|
|
704
|
+
);
|
|
705
|
+
cy.request({
|
|
706
|
+
body: patchBody,
|
|
707
|
+
method: 'PATCH',
|
|
708
|
+
url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
);
|
|
713
|
+
|
|
419
714
|
interface ShareDashboardToUserProps {
|
|
420
715
|
dashboardName: string;
|
|
421
716
|
role: string;
|
|
@@ -430,6 +725,30 @@ interface ListingRequestResult {
|
|
|
430
725
|
};
|
|
431
726
|
}
|
|
432
727
|
|
|
728
|
+
interface PatchDashboardBody {
|
|
729
|
+
panels: Array<{
|
|
730
|
+
layout: {
|
|
731
|
+
height: number;
|
|
732
|
+
min_height: number;
|
|
733
|
+
min_width: number;
|
|
734
|
+
width: number;
|
|
735
|
+
x: number;
|
|
736
|
+
y: number;
|
|
737
|
+
};
|
|
738
|
+
name: string;
|
|
739
|
+
widget_settings: {
|
|
740
|
+
options: {
|
|
741
|
+
description: {
|
|
742
|
+
content: string;
|
|
743
|
+
enabled: boolean;
|
|
744
|
+
};
|
|
745
|
+
name: string;
|
|
746
|
+
};
|
|
747
|
+
};
|
|
748
|
+
widget_type: string;
|
|
749
|
+
}>;
|
|
750
|
+
}
|
|
751
|
+
|
|
433
752
|
Cypress.Commands.add(
|
|
434
753
|
'shareDashboardToUser',
|
|
435
754
|
({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
|
|
@@ -465,7 +784,7 @@ Cypress.Commands.add(
|
|
|
465
784
|
|
|
466
785
|
Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
|
|
467
786
|
return cy
|
|
468
|
-
.get('header div[data-cy="clock"]', { timeout:
|
|
787
|
+
.get('header div[data-cy="clock"]', { timeout: 20000 })
|
|
469
788
|
.should('be.visible')
|
|
470
789
|
.then(($time) => {
|
|
471
790
|
const headerTime = $time.children()[1].textContent;
|
|
@@ -491,46 +810,85 @@ declare global {
|
|
|
491
810
|
props: CopyToContainerProps,
|
|
492
811
|
options?: Partial<Cypress.ExecOptions>
|
|
493
812
|
) => Cypress.Chainable;
|
|
813
|
+
copyWebContainerLogs: (props: CopyWebContainerLogsProps) => Cypress.Chainable;
|
|
494
814
|
createDirectory: (directoryPath: string) => Cypress.Chainable;
|
|
495
815
|
execInContainer: ({
|
|
496
816
|
command,
|
|
497
817
|
name
|
|
498
818
|
}: ExecInContainerProps) => Cypress.Chainable;
|
|
819
|
+
getByLabel: ({
|
|
820
|
+
patternType,
|
|
821
|
+
tag,
|
|
822
|
+
label
|
|
823
|
+
}: GetByLabelProps) => Cypress.Chainable;
|
|
824
|
+
getByTestId: ({
|
|
825
|
+
patternType,
|
|
826
|
+
tag,
|
|
827
|
+
testId
|
|
828
|
+
}: GetByTestIdProps) => Cypress.Chainable;
|
|
829
|
+
getContainerId: (containerName: string) => Cypress.Chainable;
|
|
830
|
+
getContainerIpAddress: (containerName: string) => Cypress.Chainable;
|
|
831
|
+
getContainersLogs: () => Cypress.Chainable;
|
|
499
832
|
getIframeBody: () => Cypress.Chainable;
|
|
833
|
+
getLogDirectory: () => Cypress.Chainable;
|
|
500
834
|
getTimeFromHeader: () => Cypress.Chainable;
|
|
501
835
|
getWebVersion: () => Cypress.Chainable;
|
|
502
836
|
hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
|
|
503
837
|
insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
|
|
504
838
|
insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
|
|
839
|
+
insertDashboardWithWidget: (
|
|
840
|
+
dashboard: Dashboard,
|
|
841
|
+
patch: PatchDashboardBody
|
|
842
|
+
) => Cypress.Chainable;
|
|
843
|
+
loginAsAdminViaApiV2: () => Cypress.Chainable;
|
|
505
844
|
loginByTypeOfUser: ({
|
|
506
845
|
jsonName,
|
|
507
846
|
loginViaApi
|
|
508
847
|
}: LoginByTypeOfUserProps) => Cypress.Chainable;
|
|
848
|
+
logout: () => void;
|
|
849
|
+
logoutViaAPI: () => Cypress.Chainable;
|
|
509
850
|
moveSortableElement: (direction: string) => Cypress.Chainable;
|
|
510
851
|
navigateTo: ({
|
|
511
852
|
page,
|
|
512
853
|
rootItemNumber,
|
|
513
854
|
subMenu
|
|
514
855
|
}: NavigateToProps) => Cypress.Chainable;
|
|
856
|
+
requestOnDatabase: ({
|
|
857
|
+
database,
|
|
858
|
+
query
|
|
859
|
+
}: RequestOnDatabaseProps) => Cypress.Chainable;
|
|
860
|
+
setUserTokenApiV1: ({
|
|
861
|
+
login,
|
|
862
|
+
password
|
|
863
|
+
}?: SetUserTokenApiV1Props) => Cypress.Chainable;
|
|
515
864
|
shareDashboardToUser: ({
|
|
516
865
|
dashboardName,
|
|
517
866
|
userName,
|
|
518
867
|
role
|
|
519
868
|
}: ShareDashboardToUserProps) => Cypress.Chainable;
|
|
520
869
|
startContainer: ({
|
|
870
|
+
command,
|
|
521
871
|
name,
|
|
522
|
-
image
|
|
872
|
+
image,
|
|
873
|
+
portBindings
|
|
523
874
|
}: StartContainerProps) => Cypress.Chainable;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
875
|
+
startContainers: ({
|
|
876
|
+
composeFile,
|
|
877
|
+
databaseImage,
|
|
878
|
+
moduleName,
|
|
879
|
+
openidImage,
|
|
880
|
+
profiles,
|
|
527
881
|
useSlim,
|
|
528
|
-
|
|
529
|
-
|
|
882
|
+
webOs,
|
|
883
|
+
webVersion
|
|
884
|
+
}?: StartContainersProps) => Cypress.Chainable;
|
|
885
|
+
waitForElementInIframe: (
|
|
886
|
+
iframeSelector: string,
|
|
887
|
+
elementSelector: string
|
|
888
|
+
) => Cypress.Chainable;
|
|
530
889
|
stopContainer: ({ name }: StopContainerProps) => Cypress.Chainable;
|
|
531
|
-
|
|
890
|
+
stopContainers: () => Cypress.Chainable;
|
|
532
891
|
visitEmptyPage: () => Cypress.Chainable;
|
|
533
|
-
waitForContainerAndSetToken: () => Cypress.Chainable;
|
|
534
892
|
}
|
|
535
893
|
}
|
|
536
894
|
}
|