Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Uptime] [Backport] Add functional UI tests (#29667) #33192

Merged
merged 1 commit into from
Mar 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions test/functional/page_objects/time_picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ export function TimePickerPageProvider({ getService, getPageObjects }) {
await find.waitForElementStale(panelElement);
}

async setAbsoluteStart(startTime) {
await this.showStartEndTimes();

await testSubjects.click('superDatePickerstartDatePopoverButton');
const panel = await this.getTimePickerPanel();
await testSubjects.click('superDatePickerAbsoluteTab');
await testSubjects.setValue('superDatePickerAbsoluteDateInput', startTime);
await testSubjects.click('superDatePickerstartDatePopoverButton');
await this.waitPanelIsGone(panel);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

/**
* @param {String} fromTime YYYY-MM-DD HH:mm:ss.SSS
* @param {String} fromTime YYYY-MM-DD HH:mm:ss.SSS
Expand Down Expand Up @@ -110,6 +122,8 @@ export function TimePickerPageProvider({ getService, getPageObjects }) {
}

async showStartEndTimes() {
// This first await makes sure the superDatePicker has loaded before we check for the ShowDatesButton
await testSubjects.exists('superDatePickerToggleQuickMenuButton', { timeout: 20000 });
const isShowDatesButton = await testSubjects.exists('superDatePickerShowDatesButton');
if (isShowDatesButton) {
await testSubjects.click('superDatePickerShowDatesButton');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const MonitorList = ({ dangerColor, loading, monitors, primaryColor }: Mo
defaultMessage: 'ID',
}),
render: (id: string, monitor: LatestMonitor) => (
<Link to={`/monitor/${id}`}>
<Link data-test-subj={`monitor-page-link-${id}`} to={`/monitor/${id}`}>
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.name
? monitor.ping.monitor.name
: id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const MonitorPageTitle = ({ pageTitle: { name, url, id } }: MonitorPageTi
<EuiFlexGroup alignItems="baseline">
<EuiFlexItem grow={false}>
<EuiTitle>
<h2>{name ? name : url}</h2>
<h2 data-test-subj="monitor-page-title">{name ? name : url}</h2>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
const route = {
controllerAs: 'uptime',
// @ts-ignore angular
controller: ($scope, $route, $http, config) => {
controller: ($scope, $route, config, $location, $window) => {
const graphQLClient = createGraphQLClient(this.uriPath, this.xsrfHeader);
$scope.$$postDigest(() => {
const elem = document.getElementById('uptimeReactRoot');
Expand All @@ -57,6 +57,23 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
const routerBasename = basePath.endsWith('/')
? `${basePath}/${PLUGIN.ROUTER_BASE_NAME}`
: basePath + PLUGIN.ROUTER_BASE_NAME;

/**
* TODO: this is a redirect hack to deal with a problem that largely
* in testing but rarely occurs in the real world, where the specified
* URL contains `.../app/uptime{SOME_URL_PARAM_TEXT}#` instead of
* a path like `.../app/uptime#{SOME_URL_PARAM_TEXT}`.
*
* This redirect will almost never be triggered in practice, but it makes more
* sense to include it here rather than altering the existing testing
* infrastructure underlying the rest of Kibana.
*
* We welcome a more permanent solution that will result in the deletion of the
* block below.
*/
if ($location.absUrl().indexOf(PLUGIN.ROUTER_BASE_NAME) === -1) {
$window.location.replace(routerBasename);
}
const persistedState = this.initializePersistedState();
const darkMode = config.get('theme:darkMode', false) || false;
const {
Expand Down
13 changes: 12 additions & 1 deletion x-pack/test/functional/apps/uptime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@

import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';

const ARCHIVE = 'uptime/full_heartbeat';

// tslint:disable-next-line:no-default-export
export default ({ loadTestFile }: KibanaFunctionalTestDefaultProviders) => {
export default ({ loadTestFile, getService }: KibanaFunctionalTestDefaultProviders) => {
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');

describe('Uptime app', function() {
before(async () => {
await esArchiver.load(ARCHIVE);
await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'UTC' });
});
after(async () => await esArchiver.unload(ARCHIVE));
this.tags('ciGroup6');

loadTestFile(require.resolve('./overview'));
loadTestFile(require.resolve('./monitor'));
});
};
28 changes: 28 additions & 0 deletions x-pack/test/functional/apps/uptime/monitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';

// tslint:disable-next-line:no-default-export
export default ({ getPageObjects, getService }: KibanaFunctionalTestDefaultProviders) => {
const esArchiver = getService('esArchiver');
const pageObjects = getPageObjects(['uptime']);
const archive = 'uptime/full_heartbeat';

describe('monitor page', () => {
before(async () => {
await esArchiver.load(archive);
});
after(async () => await esArchiver.unload(archive));
it('loads and displays uptime data based on date range', async () => {
await pageObjects.uptime.loadDataAndGoToMonitorPage(
'2019-01-28 12:40:08.078',
'auto-http-0X131221E73F825974',
'https://www.google.com/'
);
});
});
};
21 changes: 8 additions & 13 deletions x-pack/test/functional/apps/uptime/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@
import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';

// tslint:disable-next-line:no-default-export
export default ({ getPageObjects, getService }: KibanaFunctionalTestDefaultProviders) => {
const esArchiver = getService('esArchiver');
export default ({ getPageObjects }: KibanaFunctionalTestDefaultProviders) => {
// TODO: add UI functional tests
// const pageObjects = getPageObjects(['uptime']);
const archive = 'uptime/full_heartbeat';

describe('Overview page', () => {
describe('this is a simple test', () => {
beforeEach(async () => {
await esArchiver.load(archive);
});
afterEach(async () => await esArchiver.unload(archive));

// TODO: add UI functional tests
const pageObjects = getPageObjects(['uptime']);
describe('overview page', () => {
it('loads and displays uptime data based on date range', async () => {
await pageObjects.uptime.goToUptimeOverviewAndLoadData(
'2019-01-28 12:40:08.078',
'monitor-page-link-auto-http-0X131221E73F825974'
);
});
});
};
31 changes: 24 additions & 7 deletions x-pack/test/functional/page_objects/uptime_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,30 @@ export const UptimePageProvider = ({
getPageObjects,
getService,
}: KibanaFunctionalTestDefaultProviders) => {
const pageObject = getPageObjects(['common']);
const pageObjects = getPageObjects(['common', 'timePicker']);
const uptimeService = getService('uptime');

return {
async goToUptimeOverview() {
await pageObject.common.navigateToApp('uptime');
await uptimeService.assertExists();
},
};
return new class UptimePage {
public async goToUptimeOverviewAndLoadData(
datePickerStartValue: string,
monitorIdToCheck: string
) {
await pageObjects.common.navigateToApp('uptime');
await pageObjects.timePicker.setAbsoluteStart(datePickerStartValue);
await uptimeService.monitorIdExists(monitorIdToCheck);
}

public async loadDataAndGoToMonitorPage(
datePickerStartValue: string,
monitorId: string,
monitorName: string
) {
await pageObjects.common.navigateToApp('uptime');
await pageObjects.timePicker.setAbsoluteStart(datePickerStartValue);
await uptimeService.navigateToMonitorWithId(monitorId);
if ((await uptimeService.getMonitorNameDisplayedOnPageTitle()) !== monitorName) {
throw new Error('Expected monitor name not found');
}
}
}();
};
10 changes: 9 additions & 1 deletion x-pack/test/functional/services/uptime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@ import { KibanaFunctionalTestDefaultProviders } from '../../types/providers';

export const UptimeProvider = ({ getService }: KibanaFunctionalTestDefaultProviders) => {
const testSubjects = getService('testSubjects');

return {
async assertExists(key: string) {
if (!(await testSubjects.exists(key))) {
throw new Error(`Couldn't find expected element with key "${key}".`);
}
},
async monitorIdExists(key: string) {
await testSubjects.existOrFail(key);
},
async navigateToMonitorWithId(monitorId: string) {
await testSubjects.click(`monitor-page-link-${monitorId}`);
},
async getMonitorNameDisplayedOnPageTitle() {
return await testSubjects.getVisibleText('monitor-page-title');
},
};
};
2 changes: 2 additions & 0 deletions x-pack/test/types/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*/

import { EsArchiver } from '../../../src/es_archiver';
import { UptimeProvider } from '../functional/services/uptime';

export interface KibanaFunctionalTestDefaultProviders {
getService(serviceName: 'esArchiver'): EsArchiver;
getService(serviceName: 'uptime'): ReturnType<typeof UptimeProvider>;
getService(serviceName: string): any;
getPageObjects(pageObjectNames: string[]): any;
loadTestFile(path: string): void;
Expand Down