From 1e089983aac9a8ecf7a47626eaa2a5dda94a6d38 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Wed, 18 Oct 2023 15:05:44 -0700 Subject: [PATCH] Refactors tests, helpers and plugin to take delayed rendering into account. The delays stem from multiple background tasks that run simultaneously and cannot be turned off --- test/functional/services/apps_menu.ts | 1 + .../core_plugin_appleave/public/plugin.tsx | 6 +- .../core_plugins/application_leave_confirm.ts | 74 ++++++++++++++----- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/test/functional/services/apps_menu.ts b/test/functional/services/apps_menu.ts index 9fb8e36476f3e..0f63166477883 100644 --- a/test/functional/services/apps_menu.ts +++ b/test/functional/services/apps_menu.ts @@ -59,6 +59,7 @@ export class AppsMenuService extends FtrService { if (!(await this.testSubjects.exists('collapsibleNav'))) { await this.testSubjects.click('toggleNavButton'); } + await this.testSubjects.exists('collapsibleNav'); } /** diff --git a/test/plugin_functional/plugins/core_plugin_appleave/public/plugin.tsx b/test/plugin_functional/plugins/core_plugin_appleave/public/plugin.tsx index 4718007a89f56..a5107a375d8a0 100644 --- a/test/plugin_functional/plugins/core_plugin_appleave/public/plugin.tsx +++ b/test/plugin_functional/plugins/core_plugin_appleave/public/plugin.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Plugin, CoreSetup } from '@kbn/core/public'; +import { Plugin, CoreSetup, DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; export class CoreAppLeavePlugin implements Plugin @@ -15,6 +15,8 @@ export class CoreAppLeavePlugin core.application.register({ id: 'appleave1', title: 'AppLeave 1', + appRoute: '/app/appleave1', + category: DEFAULT_APP_CATEGORIES.kibana, async mount(params) { const { renderApp } = await import('./application'); params.onAppLeave((actions) => actions.confirm('confirm-message', 'confirm-title')); @@ -24,6 +26,8 @@ export class CoreAppLeavePlugin core.application.register({ id: 'appleave2', title: 'AppLeave 2', + appRoute: '/app/appleave2', + category: DEFAULT_APP_CATEGORIES.kibana, async mount(params) { const { renderApp } = await import('./application'); params.onAppLeave((actions) => actions.confirm('confirm-message', 'confirm-title')); diff --git a/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts b/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts index 610652b979d7c..e5915f9020135 100644 --- a/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts +++ b/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import url from 'url'; import expect from '@kbn/expect'; +import url from 'url'; import { PluginFunctionalProviderContext } from '../../services'; const getKibanaUrl = (pathname?: string, search?: string) => @@ -25,45 +25,81 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const appsMenu = getService('appsMenu'); const log = getService('log'); const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + const config = getService('config'); - const waitForUrlToBe = (pathname?: string, search?: string) => { + const waitForUrlToBe = async (pathname?: string, search?: string) => { const expectedUrl = getKibanaUrl(pathname, search); - return retry.waitFor(`Url to be ${expectedUrl}`, async () => { + return await retry.waitFor(`Url to be ${expectedUrl}`, async () => { const currentUrl = await browser.getCurrentUrl(); log.debug(`waiting for currentUrl ${currentUrl} to be expectedUrl ${expectedUrl}`); return currentUrl === expectedUrl; }); }; + const ensureModalOpen = async ( + defaultTryTimeout: number, + attempts: number, + timeMultiplier: number, + action: 'cancel' | 'confirm' + ): Promise => { + let isConfirmCancelModalOpenState = false; + await retry.tryForTime(defaultTryTimeout * timeMultiplier, async () => { + isConfirmCancelModalOpenState = await testSubjects.exists('confirmModalCancelButton'); + }); + if (isConfirmCancelModalOpenState) { + log.debug(`defaultTryTimeout * ${timeMultiplier} is long enough`); + return action === 'cancel' + ? await PageObjects.common.clickCancelOnModal(true, false) + : await PageObjects.common.clickConfirmOnModal(); + } else { + log.debug(`defaultTryTimeout * ${timeMultiplier} is not long enough`); + return await ensureModalOpen( + defaultTryTimeout, + (attempts = attempts > 0 ? attempts - 1 : 0), + (timeMultiplier = timeMultiplier < 10 ? timeMultiplier + 1 : 10), + action + ); + } + }; + describe('application using leave confirmation', () => { + const defaultTryTimeout = config.get('timeouts.try'); + const attempts = 5; describe('when navigating to another app', () => { - it('allows navigation if user click confirm on the confirmation dialog', async () => { + const timeMultiplier = 2; + it('prevents navigation if user click cancel on the confirmation dialog', async () => { await PageObjects.common.navigateToApp('appleave1'); await waitForUrlToBe('/app/appleave1'); await appsMenu.clickLink('AppLeave 2'); - - await PageObjects.common.expectConfirmModalOpenState(true); - await PageObjects.common.clickConfirmOnModal(); - + await ensureModalOpen(defaultTryTimeout, attempts, timeMultiplier, 'cancel'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.waitFor('navigate to appleave1', async () => { + const currentUrl = await browser.getCurrentUrl(); + log.debug(`currentUrl ${currentUrl}`); + return currentUrl.includes('appleave1'); + }); const currentUrl = await browser.getCurrentUrl(); - const kibanaUrl = getKibanaUrl('/app/appleave2'); - log.debug(`currentUrl ${currentUrl} kibanaUrl ${kibanaUrl}`); - expect(currentUrl).to.eql(kibanaUrl); + expect(currentUrl).to.contain('appleave1'); + await PageObjects.common.navigateToApp('home'); }); - it('prevents navigation if user click cancel on the confirmation dialog', async () => { + + it('allows navigation if user click confirm on the confirmation dialog', async () => { await PageObjects.common.navigateToApp('appleave1'); await waitForUrlToBe('/app/appleave1'); await appsMenu.clickLink('AppLeave 2'); - - await PageObjects.common.expectConfirmModalOpenState(true); - await PageObjects.common.clickCancelOnModal(false); - + await ensureModalOpen(defaultTryTimeout, attempts, timeMultiplier, 'confirm'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.waitFor('navigate to appleave1', async () => { + const currentUrl = await browser.getCurrentUrl(); + log.debug(`currentUrl ${currentUrl}`); + return currentUrl.includes('appleave2'); + }); const currentUrl = await browser.getCurrentUrl(); - const kibanaUrl = getKibanaUrl('/app/appleave1'); - log.debug(`currentUrl ${currentUrl} kibanaUrl ${kibanaUrl}`); - expect(currentUrl).to.eql(kibanaUrl); + expect(currentUrl).to.contain('appleave2'); + await PageObjects.common.navigateToApp('home'); }); }); });