@centreon/js-config 24.4.9 → 24.4.11
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 +23 -6
- package/cypress/component/configuration.js +14 -10
- 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 +205 -51
- package/cypress/e2e/configuration.ts +21 -30
- 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 +17 -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 +16 -55
|
@@ -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,31 @@ Cypress.Commands.add(
|
|
|
128
129
|
}
|
|
129
130
|
);
|
|
130
131
|
|
|
132
|
+
Cypress.Commands.add('adjustViewport', () => cy.viewport(1280, 590));
|
|
133
|
+
|
|
134
|
+
Cypress.Commands.add('makeSnapshot', (title?: string) => {
|
|
135
|
+
cy.adjustViewport();
|
|
136
|
+
cy.matchImageSnapshot(title);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
Cypress.Commands.add('cssDisableMotion', (): void => {
|
|
140
|
+
Cypress.on('window:before:load', (cyWindow) => {
|
|
141
|
+
disableMotion(cyWindow);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
131
145
|
declare global {
|
|
132
146
|
namespace Cypress {
|
|
133
147
|
interface Chainable {
|
|
148
|
+
adjustViewport: () => Cypress.Chainable;
|
|
149
|
+
cssDisableMotion: () => Cypress.Chainable;
|
|
134
150
|
interceptAPIRequest: <T extends object>(
|
|
135
151
|
props: InterceptAPIRequestProps<T>
|
|
136
152
|
) => Cypress.Chainable;
|
|
137
153
|
interceptRequest: (method, path, mock, alias) => Cypress.Chainable;
|
|
138
|
-
|
|
139
|
-
|
|
154
|
+
makeSnapshot: (title?: string) => void;
|
|
155
|
+
mount: ({ Component, options }: MountProps) => Cypress.Chainable;
|
|
156
|
+
moveSortableElement: ({ element, direction }) => void;
|
|
140
157
|
moveSortableElementUsingAriaLabel: ({ ariaLabel, direction }) => void;
|
|
141
158
|
waitForRequest: (alias) => Cypress.Chainable;
|
|
142
159
|
}
|
|
@@ -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;
|
|
@@ -47,6 +49,8 @@ module.exports = ({ webpackConfig, cypressFolder, specPattern, env }) => {
|
|
|
47
49
|
reportFilename: '[name]-report.json'
|
|
48
50
|
},
|
|
49
51
|
video: true,
|
|
50
|
-
videosFolder: `${mainCypressFolder}/results/videos
|
|
52
|
+
videosFolder: `${mainCypressFolder}/results/videos`,
|
|
53
|
+
viewportHeight: 590,
|
|
54
|
+
viewportWidth: 1280
|
|
51
55
|
});
|
|
52
56
|
};
|
|
@@ -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({ enableExtendedCollector: true });
|
|
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,29 +242,20 @@ interface StartContainerProps {
|
|
|
210
242
|
Cypress.Commands.add(
|
|
211
243
|
'startContainer',
|
|
212
244
|
({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
|
|
213
|
-
|
|
214
|
-
.exec('docker image list --format "{{.Repository}}:{{.Tag}}"')
|
|
215
|
-
.then(({ stdout }) => {
|
|
216
|
-
if (
|
|
217
|
-
stdout.match(
|
|
218
|
-
new RegExp(
|
|
219
|
-
`^${image.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')}`,
|
|
220
|
-
'm'
|
|
221
|
-
)
|
|
222
|
-
)
|
|
223
|
-
) {
|
|
224
|
-
cy.log(`Local docker image found : ${image}`);
|
|
225
|
-
|
|
226
|
-
return cy.wrap(image);
|
|
227
|
-
}
|
|
245
|
+
cy.log(`Starting container ${name} from image ${image}`);
|
|
228
246
|
|
|
229
|
-
|
|
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
|
+
);
|
|
230
254
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
);
|
|
255
|
+
Cypress.Commands.add(
|
|
256
|
+
'createDirectory',
|
|
257
|
+
(directoryPath: string): Cypress.Chainable => {
|
|
258
|
+
return cy.task('createDirectory', directoryPath);
|
|
236
259
|
}
|
|
237
260
|
);
|
|
238
261
|
|
|
@@ -247,7 +270,7 @@ Cypress.Commands.add(
|
|
|
247
270
|
'startWebContainer',
|
|
248
271
|
({
|
|
249
272
|
name = Cypress.env('dockerName'),
|
|
250
|
-
os = '
|
|
273
|
+
os = Cypress.env('WEB_IMAGE_OS'),
|
|
251
274
|
useSlim = true,
|
|
252
275
|
version = Cypress.env('WEB_IMAGE_VERSION')
|
|
253
276
|
}: StartWebContainerProps = {}): Cypress.Chainable => {
|
|
@@ -262,12 +285,13 @@ Cypress.Commands.add(
|
|
|
262
285
|
portBindings: [{ destination: 4000, source: 80 }]
|
|
263
286
|
})
|
|
264
287
|
.then(() => {
|
|
265
|
-
const baseUrl = 'http://
|
|
288
|
+
const baseUrl = 'http://127.0.0.1:4000';
|
|
266
289
|
|
|
267
290
|
Cypress.config('baseUrl', baseUrl);
|
|
268
291
|
|
|
269
|
-
return cy.
|
|
270
|
-
|
|
292
|
+
return cy.task(
|
|
293
|
+
'waitOn',
|
|
294
|
+
`${baseUrl}/centreon/api/latest/platform/installation/status`
|
|
271
295
|
);
|
|
272
296
|
})
|
|
273
297
|
.visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
|
|
@@ -284,7 +308,7 @@ Cypress.Commands.add(
|
|
|
284
308
|
({
|
|
285
309
|
name = Cypress.env('dockerName')
|
|
286
310
|
}: StopWebContainerProps = {}): Cypress.Chainable => {
|
|
287
|
-
const logDirectory = `
|
|
311
|
+
const logDirectory = `results/logs/${Cypress.spec.name.replace(
|
|
288
312
|
artifactIllegalCharactersMatcher,
|
|
289
313
|
'_'
|
|
290
314
|
)}/${Cypress.currentTest.title.replace(
|
|
@@ -294,25 +318,41 @@ Cypress.Commands.add(
|
|
|
294
318
|
|
|
295
319
|
return cy
|
|
296
320
|
.visitEmptyPage()
|
|
297
|
-
.
|
|
321
|
+
.createDirectory(logDirectory)
|
|
298
322
|
.copyFromContainer({
|
|
299
323
|
destination: `${logDirectory}/broker`,
|
|
324
|
+
name,
|
|
300
325
|
source: '/var/log/centreon-broker'
|
|
301
326
|
})
|
|
302
327
|
.copyFromContainer({
|
|
303
328
|
destination: `${logDirectory}/engine`,
|
|
329
|
+
name,
|
|
304
330
|
source: '/var/log/centreon-engine'
|
|
305
331
|
})
|
|
306
|
-
.execInContainer({
|
|
307
|
-
command: `bash -e <<EOF
|
|
308
|
-
chmod 777 /var/log/centreon/centreon-web.log > /dev/null 2>&1 || :
|
|
309
|
-
EOF`,
|
|
310
|
-
name
|
|
311
|
-
})
|
|
312
332
|
.copyFromContainer({
|
|
313
333
|
destination: `${logDirectory}/centreon`,
|
|
334
|
+
name,
|
|
314
335
|
source: '/var/log/centreon'
|
|
315
336
|
})
|
|
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}"`)
|
|
316
356
|
.stopContainer({ name });
|
|
317
357
|
}
|
|
318
358
|
);
|
|
@@ -324,6 +364,8 @@ interface StopContainerProps {
|
|
|
324
364
|
Cypress.Commands.add(
|
|
325
365
|
'stopContainer',
|
|
326
366
|
({ name }: StopContainerProps): Cypress.Chainable => {
|
|
367
|
+
cy.log(`Stopping container ${name}`);
|
|
368
|
+
|
|
327
369
|
cy.exec(`docker logs ${name}`).then(({ stdout }) => {
|
|
328
370
|
cy.writeFile(
|
|
329
371
|
`cypress/results/logs/${Cypress.spec.name.replace(
|
|
@@ -341,21 +383,128 @@ Cypress.Commands.add(
|
|
|
341
383
|
}
|
|
342
384
|
);
|
|
343
385
|
|
|
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
|
+
|
|
344
482
|
declare global {
|
|
345
483
|
namespace Cypress {
|
|
346
484
|
interface Chainable {
|
|
347
|
-
|
|
348
|
-
|
|
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;
|
|
349
495
|
execInContainer: ({
|
|
350
496
|
command,
|
|
351
497
|
name
|
|
352
498
|
}: ExecInContainerProps) => Cypress.Chainable;
|
|
353
499
|
getIframeBody: () => Cypress.Chainable;
|
|
500
|
+
getTimeFromHeader: () => Cypress.Chainable;
|
|
354
501
|
getWebVersion: () => Cypress.Chainable;
|
|
355
502
|
hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
|
|
503
|
+
insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
|
|
504
|
+
insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
|
|
356
505
|
loginByTypeOfUser: ({
|
|
357
|
-
jsonName
|
|
358
|
-
loginViaApi
|
|
506
|
+
jsonName,
|
|
507
|
+
loginViaApi
|
|
359
508
|
}: LoginByTypeOfUserProps) => Cypress.Chainable;
|
|
360
509
|
moveSortableElement: (direction: string) => Cypress.Chainable;
|
|
361
510
|
navigateTo: ({
|
|
@@ -363,6 +512,11 @@ declare global {
|
|
|
363
512
|
rootItemNumber,
|
|
364
513
|
subMenu
|
|
365
514
|
}: NavigateToProps) => Cypress.Chainable;
|
|
515
|
+
shareDashboardToUser: ({
|
|
516
|
+
dashboardName,
|
|
517
|
+
userName,
|
|
518
|
+
role
|
|
519
|
+
}: ShareDashboardToUserProps) => Cypress.Chainable;
|
|
366
520
|
startContainer: ({
|
|
367
521
|
name,
|
|
368
522
|
image
|