Fix refreshed dashboard losing time range (#20858) (#21264)

* Add test that would have caught the bug

* Initialize global state with current time range

* Fix issue with failing tests - need to remove added "t" parameter to the url in the new tests

* remove unneccessary extra call

* Fix tests that failed due to globally added time in new tests

* Update home page test to not care about any state.
This commit is contained in:
Stacey Gammon 2018-07-26 10:29:13 -04:00 committed by GitHub
parent 8bd705c11e
commit 1e803e7fe5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 77 deletions

View file

@ -30,18 +30,19 @@ uiModules
.directive('kbnGlobalTimepicker', (globalState, config) => {
const getConfig = (...args) => config.get(...args);
const updateGlobalStateWithTime = ($scope) => {
globalState.refreshInterval = timefilter.getRefreshInterval();
globalState.time = timefilter.getTime();
globalState.save();
setTimefilterValues($scope);
};
const listenForUpdates = ($scope) => {
$scope.$listenAndDigestAsync(timefilter, 'refreshIntervalUpdate', () => {
globalState.refreshInterval = timefilter.getRefreshInterval();
globalState.time = timefilter.getTime();
globalState.save();
setTimefilterValues($scope);
updateGlobalStateWithTime($scope);
});
$scope.$listenAndDigestAsync(timefilter, 'timeUpdate', () => {
globalState.refreshInterval = timefilter.getRefreshInterval();
globalState.time = timefilter.getTime();
globalState.save();
setTimefilterValues($scope);
updateGlobalStateWithTime($scope);
});
$scope.$listenAndDigestAsync(timefilter, 'enabledUpdated', () => {
setTimefilterValues($scope);
@ -69,8 +70,8 @@ uiModules
require: '^kbnTopNav',
link: ($scope, element, attributes, kbnTopNav) => {
listenForUpdates($scope);
updateGlobalStateWithTime($scope);
setTimefilterValues($scope);
$scope.toggleRefresh = () => {
timefilter.toggleRefresh();
};

View file

@ -29,23 +29,82 @@ import expect from 'expect.js';
export default function ({ getService, getPageObjects }) {
const find = getService('find');
const remote = getService('remote');
const dashboardExpect = getService('dashboardExpect');
const dashboardAddPanel = getService('dashboardAddPanel');
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'discover']);
const expectAllDataRenders = async () => {
await dashboardExpect.pieSliceCount(16);
await dashboardExpect.seriesElementCount(19);
await dashboardExpect.dataTableRowCount(5);
await dashboardExpect.savedSearchRowCount(50);
await dashboardExpect.goalAndGuageLabelsExist(['63%', '56%', '11.915 GB']);
await dashboardExpect.inputControlItemCount(5);
await dashboardExpect.metricValuesExist(['7,544']);
await dashboardExpect.markdownWithValuesExists(['I\'m a markdown!']);
await dashboardExpect.lineChartPointsCount(5);
await dashboardExpect.tagCloudWithValuesFound(['CN', 'IN', 'US', 'BR', 'ID']);
await dashboardExpect.timelionLegendCount(0);
const tsvbGuageExists = await find.existsByCssSelector('.thorHalfGauge');
expect(tsvbGuageExists).to.be(true);
await dashboardExpect.tsvbMetricValuesExist(['210,007,889,606']);
await dashboardExpect.tsvbMarkdownWithValuesExists(['Hi Avg last bytes: 6286.674715909091']);
await dashboardExpect.tsvbTableCellCount(20);
await dashboardExpect.tsvbTimeSeriesLegendCount(1);
await dashboardExpect.tsvbTopNValuesExist(['5,734.79', '6,286.67']);
await dashboardExpect.vegaTextsExist(['5,000']);
};
const expectNoDataRenders = async () => {
await dashboardExpect.pieSliceCount(0);
await dashboardExpect.seriesElementCount(0);
await dashboardExpect.dataTableRowCount(0);
await dashboardExpect.savedSearchRowCount(0);
await dashboardExpect.inputControlItemCount(5);
await dashboardExpect.metricValuesExist(['0']);
await dashboardExpect.markdownWithValuesExists(['I\'m a markdown!']);
// Three instead of 0 because there is a visualization based off a non time based index that
// should still show data.
await dashboardExpect.lineChartPointsCount(3);
await dashboardExpect.timelionLegendCount(0);
const tsvbGuageExists = await find.existsByCssSelector('.thorHalfGauge');
expect(tsvbGuageExists).to.be(true);
await dashboardExpect.tsvbMetricValuesExist(['0']);
await dashboardExpect.tsvbMarkdownWithValuesExists(['Hi Avg last bytes: 0']);
await dashboardExpect.tsvbTableCellCount(0);
await dashboardExpect.tsvbTimeSeriesLegendCount(1);
await dashboardExpect.tsvbTopNValuesExist(['0']);
await dashboardExpect.vegaTextsDoNotExist(['5,000']);
};
describe('dashboard embeddable rendering', function describeIndexTests() {
before(async () => {
await PageObjects.dashboard.clickNewDashboard();
const fromTime = '2018-01-01 00:00:00.000';
const toTime = '2018-04-13 00:00:00.000';
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
});
after(async () => {
// Get rid of the timestamp added in this test, as well any global or app state.
const currentUrl = await remote.getCurrentUrl();
const newUrl = currentUrl.replace(/\?.*$/, '');
await remote.get(newUrl, false);
});
it('adding visualizations', async () => {
await dashboardAddPanel.addEveryVisualization('"Rendering Test"');
// This one is rendered via svg which lets us do better testing of what is being rendered.
await dashboardAddPanel.addVisualization('Filter Bytes Test: vega');
await PageObjects.header.waitUntilLoadingHasFinished();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.be(26);
expect(panelCount).to.be(27);
});
it('adding saved searches', async () => {
@ -53,84 +112,46 @@ export default function ({ getService, getPageObjects }) {
await dashboardAddPanel.closeAddPanel();
await PageObjects.header.waitUntilLoadingHasFinished();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.be(27);
expect(panelCount).to.be(28);
// Not necessary but helpful for local debugging.
await PageObjects.dashboard.saveDashboard('embeddable rendering test');
await PageObjects.dashboard.saveDashboard('embeddable rendering test', { storeTimeWithDashboard: true });
});
it('pie charts rendered', async () => {
await dashboardExpect.pieSliceCount(16);
it('initial render test', async () => {
await expectAllDataRenders();
});
it('area, bar and heatmap charts rendered', async () => {
await dashboardExpect.seriesElementCount(19);
it('data rendered correctly when dashboard is opened from listing page', async () => {
// Change the time to make sure that it's updated when re-opened from the listing page.
const fromTime = '2018-05-10 00:00:00.000';
const toTime = '2018-05-11 00:00:00.000';
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.dashboard.loadSavedDashboard('embeddable rendering test');
await expectAllDataRenders();
});
it('data tables render', async () => {
await dashboardExpect.dataTableRowCount(5);
it('data rendered correctly when dashboard is hard refreshed', async () => {
const currentUrl = await remote.getCurrentUrl();
await remote.get(currentUrl, true);
await expectAllDataRenders();
});
it('saved searches render', async () => {
await dashboardExpect.savedSearchRowCount(50);
it('panels are updated when time changes outside of data', async () => {
const fromTime = '2018-05-11 00:00:00.000';
const toTime = '2018-05-12 00:00:00.000';
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await expectNoDataRenders();
});
it('goal and gauge render', async () => {
await dashboardExpect.goalAndGuageLabelsExist(['63%', '56%', '11.915 GB']);
});
it('panels are updated when time changes inside of data', async () => {
const fromTime = '2018-01-01 00:00:00.000';
const toTime = '2018-04-13 00:00:00.000';
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
it('input controls render', async () => {
await dashboardExpect.inputControlItemCount(5);
});
it('metric vis renders', async () => {
await dashboardExpect.metricValuesExist(['7,544']);
});
it('markdown renders', async () => {
await dashboardExpect.markdownWithValuesExists(['I\'m a markdown!']);
});
it('line charts render', async () => {
await dashboardExpect.lineChartPointsCount(5);
});
it('tag cloud renders', async () => {
await dashboardExpect.tagCloudWithValuesFound(['CN', 'IN', 'US', 'BR', 'ID']);
});
it('timelion chart renders', async () => {
await dashboardExpect.timelionLegendCount(0);
});
it('tsvb gauge renders', async () => {
const tsvbGuageExists = await find.existsByCssSelector('.thorHalfGauge');
expect(tsvbGuageExists).to.be(true);
});
it('tsvb metric chart renders', async () => {
await dashboardExpect.tsvbMetricValuesExist(['210,007,889,606']);
});
it('tsvb markdown renders', async () => {
await dashboardExpect.tsvbMarkdownWithValuesExists(['Hi Avg last bytes: 6286.674715909091']);
});
it('tsvb table chart renders', async () => {
await dashboardExpect.tsvbTableCellCount(20);
});
it('tsvb time series renders', async () => {
await dashboardExpect.tsvbTimeSeriesLegendCount(1);
});
it('tsvb top n chart renders', async () => {
await dashboardExpect.tsvbTopNValuesExist(['5,734.79', '6,286.67']);
});
it('vega chart renders', async () => {
const tsvb = await find.existsByCssSelector('.vega-view-container');
expect(tsvb).to.be(true);
await expectAllDataRenders();
});
});
}

View file

@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }) {
it('clicking on console on homepage should take you to console app', async ()=> {
await PageObjects.home.clickSynopsis('console');
const url = await remote.getCurrentUrl();
expect(url.includes('/app/kibana#/dev_tools/console?_g=()')).to.be(true);
expect(url.includes('/app/kibana#/dev_tools/console')).to.be(true);
});
});

View file

@ -61,6 +61,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async tsvbTimeSeriesLegendCount(expectedCount) {
log.debug(`DashboardExpect.tsvbTimeSeriesLegendCount(${expectedCount})`);
await retry.try(async () => {
const tsvbLegendItems = await testSubjects.findAll('tsvbLegendItem');
expect(tsvbLegendItems.length).to.be(expectedCount);
@ -68,11 +69,13 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async fieldSuggestionIndexPatterns(expectedIndexPatterns) {
log.debug(`DashboardExpect.fieldSuggestionIndexPatterns(${expectedIndexPatterns})`);
const indexPatterns = await filterBar.getFilterFieldIndexPatterns();
expect(indexPatterns).to.eql(expectedIndexPatterns);
}
async legendValuesToExist(legendValues) {
log.debug(`DashboardExpect.legendValuesToExist(${legendValues})`);
await Promise.all(legendValues.map(async legend => {
await retry.try(async () => {
const legendValueExists = await testSubjects.exists(`legend-${legend}`);
@ -82,6 +85,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async textWithinElementsExists(texts, getElementsFn) {
log.debug(`DashboardExpect.textWithinElementsExists(${texts})`);
await retry.try(async () => {
const elements = await getElementsFn();
const elementTexts = [];
@ -98,16 +102,19 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async textWithinTestSubjectsExists(texts, selector) {
log.debug(`DashboardExpect.textWithinTestSubjectsExists(${texts})`);
log.debug(`textWithinTestSubjectsExists:(${JSON.stringify(texts)},${selector})`);
await this.textWithinElementsExists(texts, async () => await testSubjects.findAll(selector));
}
async textWithinCssElementExists(texts, selector) {
log.debug(`DashboardExpect.textWithinCssElementExists(${texts})`);
log.debug(`textWithinCssElementExists:(${JSON.stringify(texts)},${selector})`);
await this.textWithinElementsExists(texts, async () => await find.allByCssSelector(selector));
}
async textWithinElementsDoNotExist(texts, getElementsFn) {
log.debug(`DashboardExpect.textWithinElementsDoNotExist(${texts})`);
await retry.try(async () => {
const elements = await getElementsFn();
const elementTexts = [];
@ -128,6 +135,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async timelionLegendCount(expectedCount) {
log.debug(`DashboardExpect.timelionLegendCount(${expectedCount})`);
await retry.try(async () => {
const flotLegendLabels = await testSubjects.findAll('flotLegendLabel');
expect(flotLegendLabels.length).to.be(expectedCount);
@ -135,6 +143,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async emptyTagCloudFound() {
log.debug(`DashboardExpect.emptyTagCloudFound()`);
const tagCloudVisualizations = await testSubjects.findAll('tagCloudVisualization');
const tagCloudsHaveContent = await Promise.all(tagCloudVisualizations.map(async tagCloud => {
return await find.descendantExistsByCssSelector('text', tagCloud);
@ -143,6 +152,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async tagCloudWithValuesFound(values) {
log.debug(`DashboardExpect.tagCloudWithValuesFound(${values})`);
const tagCloudVisualizations = await testSubjects.findAll('tagCloudVisualization');
const matches = await Promise.all(tagCloudVisualizations.map(async tagCloud => {
for (let i = 0; i < values.length; i++) {
@ -157,38 +167,47 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async goalAndGuageLabelsExist(labels) {
log.debug(`DashboardExpect.goalAndGuageLabelsExist(${labels})`);
await this.textWithinCssElementExists(labels, '.chart-label');
}
async metricValuesExist(values) {
log.debug(`DashboardExpect.metricValuesExist(${values})`);
await this.textWithinCssElementExists(values, '.metric-value');
}
async tsvbMetricValuesExist(values) {
log.debug(`DashboardExpect.tsvbMetricValuesExist(${values})`);
await this.textWithinTestSubjectsExists(values, 'tsvbMetricValue');
}
async tsvbTopNValuesExist(values) {
log.debug(`DashboardExpect.tsvbTopNValuesExist(${values})`);
await this.textWithinTestSubjectsExists(values, 'tsvbTopNValue');
}
async vegaTextsExist(values) {
log.debug(`DashboardExpect.vegaTextsExist(${values})`);
await this.textWithinCssElementExists(values, '.vega-view-container text');
}
async vegaTextsDoNotExist(values) {
log.debug(`DashboardExpect.vegaTextsDoNotExist(${values})`);
await this.textWithinCssElementDoNotExist(values, '.vega-view-container text');
}
async tsvbMarkdownWithValuesExists(values) {
log.debug(`DashboardExpect.tsvbMarkdownWithValuesExists(${values})`);
await this.textWithinTestSubjectsExists(values, 'tsvbMarkdown');
}
async markdownWithValuesExists(values) {
log.debug(`DashboardExpect.markdownWithValuesExists(${values})`);
await this.textWithinTestSubjectsExists(values, 'markdownBody');
}
async savedSearchRowCount(expectedCount) {
log.debug(`DashboardExpect.savedSearchRowCount(${expectedCount})`);
await retry.try(async () => {
const savedSearchRows = await testSubjects.findAll('docTableExpandToggleColumn');
expect(savedSearchRows.length).to.be(expectedCount);
@ -196,6 +215,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async dataTableRowCount(expectedCount) {
log.debug(`DashboardExpect.dataTableRowCount(${expectedCount})`);
await retry.try(async () => {
const dataTableRows =
await find.allByCssSelector('[data-test-subj="paginated-table-body"] [data-cell-content]');
@ -204,6 +224,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async seriesElementCount(expectedCount) {
log.debug(`DashboardExpect.seriesElementCount(${expectedCount})`);
await retry.try(async () => {
const seriesElements = await find.allByCssSelector('.series');
expect(seriesElements.length).to.be(expectedCount);
@ -211,6 +232,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async inputControlItemCount(expectedCount) {
log.debug(`DashboardExpect.inputControlItemCount(${expectedCount})`);
await retry.try(async () => {
const inputControlItems = await testSubjects.findAll('inputControlItem');
expect(inputControlItems.length).to.be(expectedCount);
@ -218,6 +240,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async lineChartPointsCount(expectedCount) {
log.debug(`DashboardExpect.lineChartPointsCount(${expectedCount})`);
await retry.try(async () => {
const points = await find.allByCssSelector('.points');
expect(points.length).to.be(expectedCount);
@ -225,6 +248,7 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
}
async tsvbTableCellCount(expectedCount) {
log.debug(`DashboardExpect.tsvbTableCellCount(${expectedCount})`);
await retry.try(async () => {
const tableCells = await find.allByCssSelector('.tsvb-table__value');
expect(tableCells.length).to.be(expectedCount);