diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/LocaleDropdown.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/LocaleDropdown.java index bed4007b26..c1195d1fe4 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/LocaleDropdown.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/LocaleDropdown.java @@ -51,7 +51,8 @@ public class LocaleDropdown { else { Actions actions = new Actions(driver); log.info("Moving mouse cursor to the localization menu"); - actions.moveToElement(currentLocaleLink).perform(); + actions.moveToElement(currentLocaleLink, -10, 0) + .moveToElement(currentLocaleLink).perform(); } // click desired locale diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/theme.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/theme.properties index 7b4bbd8cc3..a4cfa2f438 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/theme.properties +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/theme.properties @@ -1,2 +1,2 @@ parent=${theme-default-name}-preview -locales=en,lang01,lang02,lang03,lang04,lang05,test,lang06,lang07,lang08,lang09,lang10 \ No newline at end of file +locales=en,de,lang01,lang02,lang03,lang04,lang05,test,lang06,lang07,lang08,lang09,lang10 \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/theme.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/theme.properties index 39e87c7462..e7000c22a1 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/theme.properties +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/theme.properties @@ -1,2 +1,2 @@ parent=${theme-default-name} -locales=en,lang01,lang02,lang03,lang04,lang05,test,lang06,lang07,lang08,lang09,lang10 \ No newline at end of file +locales=en,de,lang01,lang02,lang03,lang04,lang05,test,lang06,lang07,lang08,lang09,lang10 \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/DeviceActivityTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/DeviceActivityTest.java index 95bcbf79b9..b919c525a5 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/DeviceActivityTest.java +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/DeviceActivityTest.java @@ -26,6 +26,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.ui.account2.page.AbstractLoggedInPage; import org.keycloak.testsuite.ui.account2.page.DeviceActivityPage; import org.keycloak.testsuite.util.ClientBuilder; @@ -33,7 +34,9 @@ import org.keycloak.testsuite.util.OAuthClient; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -50,8 +53,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD; import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; +import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad; /** * @author Vaclav Muzikar @@ -101,6 +106,7 @@ public class DeviceActivityTest extends BaseAccountPageTest { )); realm.setAccountTheme(LOCALIZED_THEME_PREVIEW); // using localized custom theme for the client localized name + configureInternationalizationForRealm(testRealms.get(0)); } @Before @@ -134,7 +140,7 @@ public class DeviceActivityTest extends BaseAccountPageTest { assertEquals(3, deviceActivityPage.getSessionsCount()); DeviceActivityPage.Session currentSession = deviceActivityPage.getSessionByIndex(0); // current session should be first - assertSessionRowsAreNotEmpty(currentSession, false); + assertSessionRowsAreNotEmpty(currentSession, false); assertTrue("Browser identification should be present", currentSession.isBrowserDisplayed()); assertTrue("Current session badge should be present", currentSession.hasCurrentBadge()); assertFalse("Icon should be present", currentSession.getBrowserIconName().isEmpty()); @@ -229,6 +235,27 @@ public class DeviceActivityTest extends BaseAccountPageTest { assertEquals(startedAt.plusSeconds(ssoLifespan), expiresAt); } + @Test + public void timeLocaleTest() { + String sessionId = createSession(Browsers.CHROME); + UserRepresentation user = testUserResource().toRepresentation(); + final Locale locale = Locale.GERMAN; + user.setAttributes(new HashMap>() {{ + put("locale", Collections.singletonList(locale.toLanguageTag())); + }}); + testUserResource().update(user); + + refreshPageAndWaitForLoad(); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d. MMMM yyyy, H:mm", locale); + DeviceActivityPage.Session session = deviceActivityPage.getSession(sessionId); + try { + LocalDateTime.parse(session.getLastAccess(), formatter); + } catch (DateTimeParseException e) { + fail("Time was not formatted with the locale"); + } + } + @Test public void ipTest() { final String ip = "146.58.69.12"; @@ -255,8 +282,7 @@ public class DeviceActivityTest extends BaseAccountPageTest { // using direct grant not to use current browser res = oauth.doGrantAccessTokenRequest( TEST, testUser.getUsername(), PASSWORD, null, TEST_CLIENT_ID, TEST_CLIENT_SECRET, browser.userAgent); - } - catch (Exception e) { + } catch (Exception e) { throw new RuntimeException(e); } return res.getSessionState(); // session id @@ -267,8 +293,7 @@ public class DeviceActivityTest extends BaseAccountPageTest { assertTrue("Session should be present", session.isPresent()); if (browser.sessionBrowser != null) { assertEquals(browser.sessionBrowser, session.getBrowser()); - } - else { + } else { assertFalse("Browser identification shouldn't be present", session.isBrowserDisplayed()); } assertEquals(browser.iconName, session.getBrowserIconName()); @@ -276,7 +301,7 @@ public class DeviceActivityTest extends BaseAccountPageTest { assertSessionRowsAreNotEmpty(session, true); } - private void assertSessionRowsAreNotEmpty(DeviceActivityPage.Session session, boolean expectSignOutPresent){ + private void assertSessionRowsAreNotEmpty(DeviceActivityPage.Session session, boolean expectSignOutPresent) { assertFalse("IP address shouldn't be empty", session.getIp().isEmpty()); assertFalse("Last accessed shouldn't be empty", session.getLastAccess().isEmpty()); assertFalse("Started shouldn't be empty", session.getStarted().isEmpty()); diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/InternationalizationTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/InternationalizationTest.java index 7090367735..86faa48436 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/InternationalizationTest.java +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/InternationalizationTest.java @@ -21,17 +21,24 @@ import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Test; import org.keycloak.models.UserModel; +import org.keycloak.models.credential.PasswordCredentialModel; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.ui.account2.page.PersonalInfoPage; +import org.keycloak.testsuite.ui.account2.page.SigningInPage; import org.keycloak.testsuite.ui.account2.page.WelcomeScreen; import org.keycloak.testsuite.util.WaitUtils; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.List; +import java.util.Locale; import java.util.Map; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * @author Vaclav Muzikar @@ -43,6 +50,10 @@ public class InternationalizationTest extends AbstractAccountTest { @Page private PersonalInfoPage personalInfoPage; + @Page + private SigningInPage signingInPage; + private SigningInPage.CredentialType passwordCredentialType; + @Override public void addTestRealms(List testRealms) { super.addTestRealms(testRealms); @@ -52,6 +63,7 @@ public class InternationalizationTest extends AbstractAccountTest { @Before public void beforeI18nTest() { assertTestUserLocale(null); + passwordCredentialType = signingInPage.getCredentialType(PasswordCredentialModel.TYPE); } @Test @@ -93,6 +105,34 @@ public class InternationalizationTest extends AbstractAccountTest { assertCustomLocalePersonalInfo(); } + @Test + public void shouldDisplayTimeUsingSelectedLocale() { + signingInPage.navigateTo(); + loginToAccount(); + SigningInPage.UserCredential passwordCred = + passwordCredentialType.getUserCredential(testUserResource().credentials().get(0).getId()); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy, h:mm a", Locale.ENGLISH); + try { + LocalDateTime.parse(passwordCred.getCreatedAtStr(), formatter); + } catch (DateTimeParseException e) { + fail("Time was not formatted with the locale"); + } + + signingInPage.header().clickLogoutBtn(); + signingInPage.navigateTo(); + loginPage.localeDropdown().selectAndAssert("Deutsch"); + loginPage.form().login(testUser); + + DateTimeFormatter formatterDe = DateTimeFormatter.ofPattern("d. MMMM yyyy, H:mm", Locale.GERMAN); + + try { + LocalDateTime.parse(passwordCred.getCreatedAtStr(), formatterDe); + } catch (DateTimeParseException e) { + fail("Time was not formatted with the locale"); + } + } + private void assertCustomLocaleWelcomeScreen() { assertEquals("Vítejte v Keycloaku", welcomeScreen.getWelcomeMessage()); } diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/page/WelcomeScreen.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/page/WelcomeScreen.java index 405125727b..6a8183fed7 100644 --- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/page/WelcomeScreen.java +++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/page/WelcomeScreen.java @@ -41,21 +41,21 @@ public class WelcomeScreen extends AbstractAccountPage { @FindBy(xpath = "//*[@id='" + ROOT_ELEMENT_ID + "']//header") private WelcomeScreenHeader header; - @FindBy(xpath = "//*[@id='landing-personal-info']/a") + @FindBy(xpath = "//a[@id='landing-personal-info']") private WebElement personalInfoLink; @FindBy(xpath = "//*[@id='landingChangePasswordLink']/a") private WebElement changePasswordLink; - @FindBy(xpath = "//*[@id='landing-authenticator']/a") + @FindBy(xpath = "//a[@id='landing-authenticator']") private WebElement authenticatorLink; @FindBy(xpath = "//*[@id='landing-device-activity']/a") private WebElement deviceActivityLink; @FindBy(xpath = "//*[@id='landing-linked-accounts']/a") private WebElement linkedAccountsLink; - @FindBy(xpath = "//*[@id='landing-applications']/a") + @FindBy(xpath = "//a[@id='landing-applications']") private WebElement applicationsLink; @FindBy(id = "landing-resources") private WebElement myResourcesCard; - @FindBy(xpath = "//*[@id='landing-resources']/a") + @FindBy(xpath = "//a[@id='landing-resources']") private WebElement myResourcesLink; @FindBy(id = "landingLogo") private WebElement logoLink;