mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Infra UI] Add infra serverless functional tests (#168621)
Closes #166749
## Summary
This PR adds serverless functional tests for the infra plugin. The main
goal is to make sure that the app loads all the pages and successfully
navigates between them. As we already have functional tests covering the
whole functionality here we want to cover the differences with
serverless and some basic checks ensuring that base functionality works
correctly.
- Update the test to cover disabling the create rule button added
[here](https://github.com/elastic/kibana/pull/167978):
([x-pack/test_serverless/functional/test_suites/observability/infra/hosts_page.ts](87fb991f2f (diff-76bd05d3fed2c44187682e27b4030ddb9cba1a36235321e0db1b371ef6739cc9)
))
⚠️ The tests for the second AC point related to user roles will go in a[
separate issue ](https://github.com/elastic/kibana/issues/168931)
Test server run:
`node scripts/functional_tests_server.js
--config=x-pack/test_serverless/functional/test_suites/observability/config.ts`
Tests run:
`node scripts/functional_test_runner
--config=x-pack/test_serverless/functional/test_suites/observability/config.ts
--grep "Observability Infra"`
This commit is contained in:
parent
a0b5898940
commit
291f5eabc1
6 changed files with 466 additions and 1 deletions
|
@ -105,7 +105,7 @@ export const Processes = () => {
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle data-test-subj="infraAssetDetailsAlertsTitle" size="xxs">
|
||||
<EuiTitle data-test-subj="infraAssetDetailsTopProcessesTitle" size="xxs">
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id="xpack.infra.metrics.nodeDetails.processesHeader"
|
||||
|
|
|
@ -6,3 +6,24 @@
|
|||
*/
|
||||
|
||||
export const HOSTS_VIEW_PATH = 'metrics/hosts';
|
||||
export const INVENTORY_PATH = 'metrics/inventory';
|
||||
export const METRICS_EXPLORER_PATH = 'metrics/explorer';
|
||||
export const NODE_DETAILS_PATH = 'detail/host';
|
||||
|
||||
export const DATES = {
|
||||
metricsAndLogs: {
|
||||
hosts: {
|
||||
withData: '10/17/2018 7:58:03 PM',
|
||||
withoutData: '10/09/2018 10:00:00 PM',
|
||||
min: '2018-10-17T19:42:21.208Z',
|
||||
max: '2018-10-17T19:58:03.952Z',
|
||||
kubernetesSectionStartDate: '2023-09-19T07:20:00.000Z',
|
||||
kubernetesSectionEndDate: '2023-09-19T07:21:00.000Z',
|
||||
},
|
||||
pods: {
|
||||
withData: '01/20/2022 5:10:00 PM',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const DATE_PICKER_FORMAT = 'MMM D, YYYY @ HH:mm:ss.SSS';
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* 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 moment from 'moment';
|
||||
import expect from '@kbn/expect';
|
||||
import type { WebElementWrapper } from '../../../../../../test/functional/services/lib/web_element_wrapper';
|
||||
import type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
import { HOSTS_VIEW_PATH } from './constants';
|
||||
import { DATES, DATE_PICKER_FORMAT } from './constants';
|
||||
|
||||
const START_DATE = moment.utc(DATES.metricsAndLogs.hosts.min);
|
||||
const END_DATE = moment.utc(DATES.metricsAndLogs.hosts.max);
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const browser = getService('browser');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const pageObjects = getPageObjects([
|
||||
'assetDetails',
|
||||
'common',
|
||||
'infraHome',
|
||||
'timePicker',
|
||||
'infraHostsView',
|
||||
'settings',
|
||||
'header',
|
||||
'svlCommonPage',
|
||||
]);
|
||||
|
||||
const waitForPageToLoad = async () =>
|
||||
await retry.waitFor(
|
||||
'wait for table and KPI charts to load',
|
||||
async () =>
|
||||
(await pageObjects.infraHostsView.isHostTableLoading()) &&
|
||||
(await pageObjects.infraHostsView.isKPIChartsLoaded())
|
||||
);
|
||||
|
||||
describe('Hosts Page', function () {
|
||||
before(async () => {
|
||||
await Promise.all([
|
||||
esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'),
|
||||
]);
|
||||
await pageObjects.svlCommonPage.login();
|
||||
await browser.setWindowSize(1600, 1200);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await Promise.all([
|
||||
esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'),
|
||||
]);
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('#Single Host Flyout', () => {
|
||||
before(async () => {
|
||||
await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
|
||||
describe('Tabs', () => {
|
||||
before(async () => {
|
||||
await pageObjects.timePicker.setAbsoluteRange(
|
||||
START_DATE.format(DATE_PICKER_FORMAT),
|
||||
END_DATE.format(DATE_PICKER_FORMAT)
|
||||
);
|
||||
|
||||
await waitForPageToLoad();
|
||||
|
||||
await pageObjects.infraHostsView.clickTableOpenFlyoutButton();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await retry.try(async () => {
|
||||
await pageObjects.infraHostsView.clickCloseFlyoutButton();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Overview Tab', () => {
|
||||
before(async () => {
|
||||
await pageObjects.assetDetails.clickOverviewTab();
|
||||
});
|
||||
|
||||
it('should render 9 charts in the Metrics section', async () => {
|
||||
const hosts = await pageObjects.assetDetails.getAssetDetailsMetricsCharts();
|
||||
expect(hosts.length).to.equal(9);
|
||||
});
|
||||
|
||||
it('should show alerts', async () => {
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await pageObjects.assetDetails.overviewAlertsTitleExists();
|
||||
const CreateRuleButtonExist = await testSubjects.exists(
|
||||
'infraAssetDetailsCreateAlertsRuleButton'
|
||||
);
|
||||
expect(CreateRuleButtonExist).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Metadata Tab', () => {
|
||||
before(async () => {
|
||||
await pageObjects.assetDetails.clickMetadataTab();
|
||||
});
|
||||
|
||||
it('should show metadata table', async () => {
|
||||
await pageObjects.assetDetails.metadataTableExists();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Processes Tab', () => {
|
||||
before(async () => {
|
||||
await pageObjects.assetDetails.clickProcessesTab();
|
||||
});
|
||||
|
||||
it('should show processes title', async () => {
|
||||
await await testSubjects.existOrFail('infraAssetDetailsTopProcessesTitle');
|
||||
});
|
||||
|
||||
describe('Logs Tab', () => {
|
||||
before(async () => {
|
||||
await pageObjects.assetDetails.clickLogsTab();
|
||||
});
|
||||
|
||||
it('should render logs tab', async () => {
|
||||
await pageObjects.assetDetails.logsExists();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#Page Content', () => {
|
||||
before(async () => {
|
||||
await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await pageObjects.timePicker.setAbsoluteRange(
|
||||
START_DATE.format(DATE_PICKER_FORMAT),
|
||||
END_DATE.format(DATE_PICKER_FORMAT)
|
||||
);
|
||||
|
||||
await waitForPageToLoad();
|
||||
});
|
||||
|
||||
it('should render the correct page title', async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain('Hosts - Infrastructure - Observability - Elastic');
|
||||
});
|
||||
|
||||
it('should render the title beta badge', async () => {
|
||||
await pageObjects.infraHostsView.getBetaBadgeExists();
|
||||
});
|
||||
|
||||
describe('Hosts table', async () => {
|
||||
let hostRows: WebElementWrapper[] = [];
|
||||
|
||||
before(async () => {
|
||||
hostRows = await pageObjects.infraHostsView.getHostsTableData();
|
||||
});
|
||||
|
||||
it('should render a table with 6 hosts', async () => {
|
||||
expect(hostRows.length).to.equal(6);
|
||||
});
|
||||
});
|
||||
|
||||
describe('KPIs', () => {
|
||||
it('should render KPIs', async () => {
|
||||
await testSubjects.existOrFail('hostsViewKPIGrid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Metrics Tab', () => {
|
||||
before(async () => {
|
||||
await browser.scrollTop();
|
||||
await pageObjects.infraHostsView.visitMetricsTab();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await browser.scrollTop();
|
||||
});
|
||||
|
||||
it('should load 12 lens metric charts', async () => {
|
||||
const metricCharts = await pageObjects.infraHostsView.getAllMetricsCharts();
|
||||
expect(metricCharts.length).to.equal(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logs Tab', () => {
|
||||
before(async () => {
|
||||
await browser.scrollTop();
|
||||
await pageObjects.infraHostsView.visitLogsTab();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await browser.scrollTop();
|
||||
});
|
||||
|
||||
it('should load the Logs tab section when clicking on it', async () => {
|
||||
await testSubjects.existOrFail('hostsView-logs');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Alerts Tab', () => {
|
||||
before(async () => {
|
||||
await browser.scrollTop();
|
||||
await pageObjects.infraHostsView.visitAlertTab();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await browser.scrollTop();
|
||||
});
|
||||
|
||||
it('should correctly load the Alerts tab section when clicking on it', async () => {
|
||||
testSubjects.existOrFail('hostsView-alerts');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -12,5 +12,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
// TimeoutError: Waiting for element to be located By(css selector, [data-test-subj="infrastructure-alerts-and-rules"])
|
||||
this.tags(['failsOnMKI']);
|
||||
loadTestFile(require.resolve('./header_menu'));
|
||||
loadTestFile(require.resolve('./node_details'));
|
||||
loadTestFile(require.resolve('./hosts_page'));
|
||||
loadTestFile(require.resolve('./infra'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import { DATES, INVENTORY_PATH, METRICS_EXPLORER_PATH } from './constants';
|
||||
|
||||
const DATE_WITH_DATA = DATES.metricsAndLogs.hosts.withData;
|
||||
const DATE_WITHOUT_DATA = DATES.metricsAndLogs.hosts.withoutData;
|
||||
const DATE_WITH_POD_WITH_DATA = DATES.metricsAndLogs.pods.withData;
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const browser = getService('browser');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const pageObjects = getPageObjects(['common', 'header', 'infraHome', 'svlCommonPage']);
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
const returnTo = async (path: string, timeout = 2000) =>
|
||||
retry.waitForWithTimeout('returned to inventory', timeout, async () => {
|
||||
await browser.goBack();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
return !!currentUrl.match(path);
|
||||
});
|
||||
|
||||
describe('Infra pages', function () {
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('Inventory page', function () {
|
||||
this.tags('includeFirefox');
|
||||
before(async () => {
|
||||
await kibanaServer.savedObjects.cleanStandardList();
|
||||
});
|
||||
|
||||
describe('with metrics present', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/8.0.0/pods_only');
|
||||
await pageObjects.common.navigateToApp(INVENTORY_PATH);
|
||||
await pageObjects.infraHome.waitForLoading();
|
||||
});
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/8.0.0/pods_only');
|
||||
});
|
||||
|
||||
it('renders the correct page title', async () => {
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain('Inventory - Infrastructure - Observability - Elastic');
|
||||
});
|
||||
|
||||
it('renders an empty data prompt for dates with no data', async () => {
|
||||
await pageObjects.infraHome.goToTime(DATE_WITHOUT_DATA);
|
||||
await pageObjects.infraHome.getNoMetricsDataPrompt();
|
||||
});
|
||||
|
||||
it('renders the waffle map and tooltips for dates with data', async () => {
|
||||
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
|
||||
await pageObjects.infraHome.getWaffleMap();
|
||||
});
|
||||
|
||||
describe('Redirect to Node Details page', () => {
|
||||
before(async () => {
|
||||
await pageObjects.common.navigateToApp(INVENTORY_PATH);
|
||||
await pageObjects.infraHome.waitForLoading();
|
||||
});
|
||||
|
||||
it('Should redirect to Host Details page', async () => {
|
||||
await pageObjects.infraHome.goToTime(DATE_WITH_DATA);
|
||||
await pageObjects.infraHome.goToHost();
|
||||
await pageObjects.infraHome.clickOnFirstNode();
|
||||
await pageObjects.infraHome.waitForLoading();
|
||||
await pageObjects.infraHome.clickOnNodeDetailsFlyoutOpenAsPage();
|
||||
|
||||
await retry.try(async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'demo-stack-redis-01 - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
await returnTo(INVENTORY_PATH);
|
||||
});
|
||||
|
||||
it('Should redirect to Node Details page', async () => {
|
||||
await pageObjects.infraHome.goToTime(DATE_WITH_POD_WITH_DATA);
|
||||
await pageObjects.infraHome.goToPods();
|
||||
await pageObjects.infraHome.clickOnFirstNode();
|
||||
await pageObjects.infraHome.clickOnGoToNodeDetails();
|
||||
|
||||
await retry.try(async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain('pod-0 - Infrastructure - Observability - Elastic');
|
||||
});
|
||||
|
||||
await returnTo(INVENTORY_PATH);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Metrics explorer page', function () {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await pageObjects.common.navigateToApp(METRICS_EXPLORER_PATH);
|
||||
await pageObjects.infraHome.waitForLoading();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
});
|
||||
|
||||
it('should be disabled', async () => {
|
||||
await testSubjects.existOrFail('infraNotFoundPage');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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 moment from 'moment';
|
||||
import expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import { DATES, NODE_DETAILS_PATH, DATE_PICKER_FORMAT } from './constants';
|
||||
|
||||
const START_HOST_KUBERNETES_SECTION_DATE = moment.utc(
|
||||
DATES.metricsAndLogs.hosts.kubernetesSectionStartDate
|
||||
);
|
||||
const END_HOST_KUBERNETES_SECTION_DATE = moment.utc(
|
||||
DATES.metricsAndLogs.hosts.kubernetesSectionEndDate
|
||||
);
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const pageObjects = getPageObjects([
|
||||
'assetDetails',
|
||||
'common',
|
||||
'infraHome',
|
||||
'header',
|
||||
'timePicker',
|
||||
'svlCommonPage',
|
||||
]);
|
||||
|
||||
describe('Node Details', () => {
|
||||
describe('#With Asset Details', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
|
||||
await pageObjects.svlCommonPage.login();
|
||||
await pageObjects.common.navigateToApp(
|
||||
`metrics/${NODE_DETAILS_PATH}/demo-stack-kubernetes-01`
|
||||
);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('Osquery Tab', () => {
|
||||
it('should not render in serverless', async () => {
|
||||
const OsqueryExist = await testSubjects.exists('infraAssetDetailsOsqueryTab');
|
||||
expect(OsqueryExist).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#With Kubernetes section', () => {
|
||||
describe('Overview Tab', () => {
|
||||
before(async () => {
|
||||
await pageObjects.assetDetails.clickOverviewTab();
|
||||
|
||||
await pageObjects.timePicker.setAbsoluteRange(
|
||||
START_HOST_KUBERNETES_SECTION_DATE.format(DATE_PICKER_FORMAT),
|
||||
END_HOST_KUBERNETES_SECTION_DATE.format(DATE_PICKER_FORMAT)
|
||||
);
|
||||
});
|
||||
|
||||
it('should show alerts', async () => {
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await pageObjects.assetDetails.overviewAlertsTitleExists();
|
||||
const CreateRuleButtonExist = await testSubjects.exists(
|
||||
'infraAssetDetailsCreateAlertsRuleButton'
|
||||
);
|
||||
expect(CreateRuleButtonExist).to.be(false);
|
||||
});
|
||||
|
||||
it('should render 12 charts in the Metrics section', async () => {
|
||||
const hosts = await pageObjects.assetDetails.getAssetDetailsMetricsCharts();
|
||||
expect(hosts.length).to.equal(12);
|
||||
});
|
||||
|
||||
it('should render 4 charts in the Kubernetes Metrics section', async () => {
|
||||
const hosts = await pageObjects.assetDetails.getAssetDetailsKubernetesMetricsCharts();
|
||||
expect(hosts.length).to.equal(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue