@centreon/js-config 24.10.3 → 24.11.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.
Files changed (33) hide show
  1. package/biome/base.json +224 -0
  2. package/cypress/component/commands.tsx +82 -22
  3. package/cypress/component/configuration.js +39 -16
  4. package/cypress/component/disableCssTransitions.ts +19 -0
  5. package/cypress/component/enableVisualTesting.ts +1 -1
  6. package/cypress/component/excludeNodeModulesFromCoverage.js +36 -0
  7. package/cypress/e2e/commands/configuration.ts +330 -1
  8. package/cypress/e2e/commands/monitoring.ts +225 -0
  9. package/cypress/e2e/commands.ts +727 -174
  10. package/cypress/e2e/configuration.ts +46 -40
  11. package/cypress/e2e/esbuild-preprocessor.ts +26 -0
  12. package/cypress/e2e/plugins.ts +52 -114
  13. package/cypress/e2e/reporter-config.js +13 -0
  14. package/cypress/e2e/tasks.ts +259 -0
  15. package/eslint/base.typescript.eslintrc.js +15 -3
  16. package/eslint/lambda/typescript.eslintrc.js +48 -0
  17. package/jest/index.js +5 -2
  18. package/jest/lambda/typescript.js +49 -0
  19. package/package.json +57 -45
  20. package/rspack/base/globalConfig.js +71 -0
  21. package/rspack/base/index.js +89 -0
  22. package/rspack/patch/dev.js +12 -0
  23. package/{webpack → rspack}/patch/devServer.js +4 -8
  24. package/rspack/patch/module.js +13 -0
  25. package/rspack/plugins/TransformPreloadScript.js +37 -0
  26. package/rspack/plugins/WriteRemoteEntryNameToModuleFederation.js +30 -0
  27. package/tsconfig/index.json +5 -4
  28. package/tsconfig/lambda/node20.tsconfig.json +12 -0
  29. package/tsconfig/lambda/tsconfig.json +14 -0
  30. package/tsconfig.json +21 -0
  31. package/webpack/base/index.js +0 -130
  32. package/webpack/patch/dev.js +0 -24
  33. package/webpack/patch/module.js +0 -46
@@ -0,0 +1,224 @@
1
+ {
2
+ "formatter": {
3
+ "enabled": true,
4
+ "indentStyle": "space",
5
+ "formatWithErrors": false
6
+ },
7
+ "organizeImports": {
8
+ "enabled": true
9
+ },
10
+ "linter": {
11
+ "enabled": true,
12
+ "rules": {
13
+ "recommended": true,
14
+ "a11y": {
15
+ "noSvgWithoutTitle": "off"
16
+ },
17
+ "complexity": {
18
+ "noBannedTypes": "off",
19
+ "noForEach": "off"
20
+ },
21
+ "correctness": {
22
+ "noUnusedImports": "error",
23
+ "noUnusedVariables": "error",
24
+ "useExhaustiveDependencies": "off",
25
+ "noUnknownUnit": "error",
26
+ "noUnknownProperty": "error",
27
+ "noUnknownFunction": "error"
28
+ },
29
+ "nursery": {
30
+ "noRestrictedImports": {
31
+ "level": "error",
32
+ "options": {
33
+ "paths": {
34
+ "lodash": "Using lodash is not encouraged.",
35
+ "moment": "Using moment is not encouraged."
36
+ }
37
+ }
38
+ }
39
+ },
40
+ "suspicious": {
41
+ "noConsole": "error",
42
+ "useAwait": "error"
43
+ },
44
+ "performance": {
45
+ "noAccumulatingSpread": "off"
46
+ },
47
+ "style": {
48
+ "useLiteralEnumMembers": "off",
49
+ "useImportType": "off",
50
+ "noNamespace": "error",
51
+ "noNamespaceImport": "error",
52
+ "useFragmentSyntax": "error",
53
+ "useFilenamingConvention": {
54
+ "level": "error",
55
+ "options": {
56
+ "strictCase": false,
57
+ "filenameCases": [
58
+ "camelCase",
59
+ "PascalCase",
60
+ "kebab-case"
61
+ ]
62
+ }
63
+ },
64
+ "useNamingConvention": {
65
+ "level": "error",
66
+ "options": {
67
+ "strictCase": false,
68
+ "conventions": [
69
+ {
70
+ "formats": [
71
+ "camelCase",
72
+ "PascalCase"
73
+ ],
74
+ "selector": {
75
+ "kind": "variable"
76
+ }
77
+ },
78
+ {
79
+ "selector": {
80
+ "kind": "interface"
81
+ },
82
+ "formats": [
83
+ "PascalCase"
84
+ ]
85
+ },
86
+ {
87
+ "selector": {
88
+ "kind": "enum"
89
+ },
90
+ "formats": [
91
+ "PascalCase"
92
+ ]
93
+ },
94
+ {
95
+ "selector": {
96
+ "kind": "objectLiteralProperty"
97
+ },
98
+ "match": ".*"
99
+ },
100
+ {
101
+ "match": "_(.*)|([a-zA-Z].*)",
102
+ "selector": {
103
+ "kind": "functionParameter"
104
+ },
105
+ "formats": [
106
+ "snake_case",
107
+ "PascalCase",
108
+ "camelCase"
109
+ ]
110
+ },
111
+ {
112
+ "match": ".*",
113
+ "formats": [
114
+ "snake_case",
115
+ "camelCase",
116
+ "PascalCase",
117
+ "CONSTANT_CASE"
118
+ ]
119
+ }
120
+ ]
121
+ }
122
+ },
123
+ "noRestrictedGlobals": {
124
+ "level": "error",
125
+ "options": {
126
+ "deniedGlobals": [
127
+ "isFinite",
128
+ "isNaN",
129
+ "addEventListener",
130
+ "blur",
131
+ "close",
132
+ "closed",
133
+ "confirm",
134
+ "defaultStatus",
135
+ "defaultstatus",
136
+ "event",
137
+ "external",
138
+ "find",
139
+ "focus",
140
+ "frameElement",
141
+ "frames",
142
+ "history",
143
+ "innerHeight",
144
+ "innerWidth",
145
+ "length",
146
+ "location",
147
+ "locationbar",
148
+ "menubar",
149
+ "moveBy",
150
+ "moveTo",
151
+ "name",
152
+ "onblur",
153
+ "onerror",
154
+ "onfocus",
155
+ "onload",
156
+ "onresize",
157
+ "onunload",
158
+ "open",
159
+ "opener",
160
+ "opera",
161
+ "outerHeight",
162
+ "outerWidth",
163
+ "pageXOffset",
164
+ "pageYOffset",
165
+ "parent",
166
+ "print",
167
+ "removeEventListener",
168
+ "resizeBy",
169
+ "resizeTo",
170
+ "screen",
171
+ "screenLeft",
172
+ "screenTop",
173
+ "screenX",
174
+ "screenY",
175
+ "scroll",
176
+ "scrollbars",
177
+ "scrollBy",
178
+ "scrollTo",
179
+ "scrollX",
180
+ "scrollY",
181
+ "self",
182
+ "status",
183
+ "statusbar",
184
+ "stop",
185
+ "toolbar",
186
+ "top"
187
+ ]
188
+ }
189
+ }
190
+ }
191
+ }
192
+ },
193
+ "javascript": {
194
+ "formatter": {
195
+ "enabled": true,
196
+ "quoteStyle": "single",
197
+ "semicolons": "always",
198
+ "indentStyle": "space",
199
+ "trailingCommas": "none"
200
+ },
201
+ "linter": {
202
+ "enabled": true
203
+ }
204
+ },
205
+ "json": {
206
+ "parser": {
207
+ "allowComments": true,
208
+ "allowTrailingCommas": false
209
+ },
210
+ "formatter": {
211
+ "enabled": true,
212
+ "indentStyle": "space"
213
+ }
214
+ },
215
+ "css": {
216
+ "formatter": {
217
+ "enabled": true,
218
+ "indentStyle": "space"
219
+ },
220
+ "linter": {
221
+ "enabled": true
222
+ }
223
+ }
224
+ }
@@ -4,17 +4,29 @@ 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
 
11
11
  import '@testing-library/cypress/add-commands';
12
12
  import 'cypress-msw-interceptor';
13
+ import 'cypress-real-events';
14
+
15
+ import disableMotion from './disableCssTransitions';
13
16
 
14
17
  interface MountProps {
15
18
  Component: React.ReactNode;
16
19
  options?: object;
17
20
  }
21
+ interface Resolution {
22
+ height: number;
23
+ width: number;
24
+ }
25
+
26
+ interface MakeSnapshotWithCustomResolution {
27
+ resolution: Resolution;
28
+ title: string;
29
+ }
18
30
 
19
31
  export enum Method {
20
32
  DELETE = 'DELETE',
@@ -24,7 +36,7 @@ export enum Method {
24
36
  PUT = 'PUT'
25
37
  }
26
38
 
27
- Cypress.Commands.add('mount', ({ Component, options }) => {
39
+ Cypress.Commands.add('mount', ({ Component, options = {} }) => {
28
40
  const wrapped = (
29
41
  <ThemeProvider>
30
42
  <Box
@@ -36,11 +48,10 @@ Cypress.Commands.add('mount', ({ Component, options }) => {
36
48
  >
37
49
  {Component}
38
50
  </Box>
51
+ <CssBaseline />
39
52
  </ThemeProvider>
40
53
  );
41
54
 
42
- document.getElementsByTagName('body')[0].setAttribute('style', 'margin:0px');
43
-
44
55
  return mount(wrapped, options);
45
56
  });
46
57
 
@@ -51,6 +62,7 @@ interface Query {
51
62
 
52
63
  export interface InterceptAPIRequestProps<T> {
53
64
  alias: string;
65
+ delay?: number;
54
66
  method: Method;
55
67
  path: string;
56
68
  query?: Query;
@@ -66,23 +78,25 @@ Cypress.Commands.add(
66
78
  response,
67
79
  alias,
68
80
  query,
69
- statusCode = 200
81
+ statusCode = 200,
82
+ delay = 500
70
83
  }: InterceptAPIRequestProps<T>): void => {
71
84
  cy.interceptRequest(
72
85
  method,
73
86
  path.replace('./', '**'),
74
87
  (req, res, ctx) => {
75
88
  const getQuery = req?.url?.searchParams?.get(query?.name);
89
+
76
90
  if (query && equals(query.value, getQuery)) {
77
91
  return res(
78
- ctx.delay(500),
92
+ ctx.delay(delay),
79
93
  ctx.json(response),
80
94
  ctx.status(statusCode)
81
95
  );
82
96
  }
83
97
  if (!getQuery && isNil(query)) {
84
98
  return res(
85
- ctx.delay(500),
99
+ ctx.delay(delay),
86
100
  ctx.json(response),
87
101
  ctx.status(statusCode)
88
102
  );
@@ -95,20 +109,32 @@ Cypress.Commands.add(
95
109
  }
96
110
  );
97
111
 
98
- Cypress.Commands.add('moveSortableElement', ({ element, direction }): void => {
99
- const key = `{${direction}arrow}`;
112
+ interface MoveSortableElementProps {
113
+ direction: 'up' | 'down' | 'left' | 'right';
114
+ element: Cypress.Chainable<JQuery<HTMLElement>>;
115
+ times?: number;
116
+ }
100
117
 
101
- element.type(' ', {
102
- force: true,
103
- scrollBehavior: false
104
- });
105
- element.eq(-1).type(key, {
106
- scrollBehavior: false
107
- });
108
- element.eq(-1).type(' ', {
109
- scrollBehavior: false
110
- });
111
- });
118
+ Cypress.Commands.add(
119
+ 'moveSortableElement',
120
+ ({ element, direction, times = 1 }: MoveSortableElementProps): void => {
121
+ const key = `{${direction}arrow}`;
122
+
123
+ element.type(' ', {
124
+ force: true,
125
+ scrollBehavior: false
126
+ });
127
+
128
+ Array.from({ length: times }).forEach(() => {
129
+ element.eq(-1).type(key, {
130
+ scrollBehavior: false
131
+ });
132
+ });
133
+ element.eq(-1).type(' ', {
134
+ scrollBehavior: false
135
+ });
136
+ }
137
+ );
112
138
 
113
139
  Cypress.Commands.add(
114
140
  'moveSortableElementUsingAriaLabel',
@@ -128,15 +154,49 @@ Cypress.Commands.add(
128
154
  }
129
155
  );
130
156
 
157
+ Cypress.Commands.add('adjustViewport', () => cy.viewport(1280, 590));
158
+
159
+ Cypress.Commands.add('makeSnapshot', (title?: string) => {
160
+ cy.adjustViewport();
161
+ cy.matchImageSnapshot(title);
162
+ });
163
+
164
+ Cypress.Commands.add(
165
+ 'makeSnapshotWithCustomResolution',
166
+ ({ title, resolution }: MakeSnapshotWithCustomResolution) => {
167
+ const { width, height } = resolution;
168
+ cy.viewport(width, height);
169
+ cy.matchImageSnapshot(title);
170
+ }
171
+ );
172
+
173
+ Cypress.Commands.add('cssDisableMotion', (): void => {
174
+ Cypress.on('window:before:load', (cyWindow) => {
175
+ disableMotion(cyWindow);
176
+ });
177
+ });
178
+
131
179
  declare global {
132
180
  namespace Cypress {
133
181
  interface Chainable {
182
+ adjustViewport: () => Cypress.Chainable;
183
+ cssDisableMotion: () => Cypress.Chainable;
184
+ getRequestCalls: (alias) => Cypress.Chainable;
134
185
  interceptAPIRequest: <T extends object>(
135
186
  props: InterceptAPIRequestProps<T>
136
187
  ) => Cypress.Chainable;
137
188
  interceptRequest: (method, path, mock, alias) => Cypress.Chainable;
138
- mount: ({ Component, options = {} }: MountProps) => Cypress.Chainable;
139
- moveSortableElement: ({ ariaLabel, direction }) => void;
189
+ makeSnapshot: (title?: string) => void;
190
+ makeSnapshotWithCustomResolution: ({
191
+ title,
192
+ resolution
193
+ }: MakeSnapshotWithCustomResolution) => Cypress.Chainable;
194
+ mount: ({ Component, options }: MountProps) => Cypress.Chainable;
195
+ moveSortableElement: ({
196
+ element,
197
+ direction,
198
+ times
199
+ }: MoveSortableElementProps) => void;
140
200
  moveSortableElementUsingAriaLabel: ({ ariaLabel, direction }) => void;
141
201
  waitForRequest: (alias) => Cypress.Chainable;
142
202
  }
@@ -1,32 +1,44 @@
1
1
  /* eslint-disable @typescript-eslint/no-var-requires */
2
+ const { devServer } = require('cypress-rspack-dev-server');
2
3
  const { defineConfig } = require('cypress');
3
4
  const {
4
5
  addMatchImageSnapshotPlugin
5
6
  } = require('@simonsmith/cypress-image-snapshot/plugin');
7
+ const cypressCodeCoverageTask = require('@cypress/code-coverage/task');
6
8
 
7
- module.exports = ({ webpackConfig, cypressFolder, specPattern, env }) => {
9
+ module.exports = ({
10
+ rspackConfig,
11
+ cypressFolder,
12
+ specPattern,
13
+ env,
14
+ excludeSpecPattern
15
+ }) => {
8
16
  const mainCypressFolder = cypressFolder || 'cypress';
9
17
 
10
18
  return defineConfig({
11
19
  component: {
12
- devServer: {
13
- bundler: 'webpack',
14
- framework: 'react',
15
- webpackConfig
16
- },
20
+ devServer: (devServerConfig) =>
21
+ devServer({
22
+ ...devServerConfig,
23
+ framework: 'react',
24
+ rspackConfig
25
+ }),
26
+ excludeSpecPattern,
17
27
  setupNodeEvents: (on, config) => {
18
28
  addMatchImageSnapshotPlugin(on, config);
19
29
 
30
+ cypressCodeCoverageTask(on, config);
31
+ on('task', {
32
+ coverageReport: () => {
33
+ return null;
34
+ }
35
+ });
36
+
20
37
  on('before:browser:launch', (browser, launchOptions) => {
21
38
  if (browser.name === 'chrome' && browser.isHeadless) {
39
+ launchOptions.args.push('--headless=new');
40
+ launchOptions.args.push('--force-color-profile=srgb');
22
41
  launchOptions.args.push('--window-size=1400,1200');
23
- launchOptions.args = launchOptions.args.map((arg) => {
24
- if (arg === '--headless') {
25
- return '--headless=new';
26
- }
27
-
28
- return arg;
29
- });
30
42
  }
31
43
 
32
44
  return launchOptions;
@@ -36,8 +48,17 @@ module.exports = ({ webpackConfig, cypressFolder, specPattern, env }) => {
36
48
  supportFile: `${mainCypressFolder}/support/component.tsx`
37
49
  },
38
50
  env: {
39
- ...env,
40
- baseUrl: 'http://localhost:9092'
51
+ baseUrl: 'http://localhost:9092',
52
+ codeCoverage: {
53
+ exclude: [
54
+ 'cypress/**/*.*',
55
+ 'packages/**',
56
+ 'node_modules',
57
+ '**/*.js',
58
+ '**/*.spec.tsx'
59
+ ]
60
+ },
61
+ ...env
41
62
  },
42
63
  reporter: 'mochawesome',
43
64
  reporterOptions: {
@@ -48,6 +69,8 @@ module.exports = ({ webpackConfig, cypressFolder, specPattern, env }) => {
48
69
  reportFilename: '[name]-report.json'
49
70
  },
50
71
  video: true,
51
- videosFolder: `${mainCypressFolder}/results/videos`
72
+ videosFolder: `${mainCypressFolder}/results/videos`,
73
+ viewportHeight: 590,
74
+ viewportWidth: 1280
52
75
  });
53
76
  };
@@ -0,0 +1,19 @@
1
+ const disableMotion = (win): void => {
2
+ const injectedStyleEl = win.document.getElementById('__cy_disable_motion__');
3
+ if (injectedStyleEl) {
4
+ return;
5
+ }
6
+ win.document.head.insertAdjacentHTML(
7
+ 'beforeend',
8
+ `
9
+ <style id="__cy_disable_motion__">
10
+ /* Disable CSS transitions. */
11
+ *, *::before, *::after { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; -ms-transition: none !important; transition: none !important; }
12
+ /* Disable CSS animations. */
13
+ *, *::before, *::after { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; -ms-animation: none !important; animation: none !important; }
14
+ </style>
15
+ `.trim()
16
+ );
17
+ };
18
+
19
+ export default disableMotion;
@@ -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.06,
16
+ failureThreshold: Cypress.env('updateSnapshots') === true ? 0 : 0.07,
17
17
  failureThresholdType: 'percent'
18
18
  });
19
19
  };
@@ -0,0 +1,36 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const filePath = process.argv[2];
5
+
6
+ const { error: logError } = console;
7
+
8
+ try {
9
+ const outFile = fs.readFileSync(path.resolve(filePath)).toString();
10
+ const outFileJson = JSON.parse(outFile);
11
+
12
+ const coveragesWithoutNodeModules = Object.entries(outFileJson)
13
+ .map(([key, value]) => {
14
+ if (key.includes('node_modules')) {
15
+ return undefined;
16
+ }
17
+
18
+ return [key, value];
19
+ })
20
+ .filter((v) => v);
21
+
22
+ const finalOutJson = coveragesWithoutNodeModules.reduce(
23
+ (acc, [key, value]) => ({
24
+ ...acc,
25
+ [key]: value
26
+ }),
27
+ {}
28
+ );
29
+
30
+ fs.writeFileSync(
31
+ path.resolve(filePath),
32
+ JSON.stringify(finalOutJson, null, 2)
33
+ );
34
+ } catch (error) {
35
+ logError(error.message);
36
+ }