kibana/test/functional/apps/discover/_discover.ts
Matthias Wilhelm c4ddb01d77
[Discover] Add "Chart options" menu (#112453)
Co-authored-by: Tim Roes <mail@timroes.de>
2021-09-28 10:53:29 +02:00

362 lines
16 KiB
TypeScript

/*
* 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 browser = getService('browser');
const log = getService('log');
const retry = getService('retry');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const queryBar = getService('queryBar');
const inspector = getService('inspector');
const elasticChart = getService('elasticChart');
const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker']);
const defaultSettings = {
defaultIndex: 'logstash-*',
};
describe('discover test', function describeIndexTests() {
before(async function () {
log.debug('load kibana index with default index pattern');
await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json');
// and load a set of makelogs data
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.uiSettings.replace(defaultSettings);
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setDefaultAbsoluteRange();
});
describe('query', function () {
const queryName1 = 'Query # 1';
it('should show correct time range string by timepicker', async function () {
const time = await PageObjects.timePicker.getTimeConfig();
expect(time.start).to.be(PageObjects.timePicker.defaultStartTime);
expect(time.end).to.be(PageObjects.timePicker.defaultEndTime);
const rowData = await PageObjects.discover.getDocTableIndex(1);
log.debug('check the newest doc timestamp in UTC (check diff timezone in last test)');
expect(rowData).to.contain('Sep 22, 2015 @ 23:50:13.253');
});
it('save query should show toast message and display query name', async function () {
await PageObjects.discover.saveSearch(queryName1);
const actualQueryNameString = await PageObjects.discover.getCurrentQueryName();
expect(actualQueryNameString).to.be(queryName1);
});
it('load query should show query name', async function () {
await PageObjects.discover.loadSavedSearch(queryName1);
await retry.try(async function () {
expect(await PageObjects.discover.getCurrentQueryName()).to.be(queryName1);
});
});
it('renaming a saved query should modify name in breadcrumb', async function () {
const queryName2 = 'Modified Query # 1';
await PageObjects.discover.loadSavedSearch(queryName1);
await PageObjects.discover.saveSearch(queryName2);
await retry.try(async function () {
expect(await PageObjects.discover.getCurrentQueryName()).to.be(queryName2);
});
});
it('should show the correct hit count', async function () {
const expectedHitCount = '14,004';
await retry.try(async function () {
expect(await PageObjects.discover.getHitCount()).to.be(expectedHitCount);
});
});
it('should show correct time range string in chart', async function () {
const actualTimeString = await PageObjects.discover.getChartTimespan();
const expectedTimeString = `${PageObjects.timePicker.defaultStartTime} - ${PageObjects.timePicker.defaultEndTime}`;
expect(actualTimeString).to.be(expectedTimeString);
});
it('should modify the time range when a bar is clicked', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.discover.clickHistogramBar();
await PageObjects.discover.waitUntilSearchingHasFinished();
const time = await PageObjects.timePicker.getTimeConfig();
expect(time.start).to.be('Sep 21, 2015 @ 12:00:00.000');
expect(time.end).to.be('Sep 21, 2015 @ 15:00:00.000');
await retry.waitForWithTimeout(
'doc table to contain the right search result',
1000,
async () => {
const rowData = await PageObjects.discover.getDocTableField(1);
log.debug(`The first timestamp value in doc table: ${rowData}`);
return rowData.includes('Sep 21, 2015 @ 14:59:08.840');
}
);
});
it('should modify the time range when the histogram is brushed', async function () {
// this is the number of renderings of the histogram needed when new data is fetched
// this needs to be improved
const renderingCountInc = 2;
const prevRenderingCount = await elasticChart.getVisualizationRenderingCount();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.waitFor('chart rendering complete', async () => {
const actualCount = await elasticChart.getVisualizationRenderingCount();
const expectedCount = prevRenderingCount + renderingCountInc;
log.debug(
`renderings before brushing - actual: ${actualCount} expected: ${expectedCount}`
);
return actualCount === expectedCount;
});
const prevRowData = await PageObjects.discover.getDocTableField(1);
log.debug(`The first timestamp value in doc table before brushing: ${prevRowData}`);
await PageObjects.discover.brushHistogram();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.waitFor('chart rendering complete after being brushed', async () => {
const actualCount = await elasticChart.getVisualizationRenderingCount();
const expectedCount = prevRenderingCount + renderingCountInc * 2;
log.debug(
`renderings after brushing - actual: ${actualCount} expected: ${expectedCount}`
);
return actualCount === expectedCount;
});
const newDurationHours = await PageObjects.timePicker.getTimeDurationInHours();
expect(Math.round(newDurationHours)).to.be(26);
await retry.waitFor('doc table containing the documents of the brushed range', async () => {
const rowData = await PageObjects.discover.getDocTableField(1);
log.debug(`The first timestamp value in doc table after brushing: ${rowData}`);
return prevRowData !== rowData;
});
});
it('should show correct initial chart interval of Auto', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.discover.waitUntilSearchingHasFinished();
const actualInterval = await PageObjects.discover.getChartInterval();
const expectedInterval = 'Auto';
expect(actualInterval).to.be(expectedInterval);
});
it('should not show "no results"', async () => {
const isVisible = await PageObjects.discover.hasNoResults();
expect(isVisible).to.be(false);
});
it('should reload the saved search with persisted query to show the initial hit count', async function () {
// apply query some changes
await queryBar.setQuery('test');
await queryBar.submitQuery();
await retry.try(async function () {
expect(await PageObjects.discover.getHitCount()).to.be('22');
});
// reset to persisted state
await queryBar.clearQuery();
await PageObjects.discover.clickResetSavedSearchButton();
const expectedHitCount = '14,004';
await retry.try(async function () {
expect(await queryBar.getQueryString()).to.be('');
expect(await PageObjects.discover.getHitCount()).to.be(expectedHitCount);
});
});
});
describe('query #2, which has an empty time range', () => {
const fromTime = 'Jun 11, 1999 @ 09:22:11.000';
const toTime = 'Jun 12, 1999 @ 11:21:04.000';
before(async () => {
log.debug('setAbsoluteRangeForAnotherQuery');
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
await PageObjects.discover.waitUntilSearchingHasFinished();
});
it('should show "no results"', async () => {
await retry.waitFor('no results screen is displayed', async function () {
const isVisible = await PageObjects.discover.hasNoResults();
return isVisible === true;
});
});
it('should suggest a new time range is picked', async () => {
const isVisible = await PageObjects.discover.hasNoResultsTimepicker();
expect(isVisible).to.be(true);
});
});
describe('nested query', () => {
before(async () => {
log.debug('setAbsoluteRangeForAnotherQuery');
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.discover.waitUntilSearchingHasFinished();
});
it('should support querying on nested fields', async function () {
await queryBar.setQuery('nestedField:{ child: nestedValue }');
await queryBar.submitQuery();
await retry.try(async function () {
expect(await PageObjects.discover.getHitCount()).to.be('1');
});
});
});
describe('data-shared-item', function () {
it('should have correct data-shared-item title and description', async () => {
const expected = {
title: 'A Saved Search',
description: 'A Saved Search Description',
};
await retry.try(async () => {
await PageObjects.discover.loadSavedSearch(expected.title);
const { title, description } =
await PageObjects.common.getSharedItemTitleAndDescription();
expect(title).to.eql(expected.title);
expect(description).to.eql(expected.description);
});
});
});
describe('time zone switch', () => {
it('should show bars in the correct time zone after switching', async function () {
await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'America/Phoenix' });
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.awaitKibanaChrome();
await queryBar.clearQuery();
await PageObjects.timePicker.setDefaultAbsoluteRange();
log.debug(
'check that the newest doc timestamp is now -7 hours from the UTC time in the first test'
);
const rowData = await PageObjects.discover.getDocTableIndex(1);
expect(rowData.startsWith('Sep 22, 2015 @ 16:50:13.253')).to.be.ok();
});
});
describe('usage of discover:searchOnPageLoad', () => {
it('should not fetch data from ES initially when discover:searchOnPageLoad is false', async function () {
await kibanaServer.uiSettings.replace({ 'discover:searchOnPageLoad': false });
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.awaitKibanaChrome();
expect(await PageObjects.discover.getNrOfFetches()).to.be(0);
});
it('should fetch data from ES initially when discover:searchOnPageLoad is true', async function () {
await kibanaServer.uiSettings.replace({ 'discover:searchOnPageLoad': true });
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.awaitKibanaChrome();
await retry.waitFor('number of fetches to be 1', async () => {
const nrOfFetches = await PageObjects.discover.getNrOfFetches();
return nrOfFetches === 1;
});
});
});
describe('invalid time range in URL', function () {
it('should get the default timerange', async function () {
const prevTime = await PageObjects.timePicker.getTimeConfig();
await PageObjects.common.navigateToUrl('discover', '#/?_g=(time:(from:now-15m,to:null))', {
useActualUrl: true,
});
await PageObjects.header.awaitKibanaChrome();
const time = await PageObjects.timePicker.getTimeConfig();
expect(time.start).to.be(prevTime.start);
expect(time.end).to.be(prevTime.end);
});
});
describe('empty query', function () {
it('should update the histogram timerange when the query is resubmitted', async function () {
await kibanaServer.uiSettings.update({
'timepicker:timeDefaults': '{ "from": "2015-09-18T19:37:13.000Z", "to": "now"}',
});
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.awaitKibanaChrome();
const initialTimeString = await PageObjects.discover.getChartTimespan();
await queryBar.submitQuery();
await retry.waitFor('chart timespan to have changed', async () => {
const refreshedTimeString = await PageObjects.discover.getChartTimespan();
log.debug(
`Timestamp before: ${initialTimeString}, Timestamp after: ${refreshedTimeString}`
);
return refreshedTimeString !== initialTimeString;
});
});
});
describe('managing fields', function () {
it('should add a field, sort by it, remove it and also sorting by it', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.clickFieldListItemAdd('_score');
await PageObjects.discover.clickFieldSort('_score', 'Sort Low-High');
const currentUrlWithScore = await browser.getCurrentUrl();
expect(currentUrlWithScore).to.contain('_score');
await PageObjects.discover.clickFieldListItemRemove('_score');
const currentUrlWithoutScore = await browser.getCurrentUrl();
expect(currentUrlWithoutScore).not.to.contain('_score');
});
it('should add a field with customLabel, sort by it, display it correctly', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.clickFieldListItemAdd('referer');
await PageObjects.discover.clickFieldSort('referer', 'Sort A-Z');
expect(await PageObjects.discover.getDocHeader()).to.have.string('Referer custom');
expect(await PageObjects.discover.getAllFieldNames()).to.contain('Referer custom');
const url = await browser.getCurrentUrl();
expect(url).to.contain('referer');
});
});
describe('refresh interval', function () {
it('should refetch when autofresh is enabled', async () => {
const intervalS = 5;
await PageObjects.timePicker.startAutoRefresh(intervalS);
const getRequestTimestamp = async () => {
// check inspector panel request stats for timestamp
await inspector.open();
const requestStats = await inspector.getTableData();
const requestStatsRow = requestStats.filter(
(r) => r && r[0] && r[0].includes('Request timestamp')
);
if (!requestStatsRow || !requestStatsRow[0] || !requestStatsRow[0][1]) {
return '';
}
await inspector.close();
return requestStatsRow[0][1];
};
const requestTimestampBefore = await getRequestTimestamp();
await retry.waitFor('refetch because of refresh interval', async () => {
const requestTimestampAfter = await getRequestTimestamp();
log.debug(
`Timestamp before: ${requestTimestampBefore}, Timestamp after: ${requestTimestampAfter}`
);
return Boolean(requestTimestampAfter) && requestTimestampBefore !== requestTimestampAfter;
});
});
after(async () => {
await inspector.close();
await PageObjects.timePicker.pauseAutoRefresh();
});
});
});
}