@centreon/js-config 23.10.1-remove-cypress-fail-fast.0 → 23.10.1-update-oidc-tests.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.
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { mount } from 'cypress/react18';
5
5
  import { equals, isNil } from 'ramda';
6
6
 
7
- import { Box } from '@mui/material';
7
+ import { Box, CssBaseline } from '@mui/material';
8
8
 
9
9
  import { ThemeProvider } from '@centreon/ui';
10
10
 
@@ -24,7 +24,7 @@ export enum Method {
24
24
  PUT = 'PUT'
25
25
  }
26
26
 
27
- Cypress.Commands.add('mount', ({ Component, options }) => {
27
+ Cypress.Commands.add('mount', ({ Component, options = {} }) => {
28
28
  const wrapped = (
29
29
  <ThemeProvider>
30
30
  <Box
@@ -36,11 +36,10 @@ Cypress.Commands.add('mount', ({ Component, options }) => {
36
36
  >
37
37
  {Component}
38
38
  </Box>
39
+ <CssBaseline />
39
40
  </ThemeProvider>
40
41
  );
41
42
 
42
- document.getElementsByTagName('body')[0].setAttribute('style', 'margin:0px');
43
-
44
43
  return mount(wrapped, options);
45
44
  });
46
45
 
@@ -128,6 +127,11 @@ Cypress.Commands.add(
128
127
  }
129
128
  );
130
129
 
130
+ Cypress.Commands.add('makeSnapshot', (title?: string) => {
131
+ cy.viewport(1280, 590);
132
+ cy.matchImageSnapshot(title);
133
+ });
134
+
131
135
  declare global {
132
136
  namespace Cypress {
133
137
  interface Chainable {
@@ -135,8 +139,9 @@ declare global {
135
139
  props: InterceptAPIRequestProps<T>
136
140
  ) => Cypress.Chainable;
137
141
  interceptRequest: (method, path, mock, alias) => Cypress.Chainable;
138
- mount: ({ Component, options = {} }: MountProps) => Cypress.Chainable;
139
- moveSortableElement: ({ ariaLabel, direction }) => void;
142
+ makeSnapshot: (title?: string) => void;
143
+ mount: ({ Component, options }: MountProps) => Cypress.Chainable;
144
+ moveSortableElement: ({ element, direction }) => void;
140
145
  moveSortableElementUsingAriaLabel: ({ ariaLabel, direction }) => void;
141
146
  waitForRequest: (alias) => Cypress.Chainable;
142
147
  }
@@ -0,0 +1,75 @@
1
+ /* eslint-disable @typescript-eslint/no-namespace */
2
+
3
+ const apiBase = '/centreon/api';
4
+ const apiActionV1 = `${apiBase}/index.php`;
5
+
6
+ const getStatusNumberFromString = (status: string): number => {
7
+ const statuses = {
8
+ critical: '2',
9
+ down: '1',
10
+ ok: '0',
11
+ unknown: '3',
12
+ unreachable: '2',
13
+ up: '0',
14
+ warning: '1'
15
+ };
16
+
17
+ if (status in statuses) {
18
+ return statuses[status];
19
+ }
20
+
21
+ throw new Error(`Status ${status} does not exist`);
22
+ };
23
+
24
+ interface SubmitResult {
25
+ host: string;
26
+ output: string;
27
+ perfdata?: string | null;
28
+ service?: string | null;
29
+ status: string;
30
+ }
31
+
32
+ Cypress.Commands.add(
33
+ 'submitResults',
34
+ (results: Array<SubmitResult>): Cypress.Chainable => {
35
+ results.forEach(
36
+ ({ host, output, perfdata = '', service = null, status }) => {
37
+ const timestampNow = Math.floor(Date.now() / 1000) - 15;
38
+ const updatetime = timestampNow.toString();
39
+
40
+ const result = {
41
+ host,
42
+ output,
43
+ perfdata,
44
+ service,
45
+ status: getStatusNumberFromString(status),
46
+ updatetime
47
+ };
48
+
49
+ cy.request({
50
+ body: {
51
+ results: [result]
52
+ },
53
+ headers: {
54
+ 'Content-Type': 'application/json',
55
+ 'centreon-auth-token': window.localStorage.getItem('userTokenApiV1')
56
+ },
57
+ method: 'POST',
58
+ url: `${apiActionV1}?action=submit&object=centreon_submit_results`
59
+ });
60
+ }
61
+ );
62
+
63
+ return cy.wrap(null);
64
+ }
65
+ );
66
+
67
+ declare global {
68
+ namespace Cypress {
69
+ interface Chainable {
70
+ submitResults: (props: Array<SubmitResult>) => Cypress.Chainable;
71
+ }
72
+ }
73
+ }
74
+
75
+ export {};
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
2
 
3
3
  import './commands/configuration';
4
+ import './commands/monitoring';
4
5
 
5
6
  const apiLoginV2 = '/centreon/authentication/providers/configurations/local';
6
7
 
@@ -103,12 +104,15 @@ interface CopyFromContainerProps {
103
104
 
104
105
  Cypress.Commands.add(
105
106
  'copyFromContainer',
106
- ({
107
- name = Cypress.env('dockerName'),
108
- source,
109
- destination
110
- }: CopyFromContainerProps) => {
111
- return cy.exec(`docker cp ${name}:${source} "${destination}"`);
107
+ (
108
+ {
109
+ name = Cypress.env('dockerName'),
110
+ source,
111
+ destination
112
+ }: CopyFromContainerProps,
113
+ options?: Partial<Cypress.ExecOptions>
114
+ ) => {
115
+ return cy.exec(`docker cp ${name}:${source} "${destination}"`, options);
112
116
  }
113
117
  );
114
118
 
@@ -120,12 +124,15 @@ interface CopyToContainerProps {
120
124
 
121
125
  Cypress.Commands.add(
122
126
  'copyToContainer',
123
- ({
124
- name = Cypress.env('dockerName'),
125
- source,
126
- destination
127
- }: CopyToContainerProps) => {
128
- return cy.exec(`docker cp ${source} ${name}:${destination}`);
127
+ (
128
+ {
129
+ name = Cypress.env('dockerName'),
130
+ source,
131
+ destination
132
+ }: CopyToContainerProps,
133
+ options?: Partial<Cypress.ExecOptions>
134
+ ) => {
135
+ return cy.exec(`docker cp ${source} ${name}:${destination}`, options);
129
136
  }
130
137
  );
131
138
 
@@ -153,12 +160,15 @@ Cypress.Commands.add(
153
160
  .visit(`${Cypress.config().baseUrl}`)
154
161
  .wait('@getNavigationList');
155
162
  }
163
+
156
164
  cy.visit(`${Cypress.config().baseUrl}`)
157
165
  .fixture(`users/${jsonName}.json`)
158
166
  .then((credential) => {
159
- cy.getByLabel({ label: 'Alias', tag: 'input' }).type(credential.login);
167
+ cy.getByLabel({ label: 'Alias', tag: 'input' }).type(
168
+ `{selectAll}{backspace}${credential.login}`
169
+ );
160
170
  cy.getByLabel({ label: 'Password', tag: 'input' }).type(
161
- credential.password
171
+ `{selectAll}{backspace}${credential.password}`
162
172
  );
163
173
  })
164
174
  .getByLabel({ label: 'Connect', tag: 'button' })
@@ -216,10 +226,28 @@ Cypress.Commands.add(
216
226
  'startContainer',
217
227
  ({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
218
228
  return cy
219
- .exec(`docker image inspect ${image} || docker pull ${image}`, {
220
- timeout: 120000
229
+ .exec('docker image list --format "{{.Repository}}:{{.Tag}}"')
230
+ .then(({ stdout }) => {
231
+ if (
232
+ stdout.match(
233
+ new RegExp(
234
+ `^${image.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')}`,
235
+ 'm'
236
+ )
237
+ )
238
+ ) {
239
+ cy.log(`Local docker image found : ${image}`);
240
+
241
+ return cy.wrap(image);
242
+ }
243
+
244
+ cy.log(`Pulling remote docker image : ${image}`);
245
+
246
+ return cy.exec(`docker pull ${image}`).then(() => cy.wrap(image));
221
247
  })
222
- .task('startContainer', { image, name, portBindings });
248
+ .then((imageName) =>
249
+ cy.task('startContainer', { image: imageName, name, portBindings })
250
+ );
223
251
  }
224
252
  );
225
253
 
@@ -306,12 +334,16 @@ Cypress.Commands.add(
306
334
  });
307
335
  }
308
336
 
309
- return cy.copyFromContainer({
310
- destination: `${logDirectory}/php8.1-fpm-centreon-error.log`,
311
- name,
312
- source: '/var/log/php8.1-fpm-centreon-error.log'
313
- });
337
+ return cy.copyFromContainer(
338
+ {
339
+ destination: `${logDirectory}/php8.1-fpm-centreon-error.log`,
340
+ name,
341
+ source: '/var/log/php8.1-fpm-centreon-error.log'
342
+ },
343
+ { failOnNonZeroExit: false }
344
+ );
314
345
  })
346
+ .exec(`chmod -R 755 "${logDirectory}"`)
315
347
  .stopContainer({ name });
316
348
  }
317
349
  );
@@ -373,25 +405,81 @@ Cypress.Commands.add(
373
405
  }
374
406
  );
375
407
 
408
+ interface ShareDashboardToUserProps {
409
+ dashboardName: string;
410
+ role: string;
411
+ userName: string;
412
+ }
413
+
414
+ interface ListingRequestResult {
415
+ body: {
416
+ result: Array<{
417
+ id: number;
418
+ }>;
419
+ };
420
+ }
421
+
422
+ Cypress.Commands.add(
423
+ 'shareDashboardToUser',
424
+ ({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
425
+ Promise.all([
426
+ cy.request({
427
+ method: 'GET',
428
+ url: `/centreon/api/latest/configuration/users?search={"name":"${userName}"}`
429
+ }),
430
+ cy.request({
431
+ method: 'GET',
432
+ url: `/centreon/api/latest/configuration/dashboards?search={"name":"${dashboardName}"}`
433
+ })
434
+ ]).then(
435
+ ([retrievedUser, retrievedDashboard]: [
436
+ ListingRequestResult,
437
+ ListingRequestResult
438
+ ]) => {
439
+ const userId = retrievedUser.body.result[0].id;
440
+ const dashboardId = retrievedDashboard.body.result[0].id;
441
+
442
+ cy.request({
443
+ body: {
444
+ id: userId,
445
+ role: `${role}`
446
+ },
447
+ method: 'POST',
448
+ url: `/centreon/api/latest/configuration/dashboards/${dashboardId}/access_rights/contacts`
449
+ });
450
+ }
451
+ );
452
+ }
453
+ );
454
+
376
455
  Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
377
- return cy.waitUntil(() => {
378
- return cy.get('header div[data-cy="clock"]').then(($time) => {
456
+ return cy
457
+ .get('header div[data-cy="clock"]', { timeout: 10000 })
458
+ .should('be.visible')
459
+ .then(($time) => {
379
460
  const headerTime = $time.children()[1].textContent;
380
461
  if (headerTime?.match(/\d+:\d+/)) {
381
- return headerTime;
462
+ cy.log(`header time is : ${headerTime}`);
463
+
464
+ return cy.wrap(headerTime);
382
465
  }
383
466
 
384
- return false;
467
+ throw new Error(`header time is not displayed`);
385
468
  });
386
- });
387
469
  });
388
470
 
389
471
  declare global {
390
472
  namespace Cypress {
391
473
  interface Chainable {
392
474
  clickSubRootMenuItem: (page: string) => Cypress.Chainable;
393
- copyFromContainer: (props: CopyFromContainerProps) => Cypress.Chainable;
394
- copyToContainer: (props: CopyToContainerProps) => Cypress.Chainable;
475
+ copyFromContainer: (
476
+ props: CopyFromContainerProps,
477
+ options?: Partial<Cypress.ExecOptions>
478
+ ) => Cypress.Chainable;
479
+ copyToContainer: (
480
+ props: CopyToContainerProps,
481
+ options?: Partial<Cypress.ExecOptions>
482
+ ) => Cypress.Chainable;
395
483
  execInContainer: ({
396
484
  command,
397
485
  name
@@ -412,6 +500,11 @@ declare global {
412
500
  rootItemNumber,
413
501
  subMenu
414
502
  }: NavigateToProps) => Cypress.Chainable;
503
+ shareDashboardToUser: ({
504
+ dashboardName,
505
+ userName,
506
+ role
507
+ }: ShareDashboardToUserProps) => Cypress.Chainable;
415
508
  startContainer: ({
416
509
  name,
417
510
  image
@@ -22,9 +22,7 @@ export default ({
22
22
  dockerName,
23
23
  env
24
24
  }: ConfigurationOptions): Cypress.ConfigOptions => {
25
- const resultsFolder = `${cypressFolder || 'cypress'}/results${
26
- isDevelopment ? '/dev' : ''
27
- }`;
25
+ const resultsFolder = `${cypressFolder || 'cypress'}/results`;
28
26
 
29
27
  const webImageVersion = execSync('git rev-parse --abbrev-ref HEAD')
30
28
  .toString('utf8')
@@ -58,6 +56,7 @@ export default ({
58
56
  retries: 0,
59
57
  screenshotsFolder: `${resultsFolder}/screenshots`,
60
58
  video: true,
59
+ videoCompression: isDevelopment ? 0 : 16,
61
60
  videosFolder: `${resultsFolder}/videos`
62
61
  });
63
62
  };
@@ -50,11 +50,21 @@ export default async (on, config): Promise<void> => {
50
50
  on('file:preprocessor', webpackPreprocessor(options));
51
51
 
52
52
  on('before:browser:launch', (browser = {}, launchOptions) => {
53
+ const width = 1920;
54
+ const height = 1080;
55
+
53
56
  if ((browser as { name }).name === 'chrome') {
57
+ // flags description : https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md
54
58
  launchOptions.args.push('--disable-gpu');
55
- launchOptions.args = launchOptions.args.filter(
56
- (element) => element !== '--disable-dev-shm-usage'
57
- );
59
+ launchOptions.args.push('--auto-open-devtools-for-tabs');
60
+ launchOptions.args.push('--disable-extensions');
61
+ launchOptions.args.push('--hide-scrollbars');
62
+ launchOptions.args.push('--mute-audio');
63
+ launchOptions.args.push('--hide-scrollbars');
64
+
65
+ launchOptions.args.push(`--window-size=${width},${height}`);
66
+ // force screen to be non-retina and just use our given resolution
67
+ launchOptions.args.push('--force-device-scale-factor=1');
58
68
  }
59
69
 
60
70
  return launchOptions;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@centreon/js-config",
3
3
  "description": "Centreon Frontend shared build configuration",
4
- "version": "23.10.1-remove-cypress-fail-fast.0",
4
+ "version": "23.10.1-update-oidc-tests.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/centreon/centreon-frontend.git"
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "moduleResolution": "nodenext",
4
3
  "downlevelIteration": true,
5
- "module": "esnext",
4
+ "module": "ESNext",
6
5
  "target": "es2018",
7
6
  "jsx": "react-jsx",
8
7
  "strict": true,