Skip to content

Commit

Permalink
[ML] Anomaly Detection: Adds functional tests for filtering by influe…
Browse files Browse the repository at this point in the history
…ncers in the Anomaly Explorer (elastic#146085)

## Summary

Related meta issue: elastic#142456
Adds functional tests for filtering by influencers in the Anomaly
Explorer

Flaky test build
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1592

### 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 <[email protected]>
(cherry picked from commit 395fe5a)
  • Loading branch information
alvarezmelissa87 committed Nov 23, 2022
1 parent 7bc3f2e commit 66943a6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function getAddFilter({ entityName, entityValue, filter }: EntityCellProps) {
>
<EuiButtonIcon
size="s"
data-test-subj={`mlAnomaliesTableEntityCellAddFilterButton-${entityValue}`}
className="filter-button"
onClick={blurButtonOnClick(() => {
filter(entityName, entityValue, ENTITY_FIELD_OPERATIONS.ADD);
Expand Down Expand Up @@ -68,6 +69,7 @@ function getRemoveFilter({ entityName, entityValue, filter }: EntityCellProps) {
>
<EuiButtonIcon
size="s"
data-test-subj={`mlAnomaliesTableEntityCellRemoveFilterButton-${entityValue}`}
className="filter-button"
onClick={blurButtonOnClick(() => {
filter(entityName, entityValue, ENTITY_FIELD_OPERATIONS.REMOVE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,46 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await ml.anomaliesTable.assertTableNotEmpty();
});

it('should allow filtering by influencer', async () => {
const fieldName = testData.expected.influencers[0].field;
const fieldValue = testData.expected.influencers[0].labelsContained[0];

await ml.testExecution.logTestStep(
'adds influencer filter by clicking on the influencer add filter button'
);
await ml.anomalyExplorer.addFilterForInfluencer(fieldName, fieldValue);
await ml.testExecution.logTestStep('query bar and table rows reflect filter');
await ml.anomalyExplorer.assertQueryBarContent(`${fieldName}:"${fieldValue}"`);
await ml.anomaliesTable.assertInfluencersCellsContainFilter(
`${fieldName}: ${fieldValue}`
);
await ml.testExecution.logTestStep('influencers list and swimlane reflect filter');
await ml.swimLane.assertAxisLabels(viewBySwimLaneTestSubj, 'y', [fieldValue]);
await ml.anomalyExplorer.assertInfluencerFieldListLength('airline', 1);
await ml.testExecution.logTestStep(
'removes influencer filter by clicking on the influencer remove filter button'
);
await ml.anomalyExplorer.removeFilterForInfluencer(fieldName, fieldValue);
await ml.testExecution.logTestStep('query bar reflects filter removal');
await ml.anomalyExplorer.assertQueryBarContent('');
await ml.testExecution.logTestStep(
'influencers list and swimlane reflect filter removal'
);
await ml.swimLane.assertAxisLabels(viewBySwimLaneTestSubj, 'y', [
'AAL',
'EGF',
'VRD',
'SWR',
'JZA',
'AMX',
'TRS',
'ACA',
'BAW',
'ASA',
]);
await ml.anomalyExplorer.assertInfluencerFieldListLength('airline', 10);
});

it('has enabled Single Metric Viewer button', async () => {
await ml.anomalyExplorer.assertSingleMetricViewerButtonEnabled(true);
});
Expand Down
8 changes: 8 additions & 0 deletions x-pack/test/functional/services/ml/anomalies_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ export function MachineLearningAnomaliesTableProvider({ getService }: FtrProvide
);
},

async assertInfluencersCellsContainFilter(filterString: string) {
const tableRows = await testSubjects.findAll('mlAnomaliesListColumnInfluencers');
for (const row of tableRows) {
const influencerColumnCellText = await row.getVisibleText();
expect(influencerColumnCellText).to.eql(filterString);
}
},

async assertAnomalyActionsMenuButtonExists(rowIndex: number) {
const rowSubj = await this.getRowSubjByRowIndex(rowIndex);
await testSubjects.existOrFail(`${rowSubj} > mlAnomaliesListRowActionsButton`);
Expand Down
28 changes: 28 additions & 0 deletions x-pack/test/functional/services/ml/anomaly_explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ export function MachineLearningAnomalyExplorerProvider(
return influencerFieldLabels;
},

async getQueryBarText() {
const queryBarElement = await testSubjects.find('explorerQueryInput');
const queryBarText = await queryBarElement.getVisibleText();
return queryBarText;
},

async assertQueryBarContent(contentString: string) {
const queryBarText = await this.getQueryBarText();
expect(queryBarText).to.eql(
contentString,
`Expected influencer filter to be '${contentString}' (got '${queryBarText}')`
);
},

async assertInfluencerListContainsLabel(influencerField: string, label: string) {
const influencerFieldLabels = await this.getInfluencerFieldLabels(influencerField);
expect(influencerFieldLabels).to.contain(
Expand Down Expand Up @@ -84,6 +98,20 @@ export function MachineLearningAnomalyExplorerProvider(
});
},

async addFilterForInfluencer(influencerField: string, influencerValue: string) {
await testSubjects.existOrFail(
`mlAnomaliesTableEntityCellAddFilterButton-${influencerValue}`
);
await testSubjects.click(`mlAnomaliesTableEntityCellAddFilterButton-${influencerValue}`);
},

async removeFilterForInfluencer(influencerField: string, influencerValue: string) {
await testSubjects.existOrFail(
`mlAnomaliesTableEntityCellRemoveFilterButton-${influencerValue}`
);
await testSubjects.click(`mlAnomaliesTableEntityCellRemoveFilterButton-${influencerValue}`);
},

async openAddToDashboardControl() {
await testSubjects.click('mlAnomalyTimelinePanelMenu');
await testSubjects.click('mlAnomalyTimelinePanelAddToDashboardButton');
Expand Down

0 comments on commit 66943a6

Please sign in to comment.