mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
# Backport This will backport the following commits from `main` to `8.11`: - [unskips application leave confirm & application deep links tests (#168741)](https://github.com/elastic/kibana/pull/168741) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Christiane (Tina) Heiligers","email":"christiane.heiligers@elastic.co"},"sourceCommit":{"committedDate":"2023-10-19T13:03:24Z","message":"unskips application leave confirm & application deep links tests (#168741)\n\nfix https://github.com/elastic/kibana/issues/166838\r\nfix https://github.com/elastic/kibana/issues/166893\r\nfix https://github.com/elastic/kibana/issues/75963\r\n\r\nI modified the deep links tests because the side nav was overlaying the\r\nin-app nav.\r\nWhile, theoretically, the side nav should work for the tests, it tends\r\nto be flaky.\r\n\r\nI added logs for the url so that if these tests do fail, we'll have a\r\nbit more data to go on for debugging.\r\nThese tests pass on local test runs.\r\n\r\nlatest flaky test runs (50):\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3604\r\n\r\n\r\n- [X] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e811b624ff5e706a283949a406af31bf090e963c","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["backport","Team:Core","release_note:skip","v8.11.0","v8.12.0"],"number":168741,"url":"https://github.com/elastic/kibana/pull/168741","mergeCommit":{"message":"unskips application leave confirm & application deep links tests (#168741)\n\nfix https://github.com/elastic/kibana/issues/166838\r\nfix https://github.com/elastic/kibana/issues/166893\r\nfix https://github.com/elastic/kibana/issues/75963\r\n\r\nI modified the deep links tests because the side nav was overlaying the\r\nin-app nav.\r\nWhile, theoretically, the side nav should work for the tests, it tends\r\nto be flaky.\r\n\r\nI added logs for the url so that if these tests do fail, we'll have a\r\nbit more data to go on for debugging.\r\nThese tests pass on local test runs.\r\n\r\nlatest flaky test runs (50):\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3604\r\n\r\n\r\n- [X] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e811b624ff5e706a283949a406af31bf090e963c"}},"sourceBranch":"main","suggestedTargetBranches":["8.11"],"targetPullRequestStates":[{"branch":"8.11","label":"v8.11.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/168741","number":168741,"mergeCommit":{"message":"unskips application leave confirm & application deep links tests (#168741)\n\nfix https://github.com/elastic/kibana/issues/166838\r\nfix https://github.com/elastic/kibana/issues/166893\r\nfix https://github.com/elastic/kibana/issues/75963\r\n\r\nI modified the deep links tests because the side nav was overlaying the\r\nin-app nav.\r\nWhile, theoretically, the side nav should work for the tests, it tends\r\nto be flaky.\r\n\r\nI added logs for the url so that if these tests do fail, we'll have a\r\nbit more data to go on for debugging.\r\nThese tests pass on local test runs.\r\n\r\nlatest flaky test runs (50):\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3604\r\n\r\n\r\n- [X] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e811b624ff5e706a283949a406af31bf090e963c"}}]}] BACKPORT--> Co-authored-by: Christiane (Tina) Heiligers <christiane.heiligers@elastic.co>
This commit is contained in:
parent
95ac33b9c9
commit
56931545af
7 changed files with 122 additions and 32 deletions
|
@ -411,9 +411,18 @@ export class CommonPageObject extends FtrService {
|
|||
* Clicks cancel button on modal
|
||||
* @param overlayWillStay pass in true if your test will show multiple modals in succession
|
||||
*/
|
||||
async clickCancelOnModal(overlayWillStay = true) {
|
||||
async clickCancelOnModal(overlayWillStay = true, ignorePageLeaveWarning = false) {
|
||||
this.log.debug('Clicking modal cancel');
|
||||
await this.testSubjects.click('confirmModalCancelButton');
|
||||
await this.testSubjects.exists('confirmModalTitleText');
|
||||
|
||||
await this.retry.try(async () => {
|
||||
const warning = await this.testSubjects.exists('confirmModalTitleText');
|
||||
if (warning) {
|
||||
await this.testSubjects.click(
|
||||
ignorePageLeaveWarning ? 'confirmModalConfirmButton' : 'confirmModalCancelButton'
|
||||
);
|
||||
}
|
||||
});
|
||||
if (!overlayWillStay) {
|
||||
await this.ensureModalOverlayHidden();
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<CoreAppLeavePluginSetup, CoreAppLeavePluginStart>
|
||||
|
@ -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,9 +26,11 @@ 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.default());
|
||||
params.onAppLeave((actions) => actions.confirm('confirm-message', 'confirm-title'));
|
||||
return renderApp('AppLeave 2', params);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -50,7 +50,7 @@ const PageA = () => (
|
|||
<EuiPageHeader>
|
||||
<EuiPageHeaderSection>
|
||||
<EuiTitle size="l">
|
||||
<h1>DL Page A</h1>
|
||||
<h1>DL page A</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageHeaderSection>
|
||||
</EuiPageHeader>
|
||||
|
@ -70,7 +70,7 @@ const PageB = () => (
|
|||
<EuiPageHeader>
|
||||
<EuiPageHeaderSection>
|
||||
<EuiTitle size="l">
|
||||
<h1>DL Page B</h1>
|
||||
<h1>DL page B</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageHeaderSection>
|
||||
</EuiPageHeader>
|
||||
|
|
|
@ -29,7 +29,7 @@ export class CorePluginDeepLinksPlugin
|
|||
},
|
||||
{
|
||||
id: 'pageA',
|
||||
title: 'DL Page A',
|
||||
title: 'DL page A',
|
||||
path: '/page-a',
|
||||
navLinkStatus: AppNavLinkStatus.visible,
|
||||
},
|
||||
|
@ -39,7 +39,7 @@ export class CorePluginDeepLinksPlugin
|
|||
deepLinks: [
|
||||
{
|
||||
id: 'pageB',
|
||||
title: 'DL Page B',
|
||||
title: 'DL page B',
|
||||
path: '/page-b',
|
||||
navLinkStatus: AppNavLinkStatus.visible,
|
||||
},
|
||||
|
@ -47,7 +47,7 @@ export class CorePluginDeepLinksPlugin
|
|||
},
|
||||
{
|
||||
id: 'pageC',
|
||||
title: 'DL Page C',
|
||||
title: 'DL page C',
|
||||
path: '/page-c',
|
||||
// navLinkStatus hidden by default
|
||||
},
|
||||
|
|
|
@ -18,6 +18,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
|
|||
const testSubjects = getService('testSubjects');
|
||||
const retry = getService('retry');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const log = getService('log');
|
||||
|
||||
const loadingScreenNotShown = async () =>
|
||||
expect(await testSubjects.exists('kbnLoadingMessage')).to.be(false);
|
||||
|
@ -35,12 +36,20 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
|
|||
const waitForUrlToBe = (pathname?: string, search?: string) => {
|
||||
const expectedUrl = getKibanaUrl(pathname, search);
|
||||
return retry.waitFor(`Url to be ${expectedUrl}`, async () => {
|
||||
return (await browser.getCurrentUrl()) === expectedUrl;
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
log?.debug(`waiting for currentUrl ${currentUrl} to be expectedUrl ${expectedUrl}`);
|
||||
return currentUrl === expectedUrl;
|
||||
});
|
||||
};
|
||||
|
||||
// Failing: See https://github.com/elastic/kibana/issues/166893
|
||||
describe.skip('application deep links navigation', function describeDeepLinksTests() {
|
||||
const navigateToAppLinks = async (subject: string) => {
|
||||
if (!(await testSubjects.exists(subject))) {
|
||||
log.debug(`side nav in app not in DOM`);
|
||||
}
|
||||
await testSubjects.click(subject);
|
||||
};
|
||||
|
||||
describe('application deep links navigation', function describeDeepLinksTests() {
|
||||
before(async () => {
|
||||
await esArchiver.emptyKibanaIndex();
|
||||
await PageObjects.common.navigateToApp('dl');
|
||||
|
@ -51,28 +60,29 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
|
|||
});
|
||||
|
||||
it('should navigate to page A when navlink is clicked', async () => {
|
||||
await appsMenu.clickLink('DL Page A');
|
||||
await navigateToAppLinks('dlNavPageA');
|
||||
await waitForUrlToBe('/app/dl/page-a');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppPageA');
|
||||
await testSubjects.existOrFail('dlNavPageA');
|
||||
});
|
||||
|
||||
it('should be able to use the back button to navigate back to previous deep link', async () => {
|
||||
await browser.goBack();
|
||||
await waitForUrlToBe('/app/dl/home');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppHome');
|
||||
await testSubjects.existOrFail('dlNavHome');
|
||||
});
|
||||
|
||||
it('should navigate to nested page B when navlink is clicked', async () => {
|
||||
await appsMenu.clickLink('DL Page B');
|
||||
await navigateToAppLinks('dlNavDeepPageB');
|
||||
await waitForUrlToBe('/app/dl/page-b');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppPageB');
|
||||
await testSubjects.existOrFail('dlNavDeepPageB');
|
||||
});
|
||||
|
||||
it('should navigate to Home when navlink is clicked inside the defined category group', async () => {
|
||||
await appsMenu.clickLink('DL Home', { category: 'securitySolution' });
|
||||
await navigateToAppLinks('dlAppHome');
|
||||
await waitForUrlToBe('/app/dl/home');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppHome');
|
||||
|
@ -82,14 +92,14 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
|
|||
await testSubjects.click('dlNavDeepPageB');
|
||||
await waitForUrlToBe('/app/dl/page-b');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppPageB');
|
||||
await testSubjects.existOrFail('dlNavDeepPageB');
|
||||
});
|
||||
|
||||
it('should navigate to nested page A using navigateToApp deepLinkId', async () => {
|
||||
await testSubjects.click('dlNavDeepPageAById');
|
||||
await waitForUrlToBe('/app/dl/page-a');
|
||||
await loadingScreenNotShown();
|
||||
await testSubjects.existOrFail('dlAppPageA');
|
||||
await testSubjects.existOrFail('dlNavPageA');
|
||||
});
|
||||
|
||||
it('should not display hidden deep links', async () => {
|
||||
|
|
|
@ -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) =>
|
||||
|
@ -20,30 +20,96 @@ const getKibanaUrl = (pathname?: string, search?: string) =>
|
|||
});
|
||||
|
||||
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||
const PageObjects = getPageObjects(['common']);
|
||||
const PageObjects = getPageObjects(['common', 'header']);
|
||||
const browser = getService('browser');
|
||||
const appsMenu = getService('appsMenu');
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const config = getService('config');
|
||||
|
||||
// Failing: See https://github.com/elastic/kibana/issues/75963
|
||||
// Failing: See https://github.com/elastic/kibana/issues/166838
|
||||
describe.skip('application using leave confirmation', () => {
|
||||
const waitForUrlToBe = async (pathname?: string, search?: string) => {
|
||||
const expectedUrl = getKibanaUrl(pathname, search);
|
||||
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',
|
||||
linkText: string = 'home'
|
||||
): Promise<void> => {
|
||||
let isConfirmCancelModalOpenState = false;
|
||||
|
||||
await retry.tryForTime(defaultTryTimeout * timeMultiplier, async () => {
|
||||
await appsMenu.clickLink(linkText);
|
||||
isConfirmCancelModalOpenState = await testSubjects.exists('confirmModalTitleText', {
|
||||
allowHidden: true,
|
||||
timeout: defaultTryTimeout * timeMultiplier,
|
||||
});
|
||||
});
|
||||
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,
|
||||
linkText
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
describe('application using leave confirmation', () => {
|
||||
const defaultTryTimeout = config.get('timeouts.try');
|
||||
const attempts = 5;
|
||||
describe('when navigating to another app', () => {
|
||||
const timeMultiplier = 10;
|
||||
beforeEach(async () => {
|
||||
await PageObjects.common.navigateToApp('home');
|
||||
});
|
||||
it('prevents navigation if user click cancel on the confirmation dialog', async () => {
|
||||
await PageObjects.common.navigateToApp('appleave1');
|
||||
await appsMenu.clickLink('AppLeave 2');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await waitForUrlToBe('/app/appleave1');
|
||||
|
||||
await testSubjects.existOrFail('appLeaveConfirmModal');
|
||||
await PageObjects.common.clickCancelOnModal(false);
|
||||
expect(await browser.getCurrentUrl()).to.eql(getKibanaUrl('/app/appleave1'));
|
||||
await ensureModalOpen(defaultTryTimeout, attempts, timeMultiplier, 'cancel', 'AppLeave 2');
|
||||
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();
|
||||
expect(currentUrl).to.contain('appleave1');
|
||||
await PageObjects.common.navigateToApp('home');
|
||||
});
|
||||
|
||||
it('allows navigation if user click confirm on the confirmation dialog', async () => {
|
||||
await PageObjects.common.navigateToApp('appleave1');
|
||||
await appsMenu.clickLink('AppLeave 2');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await waitForUrlToBe('/app/appleave1');
|
||||
|
||||
await testSubjects.existOrFail('appLeaveConfirmModal');
|
||||
await PageObjects.common.clickConfirmOnModal();
|
||||
expect(await browser.getCurrentUrl()).to.eql(getKibanaUrl('/app/appleave2'));
|
||||
await ensureModalOpen(defaultTryTimeout, attempts, timeMultiplier, 'confirm', 'AppLeave 2');
|
||||
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();
|
||||
expect(currentUrl).to.contain('appleave2');
|
||||
await PageObjects.common.navigateToApp('home');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue