[Kibana Overview] First round of functional tests (#134680)

* [Kibana Overview] First round of functional tests

* Update tests

* Update snapshot

* Update failing test

* Fix failing test

* Fix failing test

* Fix failing test

* Fix failing test

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Maja Grubic 2022-06-23 07:46:04 +02:00 committed by GitHub
parent 52fa9c391f
commit 8ae497afcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 373 additions and 33 deletions

View file

@ -73,6 +73,7 @@ enabled:
- test/functional/apps/discover/config.ts
- test/functional/apps/getting_started/config.ts
- test/functional/apps/home/config.ts
- test/functional/apps/kibana_overview/config.ts
- test/functional/apps/management/config.ts
- test/functional/apps/saved_objects_management/config.ts
- test/functional/apps/status_page/config.ts

View file

@ -1,22 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Overview during loading 1`] = `
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<span
aria-label="Loading"
class="euiLoadingSpinner css-1ow0yso-euiLoadingSpinner-xl"
role="progressbar"
/>
</div>
</div>
`;
exports[`Overview render 1`] = `
exports[`Overview renders correctly 1`] = `
<Overview
features={
Array [
@ -246,7 +230,7 @@ exports[`Overview render 1`] = `
</Overview>
`;
exports[`Overview when there is no user data view 1`] = `
exports[`Overview renders correctly when there is no user data view 1`] = `
<Overview
features={
Array [
@ -746,7 +730,7 @@ exports[`Overview when there is no user data view 1`] = `
</Overview>
`;
exports[`Overview without features 1`] = `
exports[`Overview renders correctly without features 1`] = `
<Overview
features={Array []}
intl={
@ -946,7 +930,7 @@ exports[`Overview without features 1`] = `
</Overview>
`;
exports[`Overview without solutions 1`] = `
exports[`Overview renders correctly without solutions 1`] = `
<Overview
features={
Array [
@ -1140,3 +1124,19 @@ exports[`Overview without solutions 1`] = `
</KibanaPageTemplate>
</Overview>
`;
exports[`Overview show loading spinner during loading 1`] = `
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<span
aria-label="Loading"
class="euiLoadingSpinner css-1ow0yso-euiLoadingSpinner-xl"
role="progressbar"
/>
</div>
</div>
`;

View file

@ -166,7 +166,7 @@ describe('Overview', () => {
afterAll(() => jest.clearAllMocks());
test('render', async () => {
test('renders correctly', async () => {
const component = mountWithIntl(
<Overview
newsFetchResult={mockNewsFetchResult}
@ -181,7 +181,7 @@ describe('Overview', () => {
expect(component.find(KibanaPageTemplate).length).toBe(1);
});
test('without solutions', async () => {
test('renders correctly without solutions', async () => {
const component = mountWithIntl(
<Overview newsFetchResult={mockNewsFetchResult} solutions={[]} features={mockFeatures} />
);
@ -191,7 +191,7 @@ describe('Overview', () => {
expect(component).toMatchSnapshot();
});
test('without features', async () => {
test('renders correctly without features', async () => {
const component = mountWithIntl(
<Overview newsFetchResult={mockNewsFetchResult} solutions={mockSolutions} features={[]} />
);
@ -201,7 +201,7 @@ describe('Overview', () => {
expect(component).toMatchSnapshot();
});
test('when there is no user data view', async () => {
test('renders correctly when there is no user data view', async () => {
hasESData.mockResolvedValue(true);
hasUserDataView.mockResolvedValue(false);
@ -221,7 +221,7 @@ describe('Overview', () => {
expect(component.find(EuiLoadingSpinner).length).toBe(0);
});
test('during loading', async () => {
test('show loading spinner during loading', async () => {
hasESData.mockImplementation(() => new Promise(() => {}));
hasUserDataView.mockImplementation(() => new Promise(() => {}));

View file

@ -22,11 +22,11 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { CoreStart } from '@kbn/core/public';
import {
useKibana,
KibanaPageTemplateSolutionNavAvatar,
overviewPageActions,
OverviewPageFooter,
} from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
import {
AnalyticsNoDataPageKibanaProvider,
AnalyticsNoDataPage,
@ -298,13 +298,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
className={`kbnOverviewSolution ${id}`}
description={description ? description : ''}
href={addBasePath(path)}
icon={
<KibanaPageTemplateSolutionNavAvatar
name={title}
iconType={icon}
size="xl"
/>
}
icon={<KibanaSolutionAvatar name={title} iconType={icon} size="xl" />}
image={addBasePath(getSolutionGraphicURL(snakeCase(id)))}
title={title}
titleElement="h3"

View file

@ -0,0 +1,63 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
import { WebElementWrapper } from '../../services/lib/web_element_wrapper';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['common', 'header']);
describe('overview page - Analytics apps', function describeIndexTests() {
before(async () => {
await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
});
after(async () => {
await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
});
const apps = ['dashboard', 'discover', 'canvas', 'maps', 'ml'];
it('should display Analytics apps cards', async () => {
const kbnOverviewAppsCards = await find.allByCssSelector('.kbnOverviewApps__item');
expect(kbnOverviewAppsCards.length).to.be(apps.length);
const verifyImageUrl = async (el: WebElementWrapper, imgName: string) => {
const image = await el.findByCssSelector('img');
const imageUrl = await image.getAttribute('src');
expect(imageUrl.includes(imgName)).to.be(true);
};
for (let i = 0; i < apps.length; i++) {
verifyImageUrl(kbnOverviewAppsCards[i], `kibana_${apps[i]}_light.svg`);
}
});
it('click on a card should lead to the appropriate app', async () => {
const kbnOverviewAppsCards = await find.allByCssSelector('.kbnOverviewApps__item');
const dashboardCard = kbnOverviewAppsCards.at(0);
expect(dashboardCard).not.to.be(undefined);
if (dashboardCard) {
await dashboardCard.click();
await PageObjects.common.waitUntilUrlIncludes('app/dashboards');
}
});
});
}

View file

@ -0,0 +1,55 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const esArchiver = getService('esArchiver');
const retry = getService('retry');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['common', 'header']);
const defaultSettings = {
default_route: 'app/home',
};
describe('overview page - footer', function describeIndexTests() {
before(async () => {
await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
await kibanaServer.uiSettings.replace(defaultSettings);
});
after(async () => {
await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await kibanaServer.uiSettings.replace(defaultSettings);
});
it('clicking footer updates landing page', async () => {
await PageObjects.header.waitUntilLoadingHasFinished();
let footerButton = await find.byCssSelector('.kbnOverviewPageFooter__button');
await footerButton.click();
await retry.try(async () => {
footerButton = await find.byCssSelector('.kbnOverviewPageFooter__button');
const text = await (
await footerButton.findByCssSelector('.euiButtonEmpty__text')
).getVisibleText();
expect(text.toString().includes('Display a different page on log in')).to.be(true);
});
});
});
}

View file

@ -0,0 +1,42 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const testSubjects = getService('testSubjects');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['common', 'header']);
describe('overview page - no data', function describeIndexTests() {
before(async () => {
await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional');
kibanaServer.savedObjects.clean({ types: ['index-pattern'] });
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
});
it('should display no data page', async () => {
await PageObjects.header.waitUntilLoadingHasFinished();
const exists = await find.byClassName('kbnNoDataPageContents');
expect(exists).not.to.be(undefined);
});
it('click on add data opens integrations', async () => {
const addIntegrations = await testSubjects.find('kbnOverviewAddIntegrations');
await addIntegrations.click();
await PageObjects.common.waitUntilUrlIncludes('integrations/browse');
});
});
}

View file

@ -0,0 +1,69 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['common', 'header', 'dashboard']);
describe('overview page - page header', function describeIndexTests() {
before(async () => {
await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
});
after(async () => {
await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
});
it('click on integrations leads to integrations', async () => {
const headerItems = await find.byCssSelector('.euiPageHeaderContent__rightSideItems');
const items = await headerItems.findAllByCssSelector('.kbnRedirectCrossAppLinks');
expect(items!.length).to.be(3);
const integrations = await items!.at(0);
await integrations!.click();
await PageObjects.common.waitUntilUrlIncludes('app/integrations/browse');
});
it('click on management leads to management', async () => {
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
const headerItems = await find.byCssSelector('.euiPageHeaderContent__rightSideItems');
const items = await headerItems.findAllByCssSelector('.kbnRedirectCrossAppLinks');
const management = await items!.at(1);
await management!.click();
await PageObjects.common.waitUntilUrlIncludes('app/management');
});
it('click on dev tools leads to dev tools', async () => {
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
const headerItems = await find.byCssSelector('.euiPageHeaderContent__rightSideItems');
const items = await headerItems.findAllByCssSelector('.kbnRedirectCrossAppLinks');
const devTools = await items!.at(2);
await devTools!.click();
await PageObjects.common.waitUntilUrlIncludes('app/dev_tools');
});
});
}

View file

@ -0,0 +1,72 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'header']);
describe('overview page - solutions', function describeIndexTests() {
before(async () => {
await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
});
after(async () => {
await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.unload(
'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern'
);
});
it('contains the appropriate solutions', async () => {
const solutionCards = await find.allByCssSelector('.kbnOverviewMore__item');
expect(solutionCards.length).to.be(2);
const observabilityImage = await solutionCards[0].findByCssSelector('img');
const observabilityImageUrl = await observabilityImage.getAttribute('src');
expect(observabilityImageUrl.includes('/solutions_observability.svg')).to.be(true);
const securityImage = await solutionCards[1].findByCssSelector('img');
const securityImageUrl = await securityImage.getAttribute('src');
expect(securityImageUrl.includes('/solutions_security_solution.svg')).to.be(true);
});
it('click on Observability card leads to Observability', async () => {
let solutionCards: string | any[] = [];
await retry.waitForWithTimeout('all solutions to be present', 5000, async () => {
solutionCards = await find.allByCssSelector('.kbnOverviewMore__item');
return solutionCards.length === 2;
});
await solutionCards[0].click();
await PageObjects.common.waitUntilUrlIncludes('app/observability');
});
it('click on Security card leads to Security', async () => {
await PageObjects.common.navigateToUrl('kibana_overview', '', { useActualUrl: true });
await PageObjects.header.waitUntilLoadingHasFinished();
let solutionCards: string | any[] = [];
await retry.waitForWithTimeout('all solutions to be present', 5000, async () => {
solutionCards = await find.allByCssSelector('.kbnOverviewMore__item');
return solutionCards.length === 2;
});
await solutionCards[1].click();
await PageObjects.common.waitUntilUrlIncludes('app/security');
});
});
}

View file

@ -0,0 +1,18 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { FtrConfigProviderContext } from '@kbn/test';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const functionalConfig = await readConfigFile(require.resolve('../../config.base.js'));
return {
...functionalConfig.getAll(),
testFiles: [require.resolve('.')],
};
}

View file

@ -0,0 +1,23 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export default function ({ getService, loadTestFile }) {
const browser = getService('browser');
describe('kibana overview app', function () {
before(function () {
return browser.setWindowSize(1200, 800);
});
loadTestFile(require.resolve('./_no_data'));
loadTestFile(require.resolve('./_page_header'));
loadTestFile(require.resolve('./_analytics'));
loadTestFile(require.resolve('./_solutions'));
loadTestFile(require.resolve('./_footer'));
});
}

View file

@ -90,6 +90,9 @@ export default async function ({ readConfigFile }) {
integrations: {
pathname: '/app/integrations',
},
kibana_overview: {
pathname: '/app/kibana_overview',
},
},
junit: {
reportName: 'Chrome UI Functional Tests',