mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
Fix flakiness on custom time range saved searches (#165454)
A bunch of tests on dashboards are customising some of the panels settings and providing custom time ranges: <img width="409" alt="image" src="c869c1a3
-f7db-4ccd-ad00-c5403f2b4201"> Currently, the logic is not waiting for the quick toggle animation to complete, before proceeding to select a time range. This can cause a flaky behavior if the logic tries to customize the range before the button is actually available, as seen on [this failed test](018a4c46
-0e7a-4b69-9a3d-9c54c27165b0_4fcbc47e71644919129e320eea8bb3bc.html?response-content-type=text%2Fhtml&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAQPCP3C7LZWZ5UB5F%2F20230901%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230901T094837Z&X-Amz-Expires=600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEB0aCXVzLWVhc3QtMSJGMEQCIGCyKcVLGPUawZubNzZdt5oZNb5v0saiIuPqXwI7rmwlAiAsOj%2Fiep94v%2BYZJtLY3Gw0m%2FmK5mJw2IcIBdNKFXgK%2BCr6Awjm%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAAaDDAzMjM3OTcwNTMwMyIMXOd1Hm6ks%2FNE37V0Ks4DgMUso7syv87hnPcC%2BB1soxvFFnj4JnNZc6ZgkLUe93z99iPFBUsqH%2BRbUTfSbjVOEJYBKGYuvp32xvSWsYNVPXKmcej18LC0yNi%2BBzoG2X%2Bj80g%2BbGMm6YfTncjPhOE0CHHqOWXts9nQ8WpDy8XOl0zfMtuiPjzOXHo9lvw2mgYDZIJIMV72FYB9JGg8FPbLQtD3rysLGNE0VDKgl5LCnYwhY1pwRCRHnVW41QfV0pwK%2FbjNf9HjdK31LQvMY%2FGPuB3M6O2CUZLsvLGfWBeGYHtkqb0hrL9ijO1Uo28ZSS1FytPftEdF0e1kAC9C5zD56HtYm55aktOWtaaC0XPWLdWWGUq%2FKQzhxSCiXK6ovATU3zI3yPNoZs92YBYmIPMOpEI40dCCpksjPwAMCiQd%2F9gMNKP5Qp5CbYd2Khy%2FeXaT8J7HOZCueN63O0j%2FtX1tbwfznhbr74lAcRQjueRYmwboZaGSDZUQ33lSSmyZk1V9WF9eJyt88oHvIx0q9bIjvOlW05DiNKfEFWYwfBywdGuvRU6eGMs1QcDNu33Lb%2BhymudM2JZmQKIjZOcb2l3Fzctp614owH4JcRlmF4%2BIa4xHeBdRlTMysS8bTIsgMK7axacGOqYBzIpC1wgZWJ1kZ0agLWCNaMIdUl%2B4xrr7w%2Fz0843WWMhRrvbJhDTHqk5UclF%2FSROAMe0FH2XEXiQ65ILyUPlrUMels5tfQ3Pp%2FJWPi9NsQJUQ1n9uLN%2BFPDOoMo8Uxg4%2FkG2O7yTkrIdArfA6pWN9I21gFMW%2BFZy9BMYltt5T65ZKOyYAIFGpLhgfBySIBCUMgwR1kusfDhf1%2FRTvtDKD2sJKN5a0IA%3D%3D&X-Amz-SignedHeaders=host&X-Amz-Signature=35fabe908aa7514e4a92de0ed12973af85ccfb439984fc3bdd7ef3bb8fe3419b). (part of this [failed CI build](https://buildkite.com/elastic/kibana-pull-request/builds/155285#018a4c46-0e7a-4b69-9a3d-9c54c27165b0)) The goal of this PR is to add a small waiting period, to make sure the toggle animation has completed, and that the time range controls are visible and clickable. I used the opportunity to cleanup some "await delay millis" calls, reusing existing logic instead. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
823a1d542b
commit
b98b6d08cd
12 changed files with 92 additions and 44 deletions
|
@ -236,6 +236,9 @@ export class DashboardAddPanelService extends FtrService {
|
|||
await this.testSubjects.click(`savedObjectTitle${embeddableName.split(' ').join('-')}`);
|
||||
await this.testSubjects.exists('addObjectToDashboardSuccess');
|
||||
await this.closeAddPanel();
|
||||
|
||||
// close "Added successfully" toast
|
||||
await this.common.clearAllToasts();
|
||||
return embeddableName;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { CommonlyUsed } from '../../page_objects/time_picker';
|
||||
import { WebElementWrapper } from '../lib/web_element_wrapper';
|
||||
|
||||
export function DashboardCustomizePanelProvider({ getService }: FtrProviderContext) {
|
||||
export function DashboardCustomizePanelProvider({ getService, getPageObject }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const toasts = getService('toasts');
|
||||
|
@ -39,6 +40,48 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte
|
|||
await testSubjects.missingOrFail(this.TOGGLE_TIME_RANGE_TEST_SUBJ);
|
||||
}
|
||||
|
||||
public async findCustomTimeRangeToggleButton(): Promise<WebElementWrapper> {
|
||||
log.debug('findCustomTimeRangeToggleButton');
|
||||
let button: WebElementWrapper | undefined;
|
||||
await retry.waitFor('custom time range toggle button', async () => {
|
||||
button = await testSubjects.find(this.TOGGLE_TIME_RANGE_TEST_SUBJ);
|
||||
return Boolean(button);
|
||||
});
|
||||
return button!;
|
||||
}
|
||||
|
||||
public async enableCustomTimeRange() {
|
||||
log.debug('enableCustomTimeRange');
|
||||
const toggle = await this.findCustomTimeRangeToggleButton();
|
||||
|
||||
await retry.try(async () => {
|
||||
if ((await toggle.getAttribute('aria-checked')) === 'false') {
|
||||
await toggle.click();
|
||||
await retry.waitForWithTimeout(
|
||||
'custom time range to be enabled',
|
||||
1000,
|
||||
async () => (await toggle.getAttribute('aria-checked')) === 'true'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async disableCustomTimeRange() {
|
||||
log.debug('disableCustomTimeRange');
|
||||
const toggle = await this.findCustomTimeRangeToggleButton();
|
||||
|
||||
await retry.try(async () => {
|
||||
if ((await toggle.getAttribute('aria-checked')) === 'true') {
|
||||
await toggle.click();
|
||||
await retry.waitForWithTimeout(
|
||||
'custom time range to be disabled',
|
||||
1000,
|
||||
async () => (await toggle.getAttribute('aria-checked')) === 'false'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async findFlyout() {
|
||||
log.debug('findFlyout');
|
||||
return await testSubjects.find(this.FLYOUT_TEST_SUBJ);
|
||||
|
@ -50,15 +93,21 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte
|
|||
return await flyout.findByCssSelector(`[data-test-subj="${testSubject}"]`);
|
||||
}
|
||||
|
||||
public async findToggleQuickMenuButton() {
|
||||
log.debug('findToggleQuickMenuButton');
|
||||
public async findDatePickerQuickMenuButton() {
|
||||
log.debug('findDatePickerQuickMenuButton');
|
||||
return await this.findFlyoutTestSubject('superDatePickerToggleQuickMenuButton');
|
||||
}
|
||||
|
||||
public async clickToggleQuickMenuButton() {
|
||||
log.debug('clickToggleQuickMenuButton');
|
||||
const button = await this.findToggleQuickMenuButton();
|
||||
await button.click();
|
||||
public async openDatePickerQuickMenu() {
|
||||
log.debug('openDatePickerQuickMenu');
|
||||
let button: WebElementWrapper | undefined;
|
||||
await retry.waitFor('superDatePickerToggleQuickMenuButton to be present', async () => {
|
||||
button = await this.findDatePickerQuickMenuButton();
|
||||
return Boolean(button);
|
||||
});
|
||||
if (button) {
|
||||
await button.click();
|
||||
}
|
||||
}
|
||||
|
||||
public async clickCommonlyUsedTimeRange(time: CommonlyUsed) {
|
||||
|
@ -111,10 +160,5 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte
|
|||
await testSubjects.waitForDeleted('cancelCustomizePanelButton');
|
||||
});
|
||||
}
|
||||
|
||||
public async clickToggleShowCustomTimeRange() {
|
||||
log.debug('clickToggleShowCustomTimeRange');
|
||||
await testSubjects.click(this.TOGGLE_TIME_RANGE_TEST_SUBJ);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
it('can add a custom time range to a panel', async () => {
|
||||
await PageObjects.lens.createAndAddLensFromDashboard({});
|
||||
await dashboardPanelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -56,7 +56,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
it('can remove a custom time range from a panel', async () => {
|
||||
await dashboardBadgeActions.clickTimeRangeBadgeAction();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.disableCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardBadgeActions.expectMissingTimeRangeBadgeAction();
|
||||
|
@ -68,8 +68,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
it('can add a custom time range to panel', async () => {
|
||||
await dashboardPanelActions.saveToLibrary('My by reference visualization');
|
||||
await dashboardPanelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -80,7 +80,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
it('can remove a custom time range from a panel', async () => {
|
||||
await dashboardBadgeActions.clickTimeRangeBadgeAction();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.disableCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardBadgeActions.expectMissingTimeRangeBadgeAction();
|
||||
|
|
|
@ -46,7 +46,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME);
|
||||
|
||||
await panelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.disableCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await dashboard.saveDashboard('Dashboard with Pie Chart');
|
||||
});
|
||||
|
@ -80,8 +80,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME);
|
||||
|
||||
await panelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_90 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.common.unsetTime();
|
||||
});
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/104578
|
||||
describe.skip('Customize time range', () => {
|
||||
describe('Customize time range', () => {
|
||||
it('should be possible to customize time range for saved searches on dashboards', async () => {
|
||||
await PageObjects.dashboard.navigateToApp();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
@ -55,8 +54,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
expect(await dataGrid.getDocCount()).to.be(500);
|
||||
|
||||
await panelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_90 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await dashboard.waitForRenderComplete();
|
||||
const originalEmbeddableCount = await canvas.getEmbeddableCount();
|
||||
await dashboardPanelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await dashboard.waitForRenderComplete();
|
||||
|
@ -80,8 +80,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await dashboard.waitForRenderComplete();
|
||||
const originalEmbeddableCount = await canvas.getEmbeddableCount();
|
||||
await dashboardPanelActions.customizePanel();
|
||||
await dashboardCustomizePanel.clickToggleShowCustomTimeRange();
|
||||
await dashboardCustomizePanel.clickToggleQuickMenuButton();
|
||||
await dashboardCustomizePanel.enableCustomTimeRange();
|
||||
await dashboardCustomizePanel.openDatePickerQuickMenu();
|
||||
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days');
|
||||
await dashboardCustomizePanel.clickSaveButton();
|
||||
await dashboard.waitForRenderComplete();
|
||||
|
|
|
@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
export const UPTIME_HEARTBEAT_DATA = 'x-pack/test/functional/es_archives/uptime/full_heartbeat';
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const { uptime } = getPageObjects(['uptime']);
|
||||
const { uptime, common } = getPageObjects(['uptime', 'common']);
|
||||
const retry = getService('retry');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
|
@ -104,7 +104,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
});
|
||||
await uptime.setMonitorListPageSize(50);
|
||||
// the pagination parameter should be cleared after a size change
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await common.sleep(1000);
|
||||
await retry.try(async () => {
|
||||
await uptime.pageUrlContains('pagination', false);
|
||||
});
|
||||
|
|
|
@ -12,11 +12,10 @@ interface SearchResult {
|
|||
label: string;
|
||||
}
|
||||
|
||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
export class NavigationalSearchPageObject extends FtrService {
|
||||
private readonly find = this.ctx.getService('find');
|
||||
private readonly testSubjects = this.ctx.getService('testSubjects');
|
||||
private readonly common = this.ctx.getPageObject('common');
|
||||
|
||||
async focus() {
|
||||
const field = await this.testSubjects.find('nav-search-input');
|
||||
|
@ -69,7 +68,7 @@ export class NavigationalSearchPageObject extends FtrService {
|
|||
// without heavy flakiness in this situation.
|
||||
// there is NO ui indication of any kind to detect when all the emissions are done,
|
||||
// so we are forced to fallback to awaiting a given amount of time once the first options are displayed.
|
||||
await delay(waitUntil);
|
||||
await this.common.sleep(waitUntil);
|
||||
}
|
||||
|
||||
async getDisplayedResults() {
|
||||
|
@ -79,7 +78,7 @@ export class NavigationalSearchPageObject extends FtrService {
|
|||
|
||||
async isNoResultsPlaceholderDisplayed(checkAfter: number = 3000) {
|
||||
// see comment in `waitForResultsLoaded`
|
||||
await delay(checkAfter);
|
||||
await this.common.sleep(checkAfter);
|
||||
return this.testSubjects.exists('nav-search-no-results');
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft
|
|||
'[data-test-subj="euiMarkdownEditorToolbarButton"][aria-label="Visualization"]'
|
||||
);
|
||||
await addVisualizationButton.moveMouseTo();
|
||||
await new Promise((resolve) => setTimeout(resolve, 500)); // give tooltip time to open
|
||||
await common.sleep(500); // give tooltip time to open
|
||||
},
|
||||
|
||||
async assertCaseTitle(expectedTitle: string) {
|
||||
|
|
|
@ -8,15 +8,14 @@
|
|||
import type { MappingProperty } from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
const waitFor = (time: number = 1000) => new Promise((r) => setTimeout(r, time));
|
||||
|
||||
/**
|
||||
* High level interface to operate with Elasticsearch data stream and TSDS.
|
||||
*/
|
||||
export function DataStreamProvider({ getService }: FtrProviderContext) {
|
||||
export function DataStreamProvider({ getService, getPageObject }: FtrProviderContext) {
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const common = getPageObject('common');
|
||||
|
||||
const downsampleDefaultOptions = {
|
||||
isStream: true,
|
||||
|
@ -65,7 +64,7 @@ export function DataStreamProvider({ getService }: FtrProviderContext) {
|
|||
waitTime / 1000
|
||||
}s before running the downsampling to avoid a null_pointer_exception`
|
||||
);
|
||||
await waitFor(waitTime);
|
||||
await common.sleep(waitTime);
|
||||
|
||||
try {
|
||||
log.info(`downsampling "${sourceIndex}" index...`);
|
||||
|
|
|
@ -8,10 +8,14 @@
|
|||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { WebElementWrapper } from '../../../../test/functional/services/lib/web_element_wrapper';
|
||||
|
||||
export function InfraSourceConfigurationFormProvider({ getService }: FtrProviderContext) {
|
||||
export function InfraSourceConfigurationFormProvider({
|
||||
getService,
|
||||
getPageObject,
|
||||
}: FtrProviderContext) {
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
const common = getPageObject('common');
|
||||
|
||||
return {
|
||||
/**
|
||||
|
@ -94,7 +98,7 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider
|
|||
const movementDifference = destinationIndex - sourceIndex;
|
||||
await moveLogColumnHandle.pressKeys(browser.keys.SPACE);
|
||||
for (let i = 0; i < Math.abs(movementDifference); i++) {
|
||||
await new Promise((res) => setTimeout(res, KEY_PRESS_DELAY_MS));
|
||||
await common.sleep(KEY_PRESS_DELAY_MS);
|
||||
if (movementDifference > 0) {
|
||||
await moveLogColumnHandle.pressKeys(browser.keys.ARROW_DOWN);
|
||||
} else {
|
||||
|
@ -102,7 +106,7 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider
|
|||
}
|
||||
}
|
||||
await moveLogColumnHandle.pressKeys(browser.keys.SPACE);
|
||||
await new Promise((res) => setTimeout(res, KEY_PRESS_DELAY_MS));
|
||||
await common.sleep(KEY_PRESS_DELAY_MS);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@ export function UptimeNavigationProvider({ getService, getPageObjects }: FtrProv
|
|||
return {
|
||||
async refreshApp() {
|
||||
await browser.refresh();
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await PageObjects.common.sleep(1000);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue