From ab347df5eeb713bf63dffca9764312f6c2d393e2 Mon Sep 17 00:00:00 2001 From: Martin Bartos Date: Wed, 7 Oct 2020 10:36:06 +0200 Subject: [PATCH] KEYCLOAK-14915 Upgrade registration screen to PF4 --- .../testsuite/auth/page/AccountFields.java | 62 +++++++++++++- .../testsuite/auth/page/PasswordFields.java | 37 ++++++++- .../testsuite/pages/RegisterPage.java | 30 ++++++- .../federation/ldap/LDAPMSADFullNameTest.java | 2 +- .../ldap/LDAPProvidersIntegrationTest.java | 4 +- .../testsuite/forms/RegisterTest.java | 40 ++++----- .../testsuite/ui/login/LoginPageTest.java | 75 +++++------------ .../resources/theme/base/login/register.ftl | 83 +++++++++++++++---- 8 files changed, 234 insertions(+), 99 deletions(-) diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AccountFields.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AccountFields.java index 4a20517c8f..4572b1ead7 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AccountFields.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AccountFields.java @@ -17,6 +17,7 @@ package org.keycloak.testsuite.auth.page; +import org.jboss.arquillian.graphene.page.Page; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.util.UIUtils; import org.openqa.selenium.NoSuchElementException; @@ -31,6 +32,9 @@ import static org.keycloak.testsuite.util.UIUtils.getTextFromElement; */ public class AccountFields extends FieldsBase { + @Page + private AccountErrors inputErrors; + @FindBy(id = "username") private WebElement usernameInput; @FindBy(xpath = "//label[@for='username']") @@ -119,19 +123,69 @@ public class AccountFields extends FieldsBase { } public boolean hasUsernameError() { - return hasFieldError(usernameInput); + return inputErrors.getUsernameError() != null; } public boolean hasEmailError() { - return hasFieldError(emailInput); + return inputErrors.getEmailError() != null; } public boolean hasFirstNameError() { - return hasFieldError(firstNameInput); + return inputErrors.getFirstNameError() != null; } public boolean hasLastNameError() { - return hasFieldError(lastNameInput); + return inputErrors.getLastNameError() != null; } + public AccountErrors getInputErrors(){ + return inputErrors; + } + + public static class AccountErrors{ + + @FindBy(id = "input-error-firstname") + private WebElement firstNameError; + + @FindBy(id = "input-error-lastname") + private WebElement lastNameError; + + @FindBy(id = "input-error-email") + private WebElement emailError; + + @FindBy(id = "input-error-username") + private WebElement usernameError; + + public String getFirstNameError() { + try { + return getTextFromElement(firstNameError); + } catch (NoSuchElementException e) { + return null; + } + } + + public String getLastNameError() { + try { + return getTextFromElement(lastNameError); + } catch (NoSuchElementException e) { + return null; + } + } + + public String getEmailError() { + try { + return getTextFromElement(emailError); + } catch (NoSuchElementException e) { + return null; + } + } + + public String getUsernameError() { + try { + return getTextFromElement(usernameError); + } catch (NoSuchElementException e) { + return null; + } + } + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/PasswordFields.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/PasswordFields.java index 6c4e0d37e2..d115ef2d4b 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/PasswordFields.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/PasswordFields.java @@ -16,6 +16,7 @@ */ package org.keycloak.testsuite.auth.page; +import org.jboss.arquillian.graphene.page.Page; import org.keycloak.testsuite.util.UIUtils; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; @@ -29,6 +30,9 @@ import static org.keycloak.testsuite.util.UIUtils.getTextFromElement; */ public class PasswordFields extends FieldsBase { + @Page + private PasswordErrors inputErrors; + @FindBy(id = "password") private WebElement passwordInput; @FindBy(xpath = "//label[@for='password']") @@ -84,7 +88,7 @@ public class PasswordFields extends FieldsBase { } public boolean hasPasswordError() { - return hasFieldError(passwordInput); + return inputErrors.getPasswordError() != null; } public boolean hasNewPasswordError() { @@ -92,6 +96,35 @@ public class PasswordFields extends FieldsBase { } public boolean hasConfirmPasswordError() { - return hasFieldError(confirmPasswordInput); + return inputErrors.getPasswordConfirmError() != null; + } + + public PasswordErrors getInputErrors() { + return inputErrors; + } + + public static class PasswordErrors { + @FindBy(id = "input-error-password") + private WebElement passwordError; + + @FindBy(id = "input-error-password-confirm") + private WebElement passwordConfirmError; + + + public String getPasswordError() { + try { + return getTextFromElement(passwordError); + } catch (NoSuchElementException e) { + return null; + } + } + + public String getPasswordConfirmError() { + try { + return getTextFromElement(passwordConfirmError); + } catch (NoSuchElementException e) { + return null; + } + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/RegisterPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/RegisterPage.java index fe75cbaae4..8de6e61d1a 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/RegisterPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/RegisterPage.java @@ -17,7 +17,11 @@ package org.keycloak.testsuite.pages; +import org.jboss.arquillian.graphene.page.Page; import org.junit.Assert; +import org.keycloak.testsuite.auth.page.AccountFields; +import org.keycloak.testsuite.auth.page.PasswordFields; +import org.keycloak.testsuite.util.UIUtils; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -27,6 +31,12 @@ import org.openqa.selenium.support.FindBy; */ public class RegisterPage extends AbstractPage { + @Page + private AccountFields.AccountErrors accountErrors; + + @Page + private PasswordFields.PasswordErrors passwordErrors; + @FindBy(id = "firstName") private WebElement firstNameInput; @@ -49,7 +59,7 @@ public class RegisterPage extends AbstractPage { private WebElement submitButton; @FindBy(className = "alert-error") - private WebElement loginErrorMessage; + private WebElement loginAlertErrorMessage; @FindBy(className = "instruction") private WebElement loginInstructionMessage; @@ -132,13 +142,17 @@ public class RegisterPage extends AbstractPage { backToLoginLink.click(); } - public String getError() { - return loginErrorMessage != null ? loginErrorMessage.getText() : null; + public String getAlertError() { + try { + return UIUtils.getTextFromElement(loginAlertErrorMessage); + } catch (NoSuchElementException e) { + return null; + } } public String getInstruction() { try { - return loginInstructionMessage != null ? loginInstructionMessage.getText() : null; + return UIUtils.getTextFromElement(loginInstructionMessage); } catch (NoSuchElementException e){ // OK } @@ -173,6 +187,14 @@ public class RegisterPage extends AbstractPage { return PageUtils.getPageTitle(driver).equals("Register"); } + public AccountFields.AccountErrors getInputAccountErrors(){ + return accountErrors; + } + + public PasswordFields.PasswordErrors getInputPasswordErrors(){ + return passwordErrors; + } + @Override public void open() { throw new UnsupportedOperationException(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMSADFullNameTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMSADFullNameTest.java index 657fffae79..02b005eeab 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMSADFullNameTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMSADFullNameTest.java @@ -243,7 +243,7 @@ public class LDAPMSADFullNameTest extends AbstractLDAPTest { registerPage.assertCurrent(); registerPage.register("John", "Existing", "johnyanth@check.cz", "existingkc", "Password1", "Password1"); - Assert.assertEquals("Username already exists.", registerPage.getError()); + Assert.assertEquals("Username already exists.", registerPage.getInputAccountErrors().getUsernameError()); registerPage.register("John", "Existing", "johnyanth@check.cz", "existingkc2", "Password1", "Password1"); appPage.logout(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java index 23fc6596dc..3b05e3bf64 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java @@ -426,12 +426,12 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest { // check existing username registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1"); registerPage.assertCurrent(); - Assert.assertEquals("Username already exists.", registerPage.getError()); + Assert.assertEquals("Username already exists.", registerPage.getInputAccountErrors().getUsernameError()); // Check existing email registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1"); registerPage.assertCurrent(); - Assert.assertEquals("Email already exists.", registerPage.getError()); + Assert.assertEquals("Email already exists.", registerPage.getInputAccountErrors().getEmailError()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java index 46e43fef2c..9a25fc0959 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java @@ -81,7 +81,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerExistingUser@email", "roleRichUser", "password", "password"); registerPage.assertCurrent(); - assertEquals("Username already exists.", registerPage.getError()); + assertEquals("Username already exists.", registerPage.getInputAccountErrors().getUsernameError()); // assert form keeps form fields on error assertEquals("firstName", registerPage.getFirstName()); @@ -105,7 +105,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "test-user@localhost", "registerExistingUser", "password", "password"); registerPage.assertCurrent(); - assertEquals("Email already exists.", registerPage.getError()); + assertEquals("Email already exists.", registerPage.getInputAccountErrors().getEmailError()); // assert form keeps form fields on error assertEquals("firstName", registerPage.getFirstName()); @@ -155,7 +155,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerUserInvalidPasswordConfirm@email", "registerUserInvalidPasswordConfirm", "password", "invalid"); registerPage.assertCurrent(); - assertEquals("Password confirmation doesn't match.", registerPage.getError()); + assertEquals("Password confirmation doesn't match.", registerPage.getInputPasswordErrors().getPasswordConfirmError()); // assert form keeps form fields on error assertEquals("firstName", registerPage.getFirstName()); @@ -180,7 +180,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerUserMissingPassword@email", "registerUserMissingPassword", null, null); registerPage.assertCurrent(); - assertEquals("Please specify password.", registerPage.getError()); + assertEquals("Please specify password.", registerPage.getInputPasswordErrors().getPasswordError()); events.expectRegister("registerUserMissingPassword", "registerUserMissingPassword@email") .removeDetail(Details.USERNAME) @@ -208,7 +208,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "pass", "pass"); registerPage.assertCurrent(); - assertEquals("Invalid password: minimum length 8.", registerPage.getError()); + assertEquals("Invalid password: minimum length 8.", registerPage.getInputPasswordErrors().getPasswordError()); events.expectRegister("registerPasswordPolicy", "registerPasswordPolicy@email") .removeDetail(Details.USERNAME) @@ -240,7 +240,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerUserMissingUsername@email", null, "password", "password"); registerPage.assertCurrent(); - assertEquals("Please specify username.", registerPage.getError()); + assertEquals("Please specify username.", registerPage.getInputAccountErrors().getUsernameError()); events.expectRegister(null, "registerUserMissingUsername@email") .removeDetail(Details.USERNAME) @@ -258,11 +258,11 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.assertCurrent(); - assertEquals("Please specify username.\n" + - "Please specify first name.\n" + - "Please specify last name.\n" + - "Please specify email.\n" + - "Please specify password.", registerPage.getError()); + assertEquals("Please specify username.", registerPage.getInputAccountErrors().getUsernameError()); + assertEquals("Please specify first name.", registerPage.getInputAccountErrors().getFirstNameError()); + assertEquals("Please specify last name.", registerPage.getInputAccountErrors().getLastNameError()); + assertEquals("Please specify email.", registerPage.getInputAccountErrors().getEmailError()); + assertEquals("Please specify password.", registerPage.getInputPasswordErrors().getPasswordError()); events.expectRegister(null, "registerUserMissingUsername@email") .removeDetail(Details.USERNAME) @@ -278,7 +278,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", null, "registerUserMissingEmail", "password", "password"); registerPage.assertCurrent(); - assertEquals("Please specify email.", registerPage.getError()); + assertEquals("Please specify email.", registerPage.getInputAccountErrors().getEmailError()); events.expectRegister("registerUserMissingEmail", null) .removeDetail("email") .error("invalid_registration").assertEvent(); @@ -293,7 +293,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerUserInvalidEmailemail", "registerUserInvalidEmail", "password", "password"); registerPage.assertCurrent(); assertEquals("registerUserInvalidEmailemail", registerPage.getEmail()); - assertEquals("Invalid email address.", registerPage.getError()); + assertEquals("Invalid email address.", registerPage.getInputAccountErrors().getEmailError()); events.expectRegister("registerUserInvalidEmail", "registerUserInvalidEmailemail") .error("invalid_registration").assertEvent(); } @@ -480,19 +480,19 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("firstName", "lastName", "registerUserNotUsername@email", "registerUserNotUsername", "registerUserNotUsername", "registerUserNotUsername"); assertTrue(registerPage.isCurrent()); - assertEquals("Invalid password: must not be equal to the username.", registerPage.getError()); + assertEquals("Invalid password: must not be equal to the username.", registerPage.getInputPasswordErrors().getPasswordError()); adminClient.realm("test").users().create(UserBuilder.create().username("registerUserNotUsername").build()); registerPage.register("firstName", "lastName", "registerUserNotUsername@email", "registerUserNotUsername", "registerUserNotUsername", "registerUserNotUsername"); assertTrue(registerPage.isCurrent()); - assertEquals("Username already exists.", registerPage.getError()); + assertEquals("Username already exists.", registerPage.getInputAccountErrors().getUsernameError()); registerPage.register("firstName", "lastName", "registerUserNotUsername@email", null, "password", "password"); assertTrue(registerPage.isCurrent()); - assertEquals("Please specify username.", registerPage.getError()); + assertEquals("Please specify username.", registerPage.getInputAccountErrors().getUsernameError()); } // KEYCLOAK-12729 @@ -514,7 +514,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.registerWithEmailAsUsername("firstName", "lastName", "registerUserNotEmail@email", "registerUserNotEmail@email", "registerUserNotEmail@email"); assertTrue(registerPage.isCurrent()); - assertEquals("Invalid password: must not be equal to the email.", registerPage.getError()); + assertEquals("Invalid password: must not be equal to the email.", registerPage.getInputPasswordErrors().getPasswordError()); } finally { configureRealmRegistrationEmailAsUsername(false); } @@ -536,7 +536,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.registerWithEmailAsUsername("firstName", "lastName", "test-user@localhost", "password", "password"); registerPage.assertCurrent(); - assertEquals("Email already exists.", registerPage.getError()); + assertEquals("Email already exists.", registerPage.getInputAccountErrors().getEmailError()); events.expectRegister("test-user@localhost", "test-user@localhost").user((String) null).error("email_in_use").assertEvent(); } finally { @@ -555,12 +555,12 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.registerWithEmailAsUsername("firstName", "lastName", null, "password", "password"); registerPage.assertCurrent(); - assertEquals("Please specify email.", registerPage.getError()); + assertEquals("Please specify email.", registerPage.getInputAccountErrors().getEmailError()); events.expectRegister(null, null).removeDetail("username").removeDetail("email").error("invalid_registration").assertEvent(); registerPage.registerWithEmailAsUsername("firstName", "lastName", "registerUserInvalidEmailemail", "password", "password"); registerPage.assertCurrent(); - assertEquals("Invalid email address.", registerPage.getError()); + assertEquals("Invalid email address.", registerPage.getInputAccountErrors().getEmailError()); events.expectRegister("registerUserInvalidEmailemail", "registerUserInvalidEmailemail").error("invalid_registration").assertEvent(); } finally { configureRealmRegistrationEmailAsUsername(false); diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/LoginPageTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/LoginPageTest.java index b847e568cb..a32d20a9b8 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/LoginPageTest.java +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/LoginPageTest.java @@ -217,64 +217,35 @@ public class LoginPageTest extends AbstractLoginTest { private void assertRegistrationFields(String firstName, String lastName, String email, String username, boolean password, boolean passwordConfirm) { assertTrue(registrationPage.feedbackMessage().isError()); - final String errorMsg = registrationPage.feedbackMessage().getText(); - if (firstName != null) { - assertEquals(firstName, registrationPage.accountFields().getFirstName()); - assertFalse(registrationPage.accountFields().hasFirstNameError()); - assertFalse(errorMsg.contains("first name")); - } - else { - assertTrue(registrationPage.accountFields().hasFirstNameError()); - assertTrue(errorMsg.contains("first name")); - } + assertRegistrationAvailability(firstName != null, registrationPage.accountFields().hasFirstNameError(), + firstName, registrationPage.accountFields().getFirstName()); - if (lastName != null) { - assertEquals(lastName, registrationPage.accountFields().getLastName()); - assertFalse(registrationPage.accountFields().hasLastNameError()); - assertFalse(errorMsg.contains("last name")); - } - else { - assertTrue(registrationPage.accountFields().hasLastNameError()); - assertTrue(errorMsg.contains("last name")); - } + assertRegistrationAvailability(lastName != null, registrationPage.accountFields().hasLastNameError(), + lastName, registrationPage.accountFields().getLastName()); - if (email != null) { - assertEquals(email, registrationPage.accountFields().getEmail()); - assertFalse(registrationPage.accountFields().hasEmailError()); - assertFalse(errorMsg.contains("email")); - } - else { - assertTrue(registrationPage.accountFields().hasEmailError()); - assertTrue(errorMsg.contains("email")); - } + assertRegistrationAvailability(email != null, registrationPage.accountFields().hasEmailError(), + email, registrationPage.accountFields().getEmail()); - if (username != null) { - assertEquals(username, registrationPage.accountFields().getUsername()); - assertFalse(registrationPage.accountFields().hasUsernameError()); - assertFalse(errorMsg.contains("username")); - } - else { - assertTrue(registrationPage.accountFields().hasUsernameError()); - assertTrue(errorMsg.contains("username")); - } + assertRegistrationAvailability(username != null, registrationPage.accountFields().hasUsernameError(), + username, registrationPage.accountFields().getUsername()); - if (password) { - assertFalse(registrationPage.passwordFields().hasPasswordError()); - assertFalse(errorMsg.contains("Please specify password.")); - } - else { - assertTrue(registrationPage.passwordFields().hasPasswordError()); - assertTrue(errorMsg.contains("Please specify password.")); - } + assertRegistrationAvailability(password, registrationPage.passwordFields().hasPasswordError()); + assertRegistrationAvailability(passwordConfirm, registrationPage.passwordFields().hasConfirmPasswordError()); + } - if (passwordConfirm) { - assertFalse(registrationPage.passwordFields().hasConfirmPasswordError()); - assertFalse(registrationPage.feedbackMessage().getText().contains("Password confirmation doesn't match.")); - } - else { - assertTrue(registrationPage.passwordFields().hasConfirmPasswordError()); - assertTrue(registrationPage.feedbackMessage().getText().contains("Password confirmation doesn't match.")); + private void assertRegistrationAvailability(boolean isAvailable, boolean state) { + assertRegistrationAvailability(isAvailable, state, null, null); + } + + private void assertRegistrationAvailability(boolean isAvailable, boolean state, String expected, String actual) { + if (isAvailable) { + assertFalse(state); + if (expected != null && actual != null) { + assertEquals(expected, actual); + } + } else { + assertTrue(state); } } diff --git a/themes/src/main/resources/theme/base/login/register.ftl b/themes/src/main/resources/theme/base/login/register.ftl index 2a73c73a5a..db50984798 100755 --- a/themes/src/main/resources/theme/base/login/register.ftl +++ b/themes/src/main/resources/theme/base/login/register.ftl @@ -1,63 +1,118 @@ <#import "template.ftl" as layout> -<@layout.registrationLayout; section> +<@layout.registrationLayout displayMessage=!messagesPerField.existsError('firstName','lastName','email','username','password','password-confirm'); section> <#if section = "header"> ${msg("registerTitle")} <#elseif section = "form">
-
+
- + + + <#if messagesPerField.existsError('firstName')> + + ${kcSanitize(messagesPerField.get('firstName'))?no_esc} + +
-
+
- + + + <#if messagesPerField.existsError('lastName')> + + ${kcSanitize(messagesPerField.get('lastName'))?no_esc} + +
-
+
- + + + <#if messagesPerField.existsError('email')> + + ${kcSanitize(messagesPerField.get('email'))?no_esc} + +
<#if !realm.registrationEmailAsUsername> -
+
- + + + <#if messagesPerField.existsError('username')> + + ${kcSanitize(messagesPerField.get('username'))?no_esc} + +
<#if passwordRequired??> -
+
- + + + <#if messagesPerField.existsError('password')> + + ${kcSanitize(messagesPerField.get('password'))?no_esc} + +
-
+
- +
- + + + <#if messagesPerField.existsError('password-confirm')> + + ${kcSanitize(messagesPerField.get('password-confirm'))?no_esc} + +