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

Fix and re-enable basic login selector functional tests. #106822

Merged
merged 1 commit into from
Jul 28, 2021
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
23 changes: 20 additions & 3 deletions x-pack/test/functional/page_objects/security_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ interface LoginOptions {
expectForbidden?: boolean;
}

type LoginExpectedResult = 'spaceSelector' | 'error' | 'chrome';
type LoginExpectedResult =
| 'spaceSelector'
| 'error'
| 'chrome'
| (() => unknown | Promise<unknown>);

export class SecurityPageObject extends FtrService {
private readonly browser = this.ctx.getService('browser');
Expand Down Expand Up @@ -77,7 +81,13 @@ export class SecurityPageObject extends FtrService {
});

public loginSelector = Object.freeze({
login: async (providerType: string, providerName: string, options?: Record<string, any>) => {
login: async (
providerType: string,
providerName: string,
options?: Omit<Record<string, any>, 'expectedLoginResult'> & {
expectedLoginResult?: LoginExpectedResult;
}
) => {
this.log.debug(`Starting login flow for ${providerType}/${providerName}`);

await this.loginSelector.verifyLoginSelectorIsVisible();
Expand All @@ -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()}`);
},
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<div data-test-subj="testEndpointsAuthenticationApp">Authenticated!</div>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const deployment = getService('deployment');
const PageObjects = getPageObjects(['security', 'common']);

// FLAKY: 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' };
Expand Down Expand Up @@ -121,24 +120,25 @@ 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', {
Copy link
Member Author

@azasypkin azasypkin Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: the issue is explained here #98562 (comment). The idea is to use chromeless app that doesn't make any unnecessary requests that may trigger logout earlier than we need.

// 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');
});

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);
Expand All @@ -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 () => {
Expand Down