mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
This PR adds functional UI tests to create a machine learning job using the population wizard.
This commit is contained in:
parent
d2321ac427
commit
6a091380b1
17 changed files with 1630 additions and 47 deletions
|
@ -35,6 +35,7 @@ export const InfluencersSelect: FC<Props> = ({ fields, changeHandler, selectedIn
|
|||
selectedOptions={selection}
|
||||
onChange={onChange}
|
||||
isClearable={false}
|
||||
data-test-subj="influencerSelect"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -34,10 +34,10 @@ export const MultiMetricSettings: FC<Props> = ({ setIsValid }) => {
|
|||
return (
|
||||
<Fragment>
|
||||
<EuiFlexGroup gutterSize="xl">
|
||||
<EuiFlexItem data-test-subj="mlJobWizardSplitFieldSelection">
|
||||
<EuiFlexItem>
|
||||
<SplitFieldSelector />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem data-test-subj="mlJobWizardInfluencerSelection">
|
||||
<EuiFlexItem>
|
||||
<Influencers />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -49,7 +49,7 @@ export const ChartGrid: FC<ChartGridProps> = ({
|
|||
return (
|
||||
<EuiFlexGrid columns={chartSettings.cols}>
|
||||
{aggFieldPairList.map((af, i) => (
|
||||
<EuiFlexItem key={i}>
|
||||
<EuiFlexItem key={i} data-test-subj={`detector ${i}`}>
|
||||
<Fragment>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
|
|
|
@ -58,6 +58,7 @@ export const ByFieldSelector: FC<Props> = ({ detectorIndex }) => {
|
|||
changeHandler={setByField}
|
||||
selectedField={byField}
|
||||
isClearable={true}
|
||||
testSubject="byFieldSelect"
|
||||
placeholder={i18n.translate(
|
||||
'xpack.ml.newJob.wizard.pickFieldsStep.populationField.placeholder',
|
||||
{
|
||||
|
|
|
@ -48,6 +48,13 @@ export const SplitFieldSelector: FC = () => {
|
|||
changeHandler={setSplitField}
|
||||
selectedField={splitField}
|
||||
isClearable={canClearSelection}
|
||||
testSubject={
|
||||
isMultiMetricJobCreator(jc)
|
||||
? 'multiMetricSplitFieldSelect'
|
||||
: isPopulationJobCreator(jc)
|
||||
? 'populationSplitFieldSelect'
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</Description>
|
||||
);
|
||||
|
|
|
@ -19,6 +19,7 @@ interface Props {
|
|||
changeHandler(f: SplitField): void;
|
||||
selectedField: SplitField;
|
||||
isClearable: boolean;
|
||||
testSubject?: string;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
|
@ -27,6 +28,7 @@ export const SplitFieldSelect: FC<Props> = ({
|
|||
changeHandler,
|
||||
selectedField,
|
||||
isClearable,
|
||||
testSubject,
|
||||
placeholder,
|
||||
}) => {
|
||||
const options: EuiComboBoxOptionProps[] = fields.map(
|
||||
|
@ -59,6 +61,7 @@ export const SplitFieldSelect: FC<Props> = ({
|
|||
onChange={onChange}
|
||||
isClearable={isClearable}
|
||||
placeholder={placeholder}
|
||||
data-test-subj={testSubject}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -46,7 +46,7 @@ export default function({ getService }: FtrProviderContext) {
|
|||
await ml.jobSourceSelection.selectSourceIndexPattern('farequote');
|
||||
});
|
||||
|
||||
it('loads the single metric job wizard page', async () => {
|
||||
it('loads the multi metric job wizard page', async () => {
|
||||
await ml.jobTypeSelection.selectMultiMetricJob();
|
||||
});
|
||||
|
||||
|
@ -73,13 +73,13 @@ export default function({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('inputs the split field and displays split cards', async () => {
|
||||
await ml.jobWizardCommon.assertMultiMetricSplitFieldInputExists();
|
||||
await ml.jobWizardCommon.selectMultiMetricSplitField(splitField);
|
||||
await ml.jobWizardCommon.assertMultiMetricSplitFieldSelection(splitField);
|
||||
await ml.jobWizardMultiMetric.assertSplitFieldInputExists();
|
||||
await ml.jobWizardMultiMetric.selectSplitField(splitField);
|
||||
await ml.jobWizardMultiMetric.assertSplitFieldSelection(splitField);
|
||||
|
||||
await ml.jobWizardCommon.assertDetectorSplitExists(splitField);
|
||||
await ml.jobWizardCommon.assertDetectorSplitFrontCardTitle('AAL');
|
||||
await ml.jobWizardCommon.assertDetectorSplitNumberOfBackCards(9);
|
||||
await ml.jobWizardMultiMetric.assertDetectorSplitExists(splitField);
|
||||
await ml.jobWizardMultiMetric.assertDetectorSplitFrontCardTitle('AAL');
|
||||
await ml.jobWizardMultiMetric.assertDetectorSplitNumberOfBackCards(9);
|
||||
|
||||
await ml.jobWizardCommon.assertInfluencerSelection([splitField]);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const ml = getService('ml');
|
||||
const log = getService('log');
|
||||
|
||||
const jobId = `ec_population_1_${Date.now()}`;
|
||||
const jobDescription =
|
||||
'Create population job based on the ecommerce sample dataset with 2h bucketspan over customer_id' +
|
||||
' - detectors: (Mean(products.base_price) by customer_gender), (Mean(products.quantity) by category.leyword)';
|
||||
const jobGroups = ['automated', 'ecommerce', 'population'];
|
||||
const populationField = 'customer_id';
|
||||
const detectors = [
|
||||
{
|
||||
identifier: 'Mean(products.base_price)',
|
||||
splitField: 'customer_gender',
|
||||
frontCardTitle: 'FEMALE',
|
||||
numberOfBackCards: 1,
|
||||
},
|
||||
{
|
||||
identifier: 'Mean(products.quantity)',
|
||||
splitField: 'category.keyword',
|
||||
frontCardTitle: "Men's Clothing",
|
||||
numberOfBackCards: 5,
|
||||
},
|
||||
];
|
||||
const bucketSpan = '2h';
|
||||
const memoryLimit = '8MB';
|
||||
|
||||
describe('population job creation', function() {
|
||||
this.tags(['smoke', 'mlqa']);
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('ml/ecommerce');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('ml/farequote');
|
||||
await ml.api.cleanMlIndices();
|
||||
await ml.api.cleanDataframeIndices();
|
||||
});
|
||||
|
||||
it('loads the job management page', async () => {
|
||||
await ml.navigation.navigateToMl();
|
||||
await ml.navigation.navigateToJobManagement();
|
||||
});
|
||||
|
||||
it('loads the new job source selection page', async () => {
|
||||
await ml.jobManagement.navigateToNewJobSourceSelection();
|
||||
});
|
||||
|
||||
it('loads the job type selection page', async () => {
|
||||
await ml.jobSourceSelection.selectSourceIndexPattern('ecommerce');
|
||||
});
|
||||
|
||||
it('loads the population job wizard page', async () => {
|
||||
await ml.jobTypeSelection.selectPopulationJob();
|
||||
});
|
||||
|
||||
it('displays the time range step', async () => {
|
||||
await ml.jobWizardCommon.assertTimeRangeSectionExists();
|
||||
});
|
||||
|
||||
it('displays the event rate chart', async () => {
|
||||
await ml.jobWizardCommon.clickUseFullDataButton();
|
||||
await ml.jobWizardCommon.assertEventRateChartExists();
|
||||
});
|
||||
|
||||
it('displays the pick fields step', async () => {
|
||||
await ml.jobWizardCommon.clickNextButton();
|
||||
await ml.jobWizardCommon.assertPickFieldsSectionExists();
|
||||
});
|
||||
|
||||
it('selects the population field', async () => {
|
||||
await ml.jobWizardPopulation.assertPopulationFieldInputExists();
|
||||
await ml.jobWizardPopulation.selectPopulationField(populationField);
|
||||
await ml.jobWizardPopulation.assertPopulationFieldSelection(populationField);
|
||||
});
|
||||
|
||||
it('selects detectors and displays detector previews', async () => {
|
||||
for (const [index, detector] of detectors.entries()) {
|
||||
await ml.jobWizardCommon.assertAggAndFieldInputExists();
|
||||
await ml.jobWizardCommon.selectAggAndField(detector.identifier);
|
||||
await ml.jobWizardCommon.assertDetectorPreviewExists(detector.identifier, index, 'SCATTER');
|
||||
}
|
||||
});
|
||||
|
||||
it('inputs detector split fields and displays split cards', async () => {
|
||||
for (const [index, detector] of detectors.entries()) {
|
||||
log.debug(detector);
|
||||
await ml.jobWizardPopulation.assertDetectorSplitFieldInputExists(index);
|
||||
await ml.jobWizardPopulation.selectDetectorSplitField(index, detector.splitField);
|
||||
await ml.jobWizardPopulation.assertDetectorSplitFieldSelection(index, detector.splitField);
|
||||
|
||||
await ml.jobWizardPopulation.assertDetectorSplitExists(index);
|
||||
await ml.jobWizardPopulation.assertDetectorSplitFrontCardTitle(
|
||||
index,
|
||||
detector.frontCardTitle
|
||||
);
|
||||
await ml.jobWizardPopulation.assertDetectorSplitNumberOfBackCards(
|
||||
index,
|
||||
detector.numberOfBackCards
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('displays the influencer field', async () => {
|
||||
await ml.jobWizardCommon.assertInfluencerInputExists();
|
||||
await ml.jobWizardCommon.assertInfluencerSelection(
|
||||
[populationField].concat(detectors.map(detector => detector.splitField))
|
||||
);
|
||||
});
|
||||
|
||||
it('inputs the bucket span', async () => {
|
||||
await ml.jobWizardCommon.assertBucketSpanInputExists();
|
||||
await ml.jobWizardCommon.setBucketSpan(bucketSpan);
|
||||
await ml.jobWizardCommon.assertBucketSpanValue(bucketSpan);
|
||||
});
|
||||
|
||||
it('displays the job details step', async () => {
|
||||
await ml.jobWizardCommon.clickNextButton();
|
||||
await ml.jobWizardCommon.assertJobDetailsSectionExists();
|
||||
});
|
||||
|
||||
it('inputs the job id', async () => {
|
||||
await ml.jobWizardCommon.assertJobIdInputExists();
|
||||
await ml.jobWizardCommon.setJobId(jobId);
|
||||
await ml.jobWizardCommon.assertJobIdValue(jobId);
|
||||
});
|
||||
|
||||
it('inputs the job description', async () => {
|
||||
await ml.jobWizardCommon.assertJobDescriptionInputExists();
|
||||
await ml.jobWizardCommon.setJobDescription(jobDescription);
|
||||
await ml.jobWizardCommon.assertJobDescriptionValue(jobDescription);
|
||||
});
|
||||
|
||||
it('inputs job groups', async () => {
|
||||
await ml.jobWizardCommon.assertJobGroupInputExists();
|
||||
for (const jobGroup of jobGroups) {
|
||||
await ml.jobWizardCommon.addJobGroup(jobGroup);
|
||||
}
|
||||
await ml.jobWizardCommon.assertJobGroupSelection(jobGroups);
|
||||
});
|
||||
|
||||
it('opens the advanced section', async () => {
|
||||
await ml.jobWizardCommon.ensureAdvancedSectionOpen();
|
||||
});
|
||||
|
||||
it('displays the model plot switch', async () => {
|
||||
await ml.jobWizardCommon.assertModelPlotSwitchExists();
|
||||
});
|
||||
|
||||
it('enables the dedicated index switch', async () => {
|
||||
await ml.jobWizardCommon.assertDedicatedIndexSwitchExists();
|
||||
await ml.jobWizardCommon.activateDedicatedIndexSwitch();
|
||||
await ml.jobWizardCommon.assertDedicatedIndexSwitchCheckedState(true);
|
||||
});
|
||||
|
||||
it('inputs the model memory limit', async () => {
|
||||
await ml.jobWizardCommon.assertModelMemoryLimitInputExists();
|
||||
await ml.jobWizardCommon.setModelMemoryLimit(memoryLimit);
|
||||
await ml.jobWizardCommon.assertModelMemoryLimitValue(memoryLimit);
|
||||
});
|
||||
|
||||
it('displays the validation step', async () => {
|
||||
await ml.jobWizardCommon.clickNextButton();
|
||||
await ml.jobWizardCommon.assertValidationSectionExists();
|
||||
});
|
||||
|
||||
it('displays the summary step', async () => {
|
||||
await ml.jobWizardCommon.clickNextButton();
|
||||
await ml.jobWizardCommon.assertSummarySectionExists();
|
||||
});
|
||||
|
||||
it('creates the job and finishes processing', async () => {
|
||||
await ml.jobWizardCommon.assertCreateJobButtonExists();
|
||||
await ml.jobWizardCommon.createJobAndWaitForCompletion();
|
||||
});
|
||||
|
||||
it('displays the created job in the job list', async () => {
|
||||
await ml.navigation.navigateToMl();
|
||||
await ml.navigation.navigateToJobManagement();
|
||||
|
||||
await ml.jobTable.waitForJobsToLoad();
|
||||
await ml.jobTable.filterWithSearchString(jobId);
|
||||
const rows = await ml.jobTable.parseJobTable();
|
||||
expect(rows.filter(row => row.id === jobId)).to.have.length(1);
|
||||
});
|
||||
|
||||
it('displays details for the created job in the job list', async () => {
|
||||
const expectedRow = {
|
||||
id: jobId,
|
||||
description: jobDescription,
|
||||
jobGroups,
|
||||
recordCount: '4,675',
|
||||
memoryStatus: 'ok',
|
||||
jobState: 'closed',
|
||||
datafeedState: 'stopped',
|
||||
latestTimestamp: '2019-07-12 23:45:36',
|
||||
};
|
||||
await ml.jobTable.assertJobRowFields(jobId, expectedRow);
|
||||
|
||||
const expectedCounts = {
|
||||
job_id: jobId,
|
||||
processed_record_count: '4,675',
|
||||
processed_field_count: '23,375',
|
||||
input_bytes: '867.7 KB',
|
||||
input_field_count: '23,375',
|
||||
invalid_date_count: '0',
|
||||
missing_field_count: '0',
|
||||
out_of_order_timestamp_count: '0',
|
||||
empty_bucket_count: '0',
|
||||
sparse_bucket_count: '0',
|
||||
bucket_count: '371',
|
||||
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 22:00:00',
|
||||
};
|
||||
const expectedModelSizeStats = {
|
||||
job_id: jobId,
|
||||
result_type: 'model_size_stats',
|
||||
model_bytes_exceeded: '0',
|
||||
model_bytes_memory_limit: '8388608',
|
||||
total_by_field_count: '25',
|
||||
total_over_field_count: '92',
|
||||
total_partition_field_count: '3',
|
||||
bucket_allocation_failures_count: '0',
|
||||
memory_status: 'ok',
|
||||
timestamp: '2019-07-12 20:00:00',
|
||||
};
|
||||
await ml.jobTable.assertJobRowDetailsCounts(jobId, expectedCounts, expectedModelSizeStats);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -13,5 +13,6 @@ export default function({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./pages'));
|
||||
loadTestFile(require.resolve('./create_single_metric_job'));
|
||||
loadTestFile(require.resolve('./create_multi_metric_job'));
|
||||
loadTestFile(require.resolve('./create_population_job'));
|
||||
});
|
||||
}
|
||||
|
|
BIN
x-pack/test/functional/es_archives/ml/ecommerce/data.json.gz
Normal file
BIN
x-pack/test/functional/es_archives/ml/ecommerce/data.json.gz
Normal file
Binary file not shown.
1226
x-pack/test/functional/es_archives/ml/ecommerce/mappings.json
Normal file
1226
x-pack/test/functional/es_archives/ml/ecommerce/mappings.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,6 +13,8 @@ export { MachineLearningJobSourceSelectionProvider } from './job_source_selectio
|
|||
export { MachineLearningJobTableProvider } from './job_table';
|
||||
export { MachineLearningJobTypeSelectionProvider } from './job_type_selection';
|
||||
export { MachineLearningJobWizardCommonProvider } from './job_wizard_common';
|
||||
export { MachineLearningJobWizardMultiMetricProvider } from './job_wizard_multi_metric';
|
||||
export { MachineLearningJobWizardPopulationProvider } from './job_wizard_population';
|
||||
export { MachineLearningNavigationProvider } from './navigation';
|
||||
export { MachineLearningSettingsProvider } from './settings';
|
||||
export { MachineLearningSingleMetricViewerProvider } from './single_metric_viewer';
|
||||
|
|
|
@ -19,5 +19,10 @@ export function MachineLearningJobTypeSelectionProvider({ getService }: FtrProvi
|
|||
await testSubjects.clickWhenNotDisabled('mlJobTypeLinkMultiMetricJob');
|
||||
await testSubjects.existOrFail('mlPageJobWizard');
|
||||
},
|
||||
|
||||
async selectPopulationJob() {
|
||||
await testSubjects.clickWhenNotDisabled('mlJobTypeLinkPopulationJob');
|
||||
await testSubjects.existOrFail('mlPageJobWizard');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -140,25 +140,13 @@ export function MachineLearningJobWizardCommonProvider({ getService }: FtrProvid
|
|||
expect(actualModelMemoryLimit).to.eql(expectedValue);
|
||||
},
|
||||
|
||||
async assertMultiMetricSplitFieldInputExists() {
|
||||
await testSubjects.existOrFail('mlJobWizardSplitFieldSelection > comboBoxInput');
|
||||
},
|
||||
|
||||
async assertMultiMetricSplitFieldSelection(identifier: string) {
|
||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||
'mlJobWizardSplitFieldSelection > comboBoxInput'
|
||||
);
|
||||
expect(comboBoxSelectedOptions.length).to.eql(1);
|
||||
expect(comboBoxSelectedOptions[0]).to.eql(identifier);
|
||||
},
|
||||
|
||||
async assertInfluencerInputExists() {
|
||||
await testSubjects.existOrFail('mlJobWizardInfluencerSelection > comboBoxInput');
|
||||
await testSubjects.existOrFail('influencerSelect > comboBoxInput');
|
||||
},
|
||||
|
||||
async assertInfluencerSelection(influencers: string[]) {
|
||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||
'mlJobWizardInfluencerSelection > comboBoxInput'
|
||||
'influencerSelect > comboBoxInput'
|
||||
);
|
||||
expect(comboBoxSelectedOptions).to.eql(influencers);
|
||||
},
|
||||
|
@ -176,24 +164,6 @@ export function MachineLearningJobWizardCommonProvider({ getService }: FtrProvid
|
|||
await testSubjects.existOrFail(`detector ${detectorPosition} > mlAnomalyChart ${chartType}`);
|
||||
},
|
||||
|
||||
async assertDetectorSplitExists(splitField: string) {
|
||||
await testSubjects.existOrFail(`dataSplit > dataSplitTitle ${splitField}`);
|
||||
await testSubjects.existOrFail(`dataSplit > splitCard front`);
|
||||
await testSubjects.existOrFail(`dataSplit > splitCard back`);
|
||||
},
|
||||
|
||||
async assertDetectorSplitFrontCardTitle(frontCardTitle: string) {
|
||||
expect(
|
||||
await testSubjects.getVisibleText(`dataSplit > splitCard front > splitCardTitle`)
|
||||
).to.eql(frontCardTitle);
|
||||
},
|
||||
|
||||
async assertDetectorSplitNumberOfBackCards(numberOfBackCards: number) {
|
||||
expect(await testSubjects.findAll(`dataSplit > splitCard back`)).to.have.length(
|
||||
numberOfBackCards
|
||||
);
|
||||
},
|
||||
|
||||
async clickNextButton() {
|
||||
await testSubjects.clickWhenNotDisabled('mlJobWizardNavButtonNext');
|
||||
},
|
||||
|
@ -226,12 +196,8 @@ export function MachineLearningJobWizardCommonProvider({ getService }: FtrProvid
|
|||
await comboBox.setCustom('mlJobWizardComboBoxJobGroups > comboBoxInput', jobGroup);
|
||||
},
|
||||
|
||||
async selectMultiMetricSplitField(identifier: string) {
|
||||
await comboBox.set('mlJobWizardSplitFieldSelection > comboBoxInput', identifier);
|
||||
},
|
||||
|
||||
async addInfluencer(influencer: string) {
|
||||
await comboBox.setCustom('mlJobWizardInfluencerSelection > comboBoxInput', influencer);
|
||||
await comboBox.setCustom('influencerSelect > comboBoxInput', influencer);
|
||||
},
|
||||
|
||||
async ensureAdvancedSectionOpen() {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export function MachineLearningJobWizardMultiMetricProvider({ getService }: FtrProviderContext) {
|
||||
const comboBox = getService('comboBox');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
return {
|
||||
async assertSplitFieldInputExists() {
|
||||
await testSubjects.existOrFail('multiMetricSplitFieldSelect > comboBoxInput');
|
||||
},
|
||||
|
||||
async assertSplitFieldSelection(identifier: string) {
|
||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||
'multiMetricSplitFieldSelect > comboBoxInput'
|
||||
);
|
||||
expect(comboBoxSelectedOptions.length).to.eql(1);
|
||||
expect(comboBoxSelectedOptions[0]).to.eql(identifier);
|
||||
},
|
||||
|
||||
async selectSplitField(identifier: string) {
|
||||
await comboBox.set('multiMetricSplitFieldSelect > comboBoxInput', identifier);
|
||||
},
|
||||
|
||||
async assertDetectorSplitExists(splitField: string) {
|
||||
await testSubjects.existOrFail(`dataSplit > dataSplitTitle ${splitField}`);
|
||||
await testSubjects.existOrFail(`dataSplit > splitCard front`);
|
||||
},
|
||||
|
||||
async assertDetectorSplitFrontCardTitle(frontCardTitle: string) {
|
||||
expect(
|
||||
await testSubjects.getVisibleText(`dataSplit > splitCard front > splitCardTitle`)
|
||||
).to.eql(frontCardTitle);
|
||||
},
|
||||
|
||||
async assertDetectorSplitNumberOfBackCards(numberOfBackCards: number) {
|
||||
expect(await testSubjects.findAll(`dataSplit > splitCard back`)).to.have.length(
|
||||
numberOfBackCards
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export function MachineLearningJobWizardPopulationProvider({ getService }: FtrProviderContext) {
|
||||
const comboBox = getService('comboBox');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
return {
|
||||
async assertPopulationFieldInputExists() {
|
||||
await testSubjects.existOrFail('populationSplitFieldSelect > comboBoxInput');
|
||||
},
|
||||
|
||||
async assertPopulationFieldSelection(identifier: string) {
|
||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||
'populationSplitFieldSelect > comboBoxInput'
|
||||
);
|
||||
expect(comboBoxSelectedOptions.length).to.eql(1);
|
||||
expect(comboBoxSelectedOptions[0]).to.eql(identifier);
|
||||
},
|
||||
|
||||
async selectPopulationField(identifier: string) {
|
||||
await comboBox.set('populationSplitFieldSelect > comboBoxInput', identifier);
|
||||
},
|
||||
|
||||
async assertDetectorSplitFieldInputExists(detectorPosition: number) {
|
||||
await testSubjects.existOrFail(
|
||||
`detector ${detectorPosition} > byFieldSelect > comboBoxInput`
|
||||
);
|
||||
},
|
||||
|
||||
async assertDetectorSplitFieldSelection(detectorPosition: number, identifier: string) {
|
||||
const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions(
|
||||
`detector ${detectorPosition} > byFieldSelect > comboBoxInput`
|
||||
);
|
||||
expect(comboBoxSelectedOptions.length).to.eql(1);
|
||||
expect(comboBoxSelectedOptions[0]).to.eql(identifier);
|
||||
},
|
||||
|
||||
async selectDetectorSplitField(detectorPosition: number, identifier: string) {
|
||||
await comboBox.set(
|
||||
`detector ${detectorPosition} > byFieldSelect > comboBoxInput`,
|
||||
identifier
|
||||
);
|
||||
},
|
||||
|
||||
async assertDetectorSplitExists(detectorPosition: number) {
|
||||
await testSubjects.existOrFail(`detector ${detectorPosition} > dataSplit`);
|
||||
await testSubjects.existOrFail(`detector ${detectorPosition} > dataSplit > splitCard front`);
|
||||
},
|
||||
|
||||
async assertDetectorSplitFrontCardTitle(detectorPosition: number, frontCardTitle: string) {
|
||||
expect(
|
||||
await testSubjects.getVisibleText(
|
||||
`detector ${detectorPosition} > dataSplit > splitCard front > splitCardTitle`
|
||||
)
|
||||
).to.eql(frontCardTitle);
|
||||
},
|
||||
|
||||
async assertDetectorSplitNumberOfBackCards(
|
||||
detectorPosition: number,
|
||||
numberOfBackCards: number
|
||||
) {
|
||||
expect(
|
||||
await testSubjects.findAll(`detector ${detectorPosition} > dataSplit > splitCard back`)
|
||||
).to.have.length(numberOfBackCards);
|
||||
},
|
||||
};
|
||||
}
|
|
@ -16,6 +16,8 @@ import {
|
|||
MachineLearningJobTableProvider,
|
||||
MachineLearningJobTypeSelectionProvider,
|
||||
MachineLearningJobWizardCommonProvider,
|
||||
MachineLearningJobWizardMultiMetricProvider,
|
||||
MachineLearningJobWizardPopulationProvider,
|
||||
MachineLearningNavigationProvider,
|
||||
MachineLearningSettingsProvider,
|
||||
MachineLearningSingleMetricViewerProvider,
|
||||
|
@ -31,6 +33,8 @@ export function MachineLearningProvider(context: FtrProviderContext) {
|
|||
const jobTable = MachineLearningJobTableProvider(context);
|
||||
const jobTypeSelection = MachineLearningJobTypeSelectionProvider(context);
|
||||
const jobWizardCommon = MachineLearningJobWizardCommonProvider(context);
|
||||
const jobWizardMultiMetric = MachineLearningJobWizardMultiMetricProvider(context);
|
||||
const jobWizardPopulation = MachineLearningJobWizardPopulationProvider(context);
|
||||
const navigation = MachineLearningNavigationProvider(context);
|
||||
const settings = MachineLearningSettingsProvider(context);
|
||||
const singleMetricViewer = MachineLearningSingleMetricViewerProvider(context);
|
||||
|
@ -45,6 +49,8 @@ export function MachineLearningProvider(context: FtrProviderContext) {
|
|||
jobTable,
|
||||
jobTypeSelection,
|
||||
jobWizardCommon,
|
||||
jobWizardMultiMetric,
|
||||
jobWizardPopulation,
|
||||
navigation,
|
||||
settings,
|
||||
singleMetricViewer,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue