added test coverage of login settings

This commit is contained in:
vramik 2015-09-23 13:07:30 +02:00
parent d2d3a3f216
commit abb099745f
10 changed files with 416 additions and 16 deletions

View file

@ -54,6 +54,12 @@ public class Account extends AccountManagement {
return lastName.getAttribute("value");
}
public Account setUsername(String value) {
username.clear();
username.sendKeys(value);
return this;
}
public Account setEmail(String value) {
email.clear();
email.sendKeys(value);

View file

@ -21,6 +21,7 @@ import javax.ws.rs.core.UriBuilder;
import org.jboss.arquillian.graphene.findby.FindByJQuery;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.testsuite.auth.page.AuthRealm;
import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementPresent;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -61,6 +62,14 @@ public class AccountManagement extends AuthRealm {
@FindByJQuery("button[value='Save']")
private WebElement save;
@FindBy(xpath = "//div[@id='kc-error-message']/p")
private WebElement error;
public String getErrorMessage() {
waitGuiForElementPresent(error, "Error message should be visible");
return error.getText();
}
public void backToReferer() {
backToRefererLink.click();
}
@ -97,4 +106,7 @@ public class AccountManagement extends AuthRealm {
return keycloak().realm(getAuthRealm());
}
public void waitForAccountLinkPresent() {
waitGuiForElementPresent(accountLink, "account link should be present");
}
}

View file

@ -1,6 +1,24 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.keycloak.testsuite.auth.page.account;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -35,4 +53,7 @@ public class PasswordFields extends Form {
setConfirmPassword(confirmPassword);
}
public void waitForConfirmPasswordInputPresent() {
WaitUtils.waitGuiForElement(confirmPasswordInput);
}
}

View file

@ -1,3 +1,20 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.keycloak.testsuite.auth.page.login;
import javax.ws.rs.core.UriBuilder;
@ -27,6 +44,14 @@ public class LoginActions extends AuthRealm {
@FindBy(css = "span.kc-feedback-text")
private WebElement feedbackText;
@FindBy(xpath = "//div[@id='kc-error-message']/p")
private WebElement error;
public String getErrorMessage() {
waitGuiForElementPresent(error, "Error message should be visible");
return error.getText();
}
public String getFeedbackText() {
waitGuiForElementPresent(feedbackText, "Feedback message should be visible");
return feedbackText.getText();

View file

@ -1,3 +1,20 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.keycloak.testsuite.auth.page.login;
import org.jboss.arquillian.graphene.page.Page;
@ -6,8 +23,7 @@ import org.keycloak.testsuite.page.Form;
import static org.keycloak.testsuite.admin.Users.getPasswordOf;
import org.keycloak.testsuite.auth.page.account.AccountFields;
import org.keycloak.testsuite.auth.page.account.PasswordFields;
import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElementNotPresent;
import static org.keycloak.testsuite.util.WaitUtils.*;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -31,6 +47,8 @@ public class LoginForm extends Form {
private WebElement registerLink;
@FindBy(linkText = "Forgot Password?")
private WebElement forgottenPassword;
@FindBy(id = "rememberMe")
private WebElement rememberMe;
public void setUsername(String username) {
accountFields.setUsername(username);
@ -66,6 +84,14 @@ public class LoginForm extends Form {
forgottenPassword.click();
}
public void rememberMe(boolean value) {
waitForRememberMePresent();
boolean selected = rememberMe.isSelected();
if ((value && !selected) || !value && selected) {
rememberMe.click();
}
}
// @Override
// public void cancel() {
// waitAjaxForElement(cancelButton);
@ -80,4 +106,20 @@ public class LoginForm extends Form {
waitAjaxForElementNotPresent(registerLink);
}
public void waitForResetPasswordLinkNotPresent() {
waitAjaxForElementNotPresent(forgottenPassword);
}
public void waitForRememberMePresent() {
waitAjaxForElement(rememberMe);
}
public void waitForRememberMeNotPresent() {
waitAjaxForElementNotPresent(rememberMe);
}
public void waitForLoginButtonPresent() {
waitGuiForElement(loginButton);
}
}

View file

@ -18,14 +18,11 @@
package org.keycloak.testsuite.auth.page.login;
import org.keycloak.testsuite.auth.page.account.AccountFields;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import javax.ws.rs.core.UriBuilder;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.UserRepresentation;
import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementPresent;
import static org.keycloak.testsuite.admin.Users.getPasswordOf;
import org.keycloak.testsuite.auth.page.account.ContactInfoFields;
import org.keycloak.testsuite.auth.page.account.PasswordFields;
@ -74,4 +71,8 @@ public class Registration extends LoginActions {
accountFields.waitForUsernameInputNotPresent();
}
public void waitForConfirmPasswordInputPresent() {
passwordFields.waitForConfirmPasswordInputPresent();
}
}

View file

@ -56,7 +56,8 @@ public class ResetCredentials extends LoginActions {
submit();
}
public void waitForInfoMessagePresent() {
public String getInfoMessage() {
waitGuiForElementPresent(info, "Info message should be visible");
return info.getText();
}
}

View file

@ -22,6 +22,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
/**
*
@ -41,6 +42,10 @@ public class LoginSettings extends RealmSettings {
return form;
}
public enum RequireSSLOption {
all, external, none;
}
public class LoginSettingsForm extends Form {
@FindByJQuery("div[class='onoffswitch']:eq(0)")
@ -49,20 +54,20 @@ public class LoginSettings extends RealmSettings {
@FindBy(xpath = ".//div[contains(@class,'onoffswitch') and ./input[@id='registrationEmailAsUsername']]")
private OnOffSwitch emailAsUsernameOnOffSwitch;
@FindBy(xpath = ".//div[contains(@class,'onoffswitch') and ./input[@id='editUsernameAllowed']]")
private OnOffSwitch editUsernameAllowed;
@FindBy(xpath = ".//div[contains(@class,'onoffswitch') and ./input[@id='resetPasswordAllowed']]")
private OnOffSwitch resetPasswordAllowed;
@FindByJQuery("div[class='onoffswitch']:eq(2)")
@FindBy(xpath = ".//div[contains(@class,'onoffswitch') and ./input[@id='rememberMe']]")
private OnOffSwitch rememberMeEnabled;
@FindBy(xpath = ".//div[contains(@class,'onoffswitch') and ./input[@id='verifyEmail']]")
private OnOffSwitch verifyEmailEnabled;
@FindByJQuery("div[class='onoffswitch']:eq(4)")
private OnOffSwitch directGrantApiEnabled;
@FindByJQuery("div[class='onoffswitch']:eq(5)")
private OnOffSwitch requireSsl;
@FindBy(id = "sslRequired")
private Select requireSsl;
public boolean isRegistrationAllowed() {
return registrationAllowed.isOn();
@ -76,13 +81,41 @@ public class LoginSettings extends RealmSettings {
emailAsUsernameOnOffSwitch.setOn(emailAsUsername);
}
public boolean isEditUsernameAllowed() {
return editUsernameAllowed.isOn();
}
public void setEditUsernameAllowed(boolean allowed) {
editUsernameAllowed.setOn(allowed);
}
public boolean isResetPasswordAllowed() {
return resetPasswordAllowed.isOn();
}
public void setResetPasswordAllowed(boolean allowed) {
resetPasswordAllowed.setOn(allowed);
}
public boolean isRememberMeAllowed() {
return rememberMeEnabled.isOn();
}
public void setRememberMeAllowed(boolean allowed) {
rememberMeEnabled.setOn(allowed);
}
public void setVerifyEmailAllowed(boolean allowed) {
verifyEmailEnabled.setOn(allowed);
}
public boolean isVerifyEmailAllowed() {
return verifyEmailEnabled.isOn();
}
public void selectRequireSSL(RequireSSLOption option) {
requireSsl.selectByValue(option.name());
}
}
}

View file

@ -0,0 +1,71 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.keycloak.testsuite.account;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
/**
*
* @author vramik
*/
@Ignore //TODO find out the way how to restart browser during the test
public class RememberMeTest extends AbstractAccountManagementTest {
@Before
public void beforeRememberMe() {
// enable remember me in test realm
RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
testRealmRep.setRememberMe(true);
testRealmResource().update(testRealmRep);
}
@Test
public void rememberMe() {
testRealmAccountManagementPage.navigateTo();
log.info("login with remember me unchecked");
testRealmLoginPage.form().login(testUser);
testRealmAccountManagementPage.waitForAccountLinkPresent();
log.debug("logged in");
//TODO: restart browser
testRealmAccountManagementPage.navigateTo();
log.debug("user shouldn't be logged in");
testRealmLoginPage.form().waitForRememberMePresent();
log.info("login with remember me checked");
testRealmLoginPage.form().rememberMe(true);
testRealmLoginPage.form().login(testUser);
testRealmAccountManagementPage.waitForAccountLinkPresent();
//TODO: restart browser
testRealmAccountManagementPage.navigateTo();
log.debug("user should be logged in");
testRealmAccountManagementPage.waitForAccountLinkPresent();
}
}

View file

@ -1,31 +1,72 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.keycloak.testsuite.console.realm;
import java.util.HashSet;
import java.util.Set;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD;
import org.keycloak.representations.idm.UserRepresentation;
import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWithAdminClient;
import static org.keycloak.testsuite.admin.Users.setPasswordFor;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
import org.keycloak.testsuite.auth.page.account.Account;
import org.keycloak.testsuite.console.page.realm.LoginSettings;
import org.keycloak.testsuite.auth.page.login.Registration;
import org.keycloak.testsuite.auth.page.login.ResetCredentials;
import org.keycloak.testsuite.auth.page.login.VerifyEmail;
import org.keycloak.testsuite.console.page.realm.LoginSettings.RequireSSLOption;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
import org.openqa.selenium.Cookie;
/**
*
* @author tkyjovsk
* @author vramik
*/
public class LoginSettingsTest extends AbstractRealmTest {
@Page
private LoginSettings loginSettingsPage;
private static final String NEW_USERNAME = "newUsername";
@Page
private LoginSettings loginSettingsPage;
@Page
private Registration testRealmRegistrationPage;
@Page
private ResetCredentials testRealmForgottenPasswordPage;
@Page
private VerifyEmail testRealmVerifyEmailPage;
@Page
private Account testAccountPage;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmRegistrationPage.setAuthRealm(TEST);
testRealmForgottenPasswordPage.setAuthRealm(TEST);
testRealmVerifyEmailPage.setAuthRealm(TEST);
testAccountPage.setAuthRealm(TEST);
}
@Before
@ -46,6 +87,7 @@ public class LoginSettingsTest extends AbstractRealmTest {
testRealmAdminConsolePage.navigateTo();
testRealmLoginPage.form().register();
assertCurrentUrlStartsWith(testRealmRegistrationPage);
testRealmRegistrationPage.waitForConfirmPasswordInputPresent();
testRealmRegistrationPage.waitForUsernameInputPresent();
log.info("verified registration is enabled");
@ -59,6 +101,7 @@ public class LoginSettingsTest extends AbstractRealmTest {
testRealmAdminConsolePage.navigateTo();
testRealmLoginPage.form().register();
assertCurrentUrlStartsWith(testRealmRegistrationPage);
testRealmRegistrationPage.waitForConfirmPasswordInputPresent();
testRealmRegistrationPage.waitForUsernameInputNotPresent();
log.info("verified email as username");
@ -75,4 +118,149 @@ public class LoginSettingsTest extends AbstractRealmTest {
log.info("verified regisration is disabled");
}
@Test
public void editUsername() {
log.info("enabling edit username");
loginSettingsPage.form().setEditUsernameAllowed(true);
loginSettingsPage.form().save();
log.debug("enabled");
log.info("edit username");
testAccountPage.navigateTo();
testRealmLoginPage.form().login(testUser);
testAccountPage.waitForAccountLinkPresent();
testAccountPage.setUsername(NEW_USERNAME);
testAccountPage.save();
testAccountPage.signOut();
log.debug("edited");
log.info("log in with edited username");
testRealmLoginPage.form().login(NEW_USERNAME, PASSWORD);
testAccountPage.waitForAccountLinkPresent();
log.debug("user is logged in with edited username");
log.info("disabling edit username");
loginSettingsPage.navigateTo();
loginSettingsPage.form().setEditUsernameAllowed(false);
loginSettingsPage.form().save();
log.debug("disabled");
}
@Test
public void resetPassword() {
log.info("enabling reset password");
loginSettingsPage.form().setResetPasswordAllowed(true);
loginSettingsPage.form().save();
log.debug("enabled");
testRealmAdminConsolePage.navigateTo();
testRealmLoginPage.form().forgotPassword();
Assert.assertEquals("Enter your username or email address and we will send you instructions on how to create a new password.",
testRealmForgottenPasswordPage.getInfoMessage());
log.info("verified reset password is enabled");
log.info("disabling reset password");
loginSettingsPage.navigateTo();
loginSettingsPage.form().setResetPasswordAllowed(false);
loginSettingsPage.form().save();
assertFalse(loginSettingsPage.form().isResetPasswordAllowed());
log.debug("disabled");
testRealmAdminConsolePage.navigateTo();
testRealmLoginPage.form().waitForResetPasswordLinkNotPresent();
log.info("verified reset password is disabled");
}
@Test
public void rememberMe() {
log.info("enabling remember me");
loginSettingsPage.form().setRememberMeAllowed(true);
loginSettingsPage.form().save();
log.debug("enabled");
log.info("login with remember me checked");
testAccountPage.navigateTo();
testRealmLoginPage.form().rememberMe(true);
testRealmLoginPage.form().login(testUser);
assertTrue("Cookie KEYCLOAK_REMEMBER_ME should be present.", getCookieNames().contains("KEYCLOAK_REMEMBER_ME"));
log.info("verified remember me is enabled");
log.info("disabling remember me");
loginSettingsPage.navigateTo();
loginSettingsPage.form().setRememberMeAllowed(false);
loginSettingsPage.form().save();
assertFalse(loginSettingsPage.form().isRememberMeAllowed());
log.debug("disabled");
testAccountPage.navigateTo();
testAccountPage.signOut();
testRealmLoginPage.form().waitForLoginButtonPresent();
testRealmLoginPage.form().waitForRememberMeNotPresent();
log.info("verified remember me is disabled");
}
@Test
public void verifyEmail() {
log.info("enabling verify email");
loginSettingsPage.form().setVerifyEmailAllowed(true);
loginSettingsPage.form().save();
log.debug("enabled");
testAccountPage.navigateTo();
testRealmLoginPage.form().login(testUser);
Assert.assertEquals("Failed to send email, please try again later.",
testRealmVerifyEmailPage.getErrorMessage());
log.info("verified verify email is enabled");
log.info("disabling verify email");
loginSettingsPage.navigateTo();
loginSettingsPage.form().setVerifyEmailAllowed(false);
loginSettingsPage.form().save();
assertFalse(loginSettingsPage.form().isVerifyEmailAllowed());
log.debug("disabled");
log.debug("create new test user");
UserRepresentation newUser = createUserRepresentation("new_user", "new_user@email.test", "new", "user", true);
setPasswordFor(newUser, PASSWORD);
String id = createUserAndResetPasswordWithAdminClient(testRealmResource(), newUser, PASSWORD);
newUser.setId(id);
log.info("log in as new user");
testAccountPage.navigateTo();
testRealmLoginPage.form().login(newUser);
testAccountPage.waitForAccountLinkPresent();
log.info("verified verify email is disabled");
}
@Test
public void requireSSLAllRequests() throws InterruptedException {
log.info("set require ssl for all requests");
loginSettingsPage.form().selectRequireSSL(RequireSSLOption.all);
loginSettingsPage.form().save();
log.debug("set");
log.info("check HTTPS required");
testAccountPage.navigateTo();
Assert.assertEquals("HTTPS required", testAccountPage.getErrorMessage());
}
private Set<String> getCookieNames() {
Set<Cookie> cookies = driver.manage().getCookies();
Set<String> cookieNames = new HashSet<>();
for (Cookie cookie : cookies) {
cookieNames.add(cookie.getName());
}
return cookieNames;
}
}