[ML] Memory Usage and Notifications pages serverless functional tests (#205898)

Part of: https://github.com/elastic/kibana/issues/201813

- [x] Memory Usage. Check ML entities are filtered according to the
project type.

- [x] Notifications page. Check ML entities are filtered according to
the project type.
This commit is contained in:
Robert Jaszczurek 2025-01-17 12:22:34 +01:00 committed by GitHub
parent 39cc2e342f
commit 9bc2438eed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 183 additions and 0 deletions

View file

@ -106,5 +106,13 @@ export function MachineLearningMemoryUsageProvider({ getService }: FtrProviderCo
async assertEmptyTreeChartExists() {
await testSubjects.existOrFail('mlJobTreeMap empty');
},
async assertJobTreeComboBoxExists() {
await testSubjects.existOrFail('mlJobTreeMapComboBox');
},
async getJobTreeComboBoxOptions() {
return await comboBox.getOptions('mlJobTreeMapComboBox');
},
};
}

View file

@ -16,6 +16,7 @@ export function NotificationsProvider(
tableService: MlTableService
) {
const testSubjects = getService('testSubjects');
const find = getService('find');
return {
async assertNotificationIndicatorExist(expectExist = true) {
@ -31,6 +32,21 @@ export function NotificationsProvider(
expect(actualCount).to.greaterThan(expectedCount);
},
// This is a workaround for receiving available filter dropdown options,
// since EUI doesn't allow testSubjects for filters.
async getAvailableTypeFilters() {
const filterButton = await find.byCssSelector(
'.euiFilterGroup > *:nth-child(2) .euiFilterButton'
);
await filterButton.click();
const optionElements = await find.allByCssSelector('li[role="option"].euiSelectableListItem');
const optionTexts = await Promise.all(
optionElements.map(async (element) => await element.getVisibleText())
);
return optionTexts;
},
table: tableService.getServiceInstance(
'NotificationsTable',
'mlNotificationsTable',

View file

@ -26,5 +26,11 @@ export function MachineLearningNavigationProviderObservability({
async navigateToAnomalyDetection() {
await navigateToArea('anomalyDetection');
},
async navigateToMemoryUsage() {
await navigateToArea('memoryUsage');
},
async navigateToNotifications() {
await navigateToArea('notifications');
},
};
}

View file

@ -28,5 +28,11 @@ export function MachineLearningNavigationProviderSecurity({ getService }: FtrPro
async navigateToTrainedModels() {
await navigateToArea('nodesOverview');
},
async navigateToMemoryUsage() {
await navigateToArea('memoryUsage');
},
async navigateToNotifications() {
await navigateToArea('notifications');
},
};
}

View file

@ -14,5 +14,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
this.tags(['failsOnMKI']);
loadTestFile(require.resolve('./anomaly_detection_jobs_list'));
loadTestFile(require.resolve('./search_bar_features'));
loadTestFile(require.resolve('./memory_usage'));
loadTestFile(require.resolve('./notifications'));
});
}

View file

@ -0,0 +1,37 @@
/*
* 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 default function ({ getService, getPageObjects }: FtrProviderContext) {
const ml = getService('ml');
const svlMl = getService('svlMl');
const PageObjects = getPageObjects(['svlCommonPage']);
const availableMLObjectTypes = ['Anomaly detection jobs', 'Trained models'];
describe('Memory usage page', function () {
before(async () => {
await PageObjects.svlCommonPage.loginWithPrivilegedRole();
});
it('opens page with all available ML object types for Observability', async () => {
await ml.navigation.navigateToMl();
await svlMl.navigation.observability.navigateToMemoryUsage();
await ml.memoryUsage.assertJobTreeComboBoxExists();
const selectedItems = await ml.memoryUsage.getSelectedChartItems();
expect(selectedItems).to.eql(availableMLObjectTypes);
// Make sure there are no other available indicies
const options = await ml.memoryUsage.getJobTreeComboBoxOptions();
expect(options).empty();
});
});
}

View file

@ -0,0 +1,30 @@
/*
* 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 default function ({ getService, getPageObjects }: FtrProviderContext) {
const ml = getService('ml');
const svlMl = getService('svlMl');
const PageObjects = getPageObjects(['svlCommonPage']);
const expectedObservabilityTypeFilters = ['Anomaly Detection', 'Inference', 'System'];
describe('Notifications page', function () {
before(async () => {
await PageObjects.svlCommonPage.loginWithPrivilegedRole();
});
it('displays only notification types for observability projects', async () => {
await svlMl.navigation.observability.navigateToNotifications();
const availableTypeFilters = await ml.notifications.getAvailableTypeFilters();
expect(availableTypeFilters).to.eql(expectedObservabilityTypeFilters);
});
});
}

View file

@ -13,5 +13,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./data_frame_analytics_jobs_list'));
loadTestFile(require.resolve('./trained_models_list'));
loadTestFile(require.resolve('./search_bar_features'));
loadTestFile(require.resolve('./memory_usage'));
loadTestFile(require.resolve('./notifications'));
});
}

View file

@ -0,0 +1,41 @@
/*
* 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 default function ({ getService, getPageObjects }: FtrProviderContext) {
const ml = getService('ml');
const svlMl = getService('svlMl');
const PageObjects = getPageObjects(['svlCommonPage']);
const availableMLObjectTypes = [
'Anomaly detection jobs',
'Data frame analytics jobs',
'Trained models',
];
describe('Memory usage page', function () {
before(async () => {
await PageObjects.svlCommonPage.loginWithPrivilegedRole();
});
it('opens page with all available ML object types for Security', async () => {
await ml.navigation.navigateToMl();
await svlMl.navigation.security.navigateToMemoryUsage();
await ml.memoryUsage.assertJobTreeComboBoxExists();
const selectedItems = await ml.memoryUsage.getSelectedChartItems();
expect(selectedItems).to.eql(availableMLObjectTypes);
// Make sure there are no other available indicies
const options = await ml.memoryUsage.getJobTreeComboBoxOptions();
expect(options).empty();
});
});
}

View file

@ -0,0 +1,35 @@
/*
* 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 default function ({ getService, getPageObjects }: FtrProviderContext) {
const ml = getService('ml');
const svlMl = getService('svlMl');
const PageObjects = getPageObjects(['svlCommonPage']);
const expectedSecurityTypeFilters = [
'Anomaly Detection',
'Data Frame Analytics',
'Inference',
'System',
];
describe('Notifications page', function () {
before(async () => {
await PageObjects.svlCommonPage.loginWithPrivilegedRole();
});
it('displays only notification types for security projects', async () => {
await svlMl.navigation.security.navigateToNotifications();
const availableTypeFilters = await ml.notifications.getAvailableTypeFilters();
expect(availableTypeFilters).to.eql(expectedSecurityTypeFilters);
});
});
}