mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] Anomaly detection wizards: adds functional test for geo wizard (#150942)
## Summary Adds functional tests for the geo wizard in anomaly detection [Flaky test runner build](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1913) ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Robert Oskamp <traeluki@gmail.com>
This commit is contained in:
parent
a608af6425
commit
1fb3ef499f
7 changed files with 424 additions and 5 deletions
|
@ -62,7 +62,7 @@ export const SplitFieldSelector: FC = () => {
|
||||||
changeHandler={setSplitField}
|
changeHandler={setSplitField}
|
||||||
selectedField={splitField}
|
selectedField={splitField}
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
testSubject="mlMultiMetricSplitFieldSelect"
|
testSubject="mlSplitFieldSelect"
|
||||||
/>
|
/>
|
||||||
</Description>
|
</Description>
|
||||||
);
|
);
|
||||||
|
|
354
x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts
Normal file
354
x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||||
|
|
||||||
|
export default function ({ getService }: FtrProviderContext) {
|
||||||
|
const esArchiver = getService('esArchiver');
|
||||||
|
const ml = getService('ml');
|
||||||
|
|
||||||
|
const jobId = `ec_geo_1_${Date.now()}`;
|
||||||
|
const jobIdClone = `${jobId}_clone`;
|
||||||
|
const jobDescription = 'Create geo job based on the ecommerce sample dataset with 15m bucketspan';
|
||||||
|
const jobGroups = ['automated', 'ecommerce', 'geo'];
|
||||||
|
const jobGroupsClone = [...jobGroups, 'clone'];
|
||||||
|
const geoField = 'geoip.location';
|
||||||
|
const splitField = 'customer_gender';
|
||||||
|
const detectors = [
|
||||||
|
{
|
||||||
|
identifier: 'Lat long(geoip.location)',
|
||||||
|
frontCardTitle: "Men's Clothing",
|
||||||
|
function: 'lat_long',
|
||||||
|
field_name: geoField,
|
||||||
|
numberOfBackCards: 5,
|
||||||
|
splitField,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const bucketSpan = '15m';
|
||||||
|
const memoryLimit = '8mb';
|
||||||
|
|
||||||
|
function getExpectedRow(expectedJobId: string, expectedJobGroups: string[]) {
|
||||||
|
return {
|
||||||
|
id: expectedJobId,
|
||||||
|
description: jobDescription,
|
||||||
|
jobGroups: [...new Set(expectedJobGroups)].sort(),
|
||||||
|
recordCount: '4,675',
|
||||||
|
memoryStatus: 'ok',
|
||||||
|
jobState: 'closed',
|
||||||
|
datafeedState: 'stopped',
|
||||||
|
latestTimestamp: '2019-07-12 23:45:36',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpectedCounts(expectedJobId: string) {
|
||||||
|
return {
|
||||||
|
job_id: expectedJobId,
|
||||||
|
processed_record_count: '4,675',
|
||||||
|
processed_field_count: '9,350',
|
||||||
|
input_bytes: '504.1 KB',
|
||||||
|
input_field_count: '9,350',
|
||||||
|
invalid_date_count: '0',
|
||||||
|
missing_field_count: '0',
|
||||||
|
out_of_order_timestamp_count: '0',
|
||||||
|
empty_bucket_count: '492',
|
||||||
|
sparse_bucket_count: '0',
|
||||||
|
bucket_count: '2,975',
|
||||||
|
earliest_record_timestamp: '2019-06-12 00:04:19',
|
||||||
|
latest_record_timestamp: '2019-07-12 23:45:36',
|
||||||
|
input_record_count: '4,675',
|
||||||
|
latest_bucket_timestamp: '2019-07-12 23:45:00',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpectedModelSizeStats(expectedJobId: string) {
|
||||||
|
return {
|
||||||
|
job_id: expectedJobId,
|
||||||
|
result_type: 'model_size_stats',
|
||||||
|
model_bytes_exceeded: '0.0 B',
|
||||||
|
total_by_field_count: '4',
|
||||||
|
total_over_field_count: '0',
|
||||||
|
total_partition_field_count: '3',
|
||||||
|
bucket_allocation_failures_count: '0',
|
||||||
|
memory_status: 'ok',
|
||||||
|
timestamp: '2019-07-12 23:30:00',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const calendarId = `wizard-test-calendar_${Date.now()}`;
|
||||||
|
|
||||||
|
describe('geo', function () {
|
||||||
|
this.tags(['ml']);
|
||||||
|
before(async () => {
|
||||||
|
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce');
|
||||||
|
await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
|
||||||
|
await ml.testResources.setKibanaTimeZoneToUTC();
|
||||||
|
|
||||||
|
await ml.api.createCalendar(calendarId);
|
||||||
|
await ml.securityUI.loginAsMlPowerUser();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await ml.api.cleanMlIndices();
|
||||||
|
await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job creation loads the geo wizard for the source data', async () => {
|
||||||
|
await ml.testExecution.logTestStep('job creation loads the job management page');
|
||||||
|
await ml.navigation.navigateToMl();
|
||||||
|
await ml.navigation.navigateToJobManagement();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation loads the new job source selection page');
|
||||||
|
await ml.jobManagement.navigateToNewJobSourceSelection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation loads the job type selection page');
|
||||||
|
await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('ft_ecommerce');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation loads the geo job wizard page');
|
||||||
|
await ml.jobTypeSelection.selectGeoJob();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job creation navigates through the geo wizard and sets all needed fields', async () => {
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the time range step');
|
||||||
|
await ml.jobWizardCommon.assertTimeRangeSectionExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation sets the time range');
|
||||||
|
await ml.jobWizardCommon.clickUseFullDataButton(
|
||||||
|
'Jun 12, 2019 @ 00:04:19.000',
|
||||||
|
'Jul 12, 2019 @ 23:45:36.000'
|
||||||
|
);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the event rate chart');
|
||||||
|
await ml.jobWizardCommon.assertEventRateChartExists();
|
||||||
|
await ml.jobWizardCommon.assertEventRateChartHasData();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the pick fields step');
|
||||||
|
await ml.jobWizardCommon.advanceToPickFieldsSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation selects the geo field');
|
||||||
|
await ml.jobWizardGeo.assertGeoFieldInputExists();
|
||||||
|
await ml.jobWizardGeo.selectGeoField(geoField);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays detector preview');
|
||||||
|
|
||||||
|
await ml.jobWizardGeo.assertDetectorPreviewExists(detectors[0].identifier);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'job creation inputs the split field and displays split cards'
|
||||||
|
);
|
||||||
|
|
||||||
|
await ml.jobWizardMultiMetric.assertSplitFieldInputExists();
|
||||||
|
await ml.jobWizardMultiMetric.selectSplitField(splitField);
|
||||||
|
|
||||||
|
await ml.jobWizardMultiMetric.assertDetectorSplitExists(splitField);
|
||||||
|
await ml.jobWizardMultiMetric.assertDetectorSplitFrontCardTitle('FEMALE');
|
||||||
|
await ml.jobWizardMultiMetric.assertDetectorSplitNumberOfBackCards(1);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the influencer field');
|
||||||
|
await ml.jobWizardCommon.assertInfluencerInputExists();
|
||||||
|
await ml.jobWizardCommon.assertInfluencerSelection([splitField]);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation inputs the bucket span');
|
||||||
|
await ml.jobWizardCommon.assertBucketSpanInputExists();
|
||||||
|
await ml.jobWizardCommon.setBucketSpan(bucketSpan);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the job details step');
|
||||||
|
await ml.jobWizardCommon.advanceToJobDetailsSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation inputs the job id');
|
||||||
|
await ml.jobWizardCommon.assertJobIdInputExists();
|
||||||
|
await ml.jobWizardCommon.setJobId(jobId);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation inputs the job description');
|
||||||
|
await ml.jobWizardCommon.assertJobDescriptionInputExists();
|
||||||
|
await ml.jobWizardCommon.setJobDescription(jobDescription);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation inputs job groups');
|
||||||
|
await ml.jobWizardCommon.assertJobGroupInputExists();
|
||||||
|
for (const jobGroup of jobGroups) {
|
||||||
|
await ml.jobWizardCommon.addJobGroup(jobGroup);
|
||||||
|
}
|
||||||
|
await ml.jobWizardCommon.assertJobGroupSelection(jobGroups);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation opens the additional settings section');
|
||||||
|
await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation adds a new custom url');
|
||||||
|
await ml.jobWizardCommon.addCustomUrl({ label: 'check-kibana-dashboard' });
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation assigns calendars');
|
||||||
|
await ml.jobWizardCommon.addCalendar(calendarId);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation opens the advanced section');
|
||||||
|
await ml.jobWizardCommon.ensureAdvancedSectionOpen();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the model plot switch');
|
||||||
|
await ml.jobWizardCommon.assertModelPlotSwitchExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation enables the dedicated index switch');
|
||||||
|
await ml.jobWizardCommon.assertDedicatedIndexSwitchExists();
|
||||||
|
await ml.jobWizardCommon.activateDedicatedIndexSwitch();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation inputs the model memory limit');
|
||||||
|
await ml.jobWizardCommon.assertModelMemoryLimitInputExists();
|
||||||
|
await ml.jobWizardCommon.setModelMemoryLimit(memoryLimit);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the validation step');
|
||||||
|
await ml.jobWizardCommon.advanceToValidationSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the summary step');
|
||||||
|
await ml.jobWizardCommon.advanceToSummarySection();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job creation runs the job and displays it correctly in the job list', async () => {
|
||||||
|
await ml.testExecution.logTestStep('job creation creates the job and finishes processing');
|
||||||
|
await ml.jobWizardCommon.assertCreateJobButtonExists();
|
||||||
|
await ml.jobWizardCommon.createJobAndWaitForCompletion();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation displays the created job in the job list');
|
||||||
|
await ml.navigation.navigateToMl();
|
||||||
|
await ml.navigation.navigateToJobManagement();
|
||||||
|
|
||||||
|
await ml.jobTable.filterWithSearchString(jobId, 1);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'job creation displays details for the created job in the job list'
|
||||||
|
);
|
||||||
|
await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups));
|
||||||
|
|
||||||
|
await ml.jobTable.assertJobRowDetailsCounts(
|
||||||
|
jobId,
|
||||||
|
getExpectedCounts(jobId),
|
||||||
|
getExpectedModelSizeStats(jobId)
|
||||||
|
);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job creation has detector results');
|
||||||
|
for (let i = 0; i < detectors.length; i++) {
|
||||||
|
await ml.api.assertDetectorResultsExist(jobId, i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job cloning opens the existing job in the geo wizard', async () => {
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'job cloning clicks the clone action and loads the geo wizard'
|
||||||
|
);
|
||||||
|
await ml.jobTable.clickCloneJobAction(jobId);
|
||||||
|
await ml.jobTypeSelection.assertGeoJobWizardOpen();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job cloning navigates through the geo wizard, checks and sets all needed fields', async () => {
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the time range step');
|
||||||
|
await ml.jobWizardCommon.assertTimeRangeSectionExists();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning sets the time range');
|
||||||
|
await ml.jobWizardCommon.clickUseFullDataButton(
|
||||||
|
'Jun 12, 2019 @ 00:04:19.000',
|
||||||
|
'Jul 12, 2019 @ 23:45:36.000'
|
||||||
|
);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the event rate chart');
|
||||||
|
await ml.jobWizardCommon.assertEventRateChartExists();
|
||||||
|
await ml.jobWizardCommon.assertEventRateChartHasData();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the pick fields step');
|
||||||
|
await ml.jobWizardCommon.advanceToPickFieldsSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills the geo field');
|
||||||
|
await ml.jobWizardGeo.assertGeoFieldInputExists();
|
||||||
|
await ml.jobWizardGeo.assertGeoFieldSelection([geoField]);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'job cloning displays the detector preview with pre-filled geo field'
|
||||||
|
);
|
||||||
|
await ml.jobWizardGeo.assertDetectorPreviewExists(detectors[0].identifier);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills influencers');
|
||||||
|
await ml.jobWizardCommon.assertInfluencerInputExists();
|
||||||
|
await ml.jobWizardCommon.assertInfluencerSelection([splitField]);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills the bucket span');
|
||||||
|
await ml.jobWizardCommon.assertBucketSpanInputExists();
|
||||||
|
await ml.jobWizardCommon.assertBucketSpanValue(bucketSpan);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the job details step');
|
||||||
|
await ml.jobWizardCommon.advanceToJobDetailsSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning does not pre-fill the job id');
|
||||||
|
await ml.jobWizardCommon.assertJobIdInputExists();
|
||||||
|
await ml.jobWizardCommon.assertJobIdValue('');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning inputs the clone job id');
|
||||||
|
await ml.jobWizardCommon.setJobId(jobIdClone);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills the job description');
|
||||||
|
await ml.jobWizardCommon.assertJobDescriptionInputExists();
|
||||||
|
await ml.jobWizardCommon.assertJobDescriptionValue(jobDescription);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills job groups');
|
||||||
|
await ml.jobWizardCommon.assertJobGroupInputExists();
|
||||||
|
await ml.jobWizardCommon.assertJobGroupSelection(jobGroups);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning inputs the clone job group');
|
||||||
|
await ml.jobWizardCommon.assertJobGroupInputExists();
|
||||||
|
await ml.jobWizardCommon.addJobGroup('clone');
|
||||||
|
await ml.jobWizardCommon.assertJobGroupSelection(jobGroupsClone);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning opens the additional settings section');
|
||||||
|
await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning persists custom urls');
|
||||||
|
await ml.customUrls.assertCustomUrlLabel(0, 'check-kibana-dashboard');
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning persists assigned calendars');
|
||||||
|
await ml.jobWizardCommon.assertCalendarsSelection([calendarId]);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning opens the advanced section');
|
||||||
|
await ml.jobWizardCommon.ensureAdvancedSectionOpen();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills the model plot switch');
|
||||||
|
await ml.jobWizardCommon.assertModelPlotSwitchExists();
|
||||||
|
await ml.jobWizardCommon.assertModelPlotSwitchCheckedState(false);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning pre-fills the dedicated index switch');
|
||||||
|
await ml.jobWizardCommon.assertDedicatedIndexSwitchExists();
|
||||||
|
await ml.jobWizardCommon.assertDedicatedIndexSwitchCheckedState(true);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the validation step');
|
||||||
|
await ml.jobWizardCommon.advanceToValidationSection();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the summary step');
|
||||||
|
await ml.jobWizardCommon.advanceToSummarySection();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('job cloning runs the clone job and displays it correctly in the job list', async () => {
|
||||||
|
await ml.testExecution.logTestStep('job cloning creates the job and finishes processing');
|
||||||
|
await ml.jobWizardCommon.assertCreateJobButtonExists();
|
||||||
|
await ml.jobWizardCommon.createJobAndWaitForCompletion();
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning displays the created job in the job list');
|
||||||
|
await ml.navigation.navigateToMl();
|
||||||
|
await ml.navigation.navigateToJobManagement();
|
||||||
|
|
||||||
|
await ml.jobTable.filterWithSearchString(jobIdClone, 1);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep(
|
||||||
|
'job cloning displays details for the created job in the job list'
|
||||||
|
);
|
||||||
|
await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone));
|
||||||
|
|
||||||
|
await ml.jobTable.assertJobRowDetailsCounts(
|
||||||
|
jobIdClone,
|
||||||
|
getExpectedCounts(jobIdClone),
|
||||||
|
getExpectedModelSizeStats(jobIdClone)
|
||||||
|
);
|
||||||
|
|
||||||
|
await ml.testExecution.logTestStep('job cloning has detector results');
|
||||||
|
for (let i = 0; i < detectors.length; i++) {
|
||||||
|
await ml.api.assertDetectorResultsExist(jobId, i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
||||||
loadTestFile(require.resolve('./single_metric_job_without_datafeed_start'));
|
loadTestFile(require.resolve('./single_metric_job_without_datafeed_start'));
|
||||||
loadTestFile(require.resolve('./multi_metric_job'));
|
loadTestFile(require.resolve('./multi_metric_job'));
|
||||||
loadTestFile(require.resolve('./population_job'));
|
loadTestFile(require.resolve('./population_job'));
|
||||||
|
loadTestFile(require.resolve('./geo_job'));
|
||||||
loadTestFile(require.resolve('./saved_search_job'));
|
loadTestFile(require.resolve('./saved_search_job'));
|
||||||
loadTestFile(require.resolve('./advanced_job'));
|
loadTestFile(require.resolve('./advanced_job'));
|
||||||
loadTestFile(require.resolve('./categorization_job'));
|
loadTestFile(require.resolve('./categorization_job'));
|
||||||
|
|
|
@ -36,6 +36,7 @@ import { MachineLearningJobWizardCommonProvider } from './job_wizard_common';
|
||||||
import { MachineLearningJobWizardCategorizationProvider } from './job_wizard_categorization';
|
import { MachineLearningJobWizardCategorizationProvider } from './job_wizard_categorization';
|
||||||
import { MachineLearningJobWizardMultiMetricProvider } from './job_wizard_multi_metric';
|
import { MachineLearningJobWizardMultiMetricProvider } from './job_wizard_multi_metric';
|
||||||
import { MachineLearningJobWizardPopulationProvider } from './job_wizard_population';
|
import { MachineLearningJobWizardPopulationProvider } from './job_wizard_population';
|
||||||
|
import { MachineLearningJobWizardGeoProvider } from './job_wizard_geo';
|
||||||
import { MachineLearningLensVisualizationsProvider } from './lens_visualizations';
|
import { MachineLearningLensVisualizationsProvider } from './lens_visualizations';
|
||||||
import { MachineLearningNavigationProvider } from './navigation';
|
import { MachineLearningNavigationProvider } from './navigation';
|
||||||
import { MachineLearningOverviewPageProvider } from './overview_page';
|
import { MachineLearningOverviewPageProvider } from './overview_page';
|
||||||
|
@ -115,6 +116,7 @@ export function MachineLearningProvider(context: FtrProviderContext) {
|
||||||
const jobWizardCommon = MachineLearningJobWizardCommonProvider(context, commonUI, customUrls);
|
const jobWizardCommon = MachineLearningJobWizardCommonProvider(context, commonUI, customUrls);
|
||||||
const jobWizardMultiMetric = MachineLearningJobWizardMultiMetricProvider(context);
|
const jobWizardMultiMetric = MachineLearningJobWizardMultiMetricProvider(context);
|
||||||
const jobWizardPopulation = MachineLearningJobWizardPopulationProvider(context);
|
const jobWizardPopulation = MachineLearningJobWizardPopulationProvider(context);
|
||||||
|
const jobWizardGeo = MachineLearningJobWizardGeoProvider(context);
|
||||||
const lensVisualizations = MachineLearningLensVisualizationsProvider(context, commonUI);
|
const lensVisualizations = MachineLearningLensVisualizationsProvider(context, commonUI);
|
||||||
const navigation = MachineLearningNavigationProvider(context);
|
const navigation = MachineLearningNavigationProvider(context);
|
||||||
const overviewPage = MachineLearningOverviewPageProvider(context);
|
const overviewPage = MachineLearningOverviewPageProvider(context);
|
||||||
|
@ -174,6 +176,7 @@ export function MachineLearningProvider(context: FtrProviderContext) {
|
||||||
jobWizardCommon,
|
jobWizardCommon,
|
||||||
jobWizardMultiMetric,
|
jobWizardMultiMetric,
|
||||||
jobWizardPopulation,
|
jobWizardPopulation,
|
||||||
|
jobWizardGeo,
|
||||||
lensVisualizations,
|
lensVisualizations,
|
||||||
mlNodesPanel,
|
mlNodesPanel,
|
||||||
navigation,
|
navigation,
|
||||||
|
|
|
@ -34,10 +34,19 @@ export function MachineLearningJobTypeSelectionProvider({ getService }: FtrProvi
|
||||||
await this.assertPopulationJobWizardOpen();
|
await this.assertPopulationJobWizardOpen();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async selectGeoJob() {
|
||||||
|
await testSubjects.clickWhenNotDisabledWithoutRetry('mlJobTypeLinkGeoJob');
|
||||||
|
await this.assertGeoJobWizardOpen();
|
||||||
|
},
|
||||||
|
|
||||||
async assertPopulationJobWizardOpen() {
|
async assertPopulationJobWizardOpen() {
|
||||||
await testSubjects.existOrFail('mlPageJobWizard population');
|
await testSubjects.existOrFail('mlPageJobWizard population');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async assertGeoJobWizardOpen() {
|
||||||
|
await testSubjects.existOrFail('mlPageJobWizard geo');
|
||||||
|
},
|
||||||
|
|
||||||
async selectAdvancedJob() {
|
async selectAdvancedJob() {
|
||||||
await testSubjects.clickWhenNotDisabledWithoutRetry('mlJobTypeLinkAdvancedJob');
|
await testSubjects.clickWhenNotDisabledWithoutRetry('mlJobTypeLinkAdvancedJob');
|
||||||
await this.assertAdvancedJobWizardOpen();
|
await this.assertAdvancedJobWizardOpen();
|
||||||
|
|
52
x-pack/test/functional/services/ml/job_wizard_geo.ts
Normal file
52
x-pack/test/functional/services/ml/job_wizard_geo.ts
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import expect from '@kbn/expect';
|
||||||
|
|
||||||
|
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||||
|
|
||||||
|
export function MachineLearningJobWizardGeoProvider({ getService }: FtrProviderContext) {
|
||||||
|
const comboBox = getService('comboBox');
|
||||||
|
const testSubjects = getService('testSubjects');
|
||||||
|
|
||||||
|
return {
|
||||||
|
async assertGeoFieldInputExists() {
|
||||||
|
await testSubjects.existOrFail('mlGeoFieldNameSelect > comboBoxInput');
|
||||||
|
},
|
||||||
|
|
||||||
|
async assertGeoFieldSelection(expectedIdentifier: string[]) {
|
||||||
|
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||||
|
'mlGeoFieldNameSelect > comboBoxInput'
|
||||||
|
);
|
||||||
|
expect(comboBoxSelectedOptions).to.eql(
|
||||||
|
expectedIdentifier,
|
||||||
|
`Expected geo field selection to be '${expectedIdentifier}' (got '${comboBoxSelectedOptions}')`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async selectGeoField(identifier: string) {
|
||||||
|
await comboBox.set('mlGeoFieldNameSelect > comboBoxInput', identifier);
|
||||||
|
await this.assertGeoFieldSelection([identifier]);
|
||||||
|
},
|
||||||
|
|
||||||
|
async assertSplitCardWithMapExampleExists() {
|
||||||
|
await testSubjects.existOrFail('mlGeoJobWizardMap');
|
||||||
|
},
|
||||||
|
|
||||||
|
async assertDetectorPreviewExists(detectorDescription: string) {
|
||||||
|
await testSubjects.existOrFail('mlGeoMap > mlDetectorTitle');
|
||||||
|
const actualDetectorTitle = await testSubjects.getVisibleText('mlGeoMap > mlDetectorTitle');
|
||||||
|
expect(actualDetectorTitle).to.eql(
|
||||||
|
detectorDescription,
|
||||||
|
`Expected detector title to be '${detectorDescription}' (got '${actualDetectorTitle}')`
|
||||||
|
);
|
||||||
|
|
||||||
|
await testSubjects.existOrFail('mlGeoJobWizardMap');
|
||||||
|
await testSubjects.existOrFail('mlEmbeddedMapContent');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -15,12 +15,12 @@ export function MachineLearningJobWizardMultiMetricProvider({ getService }: FtrP
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async assertSplitFieldInputExists() {
|
async assertSplitFieldInputExists() {
|
||||||
await testSubjects.existOrFail('mlMultiMetricSplitFieldSelect > comboBoxInput');
|
await testSubjects.existOrFail('mlSplitFieldSelect > comboBoxInput');
|
||||||
},
|
},
|
||||||
|
|
||||||
async assertSplitFieldSelection(expectedIdentifier: string[]) {
|
async assertSplitFieldSelection(expectedIdentifier: string[]) {
|
||||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||||
'mlMultiMetricSplitFieldSelect > comboBoxInput'
|
'mlSplitFieldSelect > comboBoxInput'
|
||||||
);
|
);
|
||||||
expect(comboBoxSelectedOptions).to.eql(
|
expect(comboBoxSelectedOptions).to.eql(
|
||||||
expectedIdentifier,
|
expectedIdentifier,
|
||||||
|
@ -29,12 +29,12 @@ export function MachineLearningJobWizardMultiMetricProvider({ getService }: FtrP
|
||||||
},
|
},
|
||||||
|
|
||||||
async selectSplitField(identifier: string) {
|
async selectSplitField(identifier: string) {
|
||||||
await comboBox.set('mlMultiMetricSplitFieldSelect > comboBoxInput', identifier);
|
await comboBox.set('mlSplitFieldSelect > comboBoxInput', identifier);
|
||||||
await this.assertSplitFieldSelection([identifier]);
|
await this.assertSplitFieldSelection([identifier]);
|
||||||
},
|
},
|
||||||
|
|
||||||
async scrollSplitFieldIntoView() {
|
async scrollSplitFieldIntoView() {
|
||||||
await testSubjects.scrollIntoView('mlMultiMetricSplitFieldSelect');
|
await testSubjects.scrollIntoView('mlSplitFieldSelect');
|
||||||
},
|
},
|
||||||
|
|
||||||
async assertDetectorSplitExists(splitField: string) {
|
async assertDetectorSplitExists(splitField: string) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue