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

[8.11] unskips application leave confirm & application deep links tests (#168741) #169395

Merged
merged 1 commit into from
Oct 19, 2023
Merged
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
13 changes: 11 additions & 2 deletions test/functional/page_objects/common_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
1 change: 1 addition & 0 deletions test/functional/services/apps_menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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'));
Expand All @@ -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);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const PageA = () => (
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>DL Page A</h1>
<h1>DL page A</h1>
</EuiTitle>
</EuiPageHeaderSection>
</EuiPageHeader>
Expand All @@ -70,7 +70,7 @@ const PageB = () => (
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>DL Page B</h1>
<h1>DL page B</h1>
</EuiTitle>
</EuiPageHeaderSection>
</EuiPageHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class CorePluginDeepLinksPlugin
},
{
id: 'pageA',
title: 'DL Page A',
title: 'DL page A',
path: '/page-a',
navLinkStatus: AppNavLinkStatus.visible,
},
Expand All @@ -39,15 +39,15 @@ export class CorePluginDeepLinksPlugin
deepLinks: [
{
id: 'pageB',
title: 'DL Page B',
title: 'DL page B',
path: '/page-b',
navLinkStatus: AppNavLinkStatus.visible,
},
],
},
{
id: 'pageC',
title: 'DL Page C',
title: 'DL page C',
path: '/page-c',
// navLinkStatus hidden by default
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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');
Expand All @@ -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');
Expand All @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand All @@ -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');

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;

// Failing: See https://github.com/elastic/kibana/issues/75963
// Failing: See https://github.com/elastic/kibana/issues/166838
describe.skip('application using leave confirmation', () => {
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');
});
});
});
Expand Down
Loading