@centreon/js-config 24.4.10 → 24.4.12

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.
@@ -1,11 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
2
 
3
3
  import './commands/configuration';
4
- import './commands/monitoring';
5
-
6
- import installLogsCollector from 'cypress-terminal-report/src/installLogsCollector';
7
-
8
- installLogsCollector({ enableExtendedCollector: true });
9
4
 
10
5
  const apiLoginV2 = '/centreon/authentication/providers/configurations/local';
11
6
 
@@ -28,7 +23,7 @@ Cypress.Commands.add('getWebVersion', (): Cypress.Chainable => {
28
23
 
29
24
  Cypress.Commands.add('getIframeBody', (): Cypress.Chainable => {
30
25
  return cy
31
- .get('iframe#main-content', { timeout: 10000 })
26
+ .get('iframe#main-content')
32
27
  .its('0.contentDocument.body')
33
28
  .should('not.be.empty')
34
29
  .then(cy.wrap);
@@ -44,13 +39,6 @@ Cypress.Commands.add(
44
39
  }
45
40
  );
46
41
 
47
- Cypress.Commands.add(
48
- 'clickSubRootMenuItem',
49
- (page: string): Cypress.Chainable => {
50
- return cy.get('div[data-cy="collapse"]').eq(1).contains(page).click();
51
- }
52
- );
53
-
54
42
  interface NavigateToProps {
55
43
  page: string;
56
44
  rootItemNumber: number;
@@ -63,13 +51,8 @@ Cypress.Commands.add(
63
51
  if (subMenu) {
64
52
  cy.hoverRootMenuItem(rootItemNumber)
65
53
  .contains(subMenu)
66
- .trigger('mouseover')
67
- .get('.MuiCollapse-wrapper')
68
- .find('div[data-cy="collapse"]')
69
- .should('be.visible')
70
- .and('contain', page);
71
-
72
- cy.clickSubRootMenuItem(page);
54
+ .trigger('mouseover', { force: true });
55
+ cy.contains(page).click({ force: true });
73
56
 
74
57
  return;
75
58
  }
@@ -102,41 +85,29 @@ Cypress.Commands.add(
102
85
 
103
86
  interface CopyFromContainerProps {
104
87
  destination: string;
105
- name?: string;
106
88
  source: string;
107
89
  }
108
90
 
109
91
  Cypress.Commands.add(
110
92
  'copyFromContainer',
111
- (
112
- {
113
- name = Cypress.env('dockerName'),
114
- source,
115
- destination
116
- }: CopyFromContainerProps,
117
- options?: Partial<Cypress.ExecOptions>
118
- ) => {
119
- return cy.exec(`docker cp ${name}:${source} "${destination}"`, options);
93
+ ({ source, destination }: CopyFromContainerProps) => {
94
+ return cy.exec(
95
+ `docker cp ${Cypress.env('dockerName')}:${source} "${destination}"`
96
+ );
120
97
  }
121
98
  );
122
99
 
123
100
  interface CopyToContainerProps {
124
101
  destination: string;
125
- name?: string;
126
102
  source: string;
127
103
  }
128
104
 
129
105
  Cypress.Commands.add(
130
106
  'copyToContainer',
131
- (
132
- {
133
- name = Cypress.env('dockerName'),
134
- source,
135
- destination
136
- }: CopyToContainerProps,
137
- options?: Partial<Cypress.ExecOptions>
138
- ) => {
139
- return cy.exec(`docker cp ${source} ${name}:${destination}`, options);
107
+ ({ source, destination }: CopyToContainerProps) => {
108
+ return cy.exec(
109
+ `docker cp ${source} ${Cypress.env('dockerName')}:${destination}`
110
+ );
140
111
  }
141
112
  );
142
113
 
@@ -147,7 +118,7 @@ interface LoginByTypeOfUserProps {
147
118
 
148
119
  Cypress.Commands.add(
149
120
  'loginByTypeOfUser',
150
- ({ jsonName = 'admin', loginViaApi = false }): Cypress.Chainable => {
121
+ ({ jsonName, loginViaApi }): Cypress.Chainable => {
151
122
  if (loginViaApi) {
152
123
  return cy
153
124
  .fixture(`users/${jsonName}.json`)
@@ -164,25 +135,24 @@ Cypress.Commands.add(
164
135
  .visit(`${Cypress.config().baseUrl}`)
165
136
  .wait('@getNavigationList');
166
137
  }
167
-
168
138
  cy.visit(`${Cypress.config().baseUrl}`)
169
139
  .fixture(`users/${jsonName}.json`)
170
140
  .then((credential) => {
171
- cy.getByLabel({ label: 'Alias', tag: 'input' }).type(
172
- `{selectAll}{backspace}${credential.login}`
173
- );
141
+ cy.getByLabel({ label: 'Alias', tag: 'input' }).type(credential.login);
174
142
  cy.getByLabel({ label: 'Password', tag: 'input' }).type(
175
- `{selectAll}{backspace}${credential.password}`
143
+ credential.password
176
144
  );
177
145
  })
178
146
  .getByLabel({ label: 'Connect', tag: 'button' })
179
147
  .click();
180
148
 
181
- return cy.get('.MuiAlert-message').then(($snackbar) => {
182
- if ($snackbar.text().includes('Login succeeded')) {
183
- cy.wait('@getNavigationList');
184
- }
185
- });
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
+ });
186
156
  }
187
157
  );
188
158
 
@@ -240,20 +210,29 @@ interface StartContainerProps {
240
210
  Cypress.Commands.add(
241
211
  'startContainer',
242
212
  ({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
243
- cy.log(`Starting container ${name} from image ${image}`);
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}`);
244
225
 
245
- return cy.task(
246
- 'startContainer',
247
- { image, name, portBindings },
248
- { timeout: 600000 } // 10 minutes because docker pull can be very slow
249
- );
250
- }
251
- );
226
+ return cy.wrap(image);
227
+ }
252
228
 
253
- Cypress.Commands.add(
254
- 'createDirectory',
255
- (directoryPath: string): Cypress.Chainable => {
256
- return cy.task('createDirectory', directoryPath);
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
+ );
257
236
  }
258
237
  );
259
238
 
@@ -268,7 +247,7 @@ Cypress.Commands.add(
268
247
  'startWebContainer',
269
248
  ({
270
249
  name = Cypress.env('dockerName'),
271
- os = Cypress.env('WEB_IMAGE_OS'),
250
+ os = 'alma9',
272
251
  useSlim = true,
273
252
  version = Cypress.env('WEB_IMAGE_VERSION')
274
253
  }: StartWebContainerProps = {}): Cypress.Chainable => {
@@ -283,13 +262,12 @@ Cypress.Commands.add(
283
262
  portBindings: [{ destination: 4000, source: 80 }]
284
263
  })
285
264
  .then(() => {
286
- const baseUrl = 'http://127.0.0.1:4000';
265
+ const baseUrl = 'http://0.0.0.0:4000';
287
266
 
288
267
  Cypress.config('baseUrl', baseUrl);
289
268
 
290
- return cy.task(
291
- 'waitOn',
292
- `${baseUrl}/centreon/api/latest/platform/installation/status`
269
+ return cy.exec(
270
+ `npx wait-on ${baseUrl}/centreon/api/latest/platform/installation/status`
293
271
  );
294
272
  })
295
273
  .visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
@@ -306,7 +284,7 @@ Cypress.Commands.add(
306
284
  ({
307
285
  name = Cypress.env('dockerName')
308
286
  }: StopWebContainerProps = {}): Cypress.Chainable => {
309
- const logDirectory = `results/logs/${Cypress.spec.name.replace(
287
+ const logDirectory = `cypress/results/logs/${Cypress.spec.name.replace(
310
288
  artifactIllegalCharactersMatcher,
311
289
  '_'
312
290
  )}/${Cypress.currentTest.title.replace(
@@ -316,64 +294,25 @@ Cypress.Commands.add(
316
294
 
317
295
  return cy
318
296
  .visitEmptyPage()
319
- .createDirectory(logDirectory)
297
+ .exec(`mkdir -p "${logDirectory}"`)
320
298
  .copyFromContainer({
321
299
  destination: `${logDirectory}/broker`,
322
- name,
323
300
  source: '/var/log/centreon-broker'
324
301
  })
325
302
  .copyFromContainer({
326
303
  destination: `${logDirectory}/engine`,
327
- name,
328
304
  source: '/var/log/centreon-engine'
329
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
+ })
330
312
  .copyFromContainer({
331
313
  destination: `${logDirectory}/centreon`,
332
- name,
333
314
  source: '/var/log/centreon'
334
315
  })
335
- .copyFromContainer({
336
- destination: `${logDirectory}/centreon-gorgone`,
337
- name,
338
- source: '/var/log/centreon-gorgone'
339
- })
340
- .then(() => {
341
- if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
342
- return cy.copyFromContainer({
343
- destination: `${logDirectory}/php`,
344
- name,
345
- source: '/var/log/php-fpm'
346
- });
347
- }
348
-
349
- return cy.copyFromContainer(
350
- {
351
- destination: `${logDirectory}/php8.1-fpm-centreon-error.log`,
352
- name,
353
- source: '/var/log/php8.1-fpm-centreon-error.log'
354
- },
355
- { failOnNonZeroExit: false }
356
- );
357
- })
358
- .then(() => {
359
- if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
360
- return cy.copyFromContainer({
361
- destination: `${logDirectory}/httpd`,
362
- name,
363
- source: '/var/log/httpd'
364
- });
365
- }
366
-
367
- return cy.copyFromContainer(
368
- {
369
- destination: `${logDirectory}/apache2`,
370
- name,
371
- source: '/var/log/apache2'
372
- },
373
- { failOnNonZeroExit: false }
374
- );
375
- })
376
- .exec(`chmod -R 755 "${logDirectory}"`)
377
316
  .stopContainer({ name });
378
317
  }
379
318
  );
@@ -385,11 +324,9 @@ interface StopContainerProps {
385
324
  Cypress.Commands.add(
386
325
  'stopContainer',
387
326
  ({ name }: StopContainerProps): Cypress.Chainable => {
388
- cy.log(`Stopping container ${name}`);
389
-
390
327
  cy.exec(`docker logs ${name}`).then(({ stdout }) => {
391
328
  cy.writeFile(
392
- `results/logs/${Cypress.spec.name.replace(
329
+ `cypress/results/logs/${Cypress.spec.name.replace(
393
330
  artifactIllegalCharactersMatcher,
394
331
  '_'
395
332
  )}/${Cypress.currentTest.title.replace(
@@ -404,192 +341,21 @@ Cypress.Commands.add(
404
341
  }
405
342
  );
406
343
 
407
- interface Dashboard {
408
- description?: string;
409
- name: string;
410
- }
411
-
412
- Cypress.Commands.add(
413
- 'insertDashboardList',
414
- (fixtureFile: string): Cypress.Chainable => {
415
- return cy.fixture(fixtureFile).then((dashboardList) => {
416
- cy.wrap(
417
- Promise.all(
418
- dashboardList.map((dashboardBody: Dashboard) =>
419
- cy.insertDashboard({ ...dashboardBody })
420
- )
421
- )
422
- );
423
- });
424
- }
425
- );
426
-
427
- Cypress.Commands.add(
428
- 'insertDashboard',
429
- (dashboardBody: Dashboard): Cypress.Chainable => {
430
- return cy.request({
431
- body: {
432
- ...dashboardBody
433
- },
434
- method: 'POST',
435
- url: '/centreon/api/latest/configuration/dashboards'
436
- });
437
- }
438
- );
439
-
440
- Cypress.Commands.add(
441
- 'insertDashboardWithWidget',
442
- (dashboardBody, patchBody) => {
443
- cy.request({
444
- body: {
445
- ...dashboardBody
446
- },
447
- method: 'POST',
448
- url: '/centreon/api/latest/configuration/dashboards'
449
- }).then((response) => {
450
- const dashboardId = response.body.id;
451
- cy.waitUntil(
452
- () => {
453
- return cy
454
- .request({
455
- method: 'GET',
456
- url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
457
- })
458
- .then((getResponse) => {
459
- return getResponse.body && getResponse.body.id === dashboardId;
460
- });
461
- },
462
- {
463
- timeout: 10000
464
- }
465
- );
466
- cy.request({
467
- body: patchBody,
468
- method: 'PATCH',
469
- url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
470
- });
471
- });
472
- }
473
- );
474
-
475
- interface ShareDashboardToUserProps {
476
- dashboardName: string;
477
- role: string;
478
- userName: string;
479
- }
480
-
481
- interface ListingRequestResult {
482
- body: {
483
- result: Array<{
484
- id: number;
485
- }>;
486
- };
487
- }
488
-
489
- interface PatchDashboardBody {
490
- panels: Array<{
491
- layout: {
492
- height: number;
493
- min_height: number;
494
- min_width: number;
495
- width: number;
496
- x: number;
497
- y: number;
498
- };
499
- name: string;
500
- widget_settings: {
501
- options: {
502
- description: {
503
- content: string;
504
- enabled: boolean;
505
- };
506
- name: string;
507
- };
508
- };
509
- widget_type: string;
510
- }>;
511
- }
512
-
513
- Cypress.Commands.add(
514
- 'shareDashboardToUser',
515
- ({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
516
- Promise.all([
517
- cy.request({
518
- method: 'GET',
519
- url: `/centreon/api/latest/configuration/users?search={"name":"${userName}"}`
520
- }),
521
- cy.request({
522
- method: 'GET',
523
- url: `/centreon/api/latest/configuration/dashboards?search={"name":"${dashboardName}"}`
524
- })
525
- ]).then(
526
- ([retrievedUser, retrievedDashboard]: [
527
- ListingRequestResult,
528
- ListingRequestResult
529
- ]) => {
530
- const userId = retrievedUser.body.result[0].id;
531
- const dashboardId = retrievedDashboard.body.result[0].id;
532
-
533
- cy.request({
534
- body: {
535
- id: userId,
536
- role: `${role}`
537
- },
538
- method: 'POST',
539
- url: `/centreon/api/latest/configuration/dashboards/${dashboardId}/access_rights/contacts`
540
- });
541
- }
542
- );
543
- }
544
- );
545
-
546
- Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
547
- return cy
548
- .get('header div[data-cy="clock"]', { timeout: 10000 })
549
- .should('be.visible')
550
- .then(($time) => {
551
- const headerTime = $time.children()[1].textContent;
552
- if (headerTime?.match(/\d+:\d+/)) {
553
- cy.log(`header time is : ${headerTime}`);
554
-
555
- return cy.wrap(headerTime);
556
- }
557
-
558
- throw new Error(`header time is not displayed`);
559
- });
560
- });
561
-
562
344
  declare global {
563
345
  namespace Cypress {
564
346
  interface Chainable {
565
- clickSubRootMenuItem: (page: string) => Cypress.Chainable;
566
- copyFromContainer: (
567
- props: CopyFromContainerProps,
568
- options?: Partial<Cypress.ExecOptions>
569
- ) => Cypress.Chainable;
570
- copyToContainer: (
571
- props: CopyToContainerProps,
572
- options?: Partial<Cypress.ExecOptions>
573
- ) => Cypress.Chainable;
574
- createDirectory: (directoryPath: string) => Cypress.Chainable;
347
+ copyFromContainer: (props: CopyFromContainerProps) => Cypress.Chainable;
348
+ copyToContainer: (props: CopyToContainerProps) => Cypress.Chainable;
575
349
  execInContainer: ({
576
350
  command,
577
351
  name
578
352
  }: ExecInContainerProps) => Cypress.Chainable;
579
353
  getIframeBody: () => Cypress.Chainable;
580
- getTimeFromHeader: () => Cypress.Chainable;
581
354
  getWebVersion: () => Cypress.Chainable;
582
355
  hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
583
- insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
584
- insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
585
- insertDashboardWithWidget: (
586
- dashboard: Dashboard,
587
- patch: PatchDashboardBody
588
- ) => Cypress.Chainable;
589
-
590
356
  loginByTypeOfUser: ({
591
- jsonName,
592
- loginViaApi
357
+ jsonName = 'admin',
358
+ loginViaApi = false
593
359
  }: LoginByTypeOfUserProps) => Cypress.Chainable;
594
360
  moveSortableElement: (direction: string) => Cypress.Chainable;
595
361
  navigateTo: ({
@@ -597,11 +363,6 @@ declare global {
597
363
  rootItemNumber,
598
364
  subMenu
599
365
  }: NavigateToProps) => Cypress.Chainable;
600
- shareDashboardToUser: ({
601
- dashboardName,
602
- userName,
603
- role
604
- }: ShareDashboardToUserProps) => Cypress.Chainable;
605
366
  startContainer: ({
606
367
  name,
607
368
  image
@@ -4,18 +4,13 @@
4
4
  import { execSync } from 'child_process';
5
5
 
6
6
  import { defineConfig } from 'cypress';
7
- import installLogsPrinter from 'cypress-terminal-report/src/installLogsPrinter';
8
- import { config as configDotenv } from 'dotenv';
9
7
 
10
- import esbuildPreprocessor from './esbuild-preprocessor';
11
- import plugins from './plugins';
12
- import tasks from './tasks';
8
+ import setupNodeEvents from './plugins';
13
9
 
14
10
  interface ConfigurationOptions {
15
11
  cypressFolder?: string;
16
12
  dockerName?: string;
17
13
  env?: Record<string, unknown>;
18
- envFile?: string;
19
14
  isDevelopment?: boolean;
20
15
  specPattern: string;
21
16
  }
@@ -25,14 +20,11 @@ export default ({
25
20
  cypressFolder,
26
21
  isDevelopment,
27
22
  dockerName,
28
- env,
29
- envFile
23
+ env
30
24
  }: ConfigurationOptions): Cypress.ConfigOptions => {
31
- if (envFile) {
32
- configDotenv({ path: envFile });
33
- }
34
-
35
- const resultsFolder = `${cypressFolder || '.'}/results`;
25
+ const resultsFolder = `${cypressFolder || 'cypress'}/results${
26
+ isDevelopment ? '/dev' : ''
27
+ }`;
36
28
 
37
29
  const webImageVersion = execSync('git rev-parse --abbrev-ref HEAD')
38
30
  .toString('utf8')
@@ -43,34 +35,44 @@ export default ({
43
35
  defaultCommandTimeout: 6000,
44
36
  e2e: {
45
37
  excludeSpecPattern: ['*.js', '*.ts', '*.md'],
46
- fixturesFolder: 'fixtures',
47
- reporter: require.resolve('cypress-multi-reporters'),
48
- reporterOptions: {
49
- configFile: `${__dirname}/reporter-config.js`
50
- },
51
- setupNodeEvents: async (on, config) => {
52
- installLogsPrinter(on);
53
- await esbuildPreprocessor(on, config);
54
- tasks(on);
55
-
56
- return plugins(on, config);
57
- },
58
- specPattern,
59
- supportFile: 'support/e2e.{js,jsx,ts,tsx}'
38
+ setupNodeEvents,
39
+ specPattern
60
40
  },
61
41
  env: {
62
42
  ...env,
63
- OPENID_IMAGE_VERSION: process.env.MAJOR || '24.04',
43
+ OPENID_IMAGE_VERSION: '23.04',
64
44
  WEB_IMAGE_OS: 'alma9',
65
45
  WEB_IMAGE_VERSION: webImageVersion,
66
46
  dockerName: dockerName || 'centreon-dev'
67
47
  },
68
- execTimeout: 60000,
48
+ execTimeout: 120000,
49
+ reporter: 'mochawesome',
50
+ reporterOptions: {
51
+ html: false,
52
+ json: true,
53
+ overwrite: true,
54
+ reportDir: `${resultsFolder}/reports`,
55
+ reportFilename: '[name]-report.json'
56
+ },
69
57
  requestTimeout: 10000,
70
58
  retries: 0,
71
59
  screenshotsFolder: `${resultsFolder}/screenshots`,
60
+ setupNodeEvents: (on, config) => {
61
+ on('before:browser:launch', (browser, launchOptions) => {
62
+ if (browser.name === 'chrome' && browser.isHeadless) {
63
+ launchOptions.args = launchOptions.args.map((arg) => {
64
+ if (arg === '--headless') {
65
+ return '--headless=new';
66
+ }
67
+
68
+ return arg;
69
+ });
70
+ }
71
+
72
+ return launchOptions;
73
+ });
74
+ },
72
75
  video: true,
73
- videoCompression: 0,
74
76
  videosFolder: `${resultsFolder}/videos`
75
77
  });
76
78
  };