Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a bunch of dashboard flaky test issues when network speed is slow #22766

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 5 additions & 16 deletions test/functional/apps/dashboard/_dashboard_save.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

import expect from 'expect.js';

export default function ({ getService, getPageObjects }) {
const retry = getService('retry');
export default function ({ getPageObjects }) {
const PageObjects = getPageObjects(['dashboard', 'header']);

describe('dashboard save', function describeIndexTests() {
Expand All @@ -38,15 +37,14 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.saveDashboard(dashboardName);

let isWarningDisplayed = await PageObjects.dashboard.isDuplicateTitleWarningDisplayed();
const isWarningDisplayed = await PageObjects.dashboard.isDuplicateTitleWarningDisplayed();
expect(isWarningDisplayed).to.equal(false);

await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName);

isWarningDisplayed = await PageObjects.dashboard.isDuplicateTitleWarningDisplayed();
expect(isWarningDisplayed).to.equal(true);
await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed();
});

it('does not save on reject confirmation', async function () {
Expand Down Expand Up @@ -87,10 +85,7 @@ export default function ({ getService, getPageObjects }) {
it('Warns you when you Save as New Dashboard, and the title is a duplicate', async function () {
await PageObjects.dashboard.switchToEditMode();
await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName, { saveAsNew: true });

const isWarningDisplayed = await PageObjects.dashboard.isDuplicateTitleWarningDisplayed();
expect(isWarningDisplayed).to.equal(true);

await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed();
await PageObjects.dashboard.cancelSave();
});

Expand All @@ -104,13 +99,7 @@ export default function ({ getService, getPageObjects }) {
it('Warns when case is different', async function () {
await PageObjects.dashboard.switchToEditMode();
await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName.toUpperCase());

// We expect isWarningDisplayed to be open, hence the retry if not found.
await retry.try(async () => {
const isWarningDisplayed = await PageObjects.dashboard.isDuplicateTitleWarningDisplayed();
expect(isWarningDisplayed).to.equal(true);
});

await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed();
await PageObjects.dashboard.cancelSave();
});
});
Expand Down
1 change: 1 addition & 0 deletions test/functional/apps/dashboard/_dashboard_state.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default function ({ getService, getPageObjects }) {

await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.loadSavedDashboard('Overridden colors');
await PageObjects.dashboard.waitForRenderComplete();
const colorChoiceRetained = await PageObjects.visualize.doesSelectedLegendColorExist('#EA6460');

expect(colorChoiceRetained).to.be(true);
Expand Down
1 change: 1 addition & 0 deletions test/functional/apps/dashboard/_panel_controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.header.clickDashboard();
await dashboardAddPanel.addSavedSearch('my search');
await PageObjects.dashboard.waitForRenderComplete();

const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.be(1);
Expand Down
3 changes: 2 additions & 1 deletion test/functional/apps/visualize/_input_control_vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export default function ({ getService, getPageObjects }) {

const FIELD_NAME = 'machine.os.raw';

describe('input control visualization', () => {
// unskip when https://github.com/elastic/kibana/issues/22233 is fixed
describe.skip('input control visualization', () => {

before(async () => {
await PageObjects.visualize.navigateToNewVisualization();
Expand Down
3 changes: 1 addition & 2 deletions test/functional/apps/visualize/_inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) {
const log = getService('log');
const PageObjects = getPageObjects(['common', 'visualize', 'header']);

describe('visualize app', function describeIndexTests() {
describe('inspector', function describeIndexTests() {
before(async function () {
const fromTime = '2015-09-19 06:31:44.000';
const toTime = '2015-09-23 18:31:44.000';
Expand All @@ -34,7 +34,6 @@ export default function ({ getService, getPageObjects }) {

log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"');
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.visualize.clickGo();
await PageObjects.header.waitUntilLoadingHasFinished();
});

Expand Down
113 changes: 55 additions & 58 deletions test/functional/apps/visualize/_linked_saved_searches.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,79 +24,76 @@ export default function ({ getService, getPageObjects }) {
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'discover', 'visualize', 'header']);

describe('visualize app', function describeIndexTests() {
describe('linked saved searches', function describeIndexTests() {
const fromTime = '2015-09-19 06:31:44.000';
const toTime = '2015-09-23 18:31:44.000';

describe('linked saved searched', () => {
const savedSearchName = 'vis_saved_search';

const savedSearchName = 'vis_saved_search';
before(async () => {
await PageObjects.common.navigateToApp('discover');
await filterBar.addFilter('extension.raw', 'is', 'jpg');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.saveSearch(savedSearchName);
// TODO: Remove this once https://github.com/elastic/kibana/issues/19750 is properly resolved
await PageObjects.common.sleep(500);
});

before(async () => {
await PageObjects.common.navigateToApp('discover');
await filterBar.addFilter('extension.raw', 'is', 'jpg');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.saveSearch(savedSearchName);
// TODO: Remove this once https://github.com/elastic/kibana/issues/19750 is properly resolved
await PageObjects.common.sleep(500);
it('should create a visualization from a saved search', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickDataTable();
await PageObjects.visualize.clickSavedSearch(savedSearchName);
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 9,109', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '9,109';
});
});

it('should create a visualization from a saved search', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickDataTable();
await PageObjects.visualize.clickSavedSearch(savedSearchName);
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 9,109', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '9,109';
});
it('should respect the time filter when linked to a saved search', async () => {
await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-21 10:00:00.000');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 3,950', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '3,950';
});
});

it('should respect the time filter when linked to a saved search', async () => {
await PageObjects.header.setAbsoluteRange('2015-09-19 06:31:44.000', '2015-09-21 10:00:00.000');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 3,950', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '3,950';
});
it('should allow adding filters while having a linked saved search', async () => {
await filterBar.addFilter('bytes', 'is between', '100', '3000');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 707', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '707';
});
});

it('should allow adding filters while having a linked saved search', async () => {
await filterBar.addFilter('bytes', 'is between', '100', '3000');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 707', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '707';
});
it('should allow unlinking from a linked search', async () => {
await PageObjects.visualize.clickUnlinkSavedSearch();
await retry.waitFor('wait for count to equal 707', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '707';
});
// The filter on the saved search should now be in the editor
expect(await filterBar.hasFilter('extension.raw', 'jpg')).to.be(true);

it('should allow unlinking from a linked search', async () => {
await PageObjects.visualize.clickUnlinkSavedSearch();
await retry.waitFor('wait for count to equal 707', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '707';
});
// The filter on the saved search should now be in the editor
expect(await filterBar.hasFilter('extension.raw', 'jpg')).to.be(true);

// Disabling this filter should now result in different values, since
// the visualization should not be linked anymore with the saved search.
await filterBar.toggleFilterEnabled('extension.raw');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 1,293', async () => {
const unfilteredData = await PageObjects.visualize.getTableVisData();
return unfilteredData.trim() === '1,293';
});
// Disabling this filter should now result in different values, since
// the visualization should not be linked anymore with the saved search.
await filterBar.toggleFilterEnabled('extension.raw');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 1,293', async () => {
const unfilteredData = await PageObjects.visualize.getTableVisData();
return unfilteredData.trim() === '1,293';
});
});

it('should not break when saving after unlinking', async () => {
await PageObjects.visualize.saveVisualizationExpectSuccess('Unlinked before saved');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 1,293', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '1,293';
});
it('should not break when saving after unlinking', async () => {
await PageObjects.visualize.saveVisualizationExpectSuccess('Unlinked before saved');
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('wait for count to equal 1,293', async () => {
const data = await PageObjects.visualize.getTableVisData();
return data.trim() === '1,293';
});
});
});
Expand Down
6 changes: 6 additions & 0 deletions test/functional/page_objects/common_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ export function CommonPageProvider({ getService, getPageObjects }) {
return currentUrl;
}

async waitForEuiTableLoading() {
await retry.waitFor('CommonPage.waitForEuiTableLoading', async () => {
const table = await find.byClassName('euiBasicTable');
return !((await table.getAttribute('class')).includes('loading'));
});
}

navigateToApp(appName) {
const self = this;
Expand Down
70 changes: 40 additions & 30 deletions test/functional/page_objects/dashboard_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,24 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
await find.clickByCssSelector(`a[href="#${DashboardConstants.LANDING_PAGE_PATH}"]`);
}

async dashboardBreadcrumbLinkExists() {
log.debug('dashboardBreadcrumbLinkExists');
return await find.existsByCssSelector(`a[href="#${DashboardConstants.LANDING_PAGE_PATH}"]`);
}

async gotoDashboardLandingPage() {
log.debug('gotoDashboardLandingPage');
const onPage = await this.onDashboardLandingPage();
if (!onPage) {
await retry.try(async () => {
await this.clickDashboardBreadcrumbLink();
await retry.try(async () => {
const onPage = await this.onDashboardLandingPage();
if (!onPage) {
const breadCrumbLinkExists = await this.dashboardBreadcrumbLinkExists();
if (breadCrumbLinkExists) {
await this.clickDashboardBreadcrumbLink();
}
const onDashboardLandingPage = await this.onDashboardLandingPage();
if (!onDashboardLandingPage) throw new Error('Not on the landing page.');
});
}
}
});
}

async clickClone() {
Expand All @@ -169,6 +177,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
await testSubjects.setValue('clonedDashboardTitle', title);
}

async expectDuplicateTitleWarningDisplayed() {
await testSubjects.existOrFail('titleDupicateWarnMsg');
}

async isDuplicateTitleWarningDisplayed() {
return await testSubjects.exists('titleDupicateWarnMsg');
}
Expand Down Expand Up @@ -197,14 +209,21 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
}

async clickNewDashboard() {
// newDashboardLink button is only visible when dashboard listing table is displayed (at least one dashboard).
const exists = await testSubjects.exists('newDashboardLink');
if (exists) {
return await testSubjects.click('newDashboardLink');
}
await retry.try(async () => {
// newDashboardLink button is only visible when dashboard listing table is displayed (at least one dashboard).
const exists = await testSubjects.exists('newDashboardLink');
if (exists) {
return await testSubjects.click('newDashboardLink');
}

// no dashboards exist, click createDashboardPromptButton to create new dashboard
return await this.clickCreateDashboardPrompt();
const promptExists = await this.getCreateDashboardPromptExists();
if (promptExists) {
// no dashboards exist, click createDashboardPromptButton to create new dashboard
await this.clickCreateDashboardPrompt();
} else {
throw new Error('No create button exists in the DOM yet, may still be rendering');
}
});
}

async clickCreateDashboardPrompt() {
Expand Down Expand Up @@ -303,6 +322,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
* @param saveOptions {{storeTimeWithDashboard: boolean, saveAsNew: boolean, needsConfirm: false}}
*/
async saveDashboard(dashName, saveOptions = {}) {
log.debug(`DashboardPage.saveDashboard(${dashName}, ${JSON.stringify(saveOptions)}`);
await this.enterDashboardTitleAndClickSave(dashName, saveOptions);

if (saveOptions.needsConfirm) {
Expand Down Expand Up @@ -340,10 +360,8 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
}

async clickSave() {
await retry.try(async () => {
log.debug('clicking final Save button for named dashboard');
return await testSubjects.click('confirmSaveDashboardButton');
});
log.debug('DashboardPage.clickSave');
await testSubjects.click('confirmSaveDashboardButton');
}

/**
Expand Down Expand Up @@ -371,6 +389,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
}

async selectDashboard(dashName) {
log.debug(`selectDashboard(${dashName})`);
await testSubjects.click(`dashboardListingTitleLink-${dashName.split(' ').join('-')}`);
}

Expand Down Expand Up @@ -405,7 +424,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
await PageObjects.common.pressEnterKey();
});

await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.waitForEuiTableLoading();
}

async getCountOfDashboardsInListingTable() {
Expand All @@ -425,19 +444,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
// entry, or at least to a single page of results
async loadSavedDashboard(dashName) {
log.debug(`Load Saved Dashboard ${dashName}`);

await this.gotoDashboardLandingPage();

await retry.try(async () => {
await this.searchForDashboardWithName(dashName);
await this.selectDashboard(dashName);
await PageObjects.header.waitUntilLoadingHasFinished();

const onDashboardLandingPage = await this.onDashboardLandingPage();
if (onDashboardLandingPage) {
throw new Error('Failed to open the dashboard up');
}
});
await this.searchForDashboardWithName(dashName);
await this.selectDashboard(dashName);
await PageObjects.header.waitUntilLoadingHasFinished();
}

async getPanelTitles() {
Expand Down
Loading