[ML] Add basic navigation tests for ML pages to functional UI tests (#39525)
This PR adds functional UI tests to navigate through the machine learning pages with some basic verification for existing elements.
This commit is contained in:
parent
1d09f5a067
commit
82d83ee5f5
|
@ -3,42 +3,42 @@
|
|||
<!-- Tabs -->
|
||||
<div data-transclude-slot="bottomRow">
|
||||
<div ng-if="showTabs" class="kuiLocalTabs" role="tablist">
|
||||
<a kbn-href="#/jobs" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/jobs" class="kuiLocalTab" role="tab" data-test-subj="mlTabJobManagement"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('jobs'), 'disabled-nav-link': disableLinks}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.jobManagementTabLinkText"
|
||||
i18n-default-message="Job Management"
|
||||
></span>
|
||||
</a>
|
||||
<a kbn-href="#/explorer" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/explorer" class="kuiLocalTab" role="tab" data-test-subj="mlTabAnomalyExplorer"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('explorer'), 'disabled-nav-link': disableLinks}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.anomalyExplorerTabLinkText"
|
||||
i18n-default-message="Anomaly Explorer"
|
||||
></span>
|
||||
</a>
|
||||
<a kbn-href="#/timeseriesexplorer" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/timeseriesexplorer" class="kuiLocalTab" role="tab" data-test-subj="mlTabSingleMetricViewer"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('timeseriesexplorer'), 'disabled-nav-link': disableLinks}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.singleMetricViewerTabLinkText"
|
||||
i18n-default-message="Single Metric Viewer"
|
||||
></span>
|
||||
</a>
|
||||
<a kbn-href="#/data_frames" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/data_frames" class="kuiLocalTab" role="tab" data-test-subj="mlTabDataFrames"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('data_frame')}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.dataFrameTabLinkText"
|
||||
i18n-default-message="Data Frames"
|
||||
></span>
|
||||
</a>
|
||||
<a kbn-href="#/datavisualizer" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/datavisualizer" class="kuiLocalTab" role="tab" data-test-subj="mlTabDataVisualizer"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('datavisualizer')}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.dataVisualizerTabLinkText"
|
||||
i18n-default-message="Data Visualizer"
|
||||
></span>
|
||||
</a>
|
||||
<a kbn-href="#/settings" class="kuiLocalTab" role="tab"
|
||||
<a kbn-href="#/settings" class="kuiLocalTab" role="tab" data-test-subj="mlTabSettings"
|
||||
ng-class="{'kuiLocalTab-isSelected': isActiveTab('settings'), 'disabled-nav-link': disableLinks}">
|
||||
<span
|
||||
i18n-id="xpack.ml.navMenu.settingsTabLinkText"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
exports[`Data Frame: Job List <Page /> Minimal initialization 1`] = `
|
||||
<EuiPage
|
||||
data-test-subj="mlPageDataFrame"
|
||||
restrictWidth={false}
|
||||
>
|
||||
<EuiPageBody
|
||||
|
|
|
@ -14,6 +14,7 @@ exports[`Data Frame: Job List <DataFrameJobList /> Minimal initialization 1`] =
|
|||
</EuiButtonEmpty>,
|
||||
]
|
||||
}
|
||||
data-test-subj="mlNoDataFrameJobsFound"
|
||||
iconColor="subdued"
|
||||
title={
|
||||
<h2>
|
||||
|
|
|
@ -68,6 +68,7 @@ export const DataFrameJobList: SFC = () => {
|
|||
Create your first data frame job
|
||||
</EuiButtonEmpty>,
|
||||
]}
|
||||
data-test-subj="mlNoDataFrameJobsFound"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import { CreateJobButton } from './components/create_job_button';
|
|||
import { DataFrameJobList } from './components/job_list';
|
||||
|
||||
export const Page: SFC = () => (
|
||||
<EuiPage>
|
||||
<EuiPage data-test-subj="mlPageDataFrame">
|
||||
<EuiPageBody>
|
||||
<EuiPageContentHeader>
|
||||
<EuiPageContentHeaderSection>
|
||||
|
|
|
@ -121,6 +121,7 @@ export const DatavisualizerSelector = injectI18n(function (props) {
|
|||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
data-test-subj="mlDataVisualizerCardImportData"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
|
@ -149,6 +150,7 @@ export const DatavisualizerSelector = injectI18n(function (props) {
|
|||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
data-test-subj="mlDataVisualizerCardIndexData"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -19,7 +19,7 @@ import uiRoutes from 'ui/routes';
|
|||
const template = `
|
||||
<div class="euiSpacer euiSpacer--s" />
|
||||
<ml-nav-menu name="datavisualizer" />
|
||||
<datavisualizer-selector />
|
||||
<datavisualizer-selector data-test-subj="mlPageDataVisualizerSelector" />
|
||||
`;
|
||||
|
||||
uiRoutes
|
||||
|
|
|
@ -18,6 +18,7 @@ exports[`ExplorerNoInfluencersFound snapshot 1`] = `
|
|||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
data-test-subj="mlNoJobsFound"
|
||||
iconColor="subdued"
|
||||
iconType="alert"
|
||||
title={
|
||||
|
|
|
@ -29,5 +29,6 @@ export const ExplorerNoJobsFound = () => (
|
|||
/>
|
||||
</EuiButton>
|
||||
}
|
||||
data-test-subj="mlNoJobsFound"
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<ml-nav-menu name="explorer"></ml-nav-menu>
|
||||
<ml-chart-tooltip></ml-chart-tooltip>
|
||||
<div class="ml-explorer" ng-controller="MlExplorerController">
|
||||
<div class="ml-explorer" ng-controller="MlExplorerController" data-test-subj="mlPageAnomalyExplorer" >
|
||||
|
||||
<ml-job-selector-react-wrapper />
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ export const JobStatsBar = ({ jobsSummaryList }) => {
|
|||
const stats = Object.keys(jobStats).map(k => jobStats[k]);
|
||||
|
||||
return (
|
||||
<div className="jobs-stats-bar">
|
||||
<div className="jobs-stats-bar" data-test-subj="mlJobStatsBar">
|
||||
{
|
||||
stats.filter(s => (s.show)).map(s => <Stat key={s.label} stat={s} />)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import { loadNewJobDefaults } from 'plugins/ml/jobs/new_job/utils/new_job_defaul
|
|||
|
||||
import uiRoutes from 'ui/routes';
|
||||
|
||||
const template = `<ml-nav-menu name="jobs" /><jobs-page />`;
|
||||
const template = `<ml-nav-menu name="jobs" /><jobs-page data-test-subj="mlPageJobManagement" />`;
|
||||
|
||||
uiRoutes
|
||||
.when('/jobs/?', {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
exports[`Settings Renders settings page 1`] = `
|
||||
<EuiPage
|
||||
className="mlSettingsPage"
|
||||
data-test-subj="mlPageSettings"
|
||||
restrictWidth={false}
|
||||
>
|
||||
<EuiPageBody
|
||||
|
@ -35,7 +36,7 @@ exports[`Settings Renders settings page 1`] = `
|
|||
>
|
||||
<EuiButtonEmpty
|
||||
color="primary"
|
||||
data-testid="ml_calendar_mng_button"
|
||||
data-test-subj="ml_calendar_mng_button"
|
||||
href="undefined/app/ml#/settings/calendars_list"
|
||||
iconSide="left"
|
||||
isDisabled={false}
|
||||
|
@ -54,7 +55,7 @@ exports[`Settings Renders settings page 1`] = `
|
|||
>
|
||||
<EuiButtonEmpty
|
||||
color="primary"
|
||||
data-testid="ml_filter_lists_button"
|
||||
data-test-subj="ml_filter_lists_button"
|
||||
href="undefined/app/ml#/settings/filter_lists"
|
||||
iconSide="left"
|
||||
isDisabled={false}
|
||||
|
|
|
@ -29,7 +29,7 @@ export function Settings({
|
|||
canGetCalendars
|
||||
}) {
|
||||
return (
|
||||
<EuiPage className="mlSettingsPage">
|
||||
<EuiPage className="mlSettingsPage" data-test-subj="mlPageSettings">
|
||||
<EuiPageBody className="mlSettingsPage__body">
|
||||
<EuiPageContent
|
||||
className="mlSettingsPage__content"
|
||||
|
@ -49,7 +49,7 @@ export function Settings({
|
|||
<EuiFlexGroup gutterSize="xl">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
data-testid="ml_calendar_mng_button"
|
||||
data-test-subj="ml_calendar_mng_button"
|
||||
size="l"
|
||||
color="primary"
|
||||
href={`${chrome.getBasePath()}/app/ml#/settings/calendars_list`}
|
||||
|
@ -64,7 +64,7 @@ export function Settings({
|
|||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
data-testid="ml_filter_lists_button"
|
||||
data-test-subj="ml_filter_lists_button"
|
||||
size="l"
|
||||
color="primary"
|
||||
href={`${chrome.getBasePath()}/app/ml#/settings/filter_lists`}
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Settings', () => {
|
|||
<Settings canGetFilters={false} canGetCalendars={true}/>
|
||||
);
|
||||
|
||||
const button = wrapper.find('[data-testid="ml_filter_lists_button"]');
|
||||
const button = wrapper.find('[data-test-subj="ml_filter_lists_button"]');
|
||||
const filterButton = button.find('EuiButtonEmpty');
|
||||
expect(filterButton.prop('isDisabled')).toBe(true);
|
||||
});
|
||||
|
@ -41,7 +41,7 @@ describe('Settings', () => {
|
|||
<Settings canGetFilters={true} canGetCalendars={false} />
|
||||
);
|
||||
|
||||
const button = wrapper.find('[data-testid="ml_calendar_mng_button"]');
|
||||
const button = wrapper.find('[data-test-subj="ml_calendar_mng_button"]');
|
||||
const calendarButton = button.find('EuiButtonEmpty');
|
||||
expect(calendarButton.prop('isDisabled')).toBe(true);
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<ml-nav-menu name="timeseriesexplorer"></ml-nav-menu>
|
||||
<ml-chart-tooltip></ml-chart-tooltip>
|
||||
<div class="ml-time-series-explorer" ng-controller="MlTimeSeriesExplorerController">
|
||||
<div class="ml-time-series-explorer" ng-controller="MlTimeSeriesExplorerController" data-test-subj="mlPageSingleMetricViewer" >
|
||||
|
||||
<ml-job-selector-react-wrapper timeseriesonly="true" singleselection="true" />
|
||||
|
||||
<div class="no-results-container" ng-if="jobs.length === 0 && loading === false">
|
||||
<div class="no-results-container" ng-if="jobs.length === 0 && loading === false" data-test-subj="mlNoSingleMetricJobsFound">
|
||||
<div class="no-results">
|
||||
<div
|
||||
i18n-id="xpack.ml.timeSeriesExplorer.noSingleMetricJobsFoundLabel"
|
||||
|
|
|
@ -11,5 +11,6 @@ export default function({ loadTestFile }: KibanaFunctionalTestDefaultProviders)
|
|||
this.tags('ciGroup3');
|
||||
|
||||
loadTestFile(require.resolve('./feature_controls'));
|
||||
loadTestFile(require.resolve('./pages'));
|
||||
});
|
||||
}
|
||||
|
|
61
x-pack/test/functional/apps/machine_learning/pages.ts
Normal file
61
x-pack/test/functional/apps/machine_learning/pages.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService }: KibanaFunctionalTestDefaultProviders) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const ml = getService('ml');
|
||||
|
||||
describe('page navigation', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('empty_kibana');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('empty_kibana');
|
||||
});
|
||||
|
||||
it('loads the home page', async () => {
|
||||
await ml.navigateTo();
|
||||
});
|
||||
|
||||
it('loads the job management page', async () => {
|
||||
await ml.navigateToJobManagement();
|
||||
await ml.assertJobStatsBarExists();
|
||||
await ml.assertJobTableExists();
|
||||
await ml.assertCreateNewJobButtonExists();
|
||||
});
|
||||
|
||||
it('loads the anomaly explorer page', async () => {
|
||||
await ml.navigateToAnomalyExplorert();
|
||||
await ml.assertAnomalyExplorerEmptyListMessageExists();
|
||||
});
|
||||
|
||||
it('loads the single metric viewer page', async () => {
|
||||
await ml.navigateToSingleMetricViewer();
|
||||
await ml.assertSingleMetricViewerEmptyListMessageExsist();
|
||||
});
|
||||
|
||||
it('loads the data frame page', async () => {
|
||||
await ml.navigateToDataFrames();
|
||||
await ml.assertDataFrameEmptyListMessageExists();
|
||||
});
|
||||
|
||||
it('loads the data visualizer page', async () => {
|
||||
await ml.navigateToDataVisualizer();
|
||||
await ml.assertDataVisualizerImportDataCardExists();
|
||||
await ml.assertDataVisualizerIndexDataCardExists();
|
||||
});
|
||||
|
||||
it('loads the settings page', async () => {
|
||||
await ml.navigateToSettings();
|
||||
await ml.assertSettingsCalendarLinkExists();
|
||||
await ml.assertSettingsFilterlistLinkExists();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -60,6 +60,7 @@ import {
|
|||
UptimeProvider,
|
||||
InfraSourceConfigurationFlyoutProvider,
|
||||
InfraLogStreamProvider,
|
||||
MachineLearningProvider,
|
||||
} from './services';
|
||||
|
||||
import {
|
||||
|
@ -150,6 +151,7 @@ export default async function ({ readConfigFile }) {
|
|||
rollup: RollupPageProvider,
|
||||
infraSourceConfigurationFlyout: InfraSourceConfigurationFlyoutProvider,
|
||||
infraLogStream: InfraLogStreamProvider,
|
||||
ml: MachineLearningProvider,
|
||||
},
|
||||
|
||||
// just like services, PageObjects are defined as a map of
|
||||
|
|
|
@ -14,3 +14,4 @@ export { UserMenuProvider } from './user_menu';
|
|||
export { UptimeProvider } from './uptime';
|
||||
export { InfraSourceConfigurationFlyoutProvider } from './infra_source_configuration_flyout';
|
||||
export { InfraLogStreamProvider } from './infra_log_stream';
|
||||
export { MachineLearningProvider } from './machine_learning';
|
||||
|
|
91
x-pack/test/functional/services/machine_learning.ts
Normal file
91
x-pack/test/functional/services/machine_learning.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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';
|
||||
|
||||
export function MachineLearningProvider({
|
||||
getService,
|
||||
getPageObjects,
|
||||
}: KibanaFunctionalTestDefaultProviders) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['common']);
|
||||
|
||||
return {
|
||||
async navigateTo() {
|
||||
return await PageObjects.common.navigateToApp('ml');
|
||||
},
|
||||
|
||||
async navigateToJobManagement() {
|
||||
await testSubjects.click('mlTabJobManagement');
|
||||
await testSubjects.exists('mlPageJobManagement');
|
||||
},
|
||||
|
||||
async navigateToAnomalyExplorert() {
|
||||
await testSubjects.click('mlTabAnomalyExplorer');
|
||||
await testSubjects.exists('mlPageAnomalyExplorer');
|
||||
},
|
||||
|
||||
async navigateToSingleMetricViewer() {
|
||||
await testSubjects.click('mlTabSingleMetricViewer');
|
||||
await testSubjects.exists('mlPageSingleMetricViewer');
|
||||
},
|
||||
|
||||
async navigateToDataFrames() {
|
||||
await testSubjects.click('mlTabDataFrames');
|
||||
await testSubjects.exists('mlPageDataFrame');
|
||||
},
|
||||
|
||||
async navigateToDataVisualizer() {
|
||||
await testSubjects.click('mlTabDataVisualizer');
|
||||
await testSubjects.exists('mlPageDataVisualizerSelector');
|
||||
},
|
||||
|
||||
async navigateToSettings() {
|
||||
await testSubjects.click('mlTabSettings');
|
||||
await testSubjects.exists('mlPageSettings');
|
||||
},
|
||||
|
||||
async assertJobTableExists() {
|
||||
await testSubjects.existOrFail('mlJobListTable');
|
||||
},
|
||||
|
||||
async assertCreateNewJobButtonExists() {
|
||||
await testSubjects.existOrFail('mlCreateNewJobButton');
|
||||
},
|
||||
|
||||
async assertJobStatsBarExists() {
|
||||
await testSubjects.existOrFail('mlJobStatsBar');
|
||||
},
|
||||
|
||||
async assertAnomalyExplorerEmptyListMessageExists() {
|
||||
await testSubjects.existOrFail('mlNoJobsFound');
|
||||
},
|
||||
|
||||
async assertSingleMetricViewerEmptyListMessageExsist() {
|
||||
await testSubjects.existOrFail('mlNoSingleMetricJobsFound');
|
||||
},
|
||||
|
||||
async assertDataFrameEmptyListMessageExists() {
|
||||
await testSubjects.existOrFail('mlNoDataFrameJobsFound');
|
||||
},
|
||||
|
||||
async assertDataVisualizerImportDataCardExists() {
|
||||
await testSubjects.existOrFail('mlDataVisualizerCardImportData');
|
||||
},
|
||||
|
||||
async assertDataVisualizerIndexDataCardExists() {
|
||||
await testSubjects.existOrFail('mlDataVisualizerCardIndexData');
|
||||
},
|
||||
|
||||
async assertSettingsCalendarLinkExists() {
|
||||
await testSubjects.existOrFail('ml_calendar_mng_button');
|
||||
},
|
||||
|
||||
async assertSettingsFilterlistLinkExists() {
|
||||
await testSubjects.existOrFail('ml_filter_lists_button');
|
||||
},
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue