keycloak-memoizeit
Changes
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/fragment/AccountManagementPatternFlyAlert.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractAccountPage.java 60(+60 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractLoggedInPage.java 55(+55 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ApplicationsPage.java 66(+66 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AuthenticatorPage.java 82(+82 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ChangePasswordPage.java 131(+131 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/DeviceActivityPage.java 82(+82 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/Card.java 31(+31 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/VerticalNavBar.java 62(+62 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/LinkedAccountsPage.java 82(+82 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/PersonalInfoPage.java 138(+138 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ResourcesPage.java 66(+66 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/WelcomeScreen.java 167(+167 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPatternFlyAlert.java 53(+44 -9)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/PatternFlyClosableAlert.java 50(+45 -5)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java 41(+40 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java 51(+36 -15)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/AbstractAccountManagementTest.java 7(+3 -4)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java 25(+14 -11)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/AbstractAccountTest.java 63(+63 -0)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/BaseAccountPageTest.java 44(+44 -0)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/ChangePasswordTest.java 127(+127 -0)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/PersonalInfoTest.java 148(+148 -0)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/WelcomeScreenTest.java 131(+131 -0)
testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/AbstractLoginTest.java 12(+8 -4)
Details
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractAccountPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractAccountPage.java
new file mode 100644
index 0000000..9b0a386
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractAccountPage.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.AuthRealm;
+import org.keycloak.testsuite.page.PatternFlyClosableAlert;
+
+import javax.ws.rs.core.UriBuilder;
+import java.util.List;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public abstract class AbstractAccountPage extends AuthRealm {
+ @Page
+ private PatternFlyClosableAlert alert;
+
+ public AbstractAccountPage() {
+ setAuthRealm(TEST);
+ }
+
+ /**
+ * Account Console is based on hash routing, e.g. [server_root]/auth/realms/test/account/#/password.
+ * All page objects for Account Console need to specify their "hash path" using this method.
+ *
+ * @return the hash path
+ */
+ protected abstract List<String> createHashPath();
+
+ @Override
+ public UriBuilder createUriBuilder() {
+ String fragment = null;
+ final List<String> hashPath = createHashPath();
+ if (hashPath != null) {
+ fragment = "/" + String.join("/", hashPath);
+ }
+
+ return super.createUriBuilder().path("account/").fragment(fragment);
+ }
+
+ public PatternFlyClosableAlert alert() {
+ return alert;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractLoggedInPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractLoggedInPage.java
new file mode 100644
index 0000000..1b65ce4
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AbstractLoggedInPage.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.VerticalNavBar;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public abstract class AbstractLoggedInPage extends AbstractAccountPage {
+ @Page
+ protected WelcomeScreen welcomeScreen;
+
+ @FindBy(className = "nav-pf-vertical nav-pf-vertical-with-badges")
+ private VerticalNavBar verticalNavBar;
+
+ @FindBy(id = "pageTitle")
+ protected WebElement pageTitle;
+
+ @Override
+ protected List<String> createHashPath() {
+ return new ArrayList<>();
+ }
+
+ /**
+ * This should simulate a user navigating to this page using links in the nav bar. It assume that user is logged in
+ * and at some Account Console page (not Welcome Screen), i.e. that the nav bar is visible.
+ */
+ public abstract void navigateToUsingNavBar();
+
+ public VerticalNavBar verticalNavBar() {
+ return verticalNavBar;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ApplicationsPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ApplicationsPage.java
new file mode 100644
index 0000000..662a514
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ApplicationsPage.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class ApplicationsPage extends AbstractLoggedInPage {
+ @Page
+ private ApplicationsCard applicationsCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("applications");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && applicationsCard.isVisible();
+ }
+
+ public ApplicationsCard applications() {
+ return applicationsCard;
+ }
+
+ public class ApplicationsCard extends Card {
+ @FindBy(className = "card-pf-application")
+ private WebElement cardRoot;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(cardRoot);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AuthenticatorPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AuthenticatorPage.java
new file mode 100644
index 0000000..638d161
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/AuthenticatorPage.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class AuthenticatorPage extends AbstractLoggedInPage {
+ @Page
+ private YourAuthenticatorsCard yourAuthenticatorsCard;
+ @Page
+ private AddAuthenticatorCard addAuthenticatorCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("authenticator");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && yourAuthenticators().isVisible() && addAuthenticator().isVisible();
+ }
+
+ public YourAuthenticatorsCard yourAuthenticators() {
+ return yourAuthenticatorsCard;
+ }
+
+ public AddAuthenticatorCard addAuthenticator() {
+ return addAuthenticatorCard;
+ }
+
+ public class YourAuthenticatorsCard extends Card {
+ @FindBy(id = "authenticatorFinishSetUpTitle")
+ private WebElement yourAuthenticatorsTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(yourAuthenticatorsTitle);
+ }
+ }
+
+ public class AddAuthenticatorCard extends Card {
+ @FindBy(id = "authenticatorSubTitle")
+ private WebElement addAuthenticatorTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(addAuthenticatorTitle);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ChangePasswordPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ChangePasswordPage.java
new file mode 100644
index 0000000..ab10ace
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ChangePasswordPage.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.clickBtnAndWaitForAlert;
+import static org.keycloak.testsuite.util.UIUtils.getTextFromElement;
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+import static org.keycloak.testsuite.util.UIUtils.setTextInputValue;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class ChangePasswordPage extends AbstractLoggedInPage {
+ @Page
+ private UpdatePasswordCard updatePasswordCard;
+ @Page
+ private PasswordLastUpdateCard passwordLastUpdateCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("password");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && updatePassword().isVisible();
+ }
+
+ public PasswordLastUpdateCard passwordLastUpdate() {
+ return passwordLastUpdateCard;
+ }
+
+ public UpdatePasswordCard updatePassword() {
+ return updatePasswordCard;
+ }
+
+ public class PasswordLastUpdateCard extends Card {
+ @FindBy(id = "passwordLastUpdate")
+ private WebElement cardRoot;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(cardRoot);
+ }
+
+ public String getTextDateTime() {
+ return getTextFromElement(cardRoot.findElement(By.tagName("strong")));
+ }
+
+ public LocalDateTime getDateTime() {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM d, yyyy, h:m:s a"); // e.g. Aug 31, 2018, 5:41:24 PM
+ return LocalDateTime.from(formatter.parse(getTextDateTime()));
+ }
+ }
+
+ public class UpdatePasswordCard extends Card {
+ @FindBy(id = "updatePasswordSubTitle")
+ private WebElement updatePasswordSubTitle;
+ @FindBy(id = "password")
+ private WebElement currentPassword;
+ @FindBy(id = "newPassword")
+ private WebElement newPassword;
+ @FindBy(id = "confirmation")
+ private WebElement confirmPassword;
+ @FindBy(name = "submitAction")
+ private WebElement submitBtn;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(updatePasswordSubTitle);
+ }
+
+ public void setCurrentPassword(String value) {
+ setTextInputValue(currentPassword, value);
+ }
+
+ public void setNewPassword(String value) {
+ setTextInputValue(newPassword, value);
+ }
+
+ public void setConfirmPassword(String value) {
+ setTextInputValue(confirmPassword, value);
+ }
+
+ public boolean isSaveDisabled() {
+ return submitBtn.getAttribute("disabled") != null;
+ }
+
+ public void clickSave() {
+ clickBtnAndWaitForAlert(submitBtn);
+ }
+
+ public void setPasswords(String currentPassword, String newPassword) {
+ setCurrentPassword(currentPassword);
+ setNewPassword(newPassword);
+ setConfirmPassword(newPassword);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/DeviceActivityPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/DeviceActivityPage.java
new file mode 100644
index 0000000..e5f5904
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/DeviceActivityPage.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class DeviceActivityPage extends AbstractLoggedInPage {
+ @Page
+ private SignedInDevicesCard signedInDevicesCard;
+ @Page
+ private RecentlyUsedDevicesCard recentlyUsedDevicesCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("device-activity");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && signedInDevices().isVisible() && recentlyUsedDevices().isVisible();
+ }
+
+ public SignedInDevicesCard signedInDevices() {
+ return signedInDevicesCard;
+ }
+
+ public RecentlyUsedDevicesCard recentlyUsedDevices() {
+ return recentlyUsedDevicesCard;
+ }
+
+ public class SignedInDevicesCard extends Card {
+ @FindBy(id = "signedInDevicesTitle")
+ private WebElement signedInDevicesTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(signedInDevicesTitle);
+ }
+ }
+
+ public class RecentlyUsedDevicesCard extends Card {
+ @FindBy(id = "recentlyUsedDevicesTitle")
+ private WebElement recentlyUsedDevicesTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(recentlyUsedDevicesTitle);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/Card.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/Card.java
new file mode 100644
index 0000000..b8540ed
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/Card.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2.fragment;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public abstract class Card {
+ @Drone
+ private WebDriver driver;
+
+ public abstract boolean isVisible();
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/VerticalNavBar.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/VerticalNavBar.java
new file mode 100644
index 0000000..ddcf46f
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/fragment/VerticalNavBar.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2.fragment;
+
+import org.jboss.arquillian.graphene.fragment.Root;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+// TODO rewrite this (blocked by KEYCLOAK-8217)
+public class VerticalNavBar {
+ @Root
+ private WebElement navBarRoot;
+
+ public void clickNavLinkByIndex(int i) {
+ clickLink(getNavLinkByIndex(i));
+ }
+
+ public void clickSubNavLinkByIndex(int i1, int i2) {
+ clickLink(getNavLinkByIndex(i1));
+ clickLink(getSubNavLinkByIndex(i1, i2));
+ }
+
+ public boolean isNavLinkActive(int i) {
+ return isNavLinkActive(getNavLinkByIndex(i));
+ }
+
+ public boolean isSubNavLinkActive(int i1, int i2) {
+ return isNavLinkActive(getSubNavLinkByIndex(i1, i2));
+ }
+
+ private WebElement getNavLinkByIndex(int i) {
+ return navBarRoot.findElement(By.xpath(String.format("./ul/li[%d]", i)));
+ }
+
+ private WebElement getSubNavLinkByIndex(int i1, int i2) {
+ return navBarRoot.findElement(By.xpath(String.format("./ul/li[%d]/div[contains(@class,'nav-pf-secondary-nav')]/ul/li[%d]", i1, i2)));
+ }
+
+ private boolean isNavLinkActive(WebElement navLink) {
+ return navLink.getAttribute("class").contains("active");
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/LinkedAccountsPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/LinkedAccountsPage.java
new file mode 100644
index 0000000..e00bfdc
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/LinkedAccountsPage.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class LinkedAccountsPage extends AbstractLoggedInPage {
+ @Page
+ private AuthorizedProvidersCard authorizedProvidersCard;
+ @Page
+ private AvailableProvidersCard availableProvidersCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("linked-accounts");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && authorizedProviders().isVisible() && availableProviders().isVisible();
+ }
+
+ public AuthorizedProvidersCard authorizedProviders() {
+ return authorizedProvidersCard;
+ }
+
+ public AvailableProvidersCard availableProviders() {
+ return availableProvidersCard;
+ }
+
+ public class AuthorizedProvidersCard extends Card {
+ @FindBy(id = "authorizedProvidersSubTitle")
+ private WebElement authorizedProvidersTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(authorizedProvidersTitle);
+ }
+ }
+
+ public class AvailableProvidersCard extends Card {
+ @FindBy(id = "identityProviderSubTitle")
+ private WebElement availableProvidersTitle;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(availableProvidersTitle);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/PersonalInfoPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/PersonalInfoPage.java
new file mode 100644
index 0000000..7f3dfc0
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/PersonalInfoPage.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.clickBtnAndWaitForAlert;
+import static org.keycloak.testsuite.util.UIUtils.getTextInputValue;
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+import static org.keycloak.testsuite.util.UIUtils.setTextInputValue;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class PersonalInfoPage extends AbstractLoggedInPage {
+ @Page
+ private PersonalInfoCard personalInfoCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("account");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && personalInfo().isVisible();
+ }
+
+ public PersonalInfoCard personalInfo() {
+ return personalInfoCard;
+ }
+
+ public class PersonalInfoCard extends Card {
+ @FindBy(id = "personalSubTitle")
+ private WebElement personalSubTitle;
+ @FindBy(id = "username")
+ private WebElement username;
+ @FindBy(id = "email")
+ private WebElement email;
+ @FindBy(id = "firstName")
+ private WebElement firstName;
+ @FindBy(id = "lastName")
+ private WebElement lastName;
+ @FindBy(name = "submitAction")
+ private WebElement submitBtn;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(personalSubTitle);
+ }
+
+ public boolean isUsernameDisabled() {
+ return !username.getTagName().equals("input"); // <div> for disabled
+ }
+
+ public String getUsername() {
+ return getTextInputValue(username);
+ }
+
+ public void setUsername(String value) {
+ setTextInputValue(username, value);
+ }
+
+ public String getEmail() {
+ return getTextInputValue(email);
+ }
+
+ public void setEmail(String value) {
+ setTextInputValue(email, value);
+ }
+
+ public String getFirstName() {
+ return getTextInputValue(firstName);
+ }
+
+ public void setFirstName(String value) {
+ setTextInputValue(firstName, value);
+ }
+
+ public String getLastName() {
+ return getTextInputValue(lastName);
+ }
+
+ public void setLastName(String value) {
+ setTextInputValue(lastName, value);
+ }
+
+ public boolean isSaveDisabled() {
+ return submitBtn.getAttribute("disabled") != null;
+ }
+
+ public void clickSave() {
+ clickBtnAndWaitForAlert(submitBtn);
+ }
+
+ public void setValues(UserRepresentation user) {
+ if (!isUsernameDisabled()) {setUsername(user.getUsername());}
+ setEmail(user.getEmail());
+ setFirstName(user.getFirstName());
+ setLastName(user.getLastName());
+ }
+
+ public boolean valuesEqual(UserRepresentation user) {
+ return user.getUsername().equals(getUsername())
+ && user.getEmail().equals(getEmail())
+ && user.getFirstName().equals(getFirstName())
+ && user.getLastName().equals(getLastName());
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ResourcesPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ResourcesPage.java
new file mode 100644
index 0000000..4004dc8
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/ResourcesPage.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class ResourcesPage extends AbstractLoggedInPage {
+ @Page
+ private ResourcesListCard resourcesListCard;
+
+ @Override
+ protected List<String> createHashPath() {
+ List<String> hashPath = super.createHashPath();
+ hashPath.add("my-resources");
+ return hashPath;
+ }
+
+ @Override
+ public void navigateToUsingNavBar() {
+ // TODO
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return super.isCurrent() && resourcesListCard.isVisible();
+ }
+
+ public ResourcesListCard resourcesList() {
+ return resourcesListCard;
+ }
+
+ public class ResourcesListCard extends Card {
+ @FindBy(className = "resources-list")
+ private WebElement cardRoot;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(cardRoot);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/WelcomeScreen.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/WelcomeScreen.java
new file mode 100644
index 0000000..74e01e9
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account2/WelcomeScreen.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.testsuite.auth.page.account2.fragment.Card;
+import org.keycloak.testsuite.util.URLUtils;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class WelcomeScreen extends AbstractAccountPage {
+ @Page
+ private PersonalInfoCard personalInfo;
+ @Page
+ private AccountSecurityCard accountSecurityCard;
+ @Page
+ private ApplicationsCard applicationsCard;
+ @Page
+ private MyResourcesCard myResourcesCard;
+ @FindBy(id = "welcomeMsg")
+ private WebElement welcomeMsg;
+ @FindBy(id = "signInButton")
+ private WebElement signInBtn;
+
+ @Override
+ protected List<String> createHashPath() {
+ return null;
+ }
+
+ @Override
+ public boolean isCurrent() {
+ return URLUtils.currentUrlEquals(toString() + "#/") && isElementVisible(welcomeMsg); // the hash will be eventually added after the page is loaded
+ }
+
+ public PersonalInfoCard personalInfo() {
+ return personalInfo;
+ }
+
+ public AccountSecurityCard accountSecurityCard() {
+ return accountSecurityCard;
+ }
+
+ public ApplicationsCard applicationsCard() {
+ return applicationsCard;
+ }
+
+ public MyResourcesCard myResourcesCard() {
+ return myResourcesCard;
+ }
+
+ public void clickLoginBtn() {
+ clickLink(signInBtn);
+ }
+
+ public boolean isLoginBtnVisible() {
+ return isElementVisible(signInBtn);
+ }
+
+ public class PersonalInfoCard extends Card {
+ @FindBy(id = "personalInfoCard")
+ private WebElement personalInfoCard;
+ @FindBy(id = "personalInfoLink")
+ private WebElement personalInfoLink;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(personalInfoCard);
+ }
+
+ public void clickPersonalInfo() {
+ clickLink(personalInfoLink);
+ }
+ }
+
+ public class AccountSecurityCard extends Card {
+ @FindBy(id = "accountSecurityCard")
+ private WebElement accountSecurityCard;
+ @FindBy(id = "changePasswordLink")
+ private WebElement changePasswordLink;
+ @FindBy(id = "authenticatorLink")
+ private WebElement authenticatorLink;
+ @FindBy(id = "deviceActivityLink")
+ private WebElement deviceActivityLink;
+ @FindBy(id = "linkedAccountsLink")
+ private WebElement linkedAccountsLink;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(accountSecurityCard);
+ }
+
+ public void clickChangePassword() {
+ clickLink(changePasswordLink);
+ }
+
+ public void clickAuthenticator() {
+ clickLink(authenticatorLink);
+ }
+
+ public void clickDeviceActivity() {
+ clickLink(deviceActivityLink);
+ }
+
+ public void clickLinkedAccounts() {
+ clickLink(linkedAccountsLink);
+ }
+
+ public boolean isLinkedAccountsVisible() {
+ return isElementVisible(linkedAccountsLink);
+ }
+ }
+
+ public class ApplicationsCard extends Card {
+ @FindBy(id = "applicationsCard")
+ private WebElement applicationsCard;
+ @FindBy(id = "applicationsLink")
+ private WebElement applicationsLink;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(applicationsCard);
+ }
+
+ public void clickApplicationsLink() {
+ clickLink(applicationsLink);
+ }
+ }
+
+ public class MyResourcesCard extends Card {
+ @FindBy(id = "myResourcesCard")
+ private WebElement myResourcesCard;
+ @FindBy(id = "myResourcesLink")
+ private WebElement myResourcesLink;
+
+ @Override
+ public boolean isVisible() {
+ return isElementVisible(myResourcesCard);
+ }
+
+ public void clickMyResources() {
+ clickLink(myResourcesLink);
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
index 81c7b4a..c497e1a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
@@ -1,7 +1,12 @@
package org.keycloak.testsuite.util;
import io.appium.java_client.android.AndroidDriver;
+import org.apache.commons.lang3.StringUtils;
+import org.keycloak.testsuite.page.AbstractPatternFlyAlert;
+import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -19,6 +24,7 @@ import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
public final class UIUtils {
public static final String VALUE_ATTR_NAME = "value";
+ public static final short EXPECTED_UI_LAYOUT = Short.parseShort(System.getProperty("testsuite.ui.layout")); // 0 == desktop layout, 1 == smartphone layout, 2 == tablet layout
public static boolean selectContainsOption(Select select, String optionText) {
for (WebElement option : select.getOptions()) {
@@ -56,6 +62,18 @@ public final class UIUtils {
}
/**
+ * This is as an alternative for {@link #clickLink(WebElement)} and should be used in situations where we can't use
+ * {@link WaitUtils#waitForPageToLoad()}. This is because {@link WaitUtils#waitForPageToLoad()} would wait until the
+ * alert would disappeared itself (timeout).
+ *
+ * @param button to click on
+ */
+ public static void clickBtnAndWaitForAlert(WebElement button) {
+ button.click();
+ AbstractPatternFlyAlert.waitUntilDisplayed();
+ }
+
+ /**
* Navigates to a link directly instead of clicking on it.
* Some browsers are sometimes having problems with clicking on links, so this should be used only in that cases,
* i.e. only when clicking directly doesn't work
@@ -93,9 +111,13 @@ public final class UIUtils {
public static void setTextInputValue(WebElement input, String value) {
input.click();
input.clear();
- if (value != null) {
+ if (!StringUtils.isEmpty(value)) { // setting new input
input.sendKeys(value);
}
+ else { // just clearing the input; input.clear() may not fire all JS events so we need to let the page know that something's changed
+ input.sendKeys("a");
+ input.sendKeys(Keys.BACK_SPACE);
+ }
WebDriver driver = getCurrentDriver();
if (driver instanceof AndroidDriver) {
@@ -117,4 +139,21 @@ public final class UIUtils {
}
return text;
}
+
+ /**
+ * Should be used solely with {@link org.jboss.arquillian.graphene.GrapheneElement}, i.e. all elements annotated by
+ * {@link org.openqa.selenium.support.FindBy}. CANNOT be used with elements found directly using
+ * {@link WebDriver#findElement(By)} and similar.
+ *
+ * @param element
+ * @return true if element is present and visible
+ */
+ public static boolean isElementVisible(WebElement element) {
+ try {
+ return element.isDisplayed();
+ }
+ catch (NoSuchElementException e) {
+ return false;
+ }
+ }
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
index 7d40f68..73398cf 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
@@ -16,21 +16,25 @@
*/
package org.keycloak.testsuite.util;
-import java.time.Duration;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import org.jboss.arquillian.graphene.wait.ElementBuilder;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
+import java.time.Duration;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
import static org.jboss.arquillian.graphene.Graphene.waitGui;
import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver;
-import static org.openqa.selenium.support.ui.ExpectedConditions.*;
+import static org.openqa.selenium.support.ui.ExpectedConditions.javaScriptThrowsNoExceptions;
+import static org.openqa.selenium.support.ui.ExpectedConditions.not;
+import static org.openqa.selenium.support.ui.ExpectedConditions.urlToBe;
/**
*
@@ -97,9 +101,11 @@ public final class WaitUtils {
return; // not needed
}
+ String currentUrl = null;
+
// Ensure the URL is "stable", i.e. is not changing anymore; if it'd changing, some redirects are probably still in progress
- for (int maxRedirects = 2; maxRedirects > 0; maxRedirects--) {
- String currentUrl = driver.getCurrentUrl();
+ for (int maxRedirects = 4; maxRedirects > 0; maxRedirects--) {
+ currentUrl = driver.getCurrentUrl();
FluentWait<WebDriver> wait = new FluentWait<>(driver).withTimeout(Duration.ofMillis(250));
try {
wait.until(not(urlToBe(currentUrl)));
@@ -113,19 +119,34 @@ public final class WaitUtils {
}
WebDriverWait wait = new WebDriverWait(getCurrentDriver(), PAGELOAD_TIMEOUT_MILLIS / 1000);
+ ExpectedCondition waitCondition = null;
- try {
- // Checks if the document is ready and asks AngularJS, if present, whether there are any REST API requests
- // in progress
- wait.until(javaScriptThrowsNoExceptions(
+ // Different wait strategies for Admin and Account Consoles
+ if (currentUrl.matches("^[^\\/]+:\\/\\/[^\\/]+\\/auth\\/admin\\/.*$")) { // Admin Console
+ // Checks if the document is ready and asks AngularJS, if present, whether there are any REST API requests in progress
+ waitCondition = javaScriptThrowsNoExceptions(
"if (document.readyState !== 'complete' "
+ "|| (typeof angular !== 'undefined' && angular.element(document.body).injector().get('$http').pendingRequests.length !== 0)) {"
+ "throw \"Not ready\";"
- + "}"));
- } catch (TimeoutException e) {
- // Sometimes, for no obvious reason, the browser/JS doesn't set document.readyState to 'complete' correctly
- // but that's no reason to let the test fail; after the timeout the page is surely fully loaded
- log.warn("waitForPageToLoad time exceeded!");
+ + "}");
+ }
+ else if (
+ currentUrl.matches("^[^\\/]+:\\/\\/[^\\/]+\\/auth\\/realms\\/[^\\/]+\\/account\\/.*$") // check for Account Console URL
+ && driver.getPageSource().contains("patternfly-ng") // check for new Account Console (don't use this strategy with the old one)
+ ) {
+ waitCondition = javaScriptThrowsNoExceptions(
+ "if (!window.getAngularTestability(document.querySelector('app-root')).isStable()) {" +
+ "throw 'Not ready';" +
+ "}"
+ );
+ }
+
+ if (waitCondition != null) {
+ try {
+ wait.until(waitCondition);
+ } catch (TimeoutException e) {
+ log.warn("waitForPageToLoad time exceeded!");
+ }
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
index ee8ab62..d488c78 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
@@ -137,7 +137,7 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest {
deleteAllSessionsInRealm(testRealmAccountPage.getAuthRealm());
}
- private void resetTestRealmSession() {
+ protected void resetTestRealmSession() {
resetRealmSession(testRealmAccountPage.getAuthRealm());
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/AbstractAccountManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/AbstractAccountManagementTest.java
index 9eda4a4..fe1b9da 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/AbstractAccountManagementTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/AbstractAccountManagementTest.java
@@ -21,8 +21,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.keycloak.testsuite.AbstractAuthTest;
import org.keycloak.testsuite.auth.page.account.AccountManagement;
-import org.keycloak.testsuite.auth.page.account.fragment.AccountManagementAlert;
-import org.openqa.selenium.support.FindBy;
+import org.keycloak.testsuite.auth.page.account.fragment.AccountManagementPatternFlyAlert;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
@@ -36,8 +35,8 @@ public abstract class AbstractAccountManagementTest extends AbstractAuthTest {
@Page
protected AccountManagement testRealmAccountManagementPage;
- @FindBy(className = "alert")
- protected AccountManagementAlert alert;
+ @Page
+ protected AccountManagementPatternFlyAlert alert;
@Override
public void setDefaultPageUriParameters() {
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java
index 389a6d5..93d847d 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java
@@ -17,16 +17,16 @@
package org.keycloak.testsuite.ui;
+import org.junit.Before;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractAuthTest;
import java.util.Arrays;
-import java.util.List;
+import java.util.HashMap;
import java.util.Set;
import java.util.stream.Collectors;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
-
/**
* @author Vaclav Muzikar <vmuzikar@redhat.com>
*/
@@ -34,14 +34,9 @@ public abstract class AbstractUiTest extends AbstractAuthTest {
public static final String LOCALIZED_THEME = "localized-theme";
public static final String CUSTOM_LOCALE_NAME = "Přísný jazyk";
- @Override
- public void addTestRealms(List<RealmRepresentation> testRealms) {
- RealmRepresentation testRealmRep = new RealmRepresentation();
- testRealmRep.setId(TEST);
- testRealmRep.setRealm(TEST);
- testRealmRep.setEnabled(true);
- configureInternationalizationForRealm(testRealmRep);
- testRealms.add(testRealmRep);
+ @Before
+ public void addTestUser() {
+ createTestUserWithAdminClient(false);
}
protected void configureInternationalizationForRealm(RealmRepresentation realm) {
@@ -58,4 +53,12 @@ public abstract class AbstractUiTest extends AbstractAuthTest {
realm.setAccountTheme(LOCALIZED_THEME);
realm.setEmailTheme(LOCALIZED_THEME);
}
+
+ protected IdentityProviderRepresentation createIdentityProviderRepresentation(String alias, String providerId) {
+ IdentityProviderRepresentation idpRep = new IdentityProviderRepresentation();
+ idpRep.setProviderId(providerId);
+ idpRep.setAlias(alias);
+ idpRep.setConfig(new HashMap<>());
+ return idpRep;
+ }
}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/AbstractAccountTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/AbstractAccountTest.java
new file mode 100644
index 0000000..2006872
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/AbstractAccountTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.ui.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.keycloak.common.Profile;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.ProfileAssume;
+import org.keycloak.testsuite.auth.page.account2.WelcomeScreen;
+import org.keycloak.testsuite.ui.AbstractUiTest;
+
+import java.util.List;
+
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public abstract class AbstractAccountTest extends AbstractUiTest {
+ public static final String ACCOUNT_THEME_NAME = "keycloak-preview";
+
+ @Page
+ protected WelcomeScreen accountWelcomeScreen;
+
+ @Override
+ public void addTestRealms(List<RealmRepresentation> testRealms) {
+ super.addTestRealms(testRealms);
+ RealmRepresentation testRealmRep = testRealms.get(0);
+ testRealmRep.setAccountTheme(ACCOUNT_THEME_NAME);
+ }
+
+ @BeforeClass
+ public static void enabled() {
+ ProfileAssume.assumeFeatureEnabled(Profile.Feature.ACCOUNT2);
+ }
+
+ @Before
+ public void beforeAccountTest() {
+ accountWelcomeScreen.navigateTo();
+ }
+
+ protected void loginToAccount() {
+ assertCurrentUrlStartsWithLoginUrlOf(accountWelcomeScreen);
+ loginPage.form().login(testUser);
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/BaseAccountPageTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/BaseAccountPageTest.java
new file mode 100644
index 0000000..a83f558
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/BaseAccountPageTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.ui.account2;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.keycloak.testsuite.auth.page.account2.AbstractLoggedInPage;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public abstract class BaseAccountPageTest extends AbstractAccountTest {
+ protected abstract AbstractLoggedInPage getAccountPage();
+
+ @Before
+ public void beforeBaseAccountPageTest() {
+ getAccountPage().navigateTo();
+ loginToAccount();
+ getAccountPage().assertCurrent();
+ }
+
+ @Test
+ @Ignore // TODO, blocked by KEYCLOAK-8217
+ public void navigationTest() {
+ getAccountPage().navigateToUsingNavBar();
+ getAccountPage().assertCurrent();
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/ChangePasswordTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/ChangePasswordTest.java
new file mode 100644
index 0000000..801d4ed
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/ChangePasswordTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.ui.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.auth.page.account2.AbstractLoggedInPage;
+import org.keycloak.testsuite.auth.page.account2.ChangePasswordPage;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.keycloak.testsuite.admin.Users.getPasswordOf;
+import static org.keycloak.testsuite.admin.Users.setPasswordFor;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class ChangePasswordTest extends BaseAccountPageTest {
+ @Page
+ private ChangePasswordPage changePasswordPage;
+
+ @Override
+ public void addTestRealms(List<RealmRepresentation> testRealms) {
+ super.addTestRealms(testRealms);
+ RealmRepresentation realm = testRealms.get(0);
+ realm.setPasswordPolicy("length(3)");
+ }
+
+ @Override
+ protected AbstractLoggedInPage getAccountPage() {
+ return changePasswordPage;
+ }
+
+ @Test
+ public void changePassword() {
+ final LocalDateTime testStartTime = LocalDateTime.now();
+
+ final String oldPwd = getPasswordOf(testUser);
+ final String newPwd = "nějaké nové heslo s háčky a čárkami";
+ setPasswordFor(testUser, newPwd);
+
+ assertTrue("The current password should be older than the start time of this test",
+ testStartTime.isAfter(changePasswordPage.passwordLastUpdate().getDateTime()));
+
+ changePasswordPage.updatePassword().setPasswords(oldPwd, newPwd);
+ changePasswordPage.updatePassword().clickSave();
+ changePasswordPage.alert().assertSuccess();
+
+ // try the new password
+ deleteAllSessionsInTestRealm(); // logout
+ changePasswordPage.navigateTo();
+ loginToAccount();
+ changePasswordPage.assertCurrent();
+
+ assertTrue("The new password should be newer than the start time of this test",
+ testStartTime.isBefore(changePasswordPage.passwordLastUpdate().getDateTime()));
+ }
+
+ @Test
+ public void formValidationTest() {
+ assertTrue(changePasswordPage.updatePassword().isSaveDisabled());
+ changePasswordPage.updatePassword().setPasswords("abc", "def");
+ assertFalse(changePasswordPage.updatePassword().isSaveDisabled());
+
+ // clear current password
+ changePasswordPage.updatePassword().setCurrentPassword("");
+ assertTrue(changePasswordPage.updatePassword().isSaveDisabled());
+ changePasswordPage.updatePassword().setCurrentPassword("abc");
+ assertFalse(changePasswordPage.updatePassword().isSaveDisabled());
+
+ // clear new password
+ changePasswordPage.updatePassword().setNewPassword("");
+ assertTrue(changePasswordPage.updatePassword().isSaveDisabled());
+ changePasswordPage.updatePassword().setNewPassword("def");
+ assertFalse(changePasswordPage.updatePassword().isSaveDisabled());
+
+ // clear confirm password
+ changePasswordPage.updatePassword().setConfirmPassword("");
+ assertTrue(changePasswordPage.updatePassword().isSaveDisabled());
+ changePasswordPage.updatePassword().setConfirmPassword("def");
+ assertFalse(changePasswordPage.updatePassword().isSaveDisabled());
+
+ // invalid current password
+ changePasswordPage.updatePassword().setPasswords("invalid", "ab");
+ changePasswordPage.updatePassword().clickSave();
+ changePasswordPage.alert().assertDanger("Invalid existing password.");
+
+ // non-matching passwords
+ changePasswordPage.updatePassword().setPasswords(getPasswordOf(testUser), "ab");
+ changePasswordPage.updatePassword().setConfirmPassword("no match");
+ changePasswordPage.updatePassword().clickSave();
+ changePasswordPage.alert().assertDanger("Passwords don't match.");
+
+ // password policy
+ changePasswordPage.updatePassword().setPasswords(getPasswordOf(testUser), "ab");
+ changePasswordPage.updatePassword().clickSave();
+ changePasswordPage.alert().assertDanger("Invalid password: minimum length 3.");
+
+ // check the password is not changed
+ deleteAllSessionsInTestRealm();
+ changePasswordPage.navigateTo();
+ loginToAccount();
+ changePasswordPage.assertCurrent();
+ }
+
+ // TODO test the last update timestamp when the password was never updated (blocked by KEYCLOAK-8193)
+ // TODO test internationalization for last update timestamp (blocked by KEYCLOAK-8194)
+}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/PersonalInfoTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/PersonalInfoTest.java
new file mode 100644
index 0000000..d40baa2
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/PersonalInfoTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.ui.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.admin.ApiUtil;
+import org.keycloak.testsuite.auth.page.account2.AbstractLoggedInPage;
+import org.keycloak.testsuite.auth.page.account2.PersonalInfoPage;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class PersonalInfoTest extends BaseAccountPageTest {
+ private UserRepresentation testUser2;
+ @Page
+ private PersonalInfoPage personalInfoPage;
+
+ @Before
+ public void setTestUser() {
+ testUser2 = new UserRepresentation();
+ testUser2.setUsername("vmuzikar");
+ testUser2.setEmail("vmuzikar@redhat.com");
+ testUser2.setFirstName("Václav");
+ testUser2.setLastName("Muzikář");
+ ApiUtil.removeUserByUsername(testRealmResource(), testUser2.getUsername());
+ }
+
+ @Override
+ protected AbstractLoggedInPage getAccountPage() {
+ return personalInfoPage;
+ }
+
+ @Test
+ public void updateUserInfo() {
+ setEditUsernameAllowed(true);
+
+ assertTrue(personalInfoPage.personalInfo().valuesEqual(testUser));
+ assertFalse(personalInfoPage.personalInfo().isUsernameDisabled());
+ assertTrue(personalInfoPage.personalInfo().isSaveDisabled());
+
+ personalInfoPage.personalInfo().setValues(testUser2);
+ assertTrue(personalInfoPage.personalInfo().valuesEqual(testUser2));
+ assertFalse(personalInfoPage.personalInfo().isSaveDisabled());
+ personalInfoPage.personalInfo().clickSave();
+ personalInfoPage.alert().assertSuccess();
+
+ personalInfoPage.navigateTo();
+ personalInfoPage.personalInfo().valuesEqual(testUser2);
+
+ // change just first and last name
+ testUser2.setFirstName("Another");
+ testUser2.setLastName("Name");
+ personalInfoPage.personalInfo().setValues(testUser2);
+ personalInfoPage.personalInfo().clickSave();
+ personalInfoPage.alert().assertSuccess();
+ personalInfoPage.navigateTo();
+ personalInfoPage.personalInfo().valuesEqual(testUser2);
+ }
+
+ @Test
+ public void formValidationTest() {
+ setEditUsernameAllowed(true);
+
+ // clear username
+ personalInfoPage.personalInfo().setUsername("");
+ assertTrue(personalInfoPage.personalInfo().isSaveDisabled());
+ personalInfoPage.personalInfo().setUsername("abc");
+ assertFalse(personalInfoPage.personalInfo().isSaveDisabled());
+
+ // clear email
+ personalInfoPage.personalInfo().setEmail("");
+ assertTrue(personalInfoPage.personalInfo().isSaveDisabled());
+ personalInfoPage.personalInfo().setEmail("vmuzikar@redhat.com");
+ assertFalse(personalInfoPage.personalInfo().isSaveDisabled());
+
+ // TODO test email validation (blocked by KEYCLOAK-8098)
+
+ // clear first name
+ personalInfoPage.personalInfo().setFirstName("");
+ assertTrue(personalInfoPage.personalInfo().isSaveDisabled());
+ personalInfoPage.personalInfo().setFirstName("abc");
+ assertFalse(personalInfoPage.personalInfo().isSaveDisabled());
+
+ // clear last name
+ personalInfoPage.personalInfo().setLastName("");
+ assertTrue(personalInfoPage.personalInfo().isSaveDisabled());
+ personalInfoPage.personalInfo().setLastName("abc");
+ assertFalse(personalInfoPage.personalInfo().isSaveDisabled());
+
+ // duplicity tests
+ ApiUtil.createUserWithAdminClient(testRealmResource(), testUser2);
+ // duplicate username
+ personalInfoPage.personalInfo().setUsername(testUser2.getUsername());
+ personalInfoPage.personalInfo().clickSave();
+ personalInfoPage.alert().assertDanger("Username already exists.");
+ personalInfoPage.personalInfo().setUsername(testUser.getUsername());
+ // duplicate email
+ personalInfoPage.personalInfo().setEmail(testUser2.getEmail());
+ personalInfoPage.personalInfo().clickSave();
+ personalInfoPage.alert().assertDanger("Email already exists.");
+ // check no changes were saved
+ personalInfoPage.navigateTo();
+ personalInfoPage.personalInfo().valuesEqual(testUser);
+ }
+
+ @Test
+ public void disabledEditUsername() {
+ setEditUsernameAllowed(false);
+
+ assertTrue(personalInfoPage.personalInfo().isUsernameDisabled());
+ personalInfoPage.personalInfo().setValues(testUser2);
+ personalInfoPage.personalInfo().clickSave();
+ personalInfoPage.alert().assertSuccess();
+
+ testUser2.setUsername(testUser.getUsername()); // the username should remain the same
+ personalInfoPage.navigateTo();
+ personalInfoPage.personalInfo().valuesEqual(testUser2);
+ }
+
+ private void setEditUsernameAllowed(boolean value) {
+ RealmRepresentation realm = testRealmResource().toRepresentation();
+ realm.setEditUsernameAllowed(value);
+ testRealmResource().update(realm);
+ personalInfoPage.navigateTo();
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/WelcomeScreenTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/WelcomeScreenTest.java
new file mode 100644
index 0000000..dedef72
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account2/WelcomeScreenTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * 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.ui.account2;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.auth.page.account2.ApplicationsPage;
+import org.keycloak.testsuite.auth.page.account2.AuthenticatorPage;
+import org.keycloak.testsuite.auth.page.account2.ChangePasswordPage;
+import org.keycloak.testsuite.auth.page.account2.DeviceActivityPage;
+import org.keycloak.testsuite.auth.page.account2.LinkedAccountsPage;
+import org.keycloak.testsuite.auth.page.account2.PersonalInfoPage;
+import org.keycloak.testsuite.auth.page.account2.ResourcesPage;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
+ */
+public class WelcomeScreenTest extends AbstractAccountTest {
+ @Page
+ private PersonalInfoPage personalInfoPage;
+ @Page
+ private ChangePasswordPage changePasswordPage;
+ @Page
+ private AuthenticatorPage authenticatorPage;
+ @Page
+ private DeviceActivityPage deviceActivityPage;
+ @Page
+ private LinkedAccountsPage linkedAccountsPage;
+ @Page
+ private ApplicationsPage applicationsPage;
+ @Page
+ private ResourcesPage resourcesPage;
+
+ @Test
+ public void loginTest() {
+ accountWelcomeScreen.assertCurrent();
+ assertTrue(accountWelcomeScreen.isLoginBtnVisible());
+
+ // login
+ accountWelcomeScreen.clickLoginBtn();
+ loginToAccount();
+ accountWelcomeScreen.assertCurrent();
+ assertFalse(accountWelcomeScreen.isLoginBtnVisible());
+
+ // TODO logout test (blocked by KEYCLOAK-8084)
+ }
+
+ @Test
+ public void personalInfoTest() {
+ assertTrue(accountWelcomeScreen.personalInfo().isVisible());
+ accountWelcomeScreen.personalInfo().clickPersonalInfo();
+ loginToAccount();
+ personalInfoPage.assertCurrent();
+ }
+
+ @Test
+ public void accountSecurityTest() {
+ assertTrue(accountWelcomeScreen.accountSecurityCard().isVisible());
+
+ // change password link
+ accountWelcomeScreen.accountSecurityCard().clickChangePassword();
+ loginToAccount();
+ changePasswordPage.assertCurrent();
+
+ // authenticator link
+ accountWelcomeScreen.navigateTo();
+ accountWelcomeScreen.accountSecurityCard().clickAuthenticator();
+ authenticatorPage.assertCurrent();
+
+ // device activity link
+ accountWelcomeScreen.navigateTo();
+ accountWelcomeScreen.accountSecurityCard().clickDeviceActivity();
+ deviceActivityPage.assertCurrent();
+
+ // linked accounts link
+ accountWelcomeScreen.navigateTo();
+ assertFalse(accountWelcomeScreen.accountSecurityCard().isLinkedAccountsVisible());
+ // add simple IdP
+ testRealmResource().identityProviders().create(createIdentityProviderRepresentation("test-idp", "test-provider"));
+ // test link appeared
+ accountWelcomeScreen.navigateTo();
+ accountWelcomeScreen.accountSecurityCard().clickLinkedAccounts();
+ linkedAccountsPage.assertCurrent();
+ // no need to remove the IdP
+ }
+
+ @Test
+ public void applicationsTest() {
+ assertTrue(accountWelcomeScreen.applicationsCard().isVisible());
+ accountWelcomeScreen.applicationsCard().clickApplicationsLink();
+ loginToAccount();
+ applicationsPage.assertCurrent();
+ }
+
+ @Test
+ public void resourcesTest() {
+ assertFalse(accountWelcomeScreen.myResourcesCard().isVisible());
+
+ // set user managed access
+ RealmRepresentation testRealm = testRealmResource().toRepresentation();
+ testRealm.setUserManagedAccessAllowed(true);
+ testRealmResource().update(testRealm);
+
+ // test my resources appeared
+ accountWelcomeScreen.navigateTo();
+ assertTrue(accountWelcomeScreen.myResourcesCard().isVisible());
+ accountWelcomeScreen.myResourcesCard().clickMyResources();
+ loginToAccount();
+ resourcesPage.assertCurrent();
+ // no need to disable user managed access
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/AbstractLoginTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/AbstractLoginTest.java
index e9c673e..9ff8bbc 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/AbstractLoginTest.java
+++ b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/login/AbstractLoginTest.java
@@ -17,9 +17,11 @@
package org.keycloak.testsuite.ui.login;
-import org.junit.Before;
+import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.ui.AbstractUiTest;
+import java.util.List;
+
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
@@ -29,9 +31,11 @@ import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
* @author Vaclav Muzikar <vmuzikar@redhat.com>
*/
public abstract class AbstractLoginTest extends AbstractUiTest {
- @Before
- public void addTestUser() {
- createTestUserWithAdminClient(false);
+ @Override
+ public void addTestRealms(List<RealmRepresentation> testRealms) {
+ super.addTestRealms(testRealms);
+ RealmRepresentation testRealmRep = testRealms.get(0);
+ configureInternationalizationForRealm(testRealmRep);
}
protected void assertLoginFailed(String message) {
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
index d01e4a5..183e91d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
@@ -26,8 +26,8 @@ import org.keycloak.testsuite.console.page.AdminConsole;
import org.keycloak.testsuite.console.page.AdminConsoleRealm;
import org.keycloak.testsuite.console.page.AdminConsoleRealm.ConfigureMenu;
import org.keycloak.testsuite.console.page.AdminConsoleRealm.ManageMenu;
-import org.keycloak.testsuite.console.page.fragment.AdminConsoleAlert;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
+import org.keycloak.testsuite.page.PatternFlyClosableAlert;
import org.openqa.selenium.support.FindBy;
import static org.junit.Assert.assertTrue;
@@ -53,8 +53,8 @@ public abstract class AbstractConsoleTest extends AbstractAuthTest {
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
- @FindBy(className = "alert")
- protected AdminConsoleAlert alert;
+ @Page
+ protected PatternFlyClosableAlert alert;
protected boolean adminLoggedIn = false;
@@ -111,13 +111,11 @@ public abstract class AbstractConsoleTest extends AbstractAuthTest {
}
public void assertAlertSuccess() {
- assertTrue("Alert is not success", alert.isSuccess());
- alert.close();
+ alert.assertSuccess();
}
public void assertAlertDanger() {
- assertTrue("Alert is not danger", alert.isDanger());
- alert.close();
+ alert.assertDanger();
}
public ConfigureMenu configure() {
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 4f03c09..9793ade 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -167,6 +167,7 @@
<backends.console.output>true</backends.console.output>
<testsuite.constants>${project.build.directory}/dependency/test-constants.properties</testsuite.constants>
+ <testsuite.ui.layout>0</testsuite.ui.layout> <!-- this is to tell the UI tests what type of layout to expect (doesn't setup the layout, just what to expect); 0 == desktop layout, 1 == smartphone layout, 2 == tablet layout -->
<skip.add.user.json>false</skip.add.user.json>
<skip.clean.second.cache>true</skip.clean.second.cache>
@@ -461,6 +462,7 @@
<kie.maven.settings>${kie.maven.settings}</kie.maven.settings>
<testsuite.constants>${testsuite.constants}</testsuite.constants>
+ <testsuite.ui.layout>${testsuite.ui.layout}</testsuite.ui.layout>
<cli.log.output>${cli.log.output}</cli.log.output>
<test.intermittent>${test.intermittent}</test.intermittent>
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
index e094738..7fd1897 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
+++ b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
@@ -194,7 +194,7 @@
<h2>${msg("accountSecurityTitle")}</h2>
<p class="card-pf-content-intro">${msg("accountSecurityIntroMessage")}</p>
<h3 id="changePasswordLink"><a href="${baseUrl}/#/password">${msg("changePasswordHtmlTitle")}</a></h3>
- <h3 id="authenticatiorLink"><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
+ <h3 id="authenticatorLink"><a href="${baseUrl}/#/authenticator">${msg("authenticatorTitle")}</a></h3>
<h3 id="deviceActivityLink"><a href="${baseUrl}/#/device-activity">${msg("deviceActivityHtmlTitle")}</a></h3>
<h3 id="linkedAccountsLink"><a href="${baseUrl}/#/linked-accounts">${msg("linkedAccountsHtmlTitle")}</a></h3>
</div>