diff --git a/.travis.yml b/.travis.yml index f6a229a359..d58778a262 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,7 +80,7 @@ jobs: script: rm -rf ./node_modules/@alfresco; node ./scripts/download-build-lib-in-cs.js -u "$E2E_USERNAME" -p "$E2E_PASSWORD" --host "$E2E_HOST" -f $TRAVIS_BUILD_NUMBER || exit 1; npm run build:dist || exit 1; node ./scripts/upload-build-in-cs.js -u "$E2E_USERNAME" -p "$E2E_PASSWORD" --host "$E2E_HOST" -f $TRAVIS_BUILD_NUMBER || exit 1 - stage: e2e Test # Test core env: STAGE=core - script: node ./scripts/download-build-in-cs.js --username "$E2E_USERNAME" --password "$E2E_PASSWORD" --host "$E2E_HOST" --folder $TRAVIS_BUILD_NUMBER; ./scripts/test-e2e-lib.sh -host localhost:4200 -proxy "$E2E_HOST" -u "$E2E_USERNAME" -p "$E2E_PASSWORD" -e $E2E_EMAIL -b -save --folder core --skip-lint --use-dist --timeout 7000 + script: node ./scripts/download-build-in-cs.js --username "$E2E_USERNAME" --password "$E2E_PASSWORD" --host "$E2E_HOST" --folder $TRAVIS_BUILD_NUMBER; ./scripts/test-e2e-lib.sh -host localhost:4200 --host_sso "$E2E_HOST_SSO" -proxy "$E2E_HOST" -u "$E2E_USERNAME" -p "$E2E_PASSWORD" -e $E2E_EMAIL -b -save --folder core --skip-lint --use-dist --timeout 7000 - stage: e2e Test # Test process-services env: STAGE=process-services script: node ./scripts/download-build-in-cs.js --username "$E2E_USERNAME" --password "$E2E_PASSWORD" --host "$E2E_HOST" --folder $TRAVIS_BUILD_NUMBER; ./scripts/test-e2e-lib.sh -host localhost:4200 -proxy "$E2E_HOST" -u "$E2E_USERNAME" -p "$E2E_PASSWORD" -e $E2E_EMAIL -b -save --folder process-services --skip-lint --use-dist --timeout 7000 diff --git a/e2e/core/login/login-sso/login_sso.e2e.ts b/e2e/core/login/login-sso/login_sso.e2e.ts new file mode 100644 index 0000000000..e0e827cb58 --- /dev/null +++ b/e2e/core/login/login-sso/login_sso.e2e.ts @@ -0,0 +1,51 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LoginAPSPage } from '../../../pages/adf/loginApsPage'; +import { SettingsPage } from '../../../pages/adf/settingsPage'; +import TestConfig = require('../../../test.config'); +import { browser } from 'protractor'; +import { NavigationBarPage } from '../../../pages/adf/NavigationBarPage'; + +describe('Login component - SSO', () => { + + const settingsPage = new SettingsPage(); + const loginApsPage = new LoginAPSPage(); + const navigationBarPage = new NavigationBarPage(); + const path = '/auth/realms/springboot'; + let silentLogin; + + afterEach(() => { + navigationBarPage.clickLogoutButton(); + browser.executeScript('window.sessionStorage.clear();'); + browser.executeScript('window.localStorage.clear();'); + }); + + it('[C261050] Should be possible login in the PS with SSO', async () => { + silentLogin = false; + await settingsPage.setProviderBpmSso(TestConfig.adf.hostSso, TestConfig.adf.hostSso + path, silentLogin); + await loginApsPage.clickOnSSOButton(); + browser.ignoreSynchronization = true; + await loginApsPage.loginAPS(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); + }); + + it ('[C280667] Should be redirect directly to keycloak without show the login page with silent login', async () => { + await settingsPage.setProviderBpmSso(TestConfig.adf.hostSso, TestConfig.adf.hostSso + path); + browser.ignoreSynchronization = true; + await loginApsPage.loginAPS(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); + }); +}); diff --git a/e2e/pages/adf/loginApsPage.ts b/e2e/pages/adf/loginApsPage.ts new file mode 100644 index 0000000000..9f7c4cdcf8 --- /dev/null +++ b/e2e/pages/adf/loginApsPage.ts @@ -0,0 +1,56 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Util = require('../../util/util'); +import { element, by } from 'protractor'; + +export class LoginAPSPage { + + ssoButton = element(by.css(`[data-automation-id="login-button-sso"]`)); + usernameField = element(by.id('username')); + passwordField = element(by.id('password')); + loginButton = element(by.id('kc-login')); + + async loginAPS (username, password) { + await this.enterUsername(username); + await this.enterPassword(password); + await this.clickLoginButton(); + } + + async clickOnSSOButton () { + Util.waitUntilElementIsVisible(this.ssoButton); + await this.ssoButton.click(); + } + + async enterUsername (username) { + Util.waitUntilElementIsVisible(this.usernameField); + await this.usernameField.clear(); + await this.usernameField.sendKeys(username); + } + + async enterPassword (password) { + Util.waitUntilElementIsVisible(this.passwordField); + await this.passwordField.clear(); + await this.passwordField.sendKeys(password); + } + + async clickLoginButton () { + Util.waitUntilElementIsVisible(this.loginButton); + await this.loginButton.click(); + } + +} diff --git a/e2e/pages/adf/settingsPage.ts b/e2e/pages/adf/settingsPage.ts index 9f1d6d1595..d5e691446d 100644 --- a/e2e/pages/adf/settingsPage.ts +++ b/e2e/pages/adf/settingsPage.ts @@ -43,6 +43,11 @@ export class SettingsPage { ecmText = element(by.css('input[data-automation-id*="ecmHost"]')); bpmText = element(by.css('input[data-automation-id*="bpmHost"]')); authHostText = element(by.css('input[id="oauthHost"]')); + ssoRadioButton = element(by.cssContainingText('[id*="mat-radio"]', 'SSO')); + silentLoginToggleLabel = element(by.css('mat-slide-toggle[name="silentLogin"] label')); + silentLoginToggleElement = element(by.css('mat-slide-toggle[name="silentLogin"]')); + implicitFlowLabel = element(by.css('mat-slide-toggle[name="implicitFlow"] label')); + implicitFlowElement = element(by.css('mat-slide-toggle[name="implicitFlow"]')); applyButton = element(by.css('button[data-automation-id*="host-button"]')); goToSettingsPage() { @@ -96,9 +101,63 @@ export class SettingsPage { return this; } - clickApply() { + async clickSsoRadioButton () { + Util.waitUntilElementIsVisible(this.ssoRadioButton); + await this.ssoRadioButton.click(); + } + + async setProviderBpmSso (processServiceURL, authHost, silentLogin = true, implicitFlow = true ) { + this.goToSettingsPage(); + this.setProvider(this.bpm.option, this.bpm.text); + Util.waitUntilElementIsVisible(this.bpmText); + Util.waitUntilElementIsNotOnPage(this.ecmText); + await this.clickSsoRadioButton(); + await this.setProcessServicesURL(processServiceURL); + await this.setAuthHost(authHost); + await this.setSilentLogin(silentLogin); + await this.setImplicitFlow(implicitFlow); + await this.clickApply(); + } + + async setProcessServicesURL (processServiceURL) { + Util.waitUntilElementIsVisible(this.bpmText); + await this.bpmText.clear(); + await this.bpmText.sendKeys(processServiceURL); + } + + async setAuthHost (authHostURL) { + Util.waitUntilElementIsVisible(this.authHostText); + await this.authHostText.clear(); + await this.authHostText.sendKeys(authHostURL); + } + + async clickApply () { Util.waitUntilElementIsVisible(this.applyButton); - this.applyButton.click(); + await this.applyButton.click(); + } + + async setSilentLogin (enableToggle) { + await Util.waitUntilElementIsVisible(this.silentLoginToggleElement); + + const isChecked = (await this.silentLoginToggleElement.getAttribute('class')).includes('mat-checked'); + + if (isChecked && !enableToggle || !isChecked && enableToggle) { + return this.silentLoginToggleLabel.click(); + } + + return Promise.resolve(); + } + + async setImplicitFlow (enableToggle) { + await Util.waitUntilElementIsVisible(this.implicitFlowElement); + + const isChecked = (await this.implicitFlowElement.getAttribute('class')).includes('mat-checked'); + + if (isChecked && !enableToggle || !isChecked && enableToggle) { + return this.implicitFlowLabel.click(); + } + + return Promise.resolve(); } checkProviderDropdownIsDisplayed() { diff --git a/e2e/test.config.js b/e2e/test.config.js index 0183937f1b..41c22499b0 100644 --- a/e2e/test.config.js +++ b/e2e/test.config.js @@ -4,6 +4,7 @@ */ var HOST = process.env.URL_HOST_ADF; +const HOST_SSO = process.env.URL_HOST_SSO_ADF; var USERNAME = process.env.USERNAME_ADF; var PASSWORD = process.env.PASSWORD_ADF; var EMAIL = process.env.EMAIL_ADF; @@ -48,7 +49,10 @@ module.exports = { /** * main admin password */ - adminPassword: PASSWORD + adminPassword: PASSWORD, + + hostSso: "http://" + HOST_SSO + }, adf_acs: { diff --git a/scripts/test-e2e-lib.sh b/scripts/test-e2e-lib.sh index 24f26156bb..87c56f8c30 100755 --- a/scripts/test-e2e-lib.sh +++ b/scripts/test-e2e-lib.sh @@ -21,6 +21,7 @@ show_help() { echo "-proxy or --proxy proxy Back end URL to use only possibel to use with -dev option" echo "-dev or --dev run it against local development environment it will deploy on localhost:4200 the current version of your branch" echo "-host or --host URL of the Front end to test" + echo "-host_sso or --host URL of the Back end to test" echo "-save save the error screenshot in the remote env" echo "-timeout or --timeout override the timeout foe the wait utils" echo "-sl --skip-lint skip lint" @@ -41,6 +42,10 @@ set_host(){ HOST=$1 } +set_host_sso(){ + HOST_SSO=$1 +} + set_test(){ SINGLE_TEST=true NAME_TEST=$1 @@ -111,6 +116,7 @@ while [[ $1 == -* ]]; do -proxy|--proxy) set_proxy $2; shift 2;; -s|--seleniumServer) set_selenium $2; shift 2;; -host|--host) set_host $2; shift 2;; + -host_sso|--host_sso) set_host_sso $2; shift 2;; -sl|--skip-lint) skip_lint; shift;; -vjsapi) version_js_api $2; shift 2;; -*) echo "invalid option: $1" 1>&2; show_help; exit 1;; @@ -120,6 +126,7 @@ done rm -rf ./e2e/downloads/ rm -rf ./e2e-output/screenshots/ +export URL_HOST_SSO_ADF=$HOST_SSO export URL_HOST_ADF=$HOST export USERNAME_ADF=$USERNAME export PASSWORD_ADF=$PASSWORD