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

Add Login Selector functional tests. #65705

Merged
merged 4 commits into from
May 15, 2020
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
6 changes: 3 additions & 3 deletions test/functional/page_objects/common_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo
const find = getService('find');
const globalNav = getService('globalNav');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['shield']);
const PageObjects = getPageObjects(['login']);

const defaultTryTimeout = config.get('timeouts.try');
const defaultFindTimeout = config.get('timeouts.find');
Expand Down Expand Up @@ -76,12 +76,12 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo
if (loginPage && !wantedLoginPage) {
log.debug('Found login page');
if (config.get('security.disableTestUser')) {
await PageObjects.shield.login(
await PageObjects.login.login(
config.get('servers.kibana.username'),
config.get('servers.kibana.password')
);
} else {
await PageObjects.shield.login('test_user', 'changeme');
await PageObjects.login.login('test_user', 'changeme');
}

await find.byCssSelector(
Expand Down
4 changes: 2 additions & 2 deletions test/functional/page_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { HomePageProvider } from './home_page';
import { NewsfeedPageProvider } from './newsfeed_page';
import { SettingsPageProvider } from './settings_page';
import { SharePageProvider } from './share_page';
import { ShieldPageProvider } from './shield_page';
import { LoginPageProvider } from './login_page';
import { TimePickerProvider } from './time_picker';
import { TimelionPageProvider } from './timelion_page';
import { VisualBuilderPageProvider } from './visual_builder_page';
Expand All @@ -51,7 +51,7 @@ export const pageObjects = {
newsfeed: NewsfeedPageProvider,
settings: SettingsPageProvider,
share: SharePageProvider,
shield: ShieldPageProvider,
login: LoginPageProvider,
timelion: TimelionPageProvider,
timePicker: TimePickerProvider,
visualBuilder: VisualBuilderPageProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@

import { FtrProviderContext } from '../ftr_provider_context';

export function ShieldPageProvider({ getService }: FtrProviderContext) {
export function LoginPageProvider({ getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');

class ShieldPage {
class LoginPage {
async login(user: string, pwd: string) {
await testSubjects.setValue('loginUsername', user);
await testSubjects.setValue('loginPassword', pwd);
await testSubjects.click('loginSubmit');
}
}

return new ShieldPage();
return new LoginPage();
Copy link
Member

Choose a reason for hiding this comment

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

👏 👏 👏

}
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export class LoginForm extends Component<Props, State> {
{this.props.selector.providers.map(provider => (
<button
key={provider.name}
data-test-subj={`loginCard-${provider.type}/${provider.name}`}
disabled={!this.isLoadingState(LoadingStateType.None)}
onClick={() =>
provider.usesLoginForm
Expand Down
3 changes: 2 additions & 1 deletion x-pack/scripts/functional_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const alwaysImportedTests = [
require.resolve('../test/functional_endpoint_ingest_failure/config.ts'),
require.resolve('../test/functional_endpoint/config.ts'),
require.resolve('../test/functional_with_es_ssl/config.ts'),
require.resolve('../test/functional/config_security_basic.js'),
require.resolve('../test/functional/config_security_basic.ts'),
require.resolve('../test/functional/config_security_trial.ts'),
require.resolve('../test/plugin_functional/config.ts'),
];
const onlyNotInCoverageTests = [
Expand Down
2 changes: 1 addition & 1 deletion x-pack/test/functional/apps/security/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
});

it('logging out of a non-default space redirects to the login page at the server root', async () => {
await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});

Expand Down
15 changes: 15 additions & 0 deletions x-pack/test/functional/apps/security/trial_license/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { FtrProviderContext } from '../../../ftr_provider_context';

export default function({ loadTestFile }: FtrProviderContext) {
describe('security app - trial license', function() {
this.tags('ciGroup4');

loadTestFile(require.resolve('./login_selector'));
});
}
123 changes: 123 additions & 0 deletions x-pack/test/functional/apps/security/trial_license/login_selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';
import { parse } from 'url';
import { USERS_PATH } from '../../../../../plugins/security/public/management/management_urls';
import { FtrProviderContext } from '../../../ftr_provider_context';

export default function({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const browser = getService('browser');
const PageObjects = getPageObjects(['security', 'common']);

describe('Login Selector', function() {
this.tags('includeFirefox');

before(async () => {
await getService('esSupertest')
.post('/_security/role_mapping/saml1')
.send({ roles: ['superuser'], enabled: true, rules: { field: { 'realm.name': 'saml1' } } })
.expect(200);

await esArchiver.load('empty_kibana');
await PageObjects.security.forceLogout();
});

after(async () => {
await esArchiver.unload('empty_kibana');
});

beforeEach(async () => {
await browser.get(`${PageObjects.common.getHostPort()}/login`);
await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();
});

afterEach(async () => {
await PageObjects.security.forceLogout();
});

it('can login with Login Form preserving original URL', async () => {
await PageObjects.common.navigateToActualUrl('kibana', USERS_PATH, {
ensureCurrentUrl: false,
shouldLoginIfPrompted: false,
});
await PageObjects.common.waitUntilUrlIncludes('next=');

await PageObjects.security.loginSelector.login('basic', 'basic1');

// We need to make sure that both path and hash are respected.
const currentURL = parse(await browser.getCurrentUrl());
expect(currentURL.pathname).to.eql('/app/kibana');
expect(currentURL.hash).to.eql(`#${USERS_PATH}`);
});

it('can login with SSO preserving original URL', async () => {
await PageObjects.common.navigateToActualUrl('kibana', USERS_PATH, {
ensureCurrentUrl: false,
shouldLoginIfPrompted: false,
});
await PageObjects.common.waitUntilUrlIncludes('next=');

await PageObjects.security.loginSelector.login('saml', 'saml1');

// We need to make sure that both path and hash are respected.
const currentURL = parse(await browser.getCurrentUrl());
expect(currentURL.pathname).to.eql('/app/kibana');
expect(currentURL.hash).to.eql(`#${USERS_PATH}`);
});

it('should show toast with error if SSO fails', async () => {
await PageObjects.security.loginSelector.selectLoginMethod('saml', 'unknown_saml');

const toastTitle = await PageObjects.common.closeToast();
expect(toastTitle).to.eql('Could not perform login.');

await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();
});

it('can go to Login Form and return back to Selector', async () => {
await PageObjects.security.loginSelector.selectLoginMethod('basic', 'basic1');
await PageObjects.security.loginSelector.verifyLoginFormIsVisible();

await testSubjects.click('loginBackToSelector');
await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();

await PageObjects.security.loginSelector.login('saml', 'saml1');
});

it('can show Login Help from both Login Selector and Login Form', async () => {
// Show Login Help from Login Selector.
await testSubjects.click('loginHelpLink');
await PageObjects.security.loginSelector.verifyLoginHelpIsVisible('Some-login-help.');

// Go back to Login Selector.
await testSubjects.click('loginBackToLoginLink');
await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();

// Go to Login Form and show Login Help there.
await PageObjects.security.loginSelector.selectLoginMethod('basic', 'basic1');
await PageObjects.security.loginSelector.verifyLoginFormIsVisible();
await testSubjects.click('loginHelpLink');
await PageObjects.security.loginSelector.verifyLoginHelpIsVisible('Some-login-help.');

// Go back to Login Form.
await testSubjects.click('loginBackToLoginLink');
await PageObjects.security.loginSelector.verifyLoginFormIsVisible();

// Go back to Login Selector and show Login Help there again.
await testSubjects.click('loginBackToSelector');
await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();
await testSubjects.click('loginHelpLink');
await PageObjects.security.loginSelector.verifyLoginHelpIsVisible('Some-login-help.');

// Go back to Login Selector.
await testSubjects.click('loginBackToLoginLink');
await PageObjects.security.loginSelector.verifyLoginSelectorIsVisible();
});
});
}
2 changes: 1 addition & 1 deletion x-pack/test/functional/apps/spaces/copy_saved_objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function spaceSelectorFunctonalTests({
disabledFeatures: [],
});

await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});

Expand Down
4 changes: 2 additions & 2 deletions x-pack/test/functional/apps/spaces/enter_space.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function enterSpaceFunctonalTests({
it('falls back to the default home page when the configured default route is malformed', async () => {
const spaceId = 'default';

await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});

Expand All @@ -39,7 +39,7 @@ export default function enterSpaceFunctonalTests({
it('allows user to navigate to different spaces, respecting the configured default route', async () => {
const spaceId = 'another-space';

await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});

Expand Down
4 changes: 2 additions & 2 deletions x-pack/test/functional/apps/spaces/spaces_selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function spaceSelectorFunctonalTests({
it('allows user to navigate to different spaces', async () => {
const spaceId = 'another-space';

await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});

Expand Down Expand Up @@ -67,7 +67,7 @@ export default function spaceSelectorFunctonalTests({

before(async () => {
await esArchiver.load('spaces/selector');
await PageObjects.security.login(null, null, {
await PageObjects.security.login(undefined, undefined, {
expectSpaceSelector: true,
});
await PageObjects.spaceSelector.clickSpaceCard('default');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.security.login(
'no_visualize_privileges_user',
'no_visualize_privileges_user-password',
{
expectSpaceSelector: false,
shouldLoginIfPrompted: false,
}
{ expectSpaceSelector: false }
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

import { resolve } from 'path';

import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import { services } from './services';
import { pageObjects } from './page_objects';

// the default export of config files must be a config provider
// that returns an object with the projects config values
export default async function({ readConfigFile }) {
export default async function({ readConfigFile }: FtrConfigProviderContext) {
const kibanaCommonConfig = await readConfigFile(
require.resolve('../../../test/common/config.js')
);
Expand Down
84 changes: 84 additions & 0 deletions x-pack/test/functional/config_security_trial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/* eslint-disable import/no-default-export */

import { resolve } from 'path';
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import { services } from './services';
import { pageObjects } from './page_objects';

// the default export of config files must be a config provider
// that returns an object with the projects config values
export default async function({ readConfigFile }: FtrConfigProviderContext) {
const kibanaCommonConfig = await readConfigFile(
require.resolve('../../../test/common/config.js')
);
const kibanaFunctionalConfig = await readConfigFile(
require.resolve('../../../test/functional/config.js')
);

const kibanaPort = kibanaFunctionalConfig.get('servers.kibana.port');
const idpPath = resolve(__dirname, '../saml_api_integration/fixtures/saml_provider/metadata.xml');
const samlIdPPlugin = resolve(__dirname, '../saml_api_integration/fixtures/saml_provider');

return {
testFiles: [resolve(__dirname, './apps/security/trial_license')],

services,
pageObjects,

servers: kibanaFunctionalConfig.get('servers'),

esTestCluster: {
license: 'trial',
from: 'snapshot',
serverArgs: [
'xpack.security.authc.token.enabled=true',
'xpack.security.authc.realms.saml.saml1.order=0',
`xpack.security.authc.realms.saml.saml1.idp.metadata.path=${idpPath}`,
'xpack.security.authc.realms.saml.saml1.idp.entity_id=http://www.elastic.co/saml1',
`xpack.security.authc.realms.saml.saml1.sp.entity_id=http://localhost:${kibanaPort}`,
`xpack.security.authc.realms.saml.saml1.sp.logout=http://localhost:${kibanaPort}/logout`,
`xpack.security.authc.realms.saml.saml1.sp.acs=http://localhost:${kibanaPort}/api/security/saml/callback`,
'xpack.security.authc.realms.saml.saml1.attributes.principal=urn:oid:0.0.7',
],
},

kbnTestServer: {
...kibanaCommonConfig.get('kbnTestServer'),
serverArgs: [
...kibanaCommonConfig.get('kbnTestServer.serverArgs'),
`--plugin-path=${samlIdPPlugin}`,
'--server.uuid=5b2de169-2785-441b-ae8c-186a1936b17d',
'--xpack.security.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"',
`--xpack.security.loginHelp="Some-login-help."`,
'--xpack.security.authc.providers.basic.basic1.order=0',
'--xpack.security.authc.providers.saml.saml1.order=1',
'--xpack.security.authc.providers.saml.saml1.realm=saml1',
'--xpack.security.authc.providers.saml.saml1.description="Log-in-with-SAML"',
'--xpack.security.authc.providers.saml.saml1.icon=logoKibana',
'--xpack.security.authc.providers.saml.unknown_saml.order=2',
'--xpack.security.authc.providers.saml.unknown_saml.realm=unknown_realm',
'--xpack.security.authc.providers.saml.unknown_saml.description="Do-not-log-in-with-THIS-SAML"',
'--xpack.security.authc.providers.saml.unknown_saml.icon=logoAWS',
],
},
uiSettings: {
defaults: {
'accessibility:disableAnimations': true,
'dateFormat:tz': 'UTC',
},
},
apps: kibanaFunctionalConfig.get('apps'),
esArchiver: { directory: resolve(__dirname, 'es_archives') },
screenshots: { directory: resolve(__dirname, 'screenshots') },

junit: {
reportName: 'Chrome X-Pack UI Functional Tests',
},
};
}
Loading