@centreon/js-config 23.10.53 → 23.10.54

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.
@@ -4,15 +4,13 @@ import React from 'react';
4
4
  import { mount } from 'cypress/react18';
5
5
  import { equals, isNil } from 'ramda';
6
6
 
7
- import { Box, CssBaseline } from '@mui/material';
7
+ import { Box } from '@mui/material';
8
8
 
9
9
  import { ThemeProvider } from '@centreon/ui';
10
10
 
11
11
  import '@testing-library/cypress/add-commands';
12
12
  import 'cypress-msw-interceptor';
13
13
 
14
- import disableMotion from './disableCssTransitions';
15
-
16
14
  interface MountProps {
17
15
  Component: React.ReactNode;
18
16
  options?: object;
@@ -26,7 +24,7 @@ export enum Method {
26
24
  PUT = 'PUT'
27
25
  }
28
26
 
29
- Cypress.Commands.add('mount', ({ Component, options = {} }) => {
27
+ Cypress.Commands.add('mount', ({ Component, options }) => {
30
28
  const wrapped = (
31
29
  <ThemeProvider>
32
30
  <Box
@@ -38,10 +36,11 @@ Cypress.Commands.add('mount', ({ Component, options = {} }) => {
38
36
  >
39
37
  {Component}
40
38
  </Box>
41
- <CssBaseline />
42
39
  </ThemeProvider>
43
40
  );
44
41
 
42
+ document.getElementsByTagName('body')[0].setAttribute('style', 'margin:0px');
43
+
45
44
  return mount(wrapped, options);
46
45
  });
47
46
 
@@ -129,28 +128,15 @@ Cypress.Commands.add(
129
128
  }
130
129
  );
131
130
 
132
- Cypress.Commands.add('makeSnapshot', (title?: string) => {
133
- cy.viewport(1280, 590);
134
- cy.matchImageSnapshot(title);
135
- });
136
-
137
- Cypress.Commands.add('cssDisableMotion', (): void => {
138
- Cypress.on('window:before:load', (cyWindow) => {
139
- disableMotion(cyWindow);
140
- });
141
- });
142
-
143
131
  declare global {
144
132
  namespace Cypress {
145
133
  interface Chainable {
146
- cssDisableMotion: () => Cypress.Chainable;
147
134
  interceptAPIRequest: <T extends object>(
148
135
  props: InterceptAPIRequestProps<T>
149
136
  ) => Cypress.Chainable;
150
137
  interceptRequest: (method, path, mock, alias) => Cypress.Chainable;
151
- makeSnapshot: (title?: string) => void;
152
- mount: ({ Component, options }: MountProps) => Cypress.Chainable;
153
- moveSortableElement: ({ element, direction }) => void;
138
+ mount: ({ Component, options = {} }: MountProps) => Cypress.Chainable;
139
+ moveSortableElement: ({ ariaLabel, direction }) => void;
154
140
  moveSortableElementUsingAriaLabel: ({ ariaLabel, direction }) => void;
155
141
  waitForRequest: (alias) => Cypress.Chainable;
156
142
  }
@@ -4,30 +4,28 @@ const {
4
4
  addMatchImageSnapshotPlugin
5
5
  } = require('@simonsmith/cypress-image-snapshot/plugin');
6
6
 
7
- module.exports = ({
8
- webpackConfig,
9
- cypressFolder,
10
- specPattern,
11
- env,
12
- useVite = false,
13
- excludeSpecPattern
14
- }) => {
7
+ module.exports = ({ webpackConfig, cypressFolder, specPattern, env }) => {
15
8
  const mainCypressFolder = cypressFolder || 'cypress';
16
9
 
17
10
  return defineConfig({
18
11
  component: {
19
12
  devServer: {
20
- bundler: useVite ? 'vite' : 'webpack',
13
+ bundler: 'webpack',
21
14
  framework: 'react',
22
15
  webpackConfig
23
16
  },
24
- excludeSpecPattern,
25
17
  setupNodeEvents: (on, config) => {
26
18
  addMatchImageSnapshotPlugin(on, config);
27
19
 
28
20
  on('before:browser:launch', (browser, launchOptions) => {
29
21
  if (browser.name === 'chrome' && browser.isHeadless) {
30
- launchOptions.args.push('--headless=new');
22
+ launchOptions.args = launchOptions.args.map((arg) => {
23
+ if (arg === '--headless') {
24
+ return '--headless=new';
25
+ }
26
+
27
+ return arg;
28
+ });
31
29
  }
32
30
 
33
31
  return launchOptions;
@@ -13,7 +13,7 @@ const enableVisualTesting = (cypressFolder = 'cypress'): void => {
13
13
  capture: 'viewport',
14
14
  customDiffConfig: { threshold: 0.01 },
15
15
  customSnapshotsDir: `${cypressFolder}/visual-testing-snapshots`,
16
- failureThreshold: 0.07,
16
+ failureThreshold: 0.06,
17
17
  failureThresholdType: 'percent'
18
18
  });
19
19
  };
@@ -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,15 +135,12 @@ 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' })
@@ -242,20 +210,9 @@ interface StartContainerProps {
242
210
  Cypress.Commands.add(
243
211
  'startContainer',
244
212
  ({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
245
- cy.log(`Starting container ${name} from image ${image}`);
246
-
247
- return cy.task(
248
- 'startContainer',
249
- { image, name, portBindings },
250
- { timeout: 600000 } // 10 minutes because docker pull can be very slow
251
- );
252
- }
253
- );
254
-
255
- Cypress.Commands.add(
256
- 'createDirectory',
257
- (directoryPath: string): Cypress.Chainable => {
258
- return cy.task('createDirectory', directoryPath);
213
+ return cy
214
+ .exec(`docker image inspect ${image} || docker pull ${image}`)
215
+ .task('startContainer', { image, name, portBindings });
259
216
  }
260
217
  );
261
218
 
@@ -270,7 +227,7 @@ Cypress.Commands.add(
270
227
  'startWebContainer',
271
228
  ({
272
229
  name = Cypress.env('dockerName'),
273
- os = Cypress.env('WEB_IMAGE_OS'),
230
+ os = 'alma9',
274
231
  useSlim = true,
275
232
  version = Cypress.env('WEB_IMAGE_VERSION')
276
233
  }: StartWebContainerProps = {}): Cypress.Chainable => {
@@ -285,13 +242,12 @@ Cypress.Commands.add(
285
242
  portBindings: [{ destination: 4000, source: 80 }]
286
243
  })
287
244
  .then(() => {
288
- const baseUrl = 'http://127.0.0.1:4000';
245
+ const baseUrl = 'http://0.0.0.0:4000';
289
246
 
290
247
  Cypress.config('baseUrl', baseUrl);
291
248
 
292
- return cy.task(
293
- 'waitOn',
294
- `${baseUrl}/centreon/api/latest/platform/installation/status`
249
+ return cy.exec(
250
+ `npx wait-on ${baseUrl}/centreon/api/latest/platform/installation/status`
295
251
  );
296
252
  })
297
253
  .visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
@@ -318,41 +274,25 @@ Cypress.Commands.add(
318
274
 
319
275
  return cy
320
276
  .visitEmptyPage()
321
- .createDirectory(logDirectory)
277
+ .exec(`mkdir -p "${logDirectory}"`)
322
278
  .copyFromContainer({
323
279
  destination: `${logDirectory}/broker`,
324
- name,
325
280
  source: '/var/log/centreon-broker'
326
281
  })
327
282
  .copyFromContainer({
328
283
  destination: `${logDirectory}/engine`,
329
- name,
330
284
  source: '/var/log/centreon-engine'
331
285
  })
286
+ .execInContainer({
287
+ command: `bash -e <<EOF
288
+ chmod 777 /var/log/centreon/centreon-web.log > /dev/null 2>&1 || :
289
+ EOF`,
290
+ name
291
+ })
332
292
  .copyFromContainer({
333
293
  destination: `${logDirectory}/centreon`,
334
- name,
335
294
  source: '/var/log/centreon'
336
295
  })
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
- .exec(`chmod -R 755 "${logDirectory}"`)
356
296
  .stopContainer({ name });
357
297
  }
358
298
  );
@@ -364,8 +304,6 @@ interface StopContainerProps {
364
304
  Cypress.Commands.add(
365
305
  'stopContainer',
366
306
  ({ name }: StopContainerProps): Cypress.Chainable => {
367
- cy.log(`Stopping container ${name}`);
368
-
369
307
  cy.exec(`docker logs ${name}`).then(({ stdout }) => {
370
308
  cy.writeFile(
371
309
  `cypress/results/logs/${Cypress.spec.name.replace(
@@ -383,128 +321,21 @@ Cypress.Commands.add(
383
321
  }
384
322
  );
385
323
 
386
- interface Dashboard {
387
- description?: string;
388
- name: string;
389
- }
390
-
391
- Cypress.Commands.add(
392
- 'insertDashboardList',
393
- (fixtureFile: string): Cypress.Chainable => {
394
- return cy.fixture(fixtureFile).then((dashboardList) => {
395
- cy.wrap(
396
- Promise.all(
397
- dashboardList.map((dashboardBody: Dashboard) =>
398
- cy.insertDashboard({ ...dashboardBody })
399
- )
400
- )
401
- );
402
- });
403
- }
404
- );
405
-
406
- Cypress.Commands.add(
407
- 'insertDashboard',
408
- (dashboardBody: Dashboard): Cypress.Chainable => {
409
- return cy.request({
410
- body: {
411
- ...dashboardBody
412
- },
413
- method: 'POST',
414
- url: '/centreon/api/latest/configuration/dashboards'
415
- });
416
- }
417
- );
418
-
419
- interface ShareDashboardToUserProps {
420
- dashboardName: string;
421
- role: string;
422
- userName: string;
423
- }
424
-
425
- interface ListingRequestResult {
426
- body: {
427
- result: Array<{
428
- id: number;
429
- }>;
430
- };
431
- }
432
-
433
- Cypress.Commands.add(
434
- 'shareDashboardToUser',
435
- ({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
436
- Promise.all([
437
- cy.request({
438
- method: 'GET',
439
- url: `/centreon/api/latest/configuration/users?search={"name":"${userName}"}`
440
- }),
441
- cy.request({
442
- method: 'GET',
443
- url: `/centreon/api/latest/configuration/dashboards?search={"name":"${dashboardName}"}`
444
- })
445
- ]).then(
446
- ([retrievedUser, retrievedDashboard]: [
447
- ListingRequestResult,
448
- ListingRequestResult
449
- ]) => {
450
- const userId = retrievedUser.body.result[0].id;
451
- const dashboardId = retrievedDashboard.body.result[0].id;
452
-
453
- cy.request({
454
- body: {
455
- id: userId,
456
- role: `${role}`
457
- },
458
- method: 'POST',
459
- url: `/centreon/api/latest/configuration/dashboards/${dashboardId}/access_rights/contacts`
460
- });
461
- }
462
- );
463
- }
464
- );
465
-
466
- Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
467
- return cy
468
- .get('header div[data-cy="clock"]', { timeout: 10000 })
469
- .should('be.visible')
470
- .then(($time) => {
471
- const headerTime = $time.children()[1].textContent;
472
- if (headerTime?.match(/\d+:\d+/)) {
473
- cy.log(`header time is : ${headerTime}`);
474
-
475
- return cy.wrap(headerTime);
476
- }
477
-
478
- throw new Error(`header time is not displayed`);
479
- });
480
- });
481
-
482
324
  declare global {
483
325
  namespace Cypress {
484
326
  interface Chainable {
485
- clickSubRootMenuItem: (page: string) => Cypress.Chainable;
486
- copyFromContainer: (
487
- props: CopyFromContainerProps,
488
- options?: Partial<Cypress.ExecOptions>
489
- ) => Cypress.Chainable;
490
- copyToContainer: (
491
- props: CopyToContainerProps,
492
- options?: Partial<Cypress.ExecOptions>
493
- ) => Cypress.Chainable;
494
- createDirectory: (directoryPath: string) => Cypress.Chainable;
327
+ copyFromContainer: (props: CopyFromContainerProps) => Cypress.Chainable;
328
+ copyToContainer: (props: CopyToContainerProps) => Cypress.Chainable;
495
329
  execInContainer: ({
496
330
  command,
497
331
  name
498
332
  }: ExecInContainerProps) => Cypress.Chainable;
499
333
  getIframeBody: () => Cypress.Chainable;
500
- getTimeFromHeader: () => Cypress.Chainable;
501
334
  getWebVersion: () => Cypress.Chainable;
502
335
  hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
503
- insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
504
- insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
505
336
  loginByTypeOfUser: ({
506
- jsonName,
507
- loginViaApi
337
+ jsonName = 'admin',
338
+ loginViaApi = false
508
339
  }: LoginByTypeOfUserProps) => Cypress.Chainable;
509
340
  moveSortableElement: (direction: string) => Cypress.Chainable;
510
341
  navigateTo: ({
@@ -512,11 +343,6 @@ declare global {
512
343
  rootItemNumber,
513
344
  subMenu
514
345
  }: NavigateToProps) => Cypress.Chainable;
515
- shareDashboardToUser: ({
516
- dashboardName,
517
- userName,
518
- role
519
- }: ShareDashboardToUserProps) => Cypress.Chainable;
520
346
  startContainer: ({
521
347
  name,
522
348
  image
@@ -4,11 +4,8 @@
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
7
 
9
- import esbuildPreprocessor from './esbuild-preprocessor';
10
- import plugins from './plugins';
11
- import tasks from './tasks';
8
+ import setupNodeEvents from './plugins';
12
9
 
13
10
  interface ConfigurationOptions {
14
11
  cypressFolder?: string;
@@ -25,7 +22,9 @@ export default ({
25
22
  dockerName,
26
23
  env
27
24
  }: ConfigurationOptions): Cypress.ConfigOptions => {
28
- const resultsFolder = `${cypressFolder || '.'}/results`;
25
+ const resultsFolder = `${cypressFolder || 'cypress'}/results${
26
+ isDevelopment ? '/dev' : ''
27
+ }`;
29
28
 
30
29
  const webImageVersion = execSync('git rev-parse --abbrev-ref HEAD')
31
30
  .toString('utf8')
@@ -36,20 +35,8 @@ export default ({
36
35
  defaultCommandTimeout: 6000,
37
36
  e2e: {
38
37
  excludeSpecPattern: ['*.js', '*.ts', '*.md'],
39
- fixturesFolder: 'fixtures',
40
- reporter: require.resolve('cypress-multi-reporters'),
41
- reporterOptions: {
42
- configFile: `${__dirname}/reporter-config.js`
43
- },
44
- setupNodeEvents: async (on, config) => {
45
- installLogsPrinter(on);
46
- await esbuildPreprocessor(on, config);
47
- tasks(on);
48
-
49
- return plugins(on, config);
50
- },
51
- specPattern,
52
- supportFile: 'support/e2e.{js,jsx,ts,tsx}'
38
+ setupNodeEvents,
39
+ specPattern
53
40
  },
54
41
  env: {
55
42
  ...env,
@@ -58,12 +45,34 @@ export default ({
58
45
  WEB_IMAGE_VERSION: webImageVersion,
59
46
  dockerName: dockerName || 'centreon-dev'
60
47
  },
61
- 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
+ },
62
57
  requestTimeout: 10000,
63
58
  retries: 0,
64
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
+ },
65
75
  video: true,
66
- videoCompression: 0,
67
76
  videosFolder: `${resultsFolder}/videos`
68
77
  });
69
78
  };