@centreon/js-config 23.10.47 → 23.10.48
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.
- package/cypress/component/commands.tsx +20 -6
- package/cypress/component/configuration.js +11 -9
- package/cypress/component/disableCssTransitions.ts +19 -0
- package/cypress/component/enableVisualTesting.ts +1 -1
- package/cypress/e2e/commands/monitoring.ts +75 -0
- package/cypress/e2e/commands.ts +202 -32
- package/cypress/e2e/configuration.ts +30 -32
- package/cypress/e2e/esbuild-preprocessor.ts +26 -0
- package/cypress/e2e/plugins.ts +21 -119
- package/cypress/e2e/reporter-config.js +13 -0
- package/cypress/e2e/tasks.ts +105 -0
- package/eslint/base.typescript.eslintrc.js +15 -3
- package/eslint/lambda/typescript.eslintrc.js +48 -0
- package/jest/index.js +5 -1
- package/jest/lambda/typescript.js +49 -0
- package/package.json +18 -5
- package/tsconfig/index.json +5 -4
- package/tsconfig/lambda/tsconfig.json +14 -0
- package/webpack/base/globalConfig.js +71 -0
- package/webpack/base/index.js +14 -57
|
@@ -4,13 +4,15 @@ 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
13
|
|
|
14
|
+
import disableMotion from './disableCssTransitions';
|
|
15
|
+
|
|
14
16
|
interface MountProps {
|
|
15
17
|
Component: React.ReactNode;
|
|
16
18
|
options?: object;
|
|
@@ -24,7 +26,7 @@ export enum Method {
|
|
|
24
26
|
PUT = 'PUT'
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
Cypress.Commands.add('mount', ({ Component, options }) => {
|
|
29
|
+
Cypress.Commands.add('mount', ({ Component, options = {} }) => {
|
|
28
30
|
const wrapped = (
|
|
29
31
|
<ThemeProvider>
|
|
30
32
|
<Box
|
|
@@ -36,11 +38,10 @@ Cypress.Commands.add('mount', ({ Component, options }) => {
|
|
|
36
38
|
>
|
|
37
39
|
{Component}
|
|
38
40
|
</Box>
|
|
41
|
+
<CssBaseline />
|
|
39
42
|
</ThemeProvider>
|
|
40
43
|
);
|
|
41
44
|
|
|
42
|
-
document.getElementsByTagName('body')[0].setAttribute('style', 'margin:0px');
|
|
43
|
-
|
|
44
45
|
return mount(wrapped, options);
|
|
45
46
|
});
|
|
46
47
|
|
|
@@ -128,15 +129,28 @@ Cypress.Commands.add(
|
|
|
128
129
|
}
|
|
129
130
|
);
|
|
130
131
|
|
|
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
|
+
|
|
131
143
|
declare global {
|
|
132
144
|
namespace Cypress {
|
|
133
145
|
interface Chainable {
|
|
146
|
+
cssDisableMotion: () => Cypress.Chainable;
|
|
134
147
|
interceptAPIRequest: <T extends object>(
|
|
135
148
|
props: InterceptAPIRequestProps<T>
|
|
136
149
|
) => Cypress.Chainable;
|
|
137
150
|
interceptRequest: (method, path, mock, alias) => Cypress.Chainable;
|
|
138
|
-
|
|
139
|
-
|
|
151
|
+
makeSnapshot: (title?: string) => void;
|
|
152
|
+
mount: ({ Component, options }: MountProps) => Cypress.Chainable;
|
|
153
|
+
moveSortableElement: ({ element, direction }) => void;
|
|
140
154
|
moveSortableElementUsingAriaLabel: ({ ariaLabel, direction }) => void;
|
|
141
155
|
waitForRequest: (alias) => Cypress.Chainable;
|
|
142
156
|
}
|
|
@@ -4,28 +4,30 @@ const {
|
|
|
4
4
|
addMatchImageSnapshotPlugin
|
|
5
5
|
} = require('@simonsmith/cypress-image-snapshot/plugin');
|
|
6
6
|
|
|
7
|
-
module.exports = ({
|
|
7
|
+
module.exports = ({
|
|
8
|
+
webpackConfig,
|
|
9
|
+
cypressFolder,
|
|
10
|
+
specPattern,
|
|
11
|
+
env,
|
|
12
|
+
useVite = false,
|
|
13
|
+
excludeSpecPattern
|
|
14
|
+
}) => {
|
|
8
15
|
const mainCypressFolder = cypressFolder || 'cypress';
|
|
9
16
|
|
|
10
17
|
return defineConfig({
|
|
11
18
|
component: {
|
|
12
19
|
devServer: {
|
|
13
|
-
bundler: 'webpack',
|
|
20
|
+
bundler: useVite ? 'vite' : 'webpack',
|
|
14
21
|
framework: 'react',
|
|
15
22
|
webpackConfig
|
|
16
23
|
},
|
|
24
|
+
excludeSpecPattern,
|
|
17
25
|
setupNodeEvents: (on, config) => {
|
|
18
26
|
addMatchImageSnapshotPlugin(on, config);
|
|
19
27
|
|
|
20
28
|
on('before:browser:launch', (browser, launchOptions) => {
|
|
21
29
|
if (browser.name === 'chrome' && browser.isHeadless) {
|
|
22
|
-
launchOptions.args
|
|
23
|
-
if (arg === '--headless') {
|
|
24
|
-
return '--headless=new';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return arg;
|
|
28
|
-
});
|
|
30
|
+
launchOptions.args.push('--headless=new');
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
return launchOptions;
|
|
@@ -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.
|
|
16
|
+
failureThreshold: 0.07,
|
|
17
17
|
failureThresholdType: 'percent'
|
|
18
18
|
});
|
|
19
19
|
};
|
|
@@ -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 {};
|
package/cypress/e2e/commands.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
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();
|
|
4
9
|
|
|
5
10
|
const apiLoginV2 = '/centreon/authentication/providers/configurations/local';
|
|
6
11
|
|
|
@@ -23,7 +28,7 @@ Cypress.Commands.add('getWebVersion', (): Cypress.Chainable => {
|
|
|
23
28
|
|
|
24
29
|
Cypress.Commands.add('getIframeBody', (): Cypress.Chainable => {
|
|
25
30
|
return cy
|
|
26
|
-
.get('iframe#main-content')
|
|
31
|
+
.get('iframe#main-content', { timeout: 10000 })
|
|
27
32
|
.its('0.contentDocument.body')
|
|
28
33
|
.should('not.be.empty')
|
|
29
34
|
.then(cy.wrap);
|
|
@@ -39,6 +44,13 @@ Cypress.Commands.add(
|
|
|
39
44
|
}
|
|
40
45
|
);
|
|
41
46
|
|
|
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
|
+
|
|
42
54
|
interface NavigateToProps {
|
|
43
55
|
page: string;
|
|
44
56
|
rootItemNumber: number;
|
|
@@ -51,8 +63,13 @@ Cypress.Commands.add(
|
|
|
51
63
|
if (subMenu) {
|
|
52
64
|
cy.hoverRootMenuItem(rootItemNumber)
|
|
53
65
|
.contains(subMenu)
|
|
54
|
-
.trigger('mouseover'
|
|
55
|
-
|
|
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);
|
|
56
73
|
|
|
57
74
|
return;
|
|
58
75
|
}
|
|
@@ -85,29 +102,41 @@ Cypress.Commands.add(
|
|
|
85
102
|
|
|
86
103
|
interface CopyFromContainerProps {
|
|
87
104
|
destination: string;
|
|
105
|
+
name?: string;
|
|
88
106
|
source: string;
|
|
89
107
|
}
|
|
90
108
|
|
|
91
109
|
Cypress.Commands.add(
|
|
92
110
|
'copyFromContainer',
|
|
93
|
-
(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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);
|
|
97
120
|
}
|
|
98
121
|
);
|
|
99
122
|
|
|
100
123
|
interface CopyToContainerProps {
|
|
101
124
|
destination: string;
|
|
125
|
+
name?: string;
|
|
102
126
|
source: string;
|
|
103
127
|
}
|
|
104
128
|
|
|
105
129
|
Cypress.Commands.add(
|
|
106
130
|
'copyToContainer',
|
|
107
|
-
(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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);
|
|
111
140
|
}
|
|
112
141
|
);
|
|
113
142
|
|
|
@@ -118,7 +147,7 @@ interface LoginByTypeOfUserProps {
|
|
|
118
147
|
|
|
119
148
|
Cypress.Commands.add(
|
|
120
149
|
'loginByTypeOfUser',
|
|
121
|
-
({ jsonName, loginViaApi }): Cypress.Chainable => {
|
|
150
|
+
({ jsonName = 'admin', loginViaApi = false }): Cypress.Chainable => {
|
|
122
151
|
if (loginViaApi) {
|
|
123
152
|
return cy
|
|
124
153
|
.fixture(`users/${jsonName}.json`)
|
|
@@ -135,12 +164,15 @@ Cypress.Commands.add(
|
|
|
135
164
|
.visit(`${Cypress.config().baseUrl}`)
|
|
136
165
|
.wait('@getNavigationList');
|
|
137
166
|
}
|
|
167
|
+
|
|
138
168
|
cy.visit(`${Cypress.config().baseUrl}`)
|
|
139
169
|
.fixture(`users/${jsonName}.json`)
|
|
140
170
|
.then((credential) => {
|
|
141
|
-
cy.getByLabel({ label: 'Alias', tag: 'input' }).type(
|
|
171
|
+
cy.getByLabel({ label: 'Alias', tag: 'input' }).type(
|
|
172
|
+
`{selectAll}{backspace}${credential.login}`
|
|
173
|
+
);
|
|
142
174
|
cy.getByLabel({ label: 'Password', tag: 'input' }).type(
|
|
143
|
-
credential.password
|
|
175
|
+
`{selectAll}{backspace}${credential.password}`
|
|
144
176
|
);
|
|
145
177
|
})
|
|
146
178
|
.getByLabel({ label: 'Connect', tag: 'button' })
|
|
@@ -210,9 +242,18 @@ interface StartContainerProps {
|
|
|
210
242
|
Cypress.Commands.add(
|
|
211
243
|
'startContainer',
|
|
212
244
|
({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
|
|
213
|
-
return cy
|
|
214
|
-
|
|
215
|
-
|
|
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);
|
|
216
257
|
}
|
|
217
258
|
);
|
|
218
259
|
|
|
@@ -227,7 +268,7 @@ Cypress.Commands.add(
|
|
|
227
268
|
'startWebContainer',
|
|
228
269
|
({
|
|
229
270
|
name = Cypress.env('dockerName'),
|
|
230
|
-
os = '
|
|
271
|
+
os = Cypress.env('WEB_IMAGE_OS'),
|
|
231
272
|
useSlim = true,
|
|
232
273
|
version = Cypress.env('WEB_IMAGE_VERSION')
|
|
233
274
|
}: StartWebContainerProps = {}): Cypress.Chainable => {
|
|
@@ -242,12 +283,13 @@ Cypress.Commands.add(
|
|
|
242
283
|
portBindings: [{ destination: 4000, source: 80 }]
|
|
243
284
|
})
|
|
244
285
|
.then(() => {
|
|
245
|
-
const baseUrl = 'http://
|
|
286
|
+
const baseUrl = 'http://127.0.0.1:4000';
|
|
246
287
|
|
|
247
288
|
Cypress.config('baseUrl', baseUrl);
|
|
248
289
|
|
|
249
|
-
return cy.
|
|
250
|
-
|
|
290
|
+
return cy.task(
|
|
291
|
+
'waitOn',
|
|
292
|
+
`${baseUrl}/centreon/api/latest/platform/installation/status`
|
|
251
293
|
);
|
|
252
294
|
})
|
|
253
295
|
.visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
|
|
@@ -274,25 +316,41 @@ Cypress.Commands.add(
|
|
|
274
316
|
|
|
275
317
|
return cy
|
|
276
318
|
.visitEmptyPage()
|
|
277
|
-
.
|
|
319
|
+
.createDirectory(logDirectory)
|
|
278
320
|
.copyFromContainer({
|
|
279
321
|
destination: `${logDirectory}/broker`,
|
|
322
|
+
name,
|
|
280
323
|
source: '/var/log/centreon-broker'
|
|
281
324
|
})
|
|
282
325
|
.copyFromContainer({
|
|
283
326
|
destination: `${logDirectory}/engine`,
|
|
327
|
+
name,
|
|
284
328
|
source: '/var/log/centreon-engine'
|
|
285
329
|
})
|
|
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
|
-
})
|
|
292
330
|
.copyFromContainer({
|
|
293
331
|
destination: `${logDirectory}/centreon`,
|
|
332
|
+
name,
|
|
294
333
|
source: '/var/log/centreon'
|
|
295
334
|
})
|
|
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}"`)
|
|
296
354
|
.stopContainer({ name });
|
|
297
355
|
}
|
|
298
356
|
);
|
|
@@ -321,21 +379,128 @@ Cypress.Commands.add(
|
|
|
321
379
|
}
|
|
322
380
|
);
|
|
323
381
|
|
|
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
|
+
|
|
324
478
|
declare global {
|
|
325
479
|
namespace Cypress {
|
|
326
480
|
interface Chainable {
|
|
327
|
-
|
|
328
|
-
|
|
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;
|
|
329
491
|
execInContainer: ({
|
|
330
492
|
command,
|
|
331
493
|
name
|
|
332
494
|
}: ExecInContainerProps) => Cypress.Chainable;
|
|
333
495
|
getIframeBody: () => Cypress.Chainable;
|
|
496
|
+
getTimeFromHeader: () => Cypress.Chainable;
|
|
334
497
|
getWebVersion: () => Cypress.Chainable;
|
|
335
498
|
hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
|
|
499
|
+
insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
|
|
500
|
+
insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
|
|
336
501
|
loginByTypeOfUser: ({
|
|
337
|
-
jsonName
|
|
338
|
-
loginViaApi
|
|
502
|
+
jsonName,
|
|
503
|
+
loginViaApi
|
|
339
504
|
}: LoginByTypeOfUserProps) => Cypress.Chainable;
|
|
340
505
|
moveSortableElement: (direction: string) => Cypress.Chainable;
|
|
341
506
|
navigateTo: ({
|
|
@@ -343,6 +508,11 @@ declare global {
|
|
|
343
508
|
rootItemNumber,
|
|
344
509
|
subMenu
|
|
345
510
|
}: NavigateToProps) => Cypress.Chainable;
|
|
511
|
+
shareDashboardToUser: ({
|
|
512
|
+
dashboardName,
|
|
513
|
+
userName,
|
|
514
|
+
role
|
|
515
|
+
}: ShareDashboardToUserProps) => Cypress.Chainable;
|
|
346
516
|
startContainer: ({
|
|
347
517
|
name,
|
|
348
518
|
image
|
|
@@ -4,13 +4,18 @@
|
|
|
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';
|
|
7
9
|
|
|
8
|
-
import
|
|
10
|
+
import esbuildPreprocessor from './esbuild-preprocessor';
|
|
11
|
+
import plugins from './plugins';
|
|
12
|
+
import tasks from './tasks';
|
|
9
13
|
|
|
10
14
|
interface ConfigurationOptions {
|
|
11
15
|
cypressFolder?: string;
|
|
12
16
|
dockerName?: string;
|
|
13
17
|
env?: Record<string, unknown>;
|
|
18
|
+
envFile?: string;
|
|
14
19
|
isDevelopment?: boolean;
|
|
15
20
|
specPattern: string;
|
|
16
21
|
}
|
|
@@ -20,11 +25,14 @@ export default ({
|
|
|
20
25
|
cypressFolder,
|
|
21
26
|
isDevelopment,
|
|
22
27
|
dockerName,
|
|
23
|
-
env
|
|
28
|
+
env,
|
|
29
|
+
envFile
|
|
24
30
|
}: ConfigurationOptions): Cypress.ConfigOptions => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
31
|
+
if (envFile) {
|
|
32
|
+
configDotenv({ path: envFile });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const resultsFolder = `${cypressFolder || '.'}/results`;
|
|
28
36
|
|
|
29
37
|
const webImageVersion = execSync('git rev-parse --abbrev-ref HEAD')
|
|
30
38
|
.toString('utf8')
|
|
@@ -35,44 +43,34 @@ export default ({
|
|
|
35
43
|
defaultCommandTimeout: 6000,
|
|
36
44
|
e2e: {
|
|
37
45
|
excludeSpecPattern: ['*.js', '*.ts', '*.md'],
|
|
38
|
-
|
|
39
|
-
|
|
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}'
|
|
40
60
|
},
|
|
41
61
|
env: {
|
|
42
62
|
...env,
|
|
43
|
-
OPENID_IMAGE_VERSION: '
|
|
63
|
+
OPENID_IMAGE_VERSION: process.env.MAJOR || '24.04',
|
|
44
64
|
WEB_IMAGE_OS: 'alma9',
|
|
45
65
|
WEB_IMAGE_VERSION: webImageVersion,
|
|
46
66
|
dockerName: dockerName || 'centreon-dev'
|
|
47
67
|
},
|
|
48
|
-
execTimeout:
|
|
49
|
-
reporter: 'mochawesome',
|
|
50
|
-
reporterOptions: {
|
|
51
|
-
html: false,
|
|
52
|
-
json: true,
|
|
53
|
-
overwrite: true,
|
|
54
|
-
reportDir: `${resultsFolder}/reports`,
|
|
55
|
-
reportFilename: '[name]-report.json'
|
|
56
|
-
},
|
|
68
|
+
execTimeout: 60000,
|
|
57
69
|
requestTimeout: 10000,
|
|
58
70
|
retries: 0,
|
|
59
71
|
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
|
-
},
|
|
75
72
|
video: true,
|
|
73
|
+
videoCompression: 0,
|
|
76
74
|
videosFolder: `${resultsFolder}/videos`
|
|
77
75
|
});
|
|
78
76
|
};
|