@centreon/js-config 23.10.65 → 24.4.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.
@@ -1,4 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
+ import path from 'path';
3
+ import 'cypress-wait-until';
2
4
 
3
5
  import './commands/configuration';
4
6
  import './commands/monitoring';
@@ -7,10 +9,53 @@ import installLogsCollector from 'cypress-terminal-report/src/installLogsCollect
7
9
 
8
10
  installLogsCollector({ enableExtendedCollector: true });
9
11
 
12
+ const apiBase = '/centreon/api';
13
+ const apiActionV1 = `${apiBase}/index.php`;
10
14
  const apiLoginV2 = '/centreon/authentication/providers/configurations/local';
11
15
 
12
16
  const artifactIllegalCharactersMatcher = /[,\s/|<>*?:"]/g;
13
17
 
18
+ export enum PatternType {
19
+ contains = '*',
20
+ endsWith = '$',
21
+ equals = '',
22
+ startsWith = '^'
23
+ }
24
+
25
+ interface GetByLabelProps {
26
+ label: string;
27
+ patternType?: PatternType;
28
+ tag?: string;
29
+ }
30
+
31
+ Cypress.Commands.add(
32
+ 'getByLabel',
33
+ ({
34
+ tag = '',
35
+ patternType = PatternType.equals,
36
+ label
37
+ }: GetByLabelProps): Cypress.Chainable => {
38
+ return cy.get(`${tag}[aria-label${patternType}="${label}"]`);
39
+ }
40
+ );
41
+
42
+ interface GetByTestIdProps {
43
+ patternType?: PatternType;
44
+ tag?: string;
45
+ testId: string;
46
+ }
47
+
48
+ Cypress.Commands.add(
49
+ 'getByTestId',
50
+ ({
51
+ tag = '',
52
+ patternType = PatternType.equals,
53
+ testId
54
+ }: GetByTestIdProps): Cypress.Chainable => {
55
+ return cy.get(`${tag}[data-testid${patternType}="${testId}"]`);
56
+ }
57
+ );
58
+
14
59
  Cypress.Commands.add('getWebVersion', (): Cypress.Chainable => {
15
60
  return cy
16
61
  .exec(
@@ -34,6 +79,34 @@ Cypress.Commands.add('getIframeBody', (): Cypress.Chainable => {
34
79
  .then(cy.wrap);
35
80
  });
36
81
 
82
+ Cypress.Commands.add(
83
+ 'waitForElementInIframe',
84
+ (iframeSelector, elementSelector) => {
85
+ cy.waitUntil(
86
+ () =>
87
+ cy.get(iframeSelector).then(($iframe) => {
88
+ const iframeBody = $iframe[0].contentDocument.body;
89
+ if (iframeBody) {
90
+ const $element = Cypress.$(iframeBody).find(elementSelector);
91
+
92
+ return $element.length > 0 && $element.is(':visible');
93
+ }
94
+
95
+ return false;
96
+ }),
97
+ {
98
+ errorMsg: 'The element is not visible within the iframe',
99
+ interval: 5000,
100
+ timeout: 100000
101
+ }
102
+ ).then((isVisible) => {
103
+ if (!isVisible) {
104
+ throw new Error('The element is not visible');
105
+ }
106
+ });
107
+ }
108
+ );
109
+
37
110
  Cypress.Commands.add(
38
111
  'hoverRootMenuItem',
39
112
  (rootItemNumber: number): Cypress.Chainable => {
@@ -59,7 +132,7 @@ interface NavigateToProps {
59
132
 
60
133
  Cypress.Commands.add(
61
134
  'navigateTo',
62
- ({ rootItemNumber, subMenu, page }): void => {
135
+ ({ rootItemNumber, subMenu, page }: NavigateToProps): void => {
63
136
  if (subMenu) {
64
137
  cy.hoverRootMenuItem(rootItemNumber)
65
138
  .contains(subMenu)
@@ -100,6 +173,24 @@ Cypress.Commands.add(
100
173
  }
101
174
  );
102
175
 
176
+ Cypress.Commands.add('getContainerId', (containerName: string) => {
177
+ cy.log(`Getting container id of ${containerName}`);
178
+
179
+ return cy.task('getContainerId', containerName);
180
+ });
181
+
182
+ Cypress.Commands.add('getContainerIpAddress', (containerName: string) => {
183
+ cy.log(`Getting container ip address of ${containerName}`);
184
+
185
+ return cy.task('getContainerIpAddress', containerName);
186
+ });
187
+
188
+ Cypress.Commands.add('getContainersLogs', () => {
189
+ cy.log('Getting containers logs');
190
+
191
+ return cy.task('getContainersLogs');
192
+ });
193
+
103
194
  interface CopyFromContainerProps {
104
195
  destination: string;
105
196
  name?: string;
@@ -108,38 +199,54 @@ interface CopyFromContainerProps {
108
199
 
109
200
  Cypress.Commands.add(
110
201
  '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);
202
+ ({ name = 'web', source, destination }: CopyFromContainerProps) => {
203
+ cy.log(`Copy content from ${name}:${source} to ${destination}`);
204
+
205
+ return cy.task('copyFromContainer', {
206
+ destination,
207
+ serviceName: name,
208
+ source
209
+ });
120
210
  }
121
211
  );
122
212
 
213
+ export enum CopyToContainerContentType {
214
+ Directory = 'directory',
215
+ File = 'file'
216
+ }
217
+
123
218
  interface CopyToContainerProps {
124
219
  destination: string;
125
220
  name?: string;
126
221
  source: string;
222
+ type: CopyToContainerContentType;
127
223
  }
128
224
 
129
225
  Cypress.Commands.add(
130
226
  'copyToContainer',
131
- (
132
- {
133
- name = Cypress.env('dockerName'),
227
+ ({ name = 'web', source, destination, type }: CopyToContainerProps) => {
228
+ cy.log(`Copy content from ${source} to ${name}:${destination}`);
229
+
230
+ return cy.task('copyToContainer', {
231
+ destination,
232
+ serviceName: name,
134
233
  source,
135
- destination
136
- }: CopyToContainerProps,
137
- options?: Partial<Cypress.ExecOptions>
138
- ) => {
139
- return cy.exec(`docker cp ${source} ${name}:${destination}`, options);
234
+ type
235
+ });
140
236
  }
141
237
  );
142
238
 
239
+ Cypress.Commands.add('loginAsAdminViaApiV2', (): Cypress.Chainable => {
240
+ return cy.request({
241
+ body: {
242
+ login: 'admin',
243
+ password: 'Centreon!2021'
244
+ },
245
+ method: 'POST',
246
+ url: apiLoginV2
247
+ });
248
+ });
249
+
143
250
  interface LoginByTypeOfUserProps {
144
251
  jsonName?: string;
145
252
  loginViaApi?: boolean;
@@ -178,16 +285,42 @@ Cypress.Commands.add(
178
285
  .getByLabel({ label: 'Connect', tag: 'button' })
179
286
  .click();
180
287
 
181
- return cy
182
- .get('.SnackbarContent-root > .MuiPaper-root')
183
- .then(($snackbar) => {
184
- if ($snackbar.text().includes('Login succeeded')) {
185
- cy.wait('@getNavigationList');
186
- }
187
- });
288
+ return cy.get('.MuiAlert-message').then(($snackbar) => {
289
+ if ($snackbar.text().includes('Login succeeded')) {
290
+ cy.wait('@getNavigationList');
291
+ cy.get('.MuiAlert-message').should('not.be.visible');
292
+ }
293
+ });
188
294
  }
189
295
  );
190
296
 
297
+ Cypress.Commands.add('logout', (): void => {
298
+ cy.getByLabel({ label: 'Profile' }).should('exist').click();
299
+
300
+ cy.intercept({
301
+ method: 'GET',
302
+ times: 1,
303
+ url: '/centreon/api/latest/authentication/logout'
304
+ }).as('logout');
305
+
306
+ cy.contains(/^Logout$/).click();
307
+
308
+ cy.wait('@logout').its('response.statusCode').should('eq', 302);
309
+
310
+ // https://github.com/cypress-io/cypress/issues/25841
311
+ cy.clearAllCookies();
312
+ });
313
+
314
+ Cypress.Commands.add('logoutViaAPI', (): Cypress.Chainable => {
315
+ return cy
316
+ .request({
317
+ method: 'GET',
318
+ url: '/centreon/authentication/logout'
319
+ })
320
+ .visit('/')
321
+ .getByLabel({ label: 'Alias', tag: 'input' });
322
+ });
323
+
191
324
  Cypress.Commands.add(
192
325
  'visitEmptyPage',
193
326
  (): Cypress.Chainable =>
@@ -199,32 +332,91 @@ Cypress.Commands.add(
199
332
  .visit('/waiting-page')
200
333
  );
201
334
 
202
- Cypress.Commands.add('waitForContainerAndSetToken', (): Cypress.Chainable => {
203
- return cy.setUserTokenApiV1();
204
- });
205
-
206
335
  interface ExecInContainerProps {
207
- command: string;
336
+ command: string | Array<string>;
208
337
  name: string;
209
338
  }
210
339
 
340
+ interface ExecInContainerResult {
341
+ exitCode: number;
342
+ output: string;
343
+ }
344
+
211
345
  Cypress.Commands.add(
212
346
  'execInContainer',
213
347
  ({ command, name }: ExecInContainerProps): Cypress.Chainable => {
214
- return cy
215
- .exec(`docker exec -i ${name} ${command}`, { failOnNonZeroExit: false })
216
- .then((result) => {
217
- if (result.code) {
218
- // output will not be truncated
219
- throw new Error(`
220
- Execution of "${command}" failed
221
- Exit code: ${result.code}
222
- Stdout:\n${result.stdout}
223
- Stderr:\n${result.stderr}`);
224
- }
348
+ const commands =
349
+ typeof command === 'string' || command instanceof String
350
+ ? [command]
351
+ : command;
352
+
353
+ const results = commands.reduce(
354
+ (acc, runCommand) => {
355
+ cy.task<ExecInContainerResult>(
356
+ 'execInContainer',
357
+ { command: runCommand, name },
358
+ { timeout: 600000 }
359
+ ).then((result) => {
360
+ if (result.exitCode) {
361
+ cy.log(result.output);
362
+
363
+ // output will not be truncated
364
+ throw new Error(`
365
+ Execution of "${runCommand}" failed
366
+ Exit code: ${result.exitCode}
367
+ Output:\n${result.output}`);
368
+ }
369
+
370
+ acc.output = `${acc.output}${result.output}`;
371
+ });
225
372
 
226
- return cy.wrap(result);
227
- });
373
+ return acc;
374
+ },
375
+ { exitCode: 0, output: '' }
376
+ );
377
+
378
+ return cy.wrap(results);
379
+ }
380
+ );
381
+
382
+ interface RequestOnDatabaseProps {
383
+ database: string;
384
+ query: string;
385
+ }
386
+
387
+ Cypress.Commands.add(
388
+ 'requestOnDatabase',
389
+ ({ database, query }: RequestOnDatabaseProps): Cypress.Chainable => {
390
+ return cy.task('requestOnDatabase', { database, query });
391
+ }
392
+ );
393
+
394
+ interface SetUserTokenApiV1Props {
395
+ login?: string;
396
+ password?: string;
397
+ }
398
+
399
+ Cypress.Commands.add(
400
+ 'setUserTokenApiV1',
401
+ ({
402
+ login = 'admin',
403
+ password = 'Centreon!2021'
404
+ }: SetUserTokenApiV1Props = {}): Cypress.Chainable => {
405
+ return cy
406
+ .request({
407
+ body: {
408
+ password,
409
+ username: login
410
+ },
411
+ headers: {
412
+ 'Content-Type': 'application/x-www-form-urlencoded'
413
+ },
414
+ method: 'POST',
415
+ url: `${apiActionV1}?action=authenticate`
416
+ })
417
+ .then(({ body }) =>
418
+ window.localStorage.setItem('userTokenApiV1', body.authToken)
419
+ );
228
420
  }
229
421
  );
230
422
 
@@ -234,6 +426,7 @@ interface PortBinding {
234
426
  }
235
427
 
236
428
  interface StartContainerProps {
429
+ command?: string;
237
430
  image: string;
238
431
  name: string;
239
432
  portBindings: Array<PortBinding>;
@@ -241,145 +434,212 @@ interface StartContainerProps {
241
434
 
242
435
  Cypress.Commands.add(
243
436
  'startContainer',
244
- ({ name, image, portBindings }: StartContainerProps): Cypress.Chainable => {
437
+ ({
438
+ command,
439
+ name,
440
+ image,
441
+ portBindings
442
+ }: StartContainerProps): Cypress.Chainable => {
245
443
  cy.log(`Starting container ${name} from image ${image}`);
246
444
 
247
445
  return cy.task(
248
446
  'startContainer',
249
- { image, name, portBindings },
447
+ { command, image, name, portBindings },
250
448
  { timeout: 600000 } // 10 minutes because docker pull can be very slow
251
449
  );
252
450
  }
253
451
  );
254
452
 
255
- Cypress.Commands.add(
256
- 'createDirectory',
257
- (directoryPath: string): Cypress.Chainable => {
258
- return cy.task('createDirectory', directoryPath);
259
- }
260
- );
261
-
262
- interface StartWebContainerProps {
263
- name?: string;
264
- os?: string;
453
+ interface StartContainersProps {
454
+ composeFile?: string;
455
+ databaseImage?: string;
456
+ moduleName?: string;
457
+ openidImage?: string;
458
+ profiles?: Array<string>;
459
+ samlImage?: string;
265
460
  useSlim?: boolean;
266
- version?: string;
461
+ webOs?: string;
462
+ webVersion?: string;
267
463
  }
268
464
 
269
465
  Cypress.Commands.add(
270
- 'startWebContainer',
466
+ 'startContainers',
271
467
  ({
272
- name = Cypress.env('dockerName'),
273
- os = Cypress.env('WEB_IMAGE_OS'),
468
+ composeFile,
469
+ databaseImage = Cypress.env('DATABASE_IMAGE'),
470
+ moduleName = 'centreon-web',
471
+ openidImage = `docker.centreon.com/centreon/keycloak:${Cypress.env(
472
+ 'OPENID_IMAGE_VERSION'
473
+ )}`,
474
+ profiles = [],
475
+ samlImage = `docker.centreon.com/centreon/keycloak:${Cypress.env(
476
+ 'SAML_IMAGE_VERSION'
477
+ )}`,
274
478
  useSlim = true,
275
- version = Cypress.env('WEB_IMAGE_VERSION')
276
- }: StartWebContainerProps = {}): Cypress.Chainable => {
479
+ webOs = Cypress.env('WEB_IMAGE_OS'),
480
+ webVersion = Cypress.env('WEB_IMAGE_VERSION')
481
+ }: StartContainersProps = {}): Cypress.Chainable => {
482
+ cy.log('Starting containers ...');
483
+
484
+ let composeFilePath = composeFile;
485
+ if (!composeFile) {
486
+ const cypressDir = path.dirname(Cypress.config('configFile'));
487
+ composeFilePath = `${cypressDir}/../../../.github/docker/docker-compose.yml`;
488
+ }
489
+
277
490
  const slimSuffix = useSlim ? '-slim' : '';
278
491
 
279
- const image = `docker.centreon.com/centreon/centreon-web${slimSuffix}-${os}:${version}`;
492
+ const webImage = `docker.centreon.com/centreon/${moduleName}${slimSuffix}-${webOs}:${webVersion}`;
280
493
 
281
494
  return cy
282
- .startContainer({
283
- image,
284
- name,
285
- portBindings: [{ destination: 4000, source: 80 }]
286
- })
495
+ .task(
496
+ 'startContainers',
497
+ {
498
+ composeFile: composeFilePath,
499
+ databaseImage,
500
+ openidImage,
501
+ profiles,
502
+ samlImage,
503
+ webImage
504
+ },
505
+ { timeout: 600000 } // 10 minutes because docker pull can be very slow
506
+ )
287
507
  .then(() => {
288
508
  const baseUrl = 'http://127.0.0.1:4000';
289
509
 
290
510
  Cypress.config('baseUrl', baseUrl);
291
511
 
292
- return cy.task(
293
- 'waitOn',
294
- `${baseUrl}/centreon/api/latest/platform/installation/status`
295
- );
512
+ return cy.wrap(null);
296
513
  })
297
514
  .visit('/') // this is necessary to refresh browser cause baseUrl has changed (flash appears in video)
298
515
  .setUserTokenApiV1();
299
516
  }
300
517
  );
301
518
 
302
- interface StopWebContainerProps {
303
- name?: string;
519
+ interface StopContainerProps {
520
+ name: string;
304
521
  }
305
522
 
306
523
  Cypress.Commands.add(
307
- 'stopWebContainer',
308
- ({
309
- name = Cypress.env('dockerName')
310
- }: StopWebContainerProps = {}): Cypress.Chainable => {
524
+ 'stopContainer',
525
+ ({ name }: StopContainerProps): Cypress.Chainable => {
526
+ cy.log(`Stopping container ${name}`);
527
+
528
+ return cy.task('stopContainer', { name });
529
+ }
530
+ );
531
+
532
+ Cypress.Commands.add(
533
+ 'getLogDirectory',
534
+ (): Cypress.Chainable => {
311
535
  const logDirectory = `results/logs/${Cypress.spec.name.replace(
312
- artifactIllegalCharactersMatcher,
313
- '_'
314
- )}/${Cypress.currentTest.title.replace(
315
- artifactIllegalCharactersMatcher,
316
- '_'
317
- )}`;
536
+ artifactIllegalCharactersMatcher,
537
+ '_'
538
+ )}/${Cypress.currentTest.title.replace(
539
+ artifactIllegalCharactersMatcher,
540
+ '_'
541
+ )}`;
318
542
 
319
543
  return cy
320
- .visitEmptyPage()
321
544
  .createDirectory(logDirectory)
322
- .copyFromContainer({
323
- destination: `${logDirectory}/broker`,
324
- name,
325
- source: '/var/log/centreon-broker'
326
- })
327
- .copyFromContainer({
328
- destination: `${logDirectory}/engine`,
329
- name,
330
- source: '/var/log/centreon-engine'
331
- })
332
- .copyFromContainer({
333
- destination: `${logDirectory}/centreon`,
334
- name,
335
- source: '/var/log/centreon'
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
545
  .exec(`chmod -R 755 "${logDirectory}"`)
356
- .stopContainer({ name });
546
+ .wrap(logDirectory);
357
547
  }
358
548
  );
359
549
 
360
- interface StopContainerProps {
550
+ interface CopyWebContainerLogsProps {
361
551
  name: string;
362
552
  }
363
553
 
364
554
  Cypress.Commands.add(
365
- 'stopContainer',
366
- ({ name }: StopContainerProps): Cypress.Chainable => {
367
- cy.log(`Stopping container ${name}`);
555
+ 'copyWebContainerLogs',
556
+ ({ name }: CopyWebContainerLogsProps): Cypress.Chainable => {
557
+ cy.log(`Getting logs from container ${name} ...`);
558
+
559
+ return cy.getLogDirectory().then((logDirectory) => {
560
+ let sourcePhpLogs = '/var/log/php8.1-fpm-centreon-error.log';
561
+ let targetPhpLogs = `${logDirectory}/php8.1-fpm-centreon-error.log`;
562
+ let sourceApacheLogs = '/var/log/apache2';
563
+ let targetApacheLogs = `${logDirectory}/apache2`;
564
+ if (Cypress.env('WEB_IMAGE_OS').includes('alma')) {
565
+ sourcePhpLogs = '/var/log/php-fpm';
566
+ targetPhpLogs = `${logDirectory}/php`;
567
+ sourceApacheLogs = '/var/log/httpd';
568
+ targetApacheLogs = `${logDirectory}/httpd`;
569
+ }
368
570
 
369
- cy.exec(`docker logs ${name}`).then(({ stdout }) => {
370
- cy.writeFile(
371
- `cypress/results/logs/${Cypress.spec.name.replace(
372
- artifactIllegalCharactersMatcher,
373
- '_'
374
- )}/${Cypress.currentTest.title.replace(
375
- artifactIllegalCharactersMatcher,
376
- '_'
377
- )}/container-${name}.log`,
378
- stdout
379
- );
571
+ return cy
572
+ .copyFromContainer({
573
+ destination: `${logDirectory}/broker`,
574
+ name,
575
+ source: '/var/log/centreon-broker'
576
+ })
577
+ .copyFromContainer({
578
+ destination: `${logDirectory}/engine`,
579
+ name,
580
+ source: '/var/log/centreon-engine'
581
+ })
582
+ .copyFromContainer({
583
+ destination: `${logDirectory}/centreon`,
584
+ name,
585
+ source: '/var/log/centreon'
586
+ })
587
+ .copyFromContainer({
588
+ destination: `${logDirectory}/centreon-gorgone`,
589
+ name,
590
+ source: '/var/log/centreon-gorgone'
591
+ })
592
+ .copyFromContainer({
593
+ destination: targetPhpLogs,
594
+ name,
595
+ source: sourcePhpLogs,
596
+ })
597
+ .copyFromContainer({
598
+ destination: targetApacheLogs,
599
+ name,
600
+ source: sourceApacheLogs,
601
+ })
602
+ .exec(`chmod -R 755 "${logDirectory}"`);
603
+ });
604
+ });
605
+
606
+ Cypress.Commands.add('stopContainers', (): Cypress.Chainable => {
607
+ cy.log('Stopping containers ...');
608
+
609
+ const name = 'web';
610
+
611
+ return cy
612
+ .visitEmptyPage()
613
+ .getLogDirectory()
614
+ .then((logDirectory) => {
615
+ return cy
616
+ .getContainersLogs()
617
+ .then((containersLogs: Array<Array<string>>) => {
618
+ if (!containersLogs) {
619
+ return;
620
+ }
621
+
622
+ Object.entries(containersLogs).forEach(([containerName, logs]) => {
623
+ cy.writeFile(
624
+ `${logDirectory}/container-${containerName}.log`,
625
+ logs
626
+ );
627
+ });
628
+ })
629
+ .copyWebContainerLogs({ name })
630
+ .exec(`chmod -R 755 "${logDirectory}"`)
631
+ .task(
632
+ 'stopContainers',
633
+ {},
634
+ { timeout: 600000 } // 10 minutes because docker pull can be very slow
635
+ );
380
636
  });
637
+ });
381
638
 
382
- return cy.task('stopContainer', { name });
639
+ Cypress.Commands.add(
640
+ 'createDirectory',
641
+ (directoryPath: string): Cypress.Chainable => {
642
+ return cy.task('createDirectory', directoryPath);
383
643
  }
384
644
  );
385
645
 
@@ -416,6 +676,41 @@ Cypress.Commands.add(
416
676
  }
417
677
  );
418
678
 
679
+ Cypress.Commands.add(
680
+ 'insertDashboardWithWidget',
681
+ (dashboardBody, patchBody) => {
682
+ cy.request({
683
+ body: {
684
+ ...dashboardBody
685
+ },
686
+ method: 'POST',
687
+ url: '/centreon/api/latest/configuration/dashboards'
688
+ }).then((response) => {
689
+ const dashboardId = response.body.id;
690
+ cy.waitUntil(
691
+ () => {
692
+ return cy
693
+ .request({
694
+ method: 'GET',
695
+ url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
696
+ })
697
+ .then((getResponse) => {
698
+ return getResponse.body && getResponse.body.id === dashboardId;
699
+ });
700
+ },
701
+ {
702
+ timeout: 10000
703
+ }
704
+ );
705
+ cy.request({
706
+ body: patchBody,
707
+ method: 'PATCH',
708
+ url: `/centreon/api/latest/configuration/dashboards/${dashboardId}`
709
+ });
710
+ });
711
+ }
712
+ );
713
+
419
714
  interface ShareDashboardToUserProps {
420
715
  dashboardName: string;
421
716
  role: string;
@@ -430,6 +725,30 @@ interface ListingRequestResult {
430
725
  };
431
726
  }
432
727
 
728
+ interface PatchDashboardBody {
729
+ panels: Array<{
730
+ layout: {
731
+ height: number;
732
+ min_height: number;
733
+ min_width: number;
734
+ width: number;
735
+ x: number;
736
+ y: number;
737
+ };
738
+ name: string;
739
+ widget_settings: {
740
+ options: {
741
+ description: {
742
+ content: string;
743
+ enabled: boolean;
744
+ };
745
+ name: string;
746
+ };
747
+ };
748
+ widget_type: string;
749
+ }>;
750
+ }
751
+
433
752
  Cypress.Commands.add(
434
753
  'shareDashboardToUser',
435
754
  ({ dashboardName, userName, role }: ShareDashboardToUserProps): void => {
@@ -465,7 +784,7 @@ Cypress.Commands.add(
465
784
 
466
785
  Cypress.Commands.add('getTimeFromHeader', (): Cypress.Chainable => {
467
786
  return cy
468
- .get('header div[data-cy="clock"]', { timeout: 10000 })
787
+ .get('header div[data-cy="clock"]', { timeout: 20000 })
469
788
  .should('be.visible')
470
789
  .then(($time) => {
471
790
  const headerTime = $time.children()[1].textContent;
@@ -491,46 +810,85 @@ declare global {
491
810
  props: CopyToContainerProps,
492
811
  options?: Partial<Cypress.ExecOptions>
493
812
  ) => Cypress.Chainable;
813
+ copyWebContainerLogs: (props: CopyWebContainerLogsProps) => Cypress.Chainable;
494
814
  createDirectory: (directoryPath: string) => Cypress.Chainable;
495
815
  execInContainer: ({
496
816
  command,
497
817
  name
498
818
  }: ExecInContainerProps) => Cypress.Chainable;
819
+ getByLabel: ({
820
+ patternType,
821
+ tag,
822
+ label
823
+ }: GetByLabelProps) => Cypress.Chainable;
824
+ getByTestId: ({
825
+ patternType,
826
+ tag,
827
+ testId
828
+ }: GetByTestIdProps) => Cypress.Chainable;
829
+ getContainerId: (containerName: string) => Cypress.Chainable;
830
+ getContainerIpAddress: (containerName: string) => Cypress.Chainable;
831
+ getContainersLogs: () => Cypress.Chainable;
499
832
  getIframeBody: () => Cypress.Chainable;
833
+ getLogDirectory: () => Cypress.Chainable;
500
834
  getTimeFromHeader: () => Cypress.Chainable;
501
835
  getWebVersion: () => Cypress.Chainable;
502
836
  hoverRootMenuItem: (rootItemNumber: number) => Cypress.Chainable;
503
837
  insertDashboard: (dashboard: Dashboard) => Cypress.Chainable;
504
838
  insertDashboardList: (fixtureFile: string) => Cypress.Chainable;
839
+ insertDashboardWithWidget: (
840
+ dashboard: Dashboard,
841
+ patch: PatchDashboardBody
842
+ ) => Cypress.Chainable;
843
+ loginAsAdminViaApiV2: () => Cypress.Chainable;
505
844
  loginByTypeOfUser: ({
506
845
  jsonName,
507
846
  loginViaApi
508
847
  }: LoginByTypeOfUserProps) => Cypress.Chainable;
848
+ logout: () => void;
849
+ logoutViaAPI: () => Cypress.Chainable;
509
850
  moveSortableElement: (direction: string) => Cypress.Chainable;
510
851
  navigateTo: ({
511
852
  page,
512
853
  rootItemNumber,
513
854
  subMenu
514
855
  }: NavigateToProps) => Cypress.Chainable;
856
+ requestOnDatabase: ({
857
+ database,
858
+ query
859
+ }: RequestOnDatabaseProps) => Cypress.Chainable;
860
+ setUserTokenApiV1: ({
861
+ login,
862
+ password
863
+ }?: SetUserTokenApiV1Props) => Cypress.Chainable;
515
864
  shareDashboardToUser: ({
516
865
  dashboardName,
517
866
  userName,
518
867
  role
519
868
  }: ShareDashboardToUserProps) => Cypress.Chainable;
520
869
  startContainer: ({
870
+ command,
521
871
  name,
522
- image
872
+ image,
873
+ portBindings
523
874
  }: StartContainerProps) => Cypress.Chainable;
524
- startWebContainer: ({
525
- name,
526
- os,
875
+ startContainers: ({
876
+ composeFile,
877
+ databaseImage,
878
+ moduleName,
879
+ openidImage,
880
+ profiles,
527
881
  useSlim,
528
- version
529
- }?: StartWebContainerProps) => Cypress.Chainable;
882
+ webOs,
883
+ webVersion
884
+ }?: StartContainersProps) => Cypress.Chainable;
885
+ waitForElementInIframe: (
886
+ iframeSelector: string,
887
+ elementSelector: string
888
+ ) => Cypress.Chainable;
530
889
  stopContainer: ({ name }: StopContainerProps) => Cypress.Chainable;
531
- stopWebContainer: ({ name }?: StopWebContainerProps) => Cypress.Chainable;
890
+ stopContainers: () => Cypress.Chainable;
532
891
  visitEmptyPage: () => Cypress.Chainable;
533
- waitForContainerAndSetToken: () => Cypress.Chainable;
534
892
  }
535
893
  }
536
894
  }