diff --git a/x-pack/test/functional/services/machine_learning/common.ts b/x-pack/test/functional/services/machine_learning/common.ts new file mode 100644 index 0000000000000..12b9e8a1cfb29 --- /dev/null +++ b/x-pack/test/functional/services/machine_learning/common.ts @@ -0,0 +1,73 @@ +/* + * 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 { FtrProviderContext } from '../../ftr_provider_context'; + +interface SetValueOptions { + clearWithKeyboard?: boolean; + typeCharByChar?: boolean; +} + +export function MachineLearningCommonProvider({ getService }: FtrProviderContext) { + const log = getService('log'); + const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + const find = getService('find'); + + return { + async setValueWithChecks( + selector: string, + text: string, + options: SetValueOptions = {} + ): Promise { + return await retry.try(async () => { + const { clearWithKeyboard = false, typeCharByChar = false } = options; + log.debug(`TestSubjects.setValueWithChecks(${selector}, ${text})`); + await testSubjects.click(selector); + // in case the input element is actually a child of the testSubject, we + // call clearValue() and type() on the element that is focused after + // clicking on the testSubject + const input = await find.activeElement(); + + await retry.tryForTime(5000, async () => { + let currentValue = await input.getAttribute('value'); + if (currentValue !== '') { + if (clearWithKeyboard === true) { + await input.clearValueWithKeyboard(); + } else { + await input.clearValue(); + } + currentValue = await input.getAttribute('value'); + } + + if (currentValue === '') { + return true; + } else { + throw new Error(`Expected input to be empty, but got value '${currentValue}'`); + } + }); + + for (const chr of text) { + await retry.tryForTime(5000, async () => { + const oldValue = await input.getAttribute('value'); + await input.type(chr, { charByChar: typeCharByChar }); + + await retry.tryForTime(1000, async () => { + const newValue = await input.getAttribute('value'); + if (newValue === `${oldValue}${chr}`) { + return true; + } else { + throw new Error( + `After typing character '${chr}', the new value in the input should be '${oldValue}${chr}' (got ${newValue})` + ); + } + }); + }); + } + }); + }, + }; +} diff --git a/x-pack/test/functional/services/machine_learning/index.ts b/x-pack/test/functional/services/machine_learning/index.ts index adaded0832522..7c393689d166c 100644 --- a/x-pack/test/functional/services/machine_learning/index.ts +++ b/x-pack/test/functional/services/machine_learning/index.ts @@ -6,6 +6,7 @@ export { MachineLearningAnomalyExplorerProvider } from './anomaly_explorer'; export { MachineLearningAPIProvider } from './api'; +export { MachineLearningCommonProvider } from './common'; export { MachineLearningCustomUrlsProvider } from './custom_urls'; export { MachineLearningDataFrameAnalyticsProvider } from './data_frame_analytics'; export { MachineLearningDataFrameAnalyticsCreationProvider } from './data_frame_analytics_creation'; diff --git a/x-pack/test/functional/services/machine_learning/job_wizard_advanced.ts b/x-pack/test/functional/services/machine_learning/job_wizard_advanced.ts index 27768f784b1c5..ab53b0412ca35 100644 --- a/x-pack/test/functional/services/machine_learning/job_wizard_advanced.ts +++ b/x-pack/test/functional/services/machine_learning/job_wizard_advanced.ts @@ -4,10 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ import expect from '@kbn/expect'; +import { ProvidedType } from '@kbn/test/types/ftr'; import { FtrProviderContext } from '../../ftr_provider_context'; +import { MachineLearningCommonProvider } from './common'; -export function MachineLearningJobWizardAdvancedProvider({ getService }: FtrProviderContext) { +export function MachineLearningJobWizardAdvancedProvider( + { getService }: FtrProviderContext, + mlCommon: ProvidedType +) { const comboBox = getService('comboBox'); const testSubjects = getService('testSubjects'); const retry = getService('retry'); @@ -44,7 +49,7 @@ export function MachineLearningJobWizardAdvancedProvider({ getService }: FtrProv }, async setQueryDelay(queryDelay: string) { - await testSubjects.setValue('mlJobWizardInputQueryDelay', queryDelay, { + await mlCommon.setValueWithChecks('mlJobWizardInputQueryDelay', queryDelay, { clearWithKeyboard: true, typeCharByChar: true, }); @@ -61,7 +66,7 @@ export function MachineLearningJobWizardAdvancedProvider({ getService }: FtrProv }, async setFrequency(frequency: string) { - await testSubjects.setValue('mlJobWizardInputFrequency', frequency, { + await mlCommon.setValueWithChecks('mlJobWizardInputFrequency', frequency, { clearWithKeyboard: true, typeCharByChar: true, }); @@ -78,7 +83,7 @@ export function MachineLearningJobWizardAdvancedProvider({ getService }: FtrProv }, async setScrollSize(scrollSize: string) { - await testSubjects.setValue('mlJobWizardInputScrollSize', scrollSize, { + await mlCommon.setValueWithChecks('mlJobWizardInputScrollSize', scrollSize, { clearWithKeyboard: true, typeCharByChar: true, }); @@ -257,7 +262,7 @@ export function MachineLearningJobWizardAdvancedProvider({ getService }: FtrProv }, async setDetectorDescription(description: string) { - await testSubjects.setValue('mlAdvancedDetectorDescriptionInput', description, { + await mlCommon.setValueWithChecks('mlAdvancedDetectorDescriptionInput', description, { clearWithKeyboard: true, }); await this.assertDetectorDescriptionValue(description); diff --git a/x-pack/test/functional/services/machine_learning/job_wizard_common.ts b/x-pack/test/functional/services/machine_learning/job_wizard_common.ts index 235e597f8c280..b9e6822c8f41a 100644 --- a/x-pack/test/functional/services/machine_learning/job_wizard_common.ts +++ b/x-pack/test/functional/services/machine_learning/job_wizard_common.ts @@ -7,10 +7,12 @@ import expect from '@kbn/expect'; import { ProvidedType } from '@kbn/test/types/ftr'; import { FtrProviderContext } from '../../ftr_provider_context'; +import { MachineLearningCommonProvider } from './common'; import { MachineLearningCustomUrlsProvider } from './custom_urls'; export function MachineLearningJobWizardCommonProvider( { getService }: FtrProviderContext, + mlCommon: ProvidedType, customUrls: ProvidedType ) { const comboBox = getService('comboBox'); @@ -113,7 +115,7 @@ export function MachineLearningJobWizardCommonProvider( }, async setBucketSpan(bucketSpan: string) { - await testSubjects.setValue('mlJobWizardInputBucketSpan', bucketSpan, { + await mlCommon.setValueWithChecks('mlJobWizardInputBucketSpan', bucketSpan, { clearWithKeyboard: true, typeCharByChar: true, }); @@ -130,7 +132,9 @@ export function MachineLearningJobWizardCommonProvider( }, async setJobId(jobId: string) { - await testSubjects.setValue('mlJobWizardInputJobId', jobId, { clearWithKeyboard: true }); + await mlCommon.setValueWithChecks('mlJobWizardInputJobId', jobId, { + clearWithKeyboard: true, + }); await this.assertJobIdValue(jobId); }, @@ -146,7 +150,7 @@ export function MachineLearningJobWizardCommonProvider( }, async setJobDescription(jobDescription: string) { - await testSubjects.setValue('mlJobWizardInputJobDescription', jobDescription, { + await mlCommon.setValueWithChecks('mlJobWizardInputJobDescription', jobDescription, { clearWithKeyboard: true, }); await this.assertJobDescriptionValue(jobDescription); @@ -307,7 +311,7 @@ export function MachineLearningJobWizardCommonProvider( await this.ensureAdvancedSectionOpen(); subj = advancedSectionSelector(subj); } - await testSubjects.setValue(subj, modelMemoryLimit, { clearWithKeyboard: true }); + await mlCommon.setValueWithChecks(subj, modelMemoryLimit, { clearWithKeyboard: true }); await this.assertModelMemoryLimitValue(modelMemoryLimit, { withAdvancedSection: sectionOptions.withAdvancedSection, }); diff --git a/x-pack/test/functional/services/ml.ts b/x-pack/test/functional/services/ml.ts index 4b6f77262b7f9..8e71c16921078 100644 --- a/x-pack/test/functional/services/ml.ts +++ b/x-pack/test/functional/services/ml.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; import { MachineLearningAnomalyExplorerProvider, MachineLearningAPIProvider, + MachineLearningCommonProvider, MachineLearningCustomUrlsProvider, MachineLearningDataFrameAnalyticsProvider, MachineLearningDataFrameAnalyticsCreationProvider, @@ -29,6 +30,8 @@ import { } from './machine_learning'; export function MachineLearningProvider(context: FtrProviderContext) { + const common = MachineLearningCommonProvider(context); + const anomalyExplorer = MachineLearningAnomalyExplorerProvider(context); const api = MachineLearningAPIProvider(context); const customUrls = MachineLearningCustomUrlsProvider(context); @@ -41,8 +44,8 @@ export function MachineLearningProvider(context: FtrProviderContext) { const jobSourceSelection = MachineLearningJobSourceSelectionProvider(context); const jobTable = MachineLearningJobTableProvider(context); const jobTypeSelection = MachineLearningJobTypeSelectionProvider(context); - const jobWizardAdvanced = MachineLearningJobWizardAdvancedProvider(context); - const jobWizardCommon = MachineLearningJobWizardCommonProvider(context, customUrls); + const jobWizardAdvanced = MachineLearningJobWizardAdvancedProvider(context, common); + const jobWizardCommon = MachineLearningJobWizardCommonProvider(context, common, customUrls); const jobWizardMultiMetric = MachineLearningJobWizardMultiMetricProvider(context); const jobWizardPopulation = MachineLearningJobWizardPopulationProvider(context); const navigation = MachineLearningNavigationProvider(context);