From 1f131b250f9ed9c568c4c213adaf3b92ee324b53 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 13 Jan 2021 10:05:05 +0100 Subject: [PATCH] [Transform] Functional tests for latest method (#86966) * [ML] create latest transform from index pattern * [Transform] refactor, tests for saved search * [Transform] cloning tests for latest transform * [Transform] fix cloning test, add editing tests * [Transform] fix typo * [Transform] disable cloning tests * [Transform] add assertion for selected tranform function * [Transform] disable editing tests * [Transform] disable editing and cloning tests for latest function --- .../step_define/latest_function_form.tsx | 1 + .../apis/transform/transforms_create.ts | 2 +- .../test/functional/apps/transform/cloning.ts | 124 +++++++--- .../apps/transform/creation_index_pattern.ts | 152 +++++++++--- .../apps/transform/creation_saved_search.ts | 131 ++++++++--- .../test/functional/apps/transform/editing.ts | 222 ++++++++++-------- .../test/functional/apps/transform/index.ts | 55 +++++ .../functional/services/transform/wizard.ts | 63 ++++- 8 files changed, 549 insertions(+), 201 deletions(-) diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx index 3515316bb109..b4d035940192 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx @@ -25,6 +25,7 @@ export const LatestFunctionForm: FC = ({ latestFunction defaultMessage="Unique keys" /> } + data-test-subj="transformLatestFunctionForm" > fullWidth diff --git a/x-pack/test/api_integration/apis/transform/transforms_create.ts b/x-pack/test/api_integration/apis/transform/transforms_create.ts index 4b2821f19e03..2d13eb190b28 100644 --- a/x-pack/test/api_integration/apis/transform/transforms_create.ts +++ b/x-pack/test/api_integration/apis/transform/transforms_create.ts @@ -25,7 +25,7 @@ export default ({ getService }: FtrProviderContext) => { await transform.api.cleanTransformIndices(); }); - it('should not allow pivot and latest configs is same transform', async () => { + it('should not allow pivot and latest configs in same transform', async () => { const transformId = 'test_transform_id'; const { body } = await supertest diff --git a/x-pack/test/functional/apps/transform/cloning.ts b/x-pack/test/functional/apps/transform/cloning.ts index 421eab656f60..aae4eae35f83 100644 --- a/x-pack/test/functional/apps/transform/cloning.ts +++ b/x-pack/test/functional/apps/transform/cloning.ts @@ -5,12 +5,26 @@ */ import { FtrProviderContext } from '../../ftr_provider_context'; -import { TransformPivotConfig } from '../../../../plugins/transform/common/types/transform'; +import { + isLatestTransform, + isPivotTransform, + TransformPivotConfig, +} from '../../../../plugins/transform/common/types/transform'; + +interface TestData { + type: 'pivot' | 'latest'; + suiteTitle: string; + originalConfig: any; + transformId: string; + transformDescription: string; + destinationIndex: string; + expected: any; +} function getTransformConfig(): TransformPivotConfig { const date = Date.now(); return { - id: `ec_cloning_${date}`, + id: `ec_cloning_1_${date}`, source: { index: ['ft_ecommerce'] }, pivot: { group_by: { category: { terms: { field: 'category.keyword' } } }, @@ -31,27 +45,39 @@ export default function ({ getService }: FtrProviderContext) { const transform = getService('transform'); describe('cloning', function () { - const transformConfig = getTransformConfig(); + const transformConfigWithPivot = getTransformConfig(); + // const transformConfigWithLatest = getLatestTransformConfig(); before(async () => { await esArchiver.loadIfNeeded('ml/ecommerce'); await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); - await transform.api.createAndRunTransform(transformConfig.id, transformConfig); + await transform.api.createAndRunTransform( + transformConfigWithPivot.id, + transformConfigWithPivot + ); + // await transform.api.createAndRunTransform( + // transformConfigWithLatest.id, + // transformConfigWithLatest + // ); await transform.testResources.setKibanaTimeZoneToUTC(); await transform.securityUI.loginAsTransformPowerUser(); }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle(transformConfig.dest.index); - await transform.api.deleteIndices(transformConfig.dest.index); + await transform.testResources.deleteIndexPatternByTitle(transformConfigWithPivot.dest.index); + // await transform.testResources.deleteIndexPatternByTitle(transformConfigWithLatest.dest.index); + await transform.api.deleteIndices(transformConfigWithPivot.dest.index); + // await transform.api.deleteIndices(transformConfigWithLatest.dest.index); await transform.api.cleanTransformIndices(); }); - const testDataList = [ + const testDataList: TestData[] = [ { + type: 'pivot' as const, suiteTitle: 'clone transform', - transformId: `clone_${transformConfig.id}`, + originalConfig: transformConfigWithPivot, + transformId: `clone_${transformConfigWithPivot.id}`, transformDescription: `a cloned transform`, get destinationIndex(): string { return `user-${this.transformId}`; @@ -69,7 +95,7 @@ export default function ({ getService }: FtrProviderContext) { index: 0, label: 'category', }, - pivotPreview: { + transformPreview: { column: 0, values: [ `Men's Accessories`, @@ -81,6 +107,33 @@ export default function ({ getService }: FtrProviderContext) { }, }, }, + // TODO enable tests when https://github.com/elastic/elasticsearch/issues/67148 is resolved + // { + // type: 'latest' as const, + // suiteTitle: 'clone transform with latest function', + // originalConfig: transformConfigWithLatest, + // transformId: `clone_${transformConfigWithLatest.id}`, + // transformDescription: `a cloned transform`, + // get destinationIndex(): string { + // return `user-${this.transformId}`; + // }, + // expected: { + // indexPreview: { + // columns: 10, + // rows: 5, + // }, + // transformPreview: { + // column: 0, + // values: [ + // 'July 12th 2019, 22:16:19', + // 'July 12th 2019, 22:50:53', + // 'July 12th 2019, 23:06:43', + // 'July 12th 2019, 23:15:22', + // 'July 12th 2019, 23:31:12', + // ], + // }, + // }, + // }, ]; for (const testData of testDataList) { @@ -102,13 +155,14 @@ export default function ({ getService }: FtrProviderContext) { 'should display the original transform in the transform list' ); await transform.table.refreshTransformList(); - await transform.table.filterWithSearchString(transformConfig.id, 1); + await transform.table.filterWithSearchString(testData.originalConfig.id, 1); await transform.testExecution.logTestStep('should show the actions popover'); await transform.table.assertTransformRowActions(false); await transform.testExecution.logTestStep('should display the define pivot step'); await transform.table.clickTransformRowAction('Clone'); + await transform.wizard.assertSelectedTransformFunction(testData.type); await transform.wizard.assertDefineStepActive(); }); @@ -126,27 +180,37 @@ export default function ({ getService }: FtrProviderContext) { await transform.wizard.assertQueryInputExists(); await transform.wizard.assertQueryValue(''); - await transform.testExecution.logTestStep( - 'should show the pre-filled group-by configuration' - ); - await transform.wizard.assertGroupByEntryExists( - testData.expected.groupBy.index, - testData.expected.groupBy.label - ); + // assert define step form + if (isPivotTransform(testData.originalConfig)) { + await transform.testExecution.logTestStep( + 'should show the pre-filled group-by configuration' + ); + await transform.wizard.assertGroupByEntryExists( + testData.expected.groupBy.index, + testData.expected.groupBy.label + ); - await transform.testExecution.logTestStep( - 'should show the pre-filled aggs configuration' - ); - await transform.wizard.assertAggregationEntryExists( - testData.expected.aggs.index, - testData.expected.aggs.label - ); + await transform.testExecution.logTestStep( + 'should show the pre-filled aggs configuration' + ); + await transform.wizard.assertAggregationEntryExists( + testData.expected.aggs.index, + testData.expected.aggs.label + ); + } else if (isLatestTransform(testData.originalConfig)) { + await transform.testExecution.logTestStep('should show pre-filler unique keys'); + await transform.wizard.assertUniqueKeysInputValue( + testData.originalConfig.latest.unique_key + ); + await transform.testExecution.logTestStep('should show pre-filler sort field'); + await transform.wizard.assertSortFieldInputValue(testData.originalConfig.latest.sort); + } await transform.testExecution.logTestStep('should show the pivot preview'); await transform.wizard.assertPivotPreviewChartHistogramButtonMissing(); await transform.wizard.assertPivotPreviewColumnValues( - testData.expected.pivotPreview.column, - testData.expected.pivotPreview.values + testData.expected.transformPreview.column, + testData.expected.transformPreview.values ); await transform.testExecution.logTestStep('should load the details step'); @@ -159,7 +223,9 @@ export default function ({ getService }: FtrProviderContext) { await transform.testExecution.logTestStep('should input the transform description'); await transform.wizard.assertTransformDescriptionInputExists(); - await transform.wizard.assertTransformDescriptionValue(transformConfig.description!); + await transform.wizard.assertTransformDescriptionValue( + testData.originalConfig.description! + ); await transform.wizard.setTransformDescription(testData.transformDescription); await transform.testExecution.logTestStep('should input the destination index'); @@ -181,9 +247,9 @@ export default function ({ getService }: FtrProviderContext) { 'should display the advanced settings and show pre-filled configuration' ); await transform.wizard.openTransformAdvancedSettingsAccordion(); - await transform.wizard.assertTransformFrequencyValue(transformConfig.frequency!); + await transform.wizard.assertTransformFrequencyValue(testData.originalConfig.frequency!); await transform.wizard.assertTransformMaxPageSearchSizeValue( - transformConfig.settings!.max_page_search_size! + testData.originalConfig.settings!.max_page_search_size! ); await transform.testExecution.logTestStep('should load the create step'); diff --git a/x-pack/test/functional/apps/transform/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation_index_pattern.ts index 13213679a611..e3e2c75bf673 100644 --- a/x-pack/test/functional/apps/transform/creation_index_pattern.ts +++ b/x-pack/test/functional/apps/transform/creation_index_pattern.ts @@ -7,12 +7,13 @@ import { TRANSFORM_STATE } from '../../../../plugins/transform/common/constants'; import { FtrProviderContext } from '../../ftr_provider_context'; - -interface GroupByEntry { - identifier: string; - label: string; - intervalLabel?: string; -} +import { + GroupByEntry, + isLatestTransformTestData, + isPivotTransformTestData, + LatestTransformTestData, + PivotTransformTestData, +} from './index'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); @@ -31,8 +32,9 @@ export default function ({ getService }: FtrProviderContext) { await transform.api.cleanTransformIndices(); }); - const testDataList = [ + const testDataList: Array = [ { + type: 'pivot', suiteTitle: 'batch transform with terms+date_histogram groups and avg agg', source: 'ft_ecommerce', groupByEntries: [ @@ -138,7 +140,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, }, - pivotPreview: { + transformPreview: { column: 0, values: [`Men's Accessories`], }, @@ -168,8 +170,9 @@ export default function ({ getService }: FtrProviderContext) { { chartAvailable: true, id: 'day_of_week', legend: '7 categories' }, ], }, - }, + } as PivotTransformTestData, { + type: 'pivot', suiteTitle: 'batch transform with terms group and percentiles agg', source: 'ft_ecommerce', groupByEntries: [ @@ -236,7 +239,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, }, - pivotPreview: { + transformPreview: { column: 0, values: ['AE', 'CO', 'EG', 'FR', 'GB'], }, @@ -251,7 +254,55 @@ export default function ({ getService }: FtrProviderContext) { }, histogramCharts: [], }, - }, + } as PivotTransformTestData, + { + type: 'latest', + suiteTitle: 'batch transform with the latest function', + source: 'ft_ecommerce', + uniqueKeys: [ + { + identifier: 'geoip.country_iso_code', + label: 'geoip.country_iso_code', + }, + ], + sortField: { + identifier: 'order_date', + label: 'order_date', + }, + transformId: `ec_3_${Date.now()}`, + + transformDescription: + 'ecommerce batch transform with the latest function config, sort by order_data, country code as unique key', + get destinationIndex(): string { + return `user-${this.transformId}`; + }, + expected: { + latestPreview: { + column: 0, + values: [], + }, + row: { + status: TRANSFORM_STATE.STOPPED, + mode: 'batch', + progress: '100', + }, + indexPreview: { + columns: 10, + rows: 5, + }, + histogramCharts: [], + transformPreview: { + column: 0, + values: [ + 'July 12th 2019, 22:16:19', + 'July 12th 2019, 22:50:53', + 'July 12th 2019, 23:06:43', + 'July 12th 2019, 23:15:22', + 'July 12th 2019, 23:31:12', + ], + }, + }, + } as LatestTransformTestData, ]; for (const testData of testDataList) { @@ -277,9 +328,12 @@ export default function ({ getService }: FtrProviderContext) { }); it('navigates through the wizard and sets all needed fields', async () => { - await transform.testExecution.logTestStep('displays the define pivot step'); + await transform.testExecution.logTestStep('displays the define step'); await transform.wizard.assertDefineStepActive(); + await transform.testExecution.logTestStep('has correct transform function selected'); + await transform.wizard.assertSelectedTransformFunction('pivot'); + await transform.testExecution.logTestStep('loads the index preview'); await transform.wizard.assertIndexPreviewLoaded(); @@ -289,8 +343,8 @@ export default function ({ getService }: FtrProviderContext) { testData.expected.indexPreview.rows ); - await transform.testExecution.logTestStep('displays an empty pivot preview'); - await transform.wizard.assertPivotPreviewEmpty(); + await transform.testExecution.logTestStep('displays an empty transform preview'); + await transform.wizard.assertTransformPreviewEmpty(); await transform.testExecution.logTestStep('displays the query input'); await transform.wizard.assertQueryInputExists(); @@ -308,39 +362,59 @@ export default function ({ getService }: FtrProviderContext) { testData.expected.histogramCharts ); - await transform.testExecution.logTestStep('adds the group by entries'); - for (const [index, entry] of testData.groupByEntries.entries()) { - await transform.wizard.assertGroupByInputExists(); - await transform.wizard.assertGroupByInputValue([]); - await transform.wizard.addGroupByEntry( - index, - entry.identifier, - entry.label, - entry.intervalLabel + if (isPivotTransformTestData(testData)) { + await transform.testExecution.logTestStep('adds the group by entries'); + for (const [index, entry] of testData.groupByEntries.entries()) { + await transform.wizard.assertGroupByInputExists(); + await transform.wizard.assertGroupByInputValue([]); + await transform.wizard.addGroupByEntry( + index, + entry.identifier, + entry.label, + entry.intervalLabel + ); + } + + await transform.testExecution.logTestStep('adds the aggregation entries'); + await transform.wizard.addAggregationEntries(testData.aggregationEntries); + + await transform.testExecution.logTestStep('displays the advanced pivot editor switch'); + await transform.wizard.assertAdvancedPivotEditorSwitchExists(); + await transform.wizard.assertAdvancedPivotEditorSwitchCheckState(false); + + await transform.testExecution.logTestStep('displays the advanced configuration'); + await transform.wizard.enableAdvancedPivotEditor(); + await transform.wizard.assertAdvancedPivotEditorContent( + testData.expected.pivotAdvancedEditorValueArr ); } - await transform.testExecution.logTestStep('adds the aggregation entries'); - await transform.wizard.addAggregationEntries(testData.aggregationEntries); + if (isLatestTransformTestData(testData)) { + await transform.testExecution.logTestStep('sets latest transform method'); + await transform.wizard.selectTransformFunction('latest'); + await transform.testExecution.logTestStep('adds unique keys'); + for (const { identifier, label } of testData.uniqueKeys) { + await transform.wizard.assertUniqueKeysInputExists(); + await transform.wizard.assertUniqueKeysInputValue([]); + await transform.wizard.addUniqueKeyEntry(identifier, label); + } + await transform.testExecution.logTestStep('sets the sort field'); + await transform.wizard.assertSortFieldInputExists(); + await transform.wizard.assertSortFieldInputValue(''); + await transform.wizard.setSortFieldValue( + testData.sortField.identifier, + testData.sortField.label + ); + } - await transform.testExecution.logTestStep('displays the advanced pivot editor switch'); - await transform.wizard.assertAdvancedPivotEditorSwitchExists(); - await transform.wizard.assertAdvancedPivotEditorSwitchCheckState(false); - - await transform.testExecution.logTestStep('displays the advanced configuration'); - await transform.wizard.enabledAdvancedPivotEditor(); - await transform.wizard.assertAdvancedPivotEditorContent( - testData.expected.pivotAdvancedEditorValueArr - ); - - await transform.testExecution.logTestStep('loads the pivot preview'); + await transform.testExecution.logTestStep('loads the transform preview'); await transform.wizard.assertPivotPreviewLoaded(); - await transform.testExecution.logTestStep('shows the pivot preview'); + await transform.testExecution.logTestStep('shows the transform preview'); await transform.wizard.assertPivotPreviewChartHistogramButtonMissing(); await transform.wizard.assertPivotPreviewColumnValues( - testData.expected.pivotPreview.column, - testData.expected.pivotPreview.values + testData.expected.transformPreview.column, + testData.expected.transformPreview.values ); await transform.testExecution.logTestStep('loads the details step'); diff --git a/x-pack/test/functional/apps/transform/creation_saved_search.ts b/x-pack/test/functional/apps/transform/creation_saved_search.ts index 20d276c2e017..70a3f2a733f5 100644 --- a/x-pack/test/functional/apps/transform/creation_saved_search.ts +++ b/x-pack/test/functional/apps/transform/creation_saved_search.ts @@ -7,12 +7,13 @@ import { TRANSFORM_STATE } from '../../../../plugins/transform/common/constants'; import { FtrProviderContext } from '../../ftr_provider_context'; - -interface GroupByEntry { - identifier: string; - label: string; - intervalLabel?: string; -} +import { + GroupByEntry, + isLatestTransformTestData, + isPivotTransformTestData, + LatestTransformTestData, + PivotTransformTestData, +} from './index'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); @@ -32,8 +33,9 @@ export default function ({ getService }: FtrProviderContext) { await transform.api.cleanTransformIndices(); }); - const testDataList = [ + const testDataList: Array = [ { + type: 'pivot', suiteTitle: 'batch transform with terms groups and avg agg with saved search filter', source: 'ft_farequote_filter', groupByEntries: [ @@ -55,7 +57,7 @@ export default function ({ getService }: FtrProviderContext) { return `user-${this.transformId}`; }, expected: { - pivotPreview: { + transformPreview: { column: 0, values: ['ASA'], }, @@ -70,7 +72,44 @@ export default function ({ getService }: FtrProviderContext) { values: ['ASA'], }, }, - }, + } as PivotTransformTestData, + { + type: 'latest', + suiteTitle: 'batch transform with unique term and sort by time with saved search filter', + source: 'ft_farequote_filter', + uniqueKeys: [ + { + identifier: 'airline', + label: 'airline', + }, + ], + sortField: { + identifier: '@timestamp', + label: '@timestamp', + }, + transformId: `fq_2_${Date.now()}`, + transformDescription: + 'farequote batch transform with airline unique key and sort by timestamp with saved search filter', + get destinationIndex(): string { + return `user-latest-${this.transformId}`; + }, + expected: { + transformPreview: { + column: 0, + values: ['February 11th 2016, 23:59:54'], + }, + row: { + status: TRANSFORM_STATE.STOPPED, + mode: 'batch', + progress: '100', + }, + sourceIndex: 'ft_farequote', + indexPreview: { + column: 2, + values: ['ASA'], + }, + }, + } as LatestTransformTestData, ]; for (const testData of testDataList) { @@ -99,6 +138,9 @@ export default function ({ getService }: FtrProviderContext) { await transform.testExecution.logTestStep('displays the define pivot step'); await transform.wizard.assertDefineStepActive(); + await transform.testExecution.logTestStep('has correct transform function selected'); + await transform.wizard.assertSelectedTransformFunction('pivot'); + await transform.testExecution.logTestStep('loads the index preview'); await transform.wizard.assertIndexPreviewLoaded(); @@ -108,8 +150,8 @@ export default function ({ getService }: FtrProviderContext) { testData.expected.indexPreview.values ); - await transform.testExecution.logTestStep('displays an empty pivot preview'); - await transform.wizard.assertPivotPreviewEmpty(); + await transform.testExecution.logTestStep('displays an empty transform preview'); + await transform.wizard.assertTransformPreviewEmpty(); await transform.testExecution.logTestStep('hides the query input'); await transform.wizard.assertQueryInputMissing(); @@ -117,36 +159,55 @@ export default function ({ getService }: FtrProviderContext) { await transform.testExecution.logTestStep('hides the advanced query editor switch'); await transform.wizard.assertAdvancedQueryEditorSwitchMissing(); - await transform.testExecution.logTestStep('adds the group by entries'); - for (const [index, entry] of testData.groupByEntries.entries()) { - await transform.wizard.assertGroupByInputExists(); - await transform.wizard.assertGroupByInputValue([]); - await transform.wizard.addGroupByEntry( - index, - entry.identifier, - entry.label, - entry.intervalLabel + if (isPivotTransformTestData(testData)) { + await transform.testExecution.logTestStep('adds the group by entries'); + for (const [index, entry] of testData.groupByEntries.entries()) { + await transform.wizard.assertGroupByInputExists(); + await transform.wizard.assertGroupByInputValue([]); + await transform.wizard.addGroupByEntry( + index, + entry.identifier, + entry.label, + entry.intervalLabel + ); + } + await transform.testExecution.logTestStep('adds the aggregation entries'); + for (const [index, agg] of testData.aggregationEntries.entries()) { + await transform.wizard.assertAggregationInputExists(); + await transform.wizard.assertAggregationInputValue([]); + await transform.wizard.addAggregationEntry(index, agg.identifier, agg.label); + } + + await transform.testExecution.logTestStep('displays the advanced pivot editor switch'); + await transform.wizard.assertAdvancedPivotEditorSwitchExists(); + await transform.wizard.assertAdvancedPivotEditorSwitchCheckState(false); + } + + if (isLatestTransformTestData(testData)) { + await transform.testExecution.logTestStep('sets latest transform method'); + await transform.wizard.selectTransformFunction('latest'); + await transform.testExecution.logTestStep('adds unique keys'); + for (const { identifier, label } of testData.uniqueKeys) { + await transform.wizard.assertUniqueKeysInputExists(); + await transform.wizard.assertUniqueKeysInputValue([]); + await transform.wizard.addUniqueKeyEntry(identifier, label); + } + await transform.testExecution.logTestStep('sets the sort field'); + await transform.wizard.assertSortFieldInputExists(); + await transform.wizard.assertSortFieldInputValue(''); + await transform.wizard.setSortFieldValue( + testData.sortField.identifier, + testData.sortField.label ); } - await transform.testExecution.logTestStep('adds the aggregation entries'); - for (const [index, agg] of testData.aggregationEntries.entries()) { - await transform.wizard.assertAggregationInputExists(); - await transform.wizard.assertAggregationInputValue([]); - await transform.wizard.addAggregationEntry(index, agg.identifier, agg.label); - } - - await transform.testExecution.logTestStep('displays the advanced pivot editor switch'); - await transform.wizard.assertAdvancedPivotEditorSwitchExists(); - await transform.wizard.assertAdvancedPivotEditorSwitchCheckState(false); - await transform.testExecution.logTestStep('loads the pivot preview'); await transform.wizard.assertPivotPreviewLoaded(); await transform.testExecution.logTestStep('shows the pivot preview'); await transform.wizard.assertPivotPreviewColumnValues( - testData.expected.pivotPreview.column, - testData.expected.pivotPreview.values + testData.expected.transformPreview.column, + testData.expected.transformPreview.values ); await transform.testExecution.logTestStep('loads the details step'); @@ -231,8 +292,8 @@ export default function ({ getService }: FtrProviderContext) { 'displays the transform preview in the expanded row' ); await transform.table.assertTransformsExpandedRowPreviewColumnValues( - testData.expected.pivotPreview.column, - testData.expected.pivotPreview.values + testData.expected.transformPreview.column, + testData.expected.transformPreview.values ); }); }); diff --git a/x-pack/test/functional/apps/transform/editing.ts b/x-pack/test/functional/apps/transform/editing.ts index 498678e7ba4b..fa778dae1794 100644 --- a/x-pack/test/functional/apps/transform/editing.ts +++ b/x-pack/test/functional/apps/transform/editing.ts @@ -29,122 +29,154 @@ export default function ({ getService }: FtrProviderContext) { const transform = getService('transform'); describe('editing', function () { - const transformConfig = getTransformConfig(); + const transformConfigWithPivot = getTransformConfig(); + // const transformConfigWithLatest = getLatestTransformConfig(); before(async () => { await esArchiver.loadIfNeeded('ml/ecommerce'); await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); - await transform.api.createAndRunTransform(transformConfig.id, transformConfig); - await transform.testResources.setKibanaTimeZoneToUTC(); + await transform.api.createAndRunTransform( + transformConfigWithPivot.id, + transformConfigWithPivot + ); + // await transform.api.createAndRunTransform( + // transformConfigWithLatest.id, + // transformConfigWithLatest + // ); + + await transform.testResources.setKibanaTimeZoneToUTC(); await transform.securityUI.loginAsTransformPowerUser(); }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle(transformConfig.dest.index); - await transform.api.deleteIndices(transformConfig.dest.index); + await transform.testResources.deleteIndexPatternByTitle(transformConfigWithPivot.dest.index); + await transform.api.deleteIndices(transformConfigWithPivot.dest.index); + // await transform.testResources.deleteIndexPatternByTitle(transformConfigWithLatest.dest.index); + // await transform.api.deleteIndices(transformConfigWithLatest.dest.index); await transform.api.cleanTransformIndices(); }); - const testData = { - suiteTitle: 'edit transform', - transformDescription: 'updated description', - transformDocsPerSecond: '1000', - transformFrequency: '10m', - expected: { - messageText: 'updated transform.', - row: { - status: TRANSFORM_STATE.STOPPED, - mode: 'batch', - progress: '100', + const testDataList = [ + { + suiteTitle: 'edit transform with pivot configuration', + originalConfig: transformConfigWithPivot, + transformDescription: 'updated description', + transformDocsPerSecond: '1000', + transformFrequency: '10m', + expected: { + messageText: 'updated transform.', + row: { + status: TRANSFORM_STATE.STOPPED, + mode: 'batch', + progress: '100', + }, }, }, - }; + // TODO enable tests when https://github.com/elastic/elasticsearch/issues/67148 is resolved + // { + // suiteTitle: 'edit transform with latest configuration', + // originalConfig: transformConfigWithLatest, + // transformDescription: 'updated description', + // transformDocsPerSecond: '1000', + // transformFrequency: '10m', + // expected: { + // messageText: 'updated transform.', + // row: { + // status: TRANSFORM_STATE.STOPPED, + // mode: 'batch', + // progress: '100', + // }, + // }, + // }, + ]; - describe(`${testData.suiteTitle}`, function () { - it('opens the edit flyout for an existing transform', async () => { - await transform.testExecution.logTestStep('should load the home page'); - await transform.navigation.navigateTo(); - await transform.management.assertTransformListPageExists(); + for (const testData of testDataList) { + describe(`${testData.suiteTitle}`, function () { + it('opens the edit flyout for an existing transform', async () => { + await transform.testExecution.logTestStep('should load the home page'); + await transform.navigation.navigateTo(); + await transform.management.assertTransformListPageExists(); - await transform.testExecution.logTestStep('should display the transforms table'); - await transform.management.assertTransformsTableExists(); + await transform.testExecution.logTestStep('should display the transforms table'); + await transform.management.assertTransformsTableExists(); - await transform.testExecution.logTestStep( - 'should display the original transform in the transform list' - ); - await transform.table.refreshTransformList(); - await transform.table.filterWithSearchString(transformConfig.id, 1); + await transform.testExecution.logTestStep( + 'should display the original transform in the transform list' + ); + await transform.table.refreshTransformList(); + await transform.table.filterWithSearchString(testData.originalConfig.id, 1); - await transform.testExecution.logTestStep('should show the actions popover'); - await transform.table.assertTransformRowActions(false); + await transform.testExecution.logTestStep('should show the actions popover'); + await transform.table.assertTransformRowActions(false); - await transform.testExecution.logTestStep('should show the edit flyout'); - await transform.table.clickTransformRowAction('Edit'); - await transform.editFlyout.assertTransformEditFlyoutExists(); - }); - - it('navigates through the edit flyout and sets all needed fields', async () => { - await transform.testExecution.logTestStep('should update the transform description'); - await transform.editFlyout.assertTransformEditFlyoutInputExists('Description'); - await transform.editFlyout.assertTransformEditFlyoutInputValue( - 'Description', - transformConfig?.description ?? '' - ); - await transform.editFlyout.setTransformEditFlyoutInputValue( - 'Description', - testData.transformDescription - ); - - await transform.testExecution.logTestStep( - 'should update the transform documents per second' - ); - await transform.editFlyout.openTransformEditAccordionAdvancedSettings(); - await transform.editFlyout.assertTransformEditFlyoutInputExists('DocsPerSecond'); - await transform.editFlyout.assertTransformEditFlyoutInputValue('DocsPerSecond', ''); - await transform.editFlyout.setTransformEditFlyoutInputValue( - 'DocsPerSecond', - testData.transformDocsPerSecond - ); - - await transform.testExecution.logTestStep('should update the transform frequency'); - await transform.editFlyout.assertTransformEditFlyoutInputExists('Frequency'); - await transform.editFlyout.assertTransformEditFlyoutInputValue('Frequency', ''); - await transform.editFlyout.setTransformEditFlyoutInputValue( - 'Frequency', - testData.transformFrequency - ); - }); - - it('updates the transform and displays it correctly in the job list', async () => { - await transform.testExecution.logTestStep('should update the transform'); - await transform.editFlyout.updateTransform(); - - await transform.testExecution.logTestStep('should display the transforms table'); - await transform.management.assertTransformsTableExists(); - - await transform.testExecution.logTestStep( - 'should display the updated transform in the transform list' - ); - await transform.table.refreshTransformList(); - await transform.table.filterWithSearchString(transformConfig.id, 1); - - await transform.testExecution.logTestStep( - 'should display the updated transform in the transform list row cells' - ); - await transform.table.assertTransformRowFields(transformConfig.id, { - id: transformConfig.id, - description: testData.transformDescription, - status: testData.expected.row.status, - mode: testData.expected.row.mode, - progress: testData.expected.row.progress, + await transform.testExecution.logTestStep('should show the edit flyout'); + await transform.table.clickTransformRowAction('Edit'); + await transform.editFlyout.assertTransformEditFlyoutExists(); }); - await transform.testExecution.logTestStep( - 'should display the messages tab and include an update message' - ); - await transform.table.assertTransformExpandedRowMessages(testData.expected.messageText); + it('navigates through the edit flyout and sets all needed fields', async () => { + await transform.testExecution.logTestStep('should update the transform description'); + await transform.editFlyout.assertTransformEditFlyoutInputExists('Description'); + await transform.editFlyout.assertTransformEditFlyoutInputValue( + 'Description', + testData.originalConfig?.description ?? '' + ); + await transform.editFlyout.setTransformEditFlyoutInputValue( + 'Description', + testData.transformDescription + ); + + await transform.testExecution.logTestStep( + 'should update the transform documents per second' + ); + await transform.editFlyout.openTransformEditAccordionAdvancedSettings(); + await transform.editFlyout.assertTransformEditFlyoutInputExists('DocsPerSecond'); + await transform.editFlyout.assertTransformEditFlyoutInputValue('DocsPerSecond', ''); + await transform.editFlyout.setTransformEditFlyoutInputValue( + 'DocsPerSecond', + testData.transformDocsPerSecond + ); + + await transform.testExecution.logTestStep('should update the transform frequency'); + await transform.editFlyout.assertTransformEditFlyoutInputExists('Frequency'); + await transform.editFlyout.assertTransformEditFlyoutInputValue('Frequency', ''); + await transform.editFlyout.setTransformEditFlyoutInputValue( + 'Frequency', + testData.transformFrequency + ); + }); + + it('updates the transform and displays it correctly in the job list', async () => { + await transform.testExecution.logTestStep('should update the transform'); + await transform.editFlyout.updateTransform(); + + await transform.testExecution.logTestStep('should display the transforms table'); + await transform.management.assertTransformsTableExists(); + + await transform.testExecution.logTestStep( + 'should display the updated transform in the transform list' + ); + await transform.table.refreshTransformList(); + await transform.table.filterWithSearchString(testData.originalConfig.id, 1); + + await transform.testExecution.logTestStep( + 'should display the updated transform in the transform list row cells' + ); + await transform.table.assertTransformRowFields(testData.originalConfig.id, { + id: testData.originalConfig.id, + description: testData.transformDescription, + status: testData.expected.row.status, + mode: testData.expected.row.mode, + progress: testData.expected.row.progress, + }); + + await transform.testExecution.logTestStep( + 'should display the messages tab and include an update message' + ); + await transform.table.assertTransformExpandedRowMessages(testData.expected.messageText); + }); }); - }); + } }); } diff --git a/x-pack/test/functional/apps/transform/index.ts b/x-pack/test/functional/apps/transform/index.ts index 2837ddb7333e..1398fdfb1b20 100644 --- a/x-pack/test/functional/apps/transform/index.ts +++ b/x-pack/test/functional/apps/transform/index.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { FtrProviderContext } from '../../ftr_provider_context'; +import { TransformLatestConfig } from '../../../../plugins/transform/common/types/transform'; export default function ({ getService, loadTestFile }: FtrProviderContext) { const esArchiver = getService('esArchiver'); @@ -40,3 +41,57 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./feature_controls')); }); } +export interface ComboboxOption { + identifier: string; + label: string; +} + +export interface GroupByEntry extends ComboboxOption { + intervalLabel?: string; +} + +export interface BaseTransformTestData { + type: 'pivot' | 'latest'; + suiteTitle: string; + source: string; + transformId: string; + transformDescription: string; + expected: any; + destinationIndex: string; +} + +export interface PivotTransformTestData extends BaseTransformTestData { + groupByEntries: GroupByEntry[]; + aggregationEntries: any[]; +} + +export interface LatestTransformTestData extends BaseTransformTestData { + uniqueKeys: ComboboxOption[]; + sortField: ComboboxOption; +} + +export function isPivotTransformTestData(arg: any): arg is PivotTransformTestData { + return arg.type === 'pivot'; +} + +export function isLatestTransformTestData(arg: any): arg is LatestTransformTestData { + return arg.type === 'latest'; +} + +export function getLatestTransformConfig(): TransformLatestConfig { + const timestamp = Date.now(); + return { + id: `ec_cloning_2_${timestamp}`, + source: { index: ['ft_ecommerce'] }, + latest: { + unique_key: ['category.keyword'], + sort: 'order_date', + }, + description: 'ecommerce batch transform with category unique key and sorted by order date', + frequency: '3s', + settings: { + max_page_search_size: 250, + }, + dest: { index: `user-ec_3_${timestamp}` }, + }; +} diff --git a/x-pack/test/functional/services/transform/wizard.ts b/x-pack/test/functional/services/transform/wizard.ts index b05f1ff26199..1bfe3284c904 100644 --- a/x-pack/test/functional/services/transform/wizard.ts +++ b/x-pack/test/functional/services/transform/wizard.ts @@ -157,7 +157,7 @@ export function TransformWizardProvider({ getService }: FtrProviderContext) { await this.assertPivotPreviewExists('loaded'); }, - async assertPivotPreviewEmpty() { + async assertTransformPreviewEmpty() { await this.assertPivotPreviewExists('empty'); }, @@ -247,6 +247,65 @@ export function TransformWizardProvider({ getService }: FtrProviderContext) { ); }, + async assertSelectedTransformFunction(transformFunction: 'pivot' | 'latest') { + await testSubjects.existOrFail( + `transformCreation-${transformFunction}-option selectedFunction` + ); + }, + + async selectTransformFunction(transformFunction: 'pivot' | 'latest') { + await testSubjects.click(`transformCreation-${transformFunction}-option`); + await this.assertSelectedTransformFunction(transformFunction); + }, + + async assertUniqueKeysInputExists() { + await testSubjects.existOrFail('transformWizardUniqueKeysSelector > comboBoxInput'); + }, + + async getUniqueKeyEntries() { + return await comboBox.getComboBoxSelectedOptions( + 'transformWizardUniqueKeysSelector > comboBoxInput' + ); + }, + + async assertUniqueKeysInputValue(expectedIdentifier: string[]) { + await retry.tryForTime(2000, async () => { + const comboBoxSelectedOptions = await this.getUniqueKeyEntries(); + expect(comboBoxSelectedOptions).to.eql( + expectedIdentifier, + `Expected unique keys value to be '${expectedIdentifier}' (got '${comboBoxSelectedOptions}')` + ); + }); + }, + + async addUniqueKeyEntry(identified: string, label: string) { + await comboBox.set('transformWizardUniqueKeysSelector > comboBoxInput', identified); + await this.assertUniqueKeysInputValue([ + ...new Set([...(await this.getUniqueKeyEntries()), identified]), + ]); + }, + + async assertSortFieldInputExists() { + await testSubjects.existOrFail('transformWizardSortFieldSelector > comboBoxInput'); + }, + + async assertSortFieldInputValue(expectedIdentifier: string) { + await retry.tryForTime(2000, async () => { + const comboBoxSelectedOptions = await comboBox.getComboBoxSelectedOptions( + 'transformWizardSortFieldSelector > comboBoxInput' + ); + expect(comboBoxSelectedOptions).to.eql( + expectedIdentifier === '' ? [] : [expectedIdentifier], + `Expected sort field to be '${expectedIdentifier}' (got '${comboBoxSelectedOptions}')` + ); + }); + }, + + async setSortFieldValue(identificator: string, label: string) { + await comboBox.set('transformWizardSortFieldSelector > comboBoxInput', identificator); + await this.assertSortFieldInputValue(identificator); + }, + async assertGroupByInputExists() { await testSubjects.existOrFail('transformGroupBySelection > comboBoxInput'); }, @@ -426,7 +485,7 @@ export function TransformWizardProvider({ getService }: FtrProviderContext) { ); }, - async enabledAdvancedPivotEditor() { + async enableAdvancedPivotEditor() { await this.assertAdvancedPivotEditorSwitchCheckState(false); await testSubjects.click('transformAdvancedPivotEditorSwitch'); await this.assertAdvancedPivotEditorSwitchCheckState(true);