});
});
- describe('create, edit & delete image test', async () => {
+ describe('create, edit & delete image test', () => {
const poolName = 'e2e_images_pool';
const imageName = 'e2e_images_image';
const newImageName = 'e2e_images_image_new';
});
});
- describe('checks that edit mode functionality shows in the pools table', async () => {
+ describe('checks that edit mode functionality shows in the pools table', () => {
const poolName = 'mirroring_test';
beforeAll(async () => {
});
describe('fields check', () => {
- beforeAll(() => {
- configuration.navigateTo();
+ beforeAll(async () => {
+ await configuration.navigateTo();
});
it('should verify that selected footer increases when an entry is clicked', async () => {
});
describe('audit logs respond to editing configuration setting test', () => {
+ let originalTimeout;
+
+ beforeEach(() => {
+ originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
+ });
+
it('should change config settings and check audit logs reacted', async () => {
await configuration.navigateTo();
await configuration.edit(configname, ['global', '5']);
await configuration.navigateTo();
await configuration.configClear(configname);
});
+
+ afterEach(function() {
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
+ });
});
});
const audit_logs_tab = $('.tab-pane.active');
const audit_logs_body = audit_logs_tab.element(by.css('.card-body'));
- const logs = audit_logs_body.all(by.cssContainingText('.ng-star-inserted', poolname));
+ const logs = audit_logs_body.all(by.cssContainingText('.message', poolname));
await expect(logs.getText()).toMatch(poolname);
await expect(logs.getText()).toMatch(`pool ${poolfunction}`);
const audit_logs_tab = $('.tab-pane.active');
const audit_logs_body = audit_logs_tab.element(by.css('.card-body'));
- const logs = audit_logs_body.all(by.cssContainingText('.ng-star-inserted', configname));
+ const logs = audit_logs_body.all(by.cssContainingText('.message', configname));
await this.waitPresence(logs.first());
};
}
- /**
- * This is a decorator to be used on methods which change the current page once, like `navigateTo`
- * and `navigateBack` in this class do. It ensures that, if the new page contains a table, its
- * data has been fully loaded. If no table is detected, it will return instantly.
- */
- static waitForTableData(): Function {
- return (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) => {
- const fn: Function = descriptor.value;
- descriptor.value = async function(...args) {
- const result = fn.apply(this, args);
-
- // If a table is on the new page, wait until it has gotten its data.
- const implicitWaitTimeout = (await browser.getProcessedConfig()).implicitWaitTimeout;
- await browser
- .manage()
- .timeouts()
- .implicitlyWait(1000);
-
- const tableCount = await element.all(by.css('cd-table')).count();
- if (tableCount > 0) {
- const progressBars = element.all(by.css('cd-table datatable-progress'));
- await progressBars.each(async (progressBar) => {
- await browser.wait(EC.stalenessOf(progressBar), TIMEOUT);
- });
- }
-
- await browser
- .manage()
- .timeouts()
- .implicitlyWait(implicitWaitTimeout);
-
- return result;
- };
- };
- }
-
/**
* Get the active breadcrumb item.
*/
}
}
- @PageHelper.waitForTableData()
async navigateTo(page = null) {
page = page || 'index';
const url = this.pages[page];
await browser.get(url);
}
- @PageHelper.waitForTableData()
async navigateBack() {
await browser.navigate().back();
}
});
});
- describe('details and performance counters table tests', async () => {
+ describe('details and performance counters table tests', () => {
beforeAll(async () => {
await daemons.navigateTo();
});
});
describe('Invalid input test', () => {
+ let originalTimeout;
+
beforeAll(async () => {
+ originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
+
await users.navigateTo();
});
it('should put invalid input into user edit form and check fields are marked invalid', async () => {
await users.invalidEdit();
});
+
+ afterAll(function() {
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
+ });
});
});
// Try to give user already taken name. Should make field invalid.
await username_field.clear();
await username_field.sendKeys(uname);
- await this.waitFn(
- async () => !(await username_field.getAttribute('class')).includes('ng-pending')
- );
await expect(username_field.getAttribute('class')).toContain('ng-invalid');
await element(by.id('display_name')).click(); // trigger validation check
await expect(element(by.css('#uid + .invalid-feedback')).getText()).toMatch(
});
});
- it('Should check that dashboard cards have correct information', async () => {
- interface TestSpec {
- cardName: string;
- regexMatcher?: RegExp;
- pageObject: PageHelper;
- }
+ describe('Correct information', () => {
+ let originalTimeout;
- const testSpecs: TestSpec[] = [
- { cardName: 'Object Gateways', regexMatcher: /(\d+)\s+total/, pageObject: daemons },
- { cardName: 'Monitors', regexMatcher: /(\d+)\s+\(quorum/, pageObject: monitors },
- { cardName: 'Hosts', regexMatcher: /(\d+)\s+total/, pageObject: hosts },
- { cardName: 'OSDs', regexMatcher: /(\d+)\s+total/, pageObject: osds },
- { cardName: 'Pools', pageObject: pools },
- { cardName: 'iSCSI Gateways', regexMatcher: /(\d+)\s+total/, pageObject: iscsi }
- ];
+ beforeEach(async () => {
+ originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
+ });
- for (let i = 0; i < testSpecs.length; i++) {
- const spec = testSpecs[i];
- await dashboard.navigateTo();
- const infoCardBodyText = await dashboard.infoCardBodyText(spec.cardName);
- let dashCount = 0;
- if (spec.regexMatcher) {
- const match = infoCardBodyText.match(new RegExp(spec.regexMatcher));
- if (match && match.length > 1) {
- dashCount = Number(match[1]);
+ it('Should check that dashboard cards have correct information', async () => {
+ interface TestSpec {
+ cardName: string;
+ regexMatcher?: RegExp;
+ pageObject: PageHelper;
+ }
+
+ const testSpecs: TestSpec[] = [
+ { cardName: 'Object Gateways', regexMatcher: /(\d+)\s+total/, pageObject: daemons },
+ { cardName: 'Monitors', regexMatcher: /(\d+)\s+\(quorum/, pageObject: monitors },
+ { cardName: 'Hosts', regexMatcher: /(\d+)\s+total/, pageObject: hosts },
+ { cardName: 'OSDs', regexMatcher: /(\d+)\s+total/, pageObject: osds },
+ { cardName: 'Pools', pageObject: pools },
+ { cardName: 'iSCSI Gateways', regexMatcher: /(\d+)\s+total/, pageObject: iscsi }
+ ];
+
+ for (let i = 0; i < testSpecs.length; i++) {
+ const spec = testSpecs[i];
+ await dashboard.navigateTo();
+ const infoCardBodyText = await dashboard.infoCardBodyText(spec.cardName);
+ let dashCount = 0;
+ if (spec.regexMatcher) {
+ const match = infoCardBodyText.match(new RegExp(spec.regexMatcher));
+ if (match && match.length > 1) {
+ dashCount = Number(match[1]);
+ } else {
+ return Promise.reject(
+ `Regex ${spec.regexMatcher} did not find a match for card with name ` +
+ `${spec.cardName}`
+ );
+ }
} else {
- return Promise.reject(
- `Regex ${spec.regexMatcher} did not find a match for card with name ` +
- `${spec.cardName}`
- );
+ dashCount = Number(infoCardBodyText);
}
- } else {
- dashCount = Number(infoCardBodyText);
+ await spec.pageObject.navigateTo();
+ const tableCount = await spec.pageObject.getTableTotalCount();
+ await expect(dashCount).toBe(
+ tableCount,
+ `Text of card "${spec.cardName}" and regex "${spec.regexMatcher}" resulted in ${dashCount} ` +
+ `but did not match table count ${tableCount}`
+ );
}
- await spec.pageObject.navigateTo();
- const tableCount = await spec.pageObject.getTableTotalCount();
- await expect(dashCount).toBe(
- tableCount,
- `Text of card "${spec.cardName}" and regex "${spec.regexMatcher}" resulted in ${dashCount} ` +
- `but did not match table count ${tableCount}`
- );
- }
+ });
+
+ afterEach(function() {
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
+ });
});
});
config.onPrepare = async () => {
await browser.manage().timeouts().implicitlyWait(config.implicitWaitTimeout);
- await browser.waitForAngularEnabled(false);
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
await browser.driver.findElement(by.name('password')).sendKeys(browser.params.login.password);
await browser.driver.findElement(by.css('input[type="submit"]')).click();
-
- // Login takes some time, so wait until it's done.
- // For the test app's login, we know it's done when it redirects to
- // dashboard.
- await browser.driver.wait(async () => {
- const url = await browser.driver.getCurrentUrl();
- return /dashboard/.test(url);
- });
};
exports.config = config;
import { DatePipe } from '@angular/common';
-import { Component, OnDestroy, OnInit } from '@angular/core';
+import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
import { LogsService } from '../../../shared/api/logs.service';
import { Icons } from '../../../shared/enum/icons.enum';
selectedDate: Date;
startTime: Date = new Date();
endTime: Date = new Date();
- constructor(private logsService: LogsService, private datePipe: DatePipe) {
+ constructor(
+ private logsService: LogsService,
+ private datePipe: DatePipe,
+ private ngZone: NgZone
+ ) {
this.startTime.setHours(0, 0);
this.endTime.setHours(23, 59);
}
ngOnInit() {
this.getInfo();
- this.interval = window.setInterval(() => {
- this.getInfo();
- }, 5000);
+ this.ngZone.runOutsideAngular(() => {
+ this.interval = window.setInterval(() => {
+ this.ngZone.run(() => {
+ this.getInfo();
+ });
+ }, 5000);
+ });
}
ngOnDestroy() {
-import { fakeAsync, tick } from '@angular/core/testing';
+import { NgZone } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { configureTestBed } from '../../../testing/unit-test-helper';
import { RefreshIntervalService } from './refresh-interval.service';
describe('RefreshIntervalService', () => {
let service: RefreshIntervalService;
+ configureTestBed({
+ imports: [],
+ providers: [RefreshIntervalService]
+ });
+
beforeEach(() => {
- service = new RefreshIntervalService();
+ service = TestBed.get(RefreshIntervalService);
});
it('should be created', () => {
it('should initial private interval time right', () => {
sessionStorage.setItem('dashboard_interval', '10000');
- service = new RefreshIntervalService();
+ const ngZone = TestBed.get(NgZone);
+ service = new RefreshIntervalService(ngZone);
expect(service.getRefreshInterval()).toBe(10000);
});
-import { Injectable, OnDestroy } from '@angular/core';
+import { Injectable, NgZone, OnDestroy } from '@angular/core';
import { BehaviorSubject, interval, Subscription } from 'rxjs';
// Observable streams
intervalData$ = this.intervalDataSource.asObservable();
- constructor() {
+ constructor(private ngZone: NgZone) {
const initialInterval = parseInt(sessionStorage.getItem('dashboard_interval'), 10) || 5000;
this.setRefreshInterval(initialInterval);
}
if (this.intervalSubscription) {
this.intervalSubscription.unsubscribe();
}
- this.intervalSubscription = interval(this.intervalTime).subscribe(() =>
- this.intervalDataSource.next(this.intervalTime)
- );
+ this.ngZone.runOutsideAngular(() => {
+ this.intervalSubscription = interval(this.intervalTime).subscribe(() =>
+ this.ngZone.run(() => {
+ this.intervalDataSource.next(this.intervalTime);
+ })
+ );
+ });
}
getRefreshInterval() {