diff --git a/x-pack/test/functional/page_objects/security_page.ts b/x-pack/test/functional/page_objects/security_page.ts index 2f0da92a2a6be..8ff8b58f44caf 100644 --- a/x-pack/test/functional/page_objects/security_page.ts +++ b/x-pack/test/functional/page_objects/security_page.ts @@ -16,7 +16,11 @@ interface LoginOptions { expectForbidden?: boolean; } -type LoginExpectedResult = 'spaceSelector' | 'error' | 'chrome'; +type LoginExpectedResult = + | 'spaceSelector' + | 'error' + | 'chrome' + | (() => unknown | Promise); export class SecurityPageObject extends FtrService { private readonly browser = this.ctx.getService('browser'); @@ -77,7 +81,13 @@ export class SecurityPageObject extends FtrService { }); public loginSelector = Object.freeze({ - login: async (providerType: string, providerName: string, options?: Record) => { + login: async ( + providerType: string, + providerName: string, + options?: Omit, 'expectedLoginResult'> & { + expectedLoginResult?: LoginExpectedResult; + } + ) => { this.log.debug(`Starting login flow for ${providerType}/${providerName}`); await this.loginSelector.verifyLoginSelectorIsVisible(); @@ -97,7 +107,7 @@ export class SecurityPageObject extends FtrService { await this.testSubjects.click('loginSubmit'); } - await this.waitForLoginResult('chrome'); + await this.waitForLoginResult(options?.expectedLoginResult ?? 'chrome'); this.log.debug(`Finished login process currentUrl = ${await this.browser.getCurrentUrl()}`); }, @@ -211,6 +221,13 @@ export class SecurityPageObject extends FtrService { await this.find.byCssSelector('[data-test-subj="userMenuButton"]', 20000); this.log.debug(`Finished login process currentUrl = ${await this.browser.getCurrentUrl()}`); } + + if (expectedResult instanceof Function) { + await expectedResult(); + this.log.debug( + `Finished login process, await for custom condition. currentUrl = ${await this.browser.getCurrentUrl()}` + ); + } } async initTests() { diff --git a/x-pack/test/security_functional/fixtures/common/test_endpoints/public/plugin.tsx b/x-pack/test/security_functional/fixtures/common/test_endpoints/public/plugin.tsx index 2796d64c01a58..b0264998db17d 100644 --- a/x-pack/test/security_functional/fixtures/common/test_endpoints/public/plugin.tsx +++ b/x-pack/test/security_functional/fixtures/common/test_endpoints/public/plugin.tsx @@ -11,10 +11,13 @@ import React from 'react'; export class TestEndpointsPlugin implements Plugin { public setup(core: CoreSetup) { + // Prevent auto-logout on server `401` errors. + core.http.anonymousPaths.register('/authentication/app'); core.application.register({ id: 'authentication_app', title: 'Authentication app', appRoute: '/authentication/app', + chromeless: true, async mount({ element }) { ReactDOM.render(
Authenticated!
, diff --git a/x-pack/test/security_functional/tests/login_selector/basic_functionality.ts b/x-pack/test/security_functional/tests/login_selector/basic_functionality.ts index 1eba7a4df31d8..b8c0859541eb9 100644 --- a/x-pack/test/security_functional/tests/login_selector/basic_functionality.ts +++ b/x-pack/test/security_functional/tests/login_selector/basic_functionality.ts @@ -17,8 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const deployment = getService('deployment'); const PageObjects = getPageObjects(['security', 'common']); - // Failing: See https://github.com/elastic/kibana/issues/98562 - describe.skip('Basic functionality', function () { + describe('Basic functionality', function () { this.tags('includeFirefox'); const testCredentials = { username: 'admin_user', password: 'change_me' }; @@ -121,7 +120,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { .post('/authentication/app/setup') .send({ simulateUnauthorized: false }) .expect(200); - await PageObjects.security.loginSelector.login('basic', 'basic1'); + await PageObjects.security.loginSelector.login('basic', 'basic1', { + // By default, login waits till chrome appears, but the test authentication app is a chromeless app. + expectedLoginResult: () => testSubjects.waitForEnabled('testEndpointsAuthenticationApp'), + }); const currentURL = parse(await browser.getCurrentUrl()); expect(currentURL.path).to.eql('/authentication/app?one=two'); @@ -129,16 +131,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('can login after `Unauthorized` error during request authentication preserving original URL', async () => { // 1. Navigate to Kibana to make sure user is properly authenticated. - await PageObjects.common.navigateToUrl('management', 'security/users', { - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - shouldUseHashForSubUrl: false, - }); + await browser.get(`${deployment.getHostPort()}/authentication/app?one=two`); await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible(); - await PageObjects.security.loginSelector.login('basic', 'basic1', testCredentials); - expect(parse(await browser.getCurrentUrl()).pathname).to.eql( - '/app/management/security/users' - ); + await PageObjects.security.loginSelector.login('basic', 'basic1', { + ...testCredentials, + // By default, login waits till chrome appears, but the test authentication app is a chromeless app. + expectedLoginResult: () => testSubjects.waitForEnabled('testEndpointsAuthenticationApp'), + }); + expect(parse(await browser.getCurrentUrl()).pathname).to.eql('/authentication/app'); // 2. Now disable user and try to refresh page causing authentication to fail. await security.user.disable(testCredentials.username); @@ -150,10 +150,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // 3. Re-enable user and try to login again. await security.user.enable(testCredentials.username); - await PageObjects.security.loginSelector.login('basic', 'basic1', testCredentials); - expect(parse(await browser.getCurrentUrl()).pathname).to.eql( - '/app/management/security/users' - ); + await PageObjects.security.loginSelector.login('basic', 'basic1', { + ...testCredentials, + // By default, login waits till chrome appears, but the test authentication app is a chromeless app. + expectedLoginResult: () => testSubjects.waitForEnabled('testEndpointsAuthenticationApp'), + }); + expect(parse(await browser.getCurrentUrl()).pathname).to.eql('/authentication/app'); }); it('should show toast with error if SSO fails', async () => {