@centreon/js-config 23.10.45 → 23.10.47

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();
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,18 +210,9 @@ interface StartContainerProps {
242
210
  Cypress.Commands.add(
243
211
  'startContainer',
244
212
  ({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
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
- );
252
-
253
- Cypress.Commands.add(
254
- 'createDirectory',
255
- (directoryPath: string): Cypress.Chainable => {
256
- return cy.task('createDirectory', directoryPath);
213
+ return cy
214
+ .exec(`docker image inspect ${image} || docker pull ${image}`)
215
+ .task('startContainer', { image, name, portBindings });
257
216
  }
258
217
  );
259
218
 
@@ -268,7 +227,7 @@ Cypress.Commands.add(
268
227
  'startWebContainer',
269
228
  ({
270
229
  name = Cypress.env('dockerName'),
271
- os = Cypress.env('WEB_IMAGE_OS'),
230
+ os = 'alma9',
272
231
  useSlim = true,
273
232
  version = Cypress.env('WEB_IMAGE_VERSION')
274
233
  }: StartWebContainerProps = {}): Cypress.Chainable => {
@@ -283,13 +242,12 @@ Cypress.Commands.add(
283
242
  portBindings: [{ destination: 4000, source: 80 }]
284
243
  })
285
244
  .then(() => {
286
- const baseUrl = 'http://127.0.0.1:4000';
245
+ const baseUrl = 'http://0.0.0.0:4000';
287
246
 
288
247
  Cypress.config('baseUrl', baseUrl);
289
248
 
290
- return cy.task(
291
- 'waitOn',
292
- `${baseUrl}/centreon/api/latest/platform/installation/status`
249
+ return cy.exec(
250
+ `npx wait-on ${baseUrl}/centreon/api/latest/platform/installation/status`
293
251
  );
294
252
  })
295
253
  .visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
@@ -316,41 +274,25 @@ Cypress.Commands.add(
316
274
 
317
275
  return cy
318
276
  .visitEmptyPage()
319
- .createDirectory(logDirectory)
277
+ .exec(`mkdir -p "${logDirectory}"`)
320
278
  .copyFromContainer({
321
279
  destination: `${logDirectory}/broker`,
322
- name,
323
280
  source: '/var/log/centreon-broker'
324
281
  })
325
282
  .copyFromContainer({
326
283
  destination: `${logDirectory}/engine`,
327
- name,
328
284
  source: '/var/log/centreon-engine'
329
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
+ })
330
292
  .copyFromContainer({
331
293
  destination: `${logDirectory}/centreon`,
332
- name,
333
294
  source: '/var/log/centreon'
334
295
  })
335
- .then(() => {
336
- if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
337
- return cy.copyFromContainer({
338
- destination: `${logDirectory}/php`,
339
- name,
340
- source: '/var/log/php-fpm'
341
- });
342
- }
343
-
344
- return cy.copyFromContainer(
345
- {
346
- destination: `${logDirectory}/php8.1-fpm-centreon-error.log`,
347
- name,
348
- source: '/var/log/php8.1-fpm-centreon-error.log'
349
- },
350
- { failOnNonZeroExit: false }
351
- );
352
- })
353
- .exec(`chmod -R 755 "${logDirectory}"`)
354
296
  .stopContainer({ name });
355
297
  }
356
298
  );
@@ -379,128 +321,21 @@ Cypress.Commands.add(
379
321
  }
380
322
  );
381
323
 
382
- interface Dashboard {
383
- description?: string;
384
- name: string;
385
- }
386
-
387
- Cypress.Commands.add(
388
- 'insertDashboardList',
389
- (fixtureFile: string): Cypress.Chainable => {
390
- return cy.fixture(fixtureFile).then((dashboardList) => {
391
- cy.wrap(
392
- Promise.all(
393
- dashboardList.map((dashboardBody: Dashboard) =>
394
- cy.insertDashboard({ ...dashboardBody })
395
- )
396
- )
397
- );
398
- });
399
- }
400
- );
401
-
402
- Cypress.Commands.add(
403
- 'insertDashboard',
404
- (dashboardBody: Dashboard): Cypress.Chainable => {
405
- return cy.request({
406
- body: {
407
- ...dashboardBody
408
- },
409
- method: 'POST',
410
- url: '/centreon/api/latest/configuration/dashboards'
411
- });
412
- }
413
- );
414
-
415
- interface ShareDashboardToUserProps {
416
- dashboardName: string;
417
- role: string;
418
- userName: string;
419
- }
420
-
421
- interface ListingRequestResult {
422
- body: {
423
- result: Array<{
424
- id: number;
425
- }>;
426
- };
427
- }
428
-
429
- Cypress.Commands.add(
430
- 'shareDashboardToUser',
431
- ({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
432
- Promise.all([
433
- cy.request({
434
- method: 'GET',
435
- url: `/centreon/api/latest/configuration/users?search={"name":"${userName}"}`
436
- }),
437
- cy.request({
438
- method: 'GET',
439
- url: `/centreon/api/latest/configuration/dashboards?search={"name":"${dashboardName}"}`
440
- })
441
- ]).then(
442
- ([retrievedUser, retrievedDashboard]: [
443
- ListingRequestResult,
444
- ListingRequestResult
445
- ]) => {
446
- const userId = retrievedUser.body.result[0].id;
447
- const dashboardId = retrievedDashboard.body.result[0].id;
448
-
449
- cy.request({
450
- body: {
451
- id: userId,
452
- role: `${role}`
453
- },
454
- method: 'POST',
455
- url: `/centreon/api/latest/configuration/dashboards/${dashboardId}/access_rights/contacts`
456
- });
457
- }
458
- );
459
- }
460
- );
461
-
462
- Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
463
- return cy
464
- .get('header div[data-cy="clock"]', { timeout: 10000 })
465
- .should('be.visible')
466
- .then(($time) => {
467
- const headerTime = $time.children()[1].textContent;
468
- if (headerTime?.match(/\d+:\d+/)) {
469
- cy.log(`header time is : ${headerTime}`);
470
-
471
- return cy.wrap(headerTime);
472
- }
473
-
474
- throw new Error(`header time is not displayed`);
475
- });
476
- });
477
-
478
324
  declare global {
479
325
  namespace Cypress {
480
326
  interface Chainable {
481
- clickSubRootMenuItem: (page: string) => Cypress.Chainable;
482
- copyFromContainer: (
483
- props: CopyFromContainerProps,
484
- options?: Partial<Cypress.ExecOptions>
485
- ) => Cypress.Chainable;
486
- copyToContainer: (
487
- props: CopyToContainerProps,
488
- options?: Partial<Cypress.ExecOptions>
489
- ) => Cypress.Chainable;
490
- createDirectory: (directoryPath: string) => Cypress.Chainable;
327
+ copyFromContainer: (props: CopyFromContainerProps) => Cypress.Chainable;
328
+ copyToContainer: (props: CopyToContainerProps) => Cypress.Chainable;
491
329
  execInContainer: ({
492
330
  command,
493
331
  name
494
332
  }: ExecInContainerProps) => Cypress.Chainable;
495
333
  getIframeBody: () => Cypress.Chainable;
496
- getTimeFromHeader: () => Cypress.Chainable;
497
334
  getWebVersion: () => Cypress.Chainable;
498
335
  hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
499
- insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
500
- insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
501
336
  loginByTypeOfUser: ({
502
- jsonName,
503
- loginViaApi
337
+ jsonName = 'admin',
338
+ loginViaApi = false
504
339
  }: LoginByTypeOfUserProps) => Cypress.Chainable;
505
340
  moveSortableElement: (direction: string) => Cypress.Chainable;
506
341
  navigateTo: ({
@@ -508,11 +343,6 @@ declare global {
508
343
  rootItemNumber,
509
344
  subMenu
510
345
  }: NavigateToProps) => Cypress.Chainable;
511
- shareDashboardToUser: ({
512
- dashboardName,
513
- userName,
514
- role
515
- }: ShareDashboardToUserProps) => Cypress.Chainable;
516
346
  startContainer: ({
517
347
  name,
518
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
  };