@centreon/js-config 24.8.2 → 24.9.1

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