diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 20a640b518..2df13cbed1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -47,4 +47,3 @@
/js/ @keycloak/ui-maintainers
/adapters/oidc/js/ @keycloak/ui-maintainers
/rest/admin-ui-ext/ @keycloak/ui-maintainers
-/testsuite/integration-arquillian/tests/other/base-ui/ @keycloak/ui-maintainers
diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md
index a60d130c81..f2adca7b5a 100644
--- a/testsuite/integration-arquillian/HOW-TO-RUN.md
+++ b/testsuite/integration-arquillian/HOW-TO-RUN.md
@@ -352,17 +352,6 @@ mvn -f testsuite/integration-arquillian/tests/other/springboot-tests/pom.xml \
[-Pspringboot27]
```
-## Base UI tests
-Similarly to Admin Console tests, these tests are focused on UI, specifically on the parts of the server that are accessed by an end user (like Login page, or Account Console).
-They are designed to work with mobile browsers (alongside the standard desktop browsers). For details on the supported browsers and their configuration please refer to [Different Browsers chapter](#different-browsers).
-#### Execution example
-```
-mvn -f testsuite/integration-arquillian/tests/other/base-ui/pom.xml \
- clean test \
- -Pandroid \
- -Dappium.avd=Nexus_5X_API_27
-```
-
## Disabling features
Some features in Keycloak can be disabled. To run the testsuite with a specific feature disabled use the `auth.server.feature` system property. For example to run the tests with authorization disabled run:
```
@@ -454,23 +443,17 @@ You can use many different real-world browsers to run the integration tests.
Although technically they can be run with almost every test in the testsuite, they can fail with some of them as the tests often require specific optimizations for given browser. Therefore, only some of the test modules have support to be run with specific browsers.
#### Mozilla Firefox
-* **Supported test modules:** `console`, `base-ui`
+* **Supported test modules:** `console`
* **Supported version:** latest stable
* **Driver download required:** [GeckoDriver](https://github.com/mozilla/geckodriver/releases)
* **Run with:** `-Dbrowser=firefox -Dwebdriver.gecko.driver=path/to/geckodriver`; optionally you can specify `-Dfirefox_binary=path/to/firefox/binary`
#### Google Chrome
-* **Supported test modules:** `console`, `base-ui`
+* **Supported test modules:** `console`
* **Supported version:** latest stable
* **Driver download required:** [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) that corresponds with your version of the browser
* **Run with:** `-Dbrowser=chrome -Dwebdriver.chrome.driver=path/to/chromedriver`
-#### Apple Safari
-* **Supported test modules:** `base-ui`
-* **Supported version:** latest stable
-* **Driver download required:** no (the driver is bundled with macOS)
-* **Run with:** `-Dbrowser=safari`
-
#### [DEPRECATED] Mozilla Firefox with legacy driver
* **Supported test modules:** `console`
* **Supported version:** [52 ESR](http://ftp.mozilla.org/pub/firefox/releases/52.9.0esr/) ([Extended Support Release](https://www.mozilla.org/en-US/firefox/organizations/))
@@ -490,25 +473,11 @@ The tests will try to start the Appium server automatically but you can do it ma
To use a mobile browser you need to create a virtual device. The most convenient way to do so is to install the desired platform's IDE - either [Android Studio](https://developer.android.com/studio/) (for Android devices) or [Xcode](https://developer.apple.com/xcode/) (for iOS devices) - then you can create a device (smartphone/tablet) there. For details please refer to documentation of those IDEs.
-#### Google Chrome on Android
-* **Supported test modules:** `base-ui`
-* **Supported host OS:** Windows, Linux, macOS
-* **Supported browser version:** latest stable
-* **Supported mobile OS version:** Android 7.x, 8.x
-* **Run with:** `mvn clean test -Pandroid -Dappium.avd=name_of_the_AVD` where AVD is the name of your Android Virtual Device (e.g. `Nexus_5X_API_27`)
-
**Tips & tricks:**
* If the AVD name contains any spaces, you need to replace them with underscores when specifying the `-Dappium.avd=...`.
* It's probable that a freshly created device will contain an outdated Chrome version. To update to the latest version (without using the Play Store) you need to download an `.apk` for Chrome and install it with `adb install -r path/to/chrome.apk`.
* Chrome on Android uses ChromeDriver similarly to regular desktop Chrome. The ChromeDriver is bundled with the Appium server. To use a newer ChromeDriver please follow the [Appium documentation](http://appium.io/docs/en/writing-running-appium/web/chromedriver/).
-#### Apple Safari on iOS
-* **Supported test modules:** `base-ui`
-* **Supported host OS:** macOS
-* **Supported browser version:** _depends on the mobile OS version_
-* **Supported mobile OS version:** iOS 11.x
-* **Run with:** `mvn clean test -Pios -Dappium.deviceName=device_name` where the device name is your device identification (e.g. `iPhone X`)
-
## Disabling TLS (SSL) in the tests
All tests are executed with TLS by default. In order to disable it, you need to switch the `auth.server.ssl.required` property off.
diff --git a/testsuite/integration-arquillian/README.md b/testsuite/integration-arquillian/README.md
index cc8e4b758f..c7467fea9f 100644
--- a/testsuite/integration-arquillian/README.md
+++ b/testsuite/integration-arquillian/README.md
@@ -110,15 +110,6 @@ UI testing is sometimes very tricky due to different demands and behaviours of d
The base testsuite contains custom Arquillian extensions and most functional tests.
The other test modules depend on this module.
-### Base UI Testsuite
-Contains most of the UI-focused tests that don't cover Admin Console, i.e. all the parts of the server that are intended to be accessed by an end user.
-The tests placed here are exclusively covering the UI functionality of the server, i.e. checking if all the page elements are visible, links clickable etc., and are focused on simplicity and stability.
-This differs them from other integration tests and Admin Console UI tests.
-
-They are designed to work with most of the desktop browsers (HtmlUnit included) as well as mobile browsers (Chrome on Android and Safari on iOS). Please see [HOW-TO-RUN.md](HOW-TO-RUN.md) for details on supported browsers.
-
-The tests are place in a separate module (`tests/other/base-ui`) and are disabled by default.
-
#### Types of adapter tests
1. Using *custom test servlets*
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/pom.xml b/testsuite/integration-arquillian/tests/other/base-ui/pom.xml
deleted file mode 100644
index 1ce0c878c4..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/pom.xml
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
- integration-arquillian-tests-other
- org.keycloak.testsuite
- 999.0.0-SNAPSHOT
-
- 4.0.0
-
- integration-arquillian-tests-base-ui
- Base UI TestSuite
-
-
- 600
- ${auth.server.home}/themes
-
-
-
-
-
- org.codehaus.mojo
- properties-maven-plugin
- 1.0.0
-
-
- process-resources
-
- read-project-properties
-
-
-
- ${testsuite.constants}
-
-
-
-
-
-
- maven-resources-plugin
-
-
- copy-theme-files
- process-resources
-
- copy-resources
-
-
- ${keycloak.theme.dir}
-
-
- src/main/resources/themes
- true
-
-
-
-
-
-
-
-
-
-
- maven-surefire-plugin
-
-
- ${keycloak.theme.dir}
-
-
-
-
-
-
-
-
-
- org.jboss.arquillian.extension
- arquillian-drone-appium-extension
- ${arquillian-drone.version}
-
-
- junit
- junit
- compile
-
-
- org.hamcrest
- hamcrest
- compile
-
-
-
-
-
-
- android
-
- appium
- android
- chrome
- doesn't matter
- Appium
- 10.0.2.2
-
-
-
-
- maven-enforcer-plugin
-
-
-
- enforce
-
-
-
-
- appium.avd
- \S+.*
-
-
- true
-
-
-
-
-
-
-
-
-
- ios
-
- appium
- ios
- safari
- XCUITest
- true
-
-
-
-
- maven-enforcer-plugin
-
-
-
- enforce
-
-
-
-
- appium.deviceName
- \S+.*
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ApplicationsPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ApplicationsPage.java
deleted file mode 100644
index 6826692394..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ApplicationsPage.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import org.keycloak.testsuite.util.UIUtils;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
-
-/**
- * @author Vaclav Muzikar
- */
-public class ApplicationsPage extends AbstractLoggedInPage {
- @FindBy(xpath = "//li[starts-with(@id,'application-client-id')]")
- private List applications;
-
- @Override
- public String getPageId() {
- return "applications";
- }
-
- public void toggleApplicationDetails(String clientId) {
- By selector = By.xpath("//button[@id='application-toggle-" + clientId + "']");
- waitUntilElement(selector).is().clickable();
- driver.findElement(selector).click();
- }
-
- public List getApplications() {
- ArrayList apps = new ArrayList<>();
- for(WebElement app : applications) {
- String clientId = app.getAttribute("id").replace("application-client-id-", "");
- apps.add(toRepresentation(app, clientId));
- }
- return apps;
- }
-
- private ClientRepresentation toRepresentation(WebElement app, String clientId) {
- String clientName = UIUtils.getTextFromElement(app.findElement(By.xpath("//div[@id='application-name-" + clientId + "']")));
- boolean userConsentRequired = !UIUtils.getTextFromElement(app.findElement(By.xpath("//div[@id='application-internal-" + clientId + "']"))).equals("Internal");
- boolean inUse = UIUtils.getTextFromElement(app.findElement(By.xpath("//div[@id='application-status-" + clientId + "']"))).equals("In use");
- boolean applicationDetailsVisible = app.findElement(By.xpath("//section[@id='application-expandable-" + clientId + "']")).isDisplayed();
- String effectiveURL = UIUtils.getTextFromElement(app.findElement(By.id("application-effectiveurl-" + clientId)));
- return new ClientRepresentation(clientId, clientName, userConsentRequired, inUse, effectiveURL, applicationDetailsVisible);
- }
-
- public class ClientRepresentation {
- private final String clientId;
- private final String clientName;
- private final boolean userConsentRequired;
- private final boolean inUse;
- private final String effectiveUrl;
- private final boolean applicationDetailsVisible;
-
- public ClientRepresentation(String clientId, String clientName, boolean userConsentRequired, boolean inUse, String effectiveUrl, boolean applicationDetailsVisible) {
- this.clientId = clientId;
- this.clientName = clientName;
- this.userConsentRequired = userConsentRequired;
- this.inUse = inUse;
- this.effectiveUrl = effectiveUrl;
- this.applicationDetailsVisible = applicationDetailsVisible;
- }
-
- public String getClientId() {
- return clientId;
- }
-
- public String getClientName() {
- return clientName;
- }
-
- public boolean isUserConsentRequired() {
- return userConsentRequired;
- }
-
- public boolean isInUse() {
- return inUse;
- }
-
- public String getEffectiveUrl() {
- return effectiveUrl;
- }
-
- public boolean isApplicationDetailsVisible() {
- return applicationDetailsVisible;
- }
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/DeviceActivityPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/DeviceActivityPage.java
deleted file mode 100644
index 64016cd6db..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/DeviceActivityPage.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import org.openqa.selenium.By;
-import org.openqa.selenium.NoSuchElementException;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import static org.keycloak.testsuite.util.UIUtils.clickLink;
-import static org.keycloak.testsuite.util.UIUtils.getTextFromElement;
-import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
-
-/**
- * @author Vaclav Muzikar
- */
-public class DeviceActivityPage extends AbstractLoggedInPage {
- @FindBy(id = "sign-out-all")
- private WebElement signOutAllBtn;
-
- @FindBy(className = "signed-in-device-grid")
- private List sessions;
-
- @Override
- public String getPageId() {
- return "device-activity";
- }
-
- @Override
- public String getParentPageId() {
- return ACCOUNT_SECURITY_ID;
- }
-
- public boolean isSignOutAllDisplayed() {
- return isElementVisible(signOutAllBtn);
- }
-
- public void clickSignOutAll() {
- clickLink(signOutAllBtn);
- }
-
- public int getSessionsCount() {
- return sessions.size();
- }
-
- public Optional getSessionByIndex(int index) {
- try {
- return Optional.of(new Session(sessions.get(index)));
- } catch (Exception e) {
- log.warn(e.getMessage());
- return Optional.empty();
- }
- }
-
- public Optional getSession(String sessionId) {
- try {
- return Optional.of(new Session(getSessionElement(sessionId)));
- } catch (Exception e) {
- log.warn(e.getMessage());
- return Optional.empty();
- }
- }
-
- private WebElement getSessionElement(String sessionId) {
- return sessions.stream()
- .filter(f -> getTrimmedSessionId(sessionId).equals(getSessionId(f)))
- .findFirst()
- .orElse(null);
- }
-
- private static String getSessionId(WebElement sessionElement) {
- if (sessionElement == null) return null;
- return sessionElement.getAttribute("id").split("-")[1]; // the id looks like session-71891504-item
- }
-
- public static String getTrimmedSessionId(String fullSessionId) {
- return fullSessionId.substring(0, 7);
- }
-
- // We cannot use standard Page Fragment as there's no root element. Even though the sessions are placed in rows,
- // there's no element that would encapsulate it. Hence we cannot simply use e.g. @FindBy annotations.
- public class Session {
- private static final String SESSION = "session";
- private static final String DEVICE_ICON = "device-icon";
- private static final String IP = "ip";
- private static final String SIGN_OUT = "sign-out";
-
- private final WebElement element;
- private final String sessionId;
-
- // we don't want Session to be instantiated outside DeviceActivityPage
- private Session(WebElement element) {
- this.element = element;
- this.sessionId = DeviceActivityPage.getSessionId(element);
- }
-
- public String getSessionId() {
- return sessionId;
- }
-
- public boolean isPresent() {
- return isItemDisplayed(IP); // no root element hence this workaround
- }
-
- public String getIcon() {
- final WebElement icon = (WebElement) Optional.ofNullable(element.findElement(By.className(DEVICE_ICON)))
- .map(f -> (WebElement) f)
- .map(f -> f.findElement(By.tagName("svg")))
- .orElse(null);
-
- if (icon == null) return "";
- return icon.getAttribute("id").split("-")[3]; // the id looks like session-71891504-icon-desktop
- }
-
- public String getIp() {
- return getTextFromItem(IP);
- }
-
- public boolean hasCurrentBadge() {
- return isItemDisplayed("current-badge");
- }
-
- public boolean isBrowserDisplayed() {
- return !"".equals(getBrowser());
- }
-
- public String getTitle() {
- return getTextFromElement(element.findElement(By.className("session-title")));
- }
-
- public String getBrowser() {
- try {
- return getTitle().split("/", 2)[1].trim();
- } catch (Exception e) {
- return "";
- }
- }
-
- public String getLastAccess() {
- return getTextFromItem("last-access");
- }
-
- public String getClients() {
- return getTextFromItem("clients");
- }
-
- public String getStarted() {
- return getTextFromItem("started");
- }
-
- public String getExpires() {
- return getTextFromItem("expires");
- }
-
- public boolean isSignOutDisplayed() {
- return getSignOutButton() != null;
- }
-
- public void clickSignOut() {
- WebElement signOutButton = getSignOutButton();
- if (signOutButton != null) {
- clickLink(signOutButton);
- } else {
- log.warn("Cannot click sign out button; not present");
- }
- }
-
- private WebElement getSignOutButton() {
- try {
- return driver.findElement(By.xpath(String.format("//button[@id='%s']", getFullItemId(SIGN_OUT))));
- } catch (NoSuchElementException e) {
- return null;
- }
- }
-
- private String getFullItemId(String itemId) {
- return String.format("%s-%s-%s", SESSION, sessionId, itemId);
- }
-
- private WebElement getItemElement(String itemId) {
- return element.findElement(By.id(getFullItemId(itemId)));
- }
-
- private String getTextFromItem(String itemId) {
- return getTextFromElement(getItemElement(itemId).findElement(By.tagName("div")));
- }
-
- private boolean isItemDisplayed(String itemId) {
- try {
- return getItemElement(itemId).isDisplayed();
- } catch (NoSuchElementException e) {
- return false;
- }
- }
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ForbiddenPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ForbiddenPage.java
deleted file mode 100644
index 107750a5cb..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/ForbiddenPage.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-/**
- * @author Vaclav Muzikar
- */
-public class ForbiddenPage extends AbstractLoggedInPage {
- @FindBy(tagName = "main")
- private WebElement mainTag;
-
- @Override
- public String getPageId() {
- return "forbidden";
- }
-
- @Override
- public boolean isCurrent() {
- return mainTag.getText().contains("You do not have access rights to this request.");
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/LinkedAccountsPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/LinkedAccountsPage.java
deleted file mode 100644
index 45b7871017..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/LinkedAccountsPage.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import org.jboss.arquillian.graphene.Graphene;
-import org.jboss.arquillian.graphene.fragment.Root;
-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.getTextFromElement;
-import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
-import static org.openqa.selenium.By.id;
-import static org.openqa.selenium.By.xpath;
-
-/**
- * @author Vaclav Muzikar
- */
-public class LinkedAccountsPage extends AbstractLoggedInPage {
- public static final String LINKED_ACCOUNTS_ID = "linked-accounts";
- public static final String LINKED_IDPS_LIST_ID = "linked-idps";
- public static final String UNLINKED_IDPS_LIST_ID = "unlinked-idps";
-
- @FindBy(id = LINKED_IDPS_LIST_ID)
- private List linkedIdPsList;
-
- @FindBy(id = UNLINKED_IDPS_LIST_ID)
- private List unlinkedIdPsList;
-
- @Override
- public String getPageId() {
- return LINKED_ACCOUNTS_ID;
- }
-
- @Override
- public String getParentPageId() {
- return ACCOUNT_SECURITY_ID;
- }
-
- public IdentityProvider getProvider(String providerAlias) {
- WebElement root = driver.findElement(id(providerAlias + "-idp"));
- return Graphene.createPageFragment(IdentityProvider.class, root);
- }
-
- public int getLinkedProvidersCount() {
- return linkedIdPsList.size();
- }
-
- public int getUnlinkedProvidersCount() {
- return unlinkedIdPsList.size();
- }
-
- public class IdentityProvider {
- @Root
- private WebElement root;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-name')]")
- private WebElement nameElement;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-icon')]")
- private WebElement iconElement;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-label')]")
- private WebElement badgeElement;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-username')]")
- private WebElement usernameElement;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-link')]")
- private WebElement linkBtn;
-
- @FindBy(xpath = ".//*[contains(@id,'idp-unlink')]")
- private WebElement unlinkBtn;
-
- public boolean isLinked() {
- String parentListId = root.findElement(xpath("ancestor::ul")).getAttribute("id");
-
- if (parentListId.equals(LINKED_IDPS_LIST_ID)) {
- return true;
- }
- else if (parentListId.equals(UNLINKED_IDPS_LIST_ID)) {
- return false;
- }
- else {
- throw new IllegalStateException("Unexpected parent list ID: " + parentListId);
- }
- }
-
- public boolean hasSocialLoginBadge() {
- return getTextFromElement(badgeElement).equals("Social login");
- }
-
- public boolean hasSystemDefinedBadge() {
- return getTextFromElement(badgeElement).equals("System defined");
- }
-
- public boolean hasSocialIcon() {
- return iconElement.getAttribute("id").contains("social");
- }
-
- public boolean hasDefaultIcon() {
- return iconElement.getAttribute("id").contains("default");
- }
-
- public String getUsername() {
- return getTextFromElement(usernameElement);
- }
-
- public boolean isLinkBtnVisible() {
- return isElementVisible(linkBtn);
- }
-
- public boolean isUnlinkBtnVisible() {
- return isElementVisible(unlinkBtn);
- }
-
- public void clickLinkBtn() {
- clickLink(linkBtn);
- }
-
- public void clickUnlinkBtn() {
- clickLink(unlinkBtn);
- }
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/MyResourcesPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/MyResourcesPage.java
deleted file mode 100644
index 0d6bbaa8d1..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/MyResourcesPage.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package org.keycloak.testsuite.ui.account3.page;
-
-import org.keycloak.testsuite.util.UIUtils;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.jboss.arquillian.graphene.Graphene.waitGui;
-import static org.junit.Assert.assertEquals;
-import static org.keycloak.testsuite.util.UIUtils.clickLink;
-
-public class MyResourcesPage extends AbstractLoggedInPage {
-
- @FindBy(xpath = "//ul[@id='resourcesList']/li")
- private List resourcesList;
-
- @FindBy(id = "refresh-page")
- private WebElement refreshButton;
-
- @Override
- public String getPageId() {
- return "resources";
- }
-
- public int getResourcesListCount() {
- return resourcesList.size();
- }
-
- public void clickRefreshButton() {
- clickLink(refreshButton);
- }
-
- public void clickExpandButton(int row) {
- driver.findElement(By.id("resourceToggle-" + row)).click();
- waitGui().until().element(By.id("ex-expand" + row)).is().visible();
- }
-
- public void clickCollapseButton(int row) {
- driver.findElement(By.id("resourceToggle-" + row)).click();
- waitGui().until().element(By.id("ex-expand" + row)).is().not().visible();
- }
-
- public String getCellText(String cell, int row) {
- return getCell(cell, row).getText();
- }
-
- public String getCellHref(String cell, int row) {
- return getCell(cell, row).findElement(By.tagName("a")).getAttribute("href");
- }
-
- private WebElement getCell(String cell, int row) {
- final String name = Character.toUpperCase(cell.charAt(0)) + cell.substring(1);
- return driver.findElement(By.id(String.format("resource%s-%d", name, row)));
- }
-
- public String getSharedWith(int row) {
- final WebElement element = driver.findElement(By.id("shared-with-user-message-" + row));
- return element.getText();
- }
-
- public void clickShareButton(int row) {
- driver.findElement(By.id("share-" + row)).click();
- waitForModalFadeIn();
- }
-
- public void clickEditButton(int row) {
- final WebElement webElement = driver.findElement(By.id("action-menu-" + row));
- webElement.click();
- webElement.findElement(By.id("edit-" + row)).click();
- waitForModalFadeIn();
- }
-
- public String getEditDialogUsername(int row) {
- return driver.findElement(By.id("username-" + row)).getAttribute("value");
- }
-
- public void clickRemoveButton(int row) {
- final WebElement webElement = driver.findElement(By.id("action-menu-" + row));
- webElement.click();
- webElement.findElement(By.id("remove-" + row)).click();
- }
-
- public String getPendingRequestRequestor(int row) {
- return driver.findElement(By.id("requestor" + row)).getText();
- }
-
- public String getPendingRequestPermissions(int row) {
- return driver.findElement(By.id("permissions" + row)).getText();
- }
-
- private WebElement getPendingRequest(String resourceName) {
- return driver.findElement(By.id("shareRequest-" + resourceNameToId(resourceName)));
- }
-
- public String getPendingRequestText(String resourceName) {
- return getPendingRequest(resourceName).getText();
- }
-
- public void clickPendingRequest(String resourceName) {
- getPendingRequest(resourceName).click();
- }
-
- public void acceptRequest(String resourceName, int row) {
- clickApproveDenyButton(resourceName, row, true);
- }
-
- public void denyRequest(String resourceName, int row) {
- clickApproveDenyButton(resourceName, row, false);
- }
-
- private void clickApproveDenyButton(String resourceName, int row, boolean approve) {
- final By id = By.id(String.format("%s-%d-shareRequest-%s", approve ? "accept" : "deny", row, resourceNameToId(resourceName)));
- driver.findElement(id).click();
- waitForModalFadeOut();
- }
-
- private String resourceNameToId(String resourceName) {
- return resourceName.replace(" ", "-");
- }
-
- public void clickSignOut() {
- driver.findElement(By.id("signOutButton")).click();
- }
-
- public void clickNextPage() {
- final WebElement webElement = driver.findElements(By.className("pf-m-primary")).get(1);
- assertEquals("Next>", webElement.getText());
- webElement.click();
- }
-
- public void clickSharedWithMeTab() {
- final WebElement sharedWithMe = driver.findElement(By.id("pf-tab-1-sharedwithMe"));
- sharedWithMe.click();
-
- final WebElement tab = sharedWithMe.findElement(By.xpath("./.."));
- //test to see that the tab is really clicked
- assertEquals("pf-v5-c-tabs__item pf-m-current", tab.getAttribute("class"));
- }
-
- public boolean containsResource(String resourceName) {
- return driver.findElement(By.id("sharedResourcesList")).getText().contains(resourceName);
- }
-
- public void createShare(String userName) {
- driver.findElement(By.id("username")).sendKeys(userName);
- driver.findElement(By.id("add")).click();
- driver.findElement(By.className("pf-v5-c-select__toggle-typeahead")).click();
- driver.findElement(By.xpath("//button[@class='pf-v5-c-select__menu-item' and text()='Scope A']")).click();
- driver.findElement(By.id("done")).click();
- waitForModalFadeOut();
- }
-
- public void removeAllPermissions() {
- assertThat(getScopesTexts(), containsInAnyOrder("Scope A", "Scope B"));
- driver.findElement(By.className("pf-v5-c-select__toggle-clear")).click();
- driver.findElement(By.id("save-0")).click();
- driver.findElement(By.id("done")).click();
- waitForModalFadeOut();
- }
-
- private List getScopesTexts() {
- return driver.findElements(By.xpath("//span[contains(@id,'pf-random-id-')]"))
- .stream()
- .filter(Objects::nonNull)
- .map(UIUtils::getTextFromElement)
- .collect(Collectors.toList());
- }
-
- private void waitForModalFadeIn() {
- waitGui().until().element(By.className("pf-v5-c-modal-box")).is().present();
- }
-
- private void waitForModalFadeOut() {
- waitGui().until().element(By.className("pf-v5-c-backdrop")).is().not().present();
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PageNotFound.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PageNotFound.java
deleted file mode 100644
index 2c2f103742..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PageNotFound.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-/**
- * @author Vaclav Muzikar
- */
-public class PageNotFound extends AbstractLoggedInPage {
- @Override
- public String getPageId() {
- return "some-nonexisting-id";
- }
-
- @Override
- public boolean isCurrent() {
- return driver.getPageSource().contains("Page not found");
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PersonalInfoPage.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PersonalInfoPage.java
deleted file mode 100644
index 7f1006541a..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/PersonalInfoPage.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.keycloak.testsuite.util.UIAssert.assertElementDisabled;
-import static org.keycloak.testsuite.util.UIAssert.assertInputElementValid;
-import static org.keycloak.testsuite.util.UIUtils.clickLink;
-import static org.keycloak.testsuite.util.UIUtils.getTextInputValue;
-import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
-import static org.keycloak.testsuite.util.UIUtils.setTextInputValue;
-
-import org.keycloak.representations.idm.UserRepresentation;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-import org.openqa.selenium.support.ui.Select;
-
-/**
- * @author Vaclav Muzikar
- */
-public class PersonalInfoPage extends AbstractLoggedInPage {
- @FindBy(id = "user-name")
- private WebElement username;
- @FindBy(id = "email-address")
- private WebElement email;
- @FindBy(id = "first-name")
- private WebElement firstName;
- @FindBy(id = "last-name")
- private WebElement lastName;
- @FindBy(id = "locale-select")
- private Select localeSelector;
- @FindBy(id = "save-btn")
- private WebElement saveBtn;
- @FindBy(id = "cancel-btn")
- private WebElement cancelBtn;
- @FindBy(id = "delete-account")
- private WebElement deleteAccountSection;
- @FindBy(id = "update-email-btn")
- private WebElement updateEmailLink;
-
- @Override
- public String getPageId() {
- return "/";
- }
-
- public void assertUsernameDisabled(boolean expected) {
- assertEquals(isUsernameDisabled(), expected);
- }
-
- public boolean isUsernameDisabled() {
- return isElementDisabled(username);
- }
-
- public boolean isEmailDisabled() {
- return isElementDisabled(email);
- }
-
- private boolean isElementDisabled(WebElement element) {
- return element.getAttribute("readonly") != null || element.getAttribute("disabled") != null;
- }
-
- public String getUsername() {
- return getTextInputValue(username);
- }
-
- public void setUsername(String value) {
- setTextInputValue(username, value);
- }
-
- public void assertUsernameValid(boolean expected) {
- assertInputElementValid(expected, username);
- }
-
- public String getEmail() {
- return getTextInputValue(email);
- }
-
- public void setEmail(String value) {
- setTextInputValue(email, value);
- }
-
- public void assertEmailValid(boolean expected) {
- assertInputElementValid(expected, email);
- }
-
- public void assertUpdateEmailLinkVisible(boolean expected){
- if (updateEmailLink == null) {
- assertFalse(expected);
- return;
- }
- assertEquals(expected, isElementVisible(updateEmailLink));
- }
-
- public void clickUpdateEmailLink(){
- clickLink(updateEmailLink);
- }
-
- public String getFirstName() {
- return getTextInputValue(firstName);
- }
-
- public void setFirstName(String value) {
- setTextInputValue(firstName, value);
- }
-
- public void assertFirstNameValid(boolean expected) {
- assertInputElementValid(expected, firstName);
- }
-
- public String getLastName() {
- return getTextInputValue(lastName);
- }
-
- public void setLastName(String value) {
- setTextInputValue(lastName, value);
- }
-
- public void assertLastNameValid(boolean expected) {
- assertInputElementValid(expected, lastName);
- }
-
- public void assertSaveDisabled(boolean expected) {
- assertElementDisabled(expected, saveBtn);
- }
-
- public void assertDeleteAccountSectionVisible(boolean expected) {
- if (deleteAccountSection == null) {
- assertFalse(expected);
- return;
- }
- assertEquals(expected, isElementVisible(deleteAccountSection));
- }
-
- public void clickSave() {
- clickSave(true);
- }
-
- public void clickSave(boolean assertAlert) {
- saveBtn.click();
- if (assertAlert) {
- alert().assertIsDisplayed();
- }
- }
-
- public void clickCancel() {
- cancelBtn.click();
- }
-
- public void clickOpenDeleteExapandable() {
- clickLink(driver.findElement(By.cssSelector(".pf-c-expandable-section__toggle")));
- }
-
- public void clickDeleteAccountButton() {
- clickLink(driver.findElement(By.id("delete-account-btn")));
- }
-
- public void setValues(UserRepresentation user, boolean includeUsername) {
- if (includeUsername) {
- setUsername(user.getUsername());
- }
- if (!isEmailDisabled()) {
- 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());
- }
-
- public void selectLocale(String customLocale) {
- localeSelector.selectByValue(customLocale);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/WelcomeScreen.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/WelcomeScreen.java
deleted file mode 100644
index 667dba8ffc..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/WelcomeScreen.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2019 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.account3.page;
-
-import org.keycloak.testsuite.ui.account3.page.fragment.WelcomeScreenHeader;
-import org.keycloak.testsuite.util.URLUtils;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import jakarta.ws.rs.core.UriBuilder;
-
-import static org.keycloak.testsuite.util.UIAssert.assertElementVisible;
-import static org.keycloak.testsuite.util.UIUtils.clickLink;
-import static org.keycloak.testsuite.util.UIUtils.getTextFromElement;
-import static org.keycloak.testsuite.util.UIUtils.isElementVisible;
-
-/**
- * @author Vaclav Muzikar
- */
-public class WelcomeScreen extends AbstractAccountPage {
- public static final String ROOT_ELEMENT_ID = "welcomeScreen";
-
- @FindBy(id = ROOT_ELEMENT_ID)
- private WebElement welcomeScreenRoot;
-
- @FindBy(xpath = "//*[@id='" + ROOT_ELEMENT_ID + "']//header")
- private WelcomeScreenHeader header;
-
- @FindBy(xpath = "//a[@id='landing-personal-info']")
- private WebElement personalInfoLink;
- @FindBy(xpath = "//*[@id='landingChangePasswordLink']/a")
- private WebElement changePasswordLink;
- @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 = "//a[@id='landing-applications']")
- private WebElement applicationsLink;
- @FindBy(id = "landing-resources")
- private WebElement myResourcesCard;
- @FindBy(xpath = "//a[@id='landing-resources']")
- private WebElement myResourcesLink;
- @FindBy(id = "landingLogo")
- private WebElement logoLink;
-
- @FindBy(id = "landingWelcomeMessage")
- private WebElement welcomeMessage; // used only for i18n testing
-
- private String referrer;
- private String referrerUri;
-
- @Override
- public boolean isCurrent() {
- return URLUtils.currentUrlEquals(toString() + "#/") && isElementVisible(welcomeScreenRoot); // the hash will be eventually added after the page is loaded
- }
-
- @Override
- public UriBuilder getUriBuilder() {
- UriBuilder uriBuilder = super.getUriBuilder();
- if (referrer != null) {
- uriBuilder.queryParam("referrer", referrer);
- }
- if (referrerUri != null) {
- uriBuilder.queryParam("referrer_uri", referrerUri);
- }
- return uriBuilder;
- }
-
- public WelcomeScreenHeader header() {
- return header;
- }
-
- public void clickLogoImage() {
- clickLink(logoLink);
- }
-
- public void clickPersonalInfoLink() {
- clickLink(personalInfoLink);
- }
-
- public void clickChangePasswordLink() {
- clickLink(changePasswordLink);
- }
-
- public void clickAuthenticatorLink() {
- clickLink(authenticatorLink);
- }
-
- public void clickDeviceActivityLink() {
- clickLink(deviceActivityLink);
- }
-
- public void assertLinkedAccountsLinkVisible(boolean expected) {
- assertElementVisible(expected, linkedAccountsLink);
- }
-
- public void clickLinkedAccountsLink() {
- clickLink(linkedAccountsLink);
- }
-
- public void clickApplicationsLink() {
- clickLink(applicationsLink);
- }
-
- public void assertMyResourcesCardVisible(boolean expected) {
- assertElementVisible(expected, myResourcesCard);
- }
-
- public void clickMyResourcesLink() {
- clickLink(myResourcesLink);
- }
-
- public String getWelcomeMessage() {
- return getTextFromElement(welcomeMessage);
- }
-
- public void navigateTo(String referrer, String referrerUri) {
- this.referrer = referrer;
- this.referrerUri = referrerUri;
- navigateTo();
- this.referrer = null;
- this.referrerUri = null;
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/WelcomeScreenHeader.java b/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/WelcomeScreenHeader.java
deleted file mode 100644
index b49b686bf2..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/WelcomeScreenHeader.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2019 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.account3.page.fragment;
-
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import static org.keycloak.testsuite.util.UIUtils.clickLink;
-import static org.keycloak.testsuite.util.UIUtils.getTextFromElement;
-
-/**
- * @author Vaclav Muzikar
- */
-public class WelcomeScreenHeader extends AbstractHeader {
- @FindBy(id = "landingSignOutButton")
- private WebElement logoutBtn;
- @FindBy(id = "landingSignOutLink")
- private WebElement logoutBtnMobile;
-
- @FindBy(id = "landingSignInButton")
- private WebElement loginBtn;
- @FindBy(id = "landingSignInLink")
- private WebElement loginBtnMobile;
-
- @FindBy(xpath = "//*[@id='landing-locale-dropdown']/button")
- private WebElement localeBtn;
- @FindBy(id = "landing-mobile-local-toggle")
- private WebElement localeBtnMobile;
-
- @FindBy(id = "landingReferrerLink")
- private WebElement referrerLink;
- @FindBy(id = "landingMobileReferrerLink")
- private WebElement referrerLinkMobile;
-
- @FindBy(id = "landingMobileDropdown")
- private WebElement mobileKebab;
-
- @FindBy(id = "landingLoggedInUser")
- private WebElement toolbarLoggedInUser;
-
- @Override
- public void clickOptions() {
- clickLink(mobileKebab);
- }
-
- public void clickLoginBtn() {
- clickToolsBtn(isMobileLayout() ? loginBtnMobile : loginBtn);
- }
-
- public void assertLoginBtnVisible(boolean expected) {
- assertToolsBtnVisible(expected, isMobileLayout() ? loginBtnMobile : loginBtn);
- }
-
- @Override
- protected WebElement getLogoutBtn() {
- return isMobileLayout() ? logoutBtnMobile : logoutBtn;
- }
-
- @Override
- protected WebElement getReferrerLink() {
- return isMobileLayout() ? referrerLinkMobile : referrerLink;
- }
-
- @Override
- protected String getLocaleElementIdPrefix() {
- return "landing-" + super.getLocaleElementIdPrefix();
- }
-
- public String getToolbarLoggedInUser() {
- return getTextFromElement(toolbarLoggedInUser);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_en.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_en.properties
deleted file mode 100644
index ccf4342cde..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_en.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-locale_test=Přísný jazyk
-client_localized-client=Přespříliš lokalizovaný klient
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_test.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_test.properties
deleted file mode 100644
index b2cc17b5a0..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/messages/messages_test.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-locale_test=Přísný jazyk
-accountManagementWelcomeMessage=Vítejte v Keycloaku
-personalInfoHtmlTitle=Osobní údaje
\ No newline at end of file
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
deleted file mode 100644
index 2451176af7..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme-preview/account/theme.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-parent=${theme-default-name}.v2
-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/account/messages/messages_en.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/messages/messages_en.properties
deleted file mode 100644
index ccf4342cde..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/messages/messages_en.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-locale_test=Přísný jazyk
-client_localized-client=Přespříliš lokalizovaný klient
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/messages/messages_test.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/messages/messages_test.properties
deleted file mode 100644
index b2cc17b5a0..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/messages/messages_test.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-locale_test=Přísný jazyk
-accountManagementWelcomeMessage=Vítejte v Keycloaku
-personalInfoHtmlTitle=Osobní údaje
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/theme.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/theme.properties
deleted file mode 100644
index 39e87c7462..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/account/theme.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-parent=${theme-default-name}
-locales=en,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/email/messages/messages_en.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/messages/messages_en.properties
deleted file mode 100644
index fc49db6b0a..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/messages/messages_en.properties
+++ /dev/null
@@ -1 +0,0 @@
-locale_test=Přísný jazyk
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/messages/messages_test.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/messages/messages_test.properties
deleted file mode 100644
index 0eda2dc94c..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/messages/messages_test.properties
+++ /dev/null
@@ -1 +0,0 @@
-locale_test=Přísný jazyk
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/theme.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/theme.properties
deleted file mode 100644
index 39e87c7462..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/email/theme.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-parent=${theme-default-name}
-locales=en,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/messages/messages_en.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/messages/messages_en.properties
deleted file mode 100644
index fc49db6b0a..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/messages/messages_en.properties
+++ /dev/null
@@ -1 +0,0 @@
-locale_test=Přísný jazyk
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/messages/messages_test.properties b/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/messages/messages_test.properties
deleted file mode 100644
index 555e51305d..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/messages/messages_test.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-locale_test=Přísný jazyk
-termsText=[TEST LOCALE] souhlas s podmínkami
-notMatchPasswordMessage=[TEST LOCALE] hesla se neshodují
-firstName=[TEST LOCALE] křestní jméno
-updateProfileMessage=[TEST LOCALE] aktualizovat profil
-verifyEmailMessage=[TEST LOCALE] je třeba ověřit emailovou adresu
-invalidTotpMessage=[TEST LOCALE] vložen chybný kód
-oauthGrantTitle=[TEST LOCALE] Udělit přístup {0}
-rememberMe=[TEST LOCALE] Zapamatuj si mě
-invalidUserMessage=[TEST LOCALE] Chybné jméno nebo heslo
-emailForgotTitle=[TEST LOCALE] Zapomenuté heslo
\ 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
deleted file mode 100644
index e7000c22a1..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/resources/themes/localized-theme/login/theme.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-parent=${theme-default-name}
-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/AbstractUiTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java
deleted file mode 100644
index 6a2f8152f2..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/AbstractUiTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.AbstractAuthTest;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.junit.Assume.assumeFalse;
-
-/**
- * @author Vaclav Muzikar
- */
-public abstract class AbstractUiTest extends AbstractAuthTest {
- public static final String LOCALIZED_THEME = "localized-theme";
- public static final String LOCALIZED_THEME_PREVIEW = "localized-theme-preview";
- public static final String CUSTOM_LOCALE = "test";
- public static final String CUSTOM_LOCALE_NAME = "Přísný jazyk";
- public static final String DEFAULT_LOCALE="en";
- public static final String DEFAULT_LOCALE_NAME = "English";
- public static final String LOCALE_CLIENT_NAME = "${client_localized-client}";
- public static final String LOCALE_CLIENT_NAME_LOCALIZED = "Přespříliš lokalizovaný klient";
-
- @BeforeClass
- public static void assumeSupportedBrowser() {
- assumeFalse("Browser must not be htmlunit", System.getProperty("browser").equals("htmlUnit"));
- assumeFalse("Browser must not be PhantomJS", System.getProperty("browser").equals("phantomjs"));
- }
-
- @Before
- public void addTestUser() {
- createTestUserWithAdminClient(false);
- }
-
- protected boolean isAccountPreviewTheme() {
- return false;
- }
-
- protected void configureInternationalizationForRealm(RealmRepresentation realm) {
- final String localizedTheme = isAccountPreviewTheme() ? LOCALIZED_THEME_PREVIEW : LOCALIZED_THEME;
-
- // fetch the supported locales for the special test theme that includes some fake test locales
- Set supportedLocales = adminClient.serverInfo().getInfo().getThemes().get("login").stream()
- .filter(x -> x.getName().equals(LOCALIZED_THEME))
- .flatMap(x -> Arrays.stream(x.getLocales()))
- .collect(Collectors.toSet());
-
- realm.setInternationalizationEnabled(true);
- realm.setSupportedLocales(supportedLocales);
- realm.setLoginTheme(LOCALIZED_THEME);
- realm.setAccountTheme(localizedTheme);
- 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/account3/AbstractAccountTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/AbstractAccountTest.java
deleted file mode 100644
index 33a74f7caa..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/AbstractAccountTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.keycloak.common.Profile;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
-import org.keycloak.testsuite.ui.AbstractUiTest;
-import org.keycloak.testsuite.ui.account3.page.PageNotFound;
-import org.keycloak.testsuite.ui.account3.page.WelcomeScreen;
-
-import java.time.format.DateTimeFormatter;
-import java.util.List;
-import java.util.Locale;
-
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
-
-/**
- * @author Vaclav Muzikar
- */
-public abstract class AbstractAccountTest extends AbstractUiTest {
- public static final String ACCOUNT_THEME_NAME_KC = "keycloak.v2";
- public static final DateTimeFormatter DEFAULT_TIME_FORMATTER = DateTimeFormatter.ofPattern("MMMM d, yyyy 'at' h:mm a", Locale.ENGLISH);
-
- @Page
- protected WelcomeScreen accountWelcomeScreen;
-
- @Page
- protected PageNotFound pageNotFound;
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation testRealmRep = testRealms.get(0);
- testRealmRep.setAccountTheme(getAccountThemeName());
- }
-
- @Before
- public void navigateBeforeTest() {
- accountWelcomeScreen.navigateTo();
- }
-
- @Override
- protected boolean isAccountPreviewTheme() {
- return true;
- }
-
- protected void loginToAccount() {
- assertCurrentUrlStartsWithLoginUrlOf(accountWelcomeScreen);
- loginPage.form().login(testUser);
- }
-
- protected String getAccountThemeName() {
- return ACCOUNT_THEME_NAME_KC;
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ApplicationsTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ApplicationsTest.java
deleted file mode 100644
index af444c0946..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ApplicationsTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.ApplicationsPage;
-import org.keycloak.testsuite.util.ClientBuilder;
-import org.keycloak.testsuite.util.OAuthClient;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.keycloak.testsuite.util.OAuthClient.APP_ROOT;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-
-/**
- * @author Vaclav Muzikar
- */
-public class ApplicationsTest extends BaseAccountPageTest {
- @Page
- private ApplicationsPage applicationsPage;
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return applicationsPage;
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation realm = testRealms.get(0);
-
- realm.setClients(Arrays.asList(
- ClientBuilder
- .create()
- .clientId("always-display-client")
- .id(KeycloakModelUtils.generateId())
- .name("Always Display Client")
- .baseUrl(APP_ROOT + "/always-display-client")
- .directAccessGrants()
- .secret("secret1")
- .alwaysDisplayInConsole(true)
- .build(),
- ClientBuilder
- .create()
- .clientId("third-party-client")
- .id(KeycloakModelUtils.generateId())
- .name("Third Party Client")
- .baseUrl(APP_ROOT + "/third-party-client")
- .directAccessGrants()
- .secret("secret1")
- .consentRequired(true)
- .build()
- ));
- }
-
- @Test
- public void applicationListTest() throws Exception {
- List applications = applicationsPage.getApplications();
- assertFalse(applications.isEmpty());
- Map apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
- assertThat(apps.keySet(), containsInAnyOrder("always-display-client", "account-console"));
- assertClientRep(apps.get("account-console"), "Account Console", false, true, getAuthServerRoot() + "realms/test/account/", false);
- assertClientRep(apps.get("always-display-client"), "Always Display Client", false, false, getAuthServerRoot() + "realms/master/app/always-display-client", false);
- }
-
- @Test
- public void toggleApplicationDetailsTest() throws Exception {
- applicationsPage.toggleApplicationDetails("account-console");
- List applications = applicationsPage.getApplications();
- assertFalse(applications.isEmpty());
- Map apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
- assertThat(apps.keySet(), containsInAnyOrder("always-display-client", "account-console"));
- assertClientRep(apps.get("account-console"), "Account Console", false, true, getAuthServerRoot() + "realms/test/account/", true);
- assertClientRep(apps.get("always-display-client"), "Always Display Client", false, false, getAuthServerRoot() + "realms/master/app/always-display-client", false);
-
- applicationsPage.toggleApplicationDetails("account-console");
- applications = applicationsPage.getApplications();
- assertFalse(applications.isEmpty());
- apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
- assertThat(apps.keySet(), containsInAnyOrder("always-display-client", "account-console"));
- assertClientRep(apps.get("account-console"), "Account Console", false, true, getAuthServerRoot() + "realms/test/account/", false);
- assertClientRep(apps.get("always-display-client"), "Always Display Client", false, false, getAuthServerRoot() + "realms/master/app/always-display-client", false);
- }
-
- private void assertClientRep(ApplicationsPage.ClientRepresentation clientRep, String name, boolean userConsentRequired, boolean inUse, String effectiveUrl, boolean applicationDetailsVisible) {
- assertNotNull(clientRep);
- assertEquals(name, clientRep.getClientName());
- assertEquals(userConsentRequired, clientRep.isUserConsentRequired());
- assertEquals(inUse, clientRep.isInUse());
- assertEquals(applicationDetailsVisible, clientRep.isApplicationDetailsVisible());
- if (applicationDetailsVisible) assertEquals(effectiveUrl, clientRep.getEffectiveUrl());
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/BaseAccountPageTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/BaseAccountPageTest.java
deleted file mode 100644
index 6035625cd2..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/BaseAccountPageTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.account3;
-
-import org.junit.Test;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * @author Vaclav Muzikar
- */
-public abstract class BaseAccountPageTest extends AbstractAccountTest {
- protected abstract AbstractLoggedInPage getAccountPage();
-
- @Override
- public void navigateBeforeTest() {
- getAccountPage().navigateTo();
- loginToAccount();
- getAccountPage().assertCurrent();
- }
-
- @Test
- public void navigationTest() {
- pageNotFound.navigateTo();
- pageNotFound.assertCurrent();
-
- getAccountPage().navigateToUsingSidebar();
- getAccountPage().assertCurrent();
-
- if (getAccountPage().getParentPageId() != null) {
- assertTrue("Nav bar subsection should be expanded after clicking nav item",
- getAccountPage().sidebar().isNavSubsectionExpanded(getAccountPage().getParentPageId()));
- }
- }
-
- protected void testModalDialog(Runnable triggerModal, Runnable onCancel) {
- SigningInPageUtils.testModalDialog(getAccountPage(), triggerModal, onCancel);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeleteAccountTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeleteAccountTest.java
deleted file mode 100644
index fa6e73e39d..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeleteAccountTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.events.EventType;
-import org.keycloak.models.AccountRoles;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.pages.PasswordPage;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.auth.page.login.DeleteAccountActionConfirmPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-
-import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
-
-/**
- * @author Zakaria Amine
- */
-public class DeleteAccountTest extends BaseAccountPageTest {
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private DeleteAccountActionConfirmPage deleteAccountActionConfirmPage;
-
- @Page
- private PasswordPage passwordPage;
-
- @Rule
- public AssertEvents events = new AssertEvents(this);
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return personalInfoPage;
- }
-
- @Before
- public void setup() {
- enableDeleteAccountRequiredAction();
- addDeleteAccountRoleToUserClientRoles();
- }
-
- @After
- public void clean() {
- disableDeleteAccountRequiredAction();
- }
-
- @Test
- public void deleteOwnAccountSectionNotVisibleWithoutClientRole() {
- removeDeleteAccountRoleFromUserClientRoles();
- refreshPageAndWaitForLoad();
- personalInfoPage.assertDeleteAccountSectionVisible(false);
- }
-
-
- @Test
- public void deleteOwnAccountSectionNotVisibleWithoutDeleteAccountActionEnabled() {
- disableDeleteAccountRequiredAction();
- refreshPageAndWaitForLoad();
- personalInfoPage.assertDeleteAccountSectionVisible(false);
- }
-
- @Test
- public void deleteOwnAccountAIACancellationSucceeds() {
- refreshPageAndWaitForLoad();
- personalInfoPage.assertDeleteAccountSectionVisible(true);
- personalInfoPage.clickOpenDeleteExapandable();
- personalInfoPage.clickDeleteAccountButton();
-
- reauthenticateUser();
-
- Assert.assertTrue(deleteAccountActionConfirmPage.isCurrent());
- deleteAccountActionConfirmPage.clickCancelAIA();
- Assert.assertTrue(personalInfoPage.isCurrent());
- }
-
- @Test
- public void deleteOwnAccountForbiddenWithoutClientRole() {
- refreshPageAndWaitForLoad();
- personalInfoPage.assertDeleteAccountSectionVisible(true);
- personalInfoPage.clickOpenDeleteExapandable();
- personalInfoPage.clickDeleteAccountButton();
-
- reauthenticateUser();
-
- Assert.assertTrue(deleteAccountActionConfirmPage.isCurrent());
- removeDeleteAccountRoleFromUserClientRoles();
- deleteAccountActionConfirmPage.clickConfirmAction();
- Assert.assertTrue(deleteAccountActionConfirmPage.isErrorMessageDisplayed());
- Assert.assertEquals(deleteAccountActionConfirmPage.getErrorMessageText(), "You do not have enough permissions to delete your own account, contact admin.");
- }
-
- @Test
- public void deleteOwnAccountSucceeds() {
- personalInfoPage.navigateTo();
- personalInfoPage.assertDeleteAccountSectionVisible(true);
- personalInfoPage.clickOpenDeleteExapandable();
- personalInfoPage.clickDeleteAccountButton();
-
- reauthenticateUser();
-
- deleteAccountActionConfirmPage.isCurrent();
- deleteAccountActionConfirmPage.clickConfirmAction();
- events.expectAccount(EventType.DELETE_ACCOUNT);
- Assert.assertTrue(testRealmResource().users().search(testUser.getUsername()).isEmpty());
- }
-
- private void reauthenticateUser() {
- passwordPage.assertCurrent();
- passwordPage.login("password");
- }
-
- private void addDeleteAccountRoleToUserClientRoles() {
- ApiUtil.assignClientRoles(testRealmResource(), testUser.getId(), "account",AccountRoles.DELETE_ACCOUNT);
- }
-
- private void disableDeleteAccountRequiredAction() {
- RequiredActionProviderRepresentation deleteAccount = testRealmResource().flows().getRequiredAction("delete_account");
- deleteAccount.setEnabled(false);
- testRealmResource().flows().updateRequiredAction("delete_account", deleteAccount);
- }
-
- private void enableDeleteAccountRequiredAction() {
- RequiredActionProviderRepresentation deleteAccount = testRealmResource().flows().getRequiredAction("delete_account");
- deleteAccount.setEnabled(true);
- testRealmResource().flows().updateRequiredAction("delete_account", deleteAccount);
- }
-
- private void removeDeleteAccountRoleFromUserClientRoles() {
- ClientRepresentation clientRepresentation = testRealmResource().clients().findByClientId("account").get(0);
- String deleteRoleId = testUserResource().roles().clientLevel(clientRepresentation.getId()).listAll().stream().filter(role -> Objects.equals(role.getName(), "delete-account")).findFirst().get().getId();
- RoleRepresentation deleteRole = new RoleRepresentation();
- deleteRole.setName("delete-account");
- deleteRole.setId(deleteRoleId);
- testUserResource().roles().clientLevel(clientRepresentation.getId()).remove(Arrays.asList(deleteRole));
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeviceActivityTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeviceActivityTest.java
deleted file mode 100644
index 177a5330ad..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/DeviceActivityTest.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.common.util.Time;
-import org.keycloak.models.ClientModel;
-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.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.DeviceActivityPage;
-import org.keycloak.testsuite.util.ClientBuilder;
-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;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.Matchers.either;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-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
- */
-public class DeviceActivityTest extends BaseAccountPageTest {
- public static final String TEST_CLIENT_ID = "test-client";
- public static final String TEST_CLIENT_SECRET = "top secret stuff";
- public static final String TEST_CLIENT2_ID = "test-client2";
- public static final String TEST_CLIENT2_SECRET = "even more top secret stuff";
- public static final String TEST_CLIENT3_ID = "test-client3";
- public static final String TEST_CLIENT3_SECRET = "dunno";
- public static final String TEST_CLIENT3_NAME = "Příliš žluťoučký kůň";
-
- @Page
- private DeviceActivityPage deviceActivityPage;
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return deviceActivityPage;
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation realm = testRealms.get(0);
-
- realm.setClients(Arrays.asList(
- ClientBuilder
- .create()
- .clientId(TEST_CLIENT_ID) // client with no name
- .secret(TEST_CLIENT_SECRET)
- .directAccessGrants()
- .build(),
- ClientBuilder
- .create().
- clientId(TEST_CLIENT2_ID)
- .name(LOCALE_CLIENT_NAME) // client with localized name
- .secret(TEST_CLIENT2_SECRET)
- .directAccessGrants().build(),
- ClientBuilder
- .create().
- clientId(TEST_CLIENT3_ID)
- .name(TEST_CLIENT3_NAME) // client without localized name
- .secret(TEST_CLIENT3_SECRET)
- .directAccessGrants().build()
-
- ));
-
- realm.setAccountTheme(LOCALIZED_THEME_PREVIEW); // using localized custom theme for the client localized name
- configureInternationalizationForRealm(testRealms.get(0));
- }
-
- @Before
- public void beforeDeviceActivityTest() {
- oauth.clientId(TEST_CLIENT3_ID);
- }
-
- @Test
- public void browsersTest() {
- Map browserSessions = new HashMap<>();
- Arrays.stream(Browsers.values()).forEach(b -> {
- browserSessions.put(b, DeviceActivityPage.getTrimmedSessionId(createSession(b)));
- });
-
- deviceActivityPage.clickRefreshPage();
-
- browserSessions.forEach((browser, sessionId) -> {
- final Optional session = deviceActivityPage.getSession(sessionId);
- assertThat(session.isPresent(), is(true));
- assertSession(browser, session.get());
- });
-
- assertEquals(Browsers.values().length + 1, deviceActivityPage.getSessionsCount()); // + 1 for the current session
- }
-
- @Test
- public void currentSessionTest() {
- createSession(Browsers.CHROME);
- createSession(Browsers.SAFARI);
-
- deviceActivityPage.clickRefreshPage();
-
- assertEquals(3, deviceActivityPage.getSessionsCount());
-
- Optional currentSession = deviceActivityPage.getSessionByIndex(0); // current session should be first
- assertThat(currentSession.isPresent(), is(true));
- assertSessionRowsAreNotEmpty(currentSession.get(), false);
- assertTrue("Browser identification should be present", currentSession.get().isBrowserDisplayed());
- assertTrue("Current session badge should be present", currentSession.get().hasCurrentBadge());
- assertFalse("Icon should be present", currentSession.get().getIcon().isEmpty());
- }
-
- @Test
- public void signOutTest() {
- assertFalse("Sign out all shouldn't be displayed", deviceActivityPage.isSignOutAllDisplayed());
- final String chromeSessionId = createSession(Browsers.CHROME);
- deviceActivityPage.clickRefreshPage();
-
- Optional chromeSessionOptional = deviceActivityPage.getSession(chromeSessionId);
- assertThat(chromeSessionOptional.isPresent(), is(true));
- DeviceActivityPage.Session chromeSession = chromeSessionOptional.get();
-
- createSession(Browsers.SAFARI);
- deviceActivityPage.clickRefreshPage();
-
- assertTrue("Sign out all should be displayed", deviceActivityPage.isSignOutAllDisplayed());
- assertEquals(3, testUserResource().getUserSessions().size());
-
- assertThat(testUserResource()
- .getUserSessions()
- .stream()
- .map(f -> f.getId())
- .map(DeviceActivityPage::getTrimmedSessionId)
- .collect(Collectors.toList()),
- hasItem(chromeSession.getSessionId()));
-
- // sign out one session
- assertThat(chromeSession.isSignOutDisplayed(), is(true));
- testModalDialog(chromeSession::clickSignOut, () -> {
- assertEquals(3, testUserResource().getUserSessions().size()); // no change, all sessions still present
- });
- deviceActivityPage.alert().assertSuccess();
- assertFalse("Chrome session should be gone", chromeSession.isPresent());
- assertEquals(2, testUserResource().getUserSessions().size());
- assertThat(testUserResource()
- .getUserSessions()
- .stream()
- .map(f -> f.getId())
- .map(DeviceActivityPage::getTrimmedSessionId)
- .collect(Collectors.toList()),
- not(hasItem(chromeSession.getSessionId())));
-
- // sign out all sessions
- testModalDialog(deviceActivityPage::clickSignOutAll, () -> {
- assertEquals(2, testUserResource().getUserSessions().size()); // no change
- });
- accountWelcomeScreen.assertCurrent();
- assertEquals(0, testUserResource().getUserSessions().size());
- }
-
- @Test
- public void clientsTest() {
- String sessionId = createSession(Browsers.CHROME);
-
- // attach more clients to the session
- testingClient.server().run(session -> {
- RealmModel realm = session.realms().getRealmByName(TEST);
- UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
-
- ClientModel client2 = session.clients().getClientByClientId(realm, TEST_CLIENT2_ID);
- ClientModel client3 = session.clients().getClientByClientId(realm, TEST_CLIENT3_ID);
-
- session.sessions().createClientSession(realm, client2, userSession);
- session.sessions().createClientSession(realm, client3, userSession);
- });
-
- deviceActivityPage.clickRefreshPage();
-
- List expectedClients = Arrays.asList(TEST_CLIENT_ID, LOCALE_CLIENT_NAME_LOCALIZED, TEST_CLIENT3_NAME);
-
- final Optional sessionById = deviceActivityPage.getSession(sessionId);
- assertThat(sessionById.isPresent(), is(true));
- String[] actualClients = sessionById.get().getClients().split(", ");
- assertThat(expectedClients, containsInAnyOrder(actualClients));
-
- final Optional session = deviceActivityPage.getSessionByIndex(0);
- assertThat(session.isPresent(), is(true));
- assertEquals("Account Console", session.get().getClients());
- }
-
- @Test
- public void timesTests() {
- LocalDateTime now = LocalDateTime.now();
- LocalDateTime nowPlus1 = now.plusMinutes(1);
- String nowStr = now.format(DEFAULT_TIME_FORMATTER);
- String nowStrPlus1 = nowPlus1.format(DEFAULT_TIME_FORMATTER);
-
- String sessionId = createSession(Browsers.CHROME);
-
- testingClient.server().run(session -> {
- RealmModel realm = session.realms().getRealmByName(TEST);
- UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
-
- userSession.setLastSessionRefresh(Time.currentTime() + 120);
- });
-
- deviceActivityPage.clickRefreshPage();
-
- final Optional session = deviceActivityPage.getSession(sessionId);
- assertThat(session.isPresent(), is(true));
-
- String startedAtStr = session.get().getStarted();
- LocalDateTime startedAt = LocalDateTime.parse(startedAtStr, DEFAULT_TIME_FORMATTER);
- LocalDateTime lastAccessed = LocalDateTime.parse(session.get().getLastAccess(), DEFAULT_TIME_FORMATTER);
- LocalDateTime expiresAt = LocalDateTime.parse(session.get().getExpires(), DEFAULT_TIME_FORMATTER);
-
- assertTrue("Last access should be after started at", lastAccessed.isAfter(startedAt));
- assertTrue("Expires at should be after last access", expiresAt.isAfter(lastAccessed));
- assertTrue("Last accessed should be in the future", lastAccessed.isAfter(now));
- assertThat(startedAtStr, either(equalTo(nowStr)).or(equalTo(nowStrPlus1)));
-
- int ssoLifespan = testRealmResource().toRepresentation().getSsoSessionMaxLifespan();
- 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 'um' H:mm", locale);
- Optional session = deviceActivityPage.getSession(sessionId);
- assertThat(session.isPresent(), is(true));
- try {
- LocalDateTime.parse(session.get().getLastAccess(), formatter);
- } catch (DateTimeParseException e) {
- fail("Time was not formatted with the locale");
- }
- }
-
- @Test
- public void ipTest() {
- final String ip = "146.58.69.12";
-
- String sessionId = "abcdefg";
- testingClient.server().run(session -> {
- RealmModel realm = session.realms().getRealmByName(TEST);
- ClientModel client = session.clients().getClientByClientId(realm, TEST_CLIENT_ID);
- UserModel user = session.users().getUserByUsername(realm, "test"); // cannot use testUser.getUsername() because it throws NotSerializableException for no apparent reason (or maybe I'm just stupid :D)
-
- UserSessionModel userSession = session.sessions().createUserSession(sessionId, realm, user, "test", ip, "form", false, null, null, null);
- session.sessions().createClientSession(realm, client, userSession);
- });
-
- deviceActivityPage.clickRefreshPage();
-
- final Optional session = deviceActivityPage.getSession(sessionId);
- assertThat(session.isPresent(), is(true));
- assertEquals(ip, session.get().getIp());
- }
-
- private String createSession(Browsers browser) {
- log.info("Creating session for " + browser);
- OAuthClient.AccessTokenResponse res;
- try {
- // 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) {
- throw new RuntimeException(e);
- }
- return res.getSessionState(); // session id
- }
-
- private void assertSession(Browsers browser, DeviceActivityPage.Session session) {
- log.infof("Asserting %s (session %s)", browser, session.getSessionId());
- assertTrue("Session should be present", session.isPresent());
- assertTrue("Browser name should be present", session.isBrowserDisplayed());
-
- if (browser.sessionBrowser != null) {
- assertEquals(browser.sessionBrowser, session.getBrowser());
- } else {
- assertEquals("Other/Unknown", session.getBrowser());
- }
-
- assertEquals(browser.iconName, session.getIcon());
- assertFalse("Session shouldn't have current badge", session.hasCurrentBadge()); // we don't test current session
- assertSessionRowsAreNotEmpty(session, true);
- }
-
- 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());
- assertFalse("Expires shouldn't be empty", session.getExpires().isEmpty());
- assertFalse("Clients shouldn't be empty", session.getClients().isEmpty());
- assertEquals("Sign out button visibility", expectSignOutPresent, session.isSignOutDisplayed());
- }
-
- public enum Browsers {
- CHROME(
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
- "Chrome/78.0.3904",
- DeviceType.DESKTOP
- ),
- CHROMIUM(
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Ubuntu/11.04 Chromium/12.0.742.112 Chrome/12.0.742.112 Safari/534.30",
- "Chromium/12.0.742",
- DeviceType.DESKTOP
- ),
- FIREFOX(
- "Mozilla/5.0 (X11; Fedora;Linux x86; rv:60.0) Gecko/20100101 Firefox/60.0",
- "Firefox/60.0",
- DeviceType.DESKTOP
- ),
- EDGE(
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763",
- "Edge/18.17763",
- DeviceType.DESKTOP
- ),
- // TODO uncomment this once KEYCLOAK-12445 is resolved
-// CHREDGE( // Edge based on Chromium
-// "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43",
-// "Edge/79.0.309 / Mac OS X 10.15.1",
-// "edge"
-// ),
- IE(
- "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
- "IE/11.0",
- DeviceType.DESKTOP
- ),
- SAFARI(
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15",
- "Safari/13.0.3",
- DeviceType.DESKTOP
- ),
- OPERA(
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 OPR/56.0.3051.52",
- "Opera/56.0.3051",
- DeviceType.DESKTOP
- ),
- YANDEX(
- "Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 YaBrowser/17.6.1.749 Yowser/2.5 Safari/537.36",
- "Yandex Browser/17.6.1",
- DeviceType.DESKTOP
- ),
- CHROME_ANDROID(
- "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Mobile Safari/537.36",
- "Chrome Mobile/68.0.3440",
- DeviceType.MOBILE
- ),
- SAFARI_IOS(
- "Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1",
- "Mobile Safari/13.0.1",
- DeviceType.MOBILE
- ),
- UNKNOWN_BROWSER(
- "Top-secret government browser running on top-secret OS",
- null,
- DeviceType.UNKNOWN
- ),
- UNKNOWN_OS(
- "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
- "Chrome/78.0.3904",
- DeviceType.UNKNOWN
- ),
- UNKNOWN_OS_VERSION(
- "Mozilla/5.0 (Windows 256.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
- "Chrome/78.0.3904",
- DeviceType.UNKNOWN
- );
- // not sure what "Amazon" browser is supposed to be (it's specified in DeviceActivityPage.tsx)
-
- private final String userAgent;
- private final String sessionBrowser; // how the browser is interpreted by the sessions endpoint
- private final DeviceType deviceType;
- private final String iconName;
-
- Browsers(String userAgent, String sessionBrowser, DeviceType deviceType) {
- this.userAgent = userAgent;
- this.sessionBrowser = sessionBrowser;
- this.deviceType = deviceType;
- this.iconName = deviceType.getIconName();
- }
-
- public String userAgent() {
- return userAgent;
- }
-
- public String sessionBrowser() {
- return sessionBrowser;
- }
-
- public String iconName() {
- return iconName;
- }
-
- private enum DeviceType {
- DESKTOP("desktop"),
- MOBILE("mobile"),
- UNKNOWN("desktop"); // Default icon
-
- private final String iconName;
-
- DeviceType(String iconName) {
- this.iconName = iconName;
- }
-
- public String getIconName() {
- return iconName;
- }
- }
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/InternationalizationTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/InternationalizationTest.java
deleted file mode 100644
index 3fa098aad7..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/InternationalizationTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Ignore;
-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.account3.page.PersonalInfoPage;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
-import org.keycloak.testsuite.ui.account3.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
- */
-public class InternationalizationTest extends AbstractAccountTest {
- @Page
- private WelcomeScreen welcomeScreen;
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private SigningInPage signingInPage;
- private SigningInPage.CredentialType passwordCredentialType;
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- configureInternationalizationForRealm(testRealms.get(0));
- }
-
- @Before
- public void beforeI18nTest() {
- assertTestUserLocale(null);
- passwordCredentialType = signingInPage.getCredentialType(PasswordCredentialModel.TYPE);
- }
-
- @Test
- public void loggedInPageTest() {
- personalInfoPage.navigateTo();
- loginToAccount();
- assertTestUserLocale(null);
- personalInfoPage.selectLocale(CUSTOM_LOCALE);
- personalInfoPage.clickSave(false);
- WaitUtils.waitForPageToLoad();
-
- assertTestUserLocale(CUSTOM_LOCALE);
- assertCustomLocalePersonalInfo();
-
- // check if selected locale is preserved
- personalInfoPage.header().clickLogoutBtn();
- welcomeScreen.assertCurrent();
- assertCustomLocaleWelcomeScreen();
- }
-
- @Test
- public void realmLocalizationMessagesAreApplied() {
- String messageKey = "personalInfoHtmlTitle";
-
- String localeEn = Locale.ENGLISH.toLanguageTag();
- String messageEn = "personalInfoHtmlTitle EN";
- testRealmResource().localization().saveRealmLocalizationText(localeEn,
- messageKey, messageEn);
- getCleanup().addLocalization(localeEn);
-
- String localeDe = Locale.GERMAN.toLanguageTag();
- String messageDe = "personalInfoHtmlTitle DE";
- testRealmResource().localization().saveRealmLocalizationText(localeDe,
- messageKey, messageDe);
- getCleanup().addLocalization(localeDe);
-
- // default locale should be "en"
- personalInfoPage.navigateTo();
- loginToAccount();
- assertTestUserLocale(null);
- assertPersonalInfo(messageEn);
-
- // switch to locale "de"
- personalInfoPage.selectLocale(localeDe);
- personalInfoPage.clickSave(false);
- WaitUtils.waitForPageToLoad();
-
- assertTestUserLocale(localeDe);
- assertPersonalInfo(messageDe);
- }
-
- @Test
- @Ignore
- public void loginFormTest() {
- personalInfoPage.navigateTo();
- loginPage.localeDropdown().selectAndAssert(CUSTOM_LOCALE_NAME);
- loginPage.form().login(testUser); // cannot use loginToAccount() because it asserts URL which is now different
- assertTestUserLocale(CUSTOM_LOCALE);
- assertCustomLocalePersonalInfo();
- }
-
- @Test
- @Ignore // TODO: Enable once chromedriver version 113.0.5672.92 is available in https://chromedriver.storage.googleapis.com/
- public void userAttributeTest() {
- testUser.setAttributes(singletonMap(UserModel.LOCALE, singletonList(CUSTOM_LOCALE)));
- testUserResource().update(testUser);
-
- welcomeScreen.navigateTo();
- welcomeScreen.clickPersonalInfoLink();
- assertEquals(DEFAULT_LOCALE_NAME, loginPage.localeDropdown().getSelected());
- loginToAccount();
- assertCustomLocalePersonalInfo();
- }
-
- @Test
- @Ignore
- public void shouldDisplayTimeUsingSelectedLocale() {
- signingInPage.navigateTo();
- loginToAccount();
- SigningInPage.UserCredential passwordCred =
- passwordCredentialType.getUserCredential(testUserResource().credentials().get(0).getId());
-
- try {
- LocalDateTime.parse(passwordCred.getCreatedAtStr(), DEFAULT_TIME_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 'um' 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());
- }
-
- private void assertCustomLocalePersonalInfo() {
- assertPersonalInfo("Osobní údaje");
- }
-
- private void assertPersonalInfo(String expectedText) {
- assertEquals(expectedText, personalInfoPage.getPageTitle());
- }
-
- private void assertTestUserLocale(String expectedLocale) {
- String actualLocale = null;
- List userLocales;
- Map> userAttributes = testUserResource().toRepresentation().getAttributes();
-
- if (userAttributes != null) {
- userLocales = userAttributes.get(UserModel.LOCALE);
- if (userLocales != null) {
- actualLocale = userLocales.get(0);
- }
- }
-
- assertEquals(expectedLocale, actualLocale);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LDAPAccountTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LDAPAccountTest.java
deleted file mode 100644
index 9abdbee51f..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LDAPAccountTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2020 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.account3;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD;
-import static org.keycloak.testsuite.admin.Users.setPasswordFor;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.credential.PasswordCredentialModel;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.storage.UserStorageProvider;
-import org.keycloak.storage.ldap.LDAPStorageProvider;
-import org.keycloak.storage.ldap.idm.model.LDAPObject;
-import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.federation.ldap.LDAPTestContext;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
-import org.keycloak.testsuite.util.LDAPRule;
-import org.keycloak.testsuite.util.LDAPTestUtils;
-
-/**
- * @author Alfredo Moises Boullosa
- */
-public class LDAPAccountTest extends AbstractAccountTest {
-
- @Page
- private SigningInPage signingInPage;
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- private SigningInPage.CredentialType passwordCredentialType;
- @ClassRule
- public static LDAPRule ldapRule = new LDAPRule();
-
- @Before
- public void beforeSigningInTest() {
- passwordCredentialType = signingInPage.getCredentialType(PasswordCredentialModel.TYPE);
-
- testingClient.testing().ldap(TEST).createLDAPProvider(ldapRule.getConfig(), true);
- log.infof("LDAP Provider created");
-
- String userName = "johnkeycloak";
- String firstName = "Jonh";
- String lastName = "Doe";
- String email = "john@email.org";
-
- testingClient.server().run(session -> {
- LDAPTestContext ctx = LDAPTestContext.init(session);
- RealmModel appRealm = ctx.getRealm();
-
- // Delete all LDAP users and add some new for testing
- LDAPTestUtils.removeAllLDAPUsers(ctx.getLdapProvider(), appRealm);
-
- LDAPObject john = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, userName, firstName, lastName, email, null, "1234");
- LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), john, PASSWORD);
- });
-
- testRealmLoginPage.setAuthRealm(testRealmPage);
-
- testUser = createUserRepresentation(userName, email, firstName, lastName, true);
- setPasswordFor(testUser, PASSWORD);
-
- resetTestRealmSession();
- }
-
- @Test
- public void createdNotVisibleTest() {
- signingInPage.navigateTo();
- loginPage.form().login(testUser);
-
- SigningInPage.UserCredential userCredential = passwordCredentialType.getUserCredential("password");
-
- assertTrue("ROW is not present", userCredential.isPresent());
- assertFalse("Created at is present", userCredential.hasCreatedAt());
- }
-
- // KEYCLOAK-15634
- @Test
- public void updateProfileWithAttributePresent() {
-
- RealmResource testRealm = adminClient.realm("test");
- assertEquals(getAccountThemeName(), testRealm.toRepresentation().getAccountTheme());
-
- UserRepresentation userRepBefore = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- assertNull("User should not exist", userRepBefore);
-
- testingClient.server().run(session -> {
- LDAPTestContext ctx = LDAPTestContext.init(session);
- RealmModel appRealm = ctx.getRealm();
-
- LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
- ldapFedProvider.getModel().put(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.UNSYNCED.toString());
- appRealm.updateComponent(ldapFedProvider.getModel());
-
- LDAPObject testUser = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(),
- appRealm, "keycloak-15634",
- "firstName",
- "lastName",
- "keycloak-15634@test.local",
- null,
- "1234");
- LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), testUser, PASSWORD);
- });
-
- // Check our test user is ok before updating profile
- userRepBefore = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- assertEquals("Test user should have an email address set", "keycloak-15634@test.local", userRepBefore.getEmail());
- assertTrue("Test user should have the LDAP_ID attribute set", userRepBefore.getAttributes().containsKey("LDAP_ID"));
- assertFalse("Test user should not have locale attribute set", userRepBefore.getAttributes().containsKey("locale"));
-
- personalInfoPage.navigateTo();
- loginPage.assertCurrent();
- loginPage.form().login("keycloak-15634","password");
- personalInfoPage.assertCurrent();
- assertEquals("keycloak-15634@test.local", personalInfoPage.getEmail());
-
- // Trigger the JS involved in KEYCLOAK-15634
- personalInfoPage.setEmail("keycloak-15634@domain.local");
- personalInfoPage.clickSave();
-
- // Check if updateProfile went well and if user is still there
- UserRepresentation userRepAfter = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- assertNotNull("Test user should still be there", userRepAfter);
- assertEquals("Email should have been updated","keycloak-15634@domain.local", userRepAfter.getEmail());
- assertTrue("LDAP_ID attribute should still be there", userRepAfter.getAttributes().containsKey("LDAP_ID"));
-
- // Clean up
- ApiUtil.removeUserByUsername(testRealm, "keycloak-15634");
- testingClient.server().run(session -> {
- LDAPTestContext ctx = LDAPTestContext.init(session);
- RealmModel appRealm = ctx.getRealm();
- LDAPTestUtils.removeAllLDAPUsers(ctx.getLdapProvider(), appRealm);
- });
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LinkedAccountsTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LinkedAccountsTest.java
deleted file mode 100644
index b083794a29..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/LinkedAccountsTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.broker.oidc.OIDCIdentityProviderFactory;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.FederatedIdentityRepresentation;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.social.google.GoogleIdentityProviderFactory;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.LinkedAccountsPage;
-import org.keycloak.testsuite.util.ClientBuilder;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
-
-/**
- * @author Vaclav Muzikar
- */
-public class LinkedAccountsTest extends BaseAccountPageTest {
- public static final String SOCIAL_IDP_ALIAS = "fake-google-account";
- public static final String SYSTEM_IDP_ALIAS = "kc-to-kc-account";
-
- public static final String REALM2_NAME = "test-realm2";
- public static final String CLIENT_ID = "cross-realm-client";
- public static final String CLIENT_SECRET = "top secret";
-
- private UserRepresentation homerUser;
-
- private LinkedAccountsPage.IdentityProvider socialIdp;
- private LinkedAccountsPage.IdentityProvider systemIdp;
-
- @Page
- private LinkedAccountsPage linkedAccountsPage;
-
- @Page
- private LoginPage loginPageWithSocialBtns;
-
- public LinkedAccountsTest() {
- // needs to be done here (setting fields in addTestRealms acts really weird resulting in Homer being null)
- homerUser = createUserRepresentation("hsimpson", "hsimpson@keycloak.org",
- "Homer", "Simpson", true, "Mmm donuts");
- }
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return linkedAccountsPage;
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation realm1 = testRealms.get(0);
-
- realm1.addIdentityProvider(createIdentityProviderRepresentation(SOCIAL_IDP_ALIAS,
- GoogleIdentityProviderFactory.PROVIDER_ID));
-
- String oidcRoot = getAuthServerRoot() + "realms/" + REALM2_NAME + "/protocol/openid-connect/";
-
- IdentityProviderRepresentation systemIdp = createIdentityProviderRepresentation(SYSTEM_IDP_ALIAS,
- OIDCIdentityProviderFactory.PROVIDER_ID);
- systemIdp.getConfig().put("clientId", CLIENT_ID);
- systemIdp.getConfig().put("clientSecret", CLIENT_SECRET);
- systemIdp.getConfig().put("clientAuthMethod", OIDCLoginProtocol.CLIENT_SECRET_POST);
- systemIdp.getConfig().put("authorizationUrl", oidcRoot + "auth");
- systemIdp.getConfig().put("tokenUrl", oidcRoot + "token");
- realm1.addIdentityProvider(systemIdp);
-
- ClientRepresentation client = ClientBuilder.create()
- .clientId(CLIENT_ID)
- .secret(CLIENT_SECRET)
- .redirectUris(getAuthServerRoot() + "realms/" + TEST + "/broker/" + SYSTEM_IDP_ALIAS + "/endpoint")
- .build();
-
- // using REALM2 as an identity provider
- RealmRepresentation realm2 = new RealmRepresentation();
- realm2.setId(REALM2_NAME);
- realm2.setRealm(REALM2_NAME);
- realm2.setEnabled(true);
- realm2.setClients(Collections.singletonList(client));
- realm2.setUsers(Collections.singletonList(homerUser));
- testRealms.add(realm2);
- }
-
- @Before
- public void beforeLinkedAccountsTest() {
- socialIdp = linkedAccountsPage.getProvider(SOCIAL_IDP_ALIAS);
- systemIdp = linkedAccountsPage.getProvider(SYSTEM_IDP_ALIAS);
- assertProvidersCount();
- }
-
- @After
- public void afterLinkedAccountsTest() {
- assertProvidersCount();
- }
-
- @Test
- public void linkAccountTest() {
- assertEquals(0, testUserResource().getFederatedIdentity().size());
-
- assertProvider(socialIdp, false, true, "");
- assertProvider(systemIdp, false, false, "");
-
- systemIdp.clickLinkBtn();
- loginPage.form().login(homerUser);
- linkedAccountsPage.assertCurrent();
- assertProvider(systemIdp, true, false, homerUser.getUsername());
-
- assertProvider(socialIdp, false, true, "");
-
- // check through admin REST endpoints
- List fids = testUserResource().getFederatedIdentity();
- assertEquals(1, fids.size());
- FederatedIdentityRepresentation fid = fids.get(0);
- assertEquals(SYSTEM_IDP_ALIAS, fid.getIdentityProvider());
- assertEquals(homerUser.getUsername(), fid.getUserName());
-
- // logout user and try to login using IdP
- testUserResource().logout();
- linkedAccountsPage.navigateTo();
- loginPageWithSocialBtns.clickSocial(SYSTEM_IDP_ALIAS);
- linkedAccountsPage.assertCurrent(); // no need for re-login to REALM2
- }
-
- @Test
- public void unlinkAccountTest() {
- FederatedIdentityRepresentation fid = new FederatedIdentityRepresentation();
- fid.setIdentityProvider(SOCIAL_IDP_ALIAS);
- fid.setUserId("Homer lost his ID at Moe's last night");
- fid.setUserName(homerUser.getUsername());
- testUserResource().addFederatedIdentity(SOCIAL_IDP_ALIAS, fid);
- assertEquals(1, testUserResource().getFederatedIdentity().size());
- linkedAccountsPage.navigateTo();
-
- assertProvider(systemIdp, false, false, "");
- assertProvider(socialIdp, true, true, homerUser.getUsername());
-
- socialIdp.clickUnlinkBtn();
- linkedAccountsPage.assertCurrent();
- assertProvider(systemIdp, false, false, "");
- assertProvider(socialIdp, false, true, "");
-
- assertEquals(0, testUserResource().getFederatedIdentity().size());
- }
-
- private void assertProvider(
- LinkedAccountsPage.IdentityProvider provider,
- boolean expectLinked,
- boolean expectSocial,
- String expectedUsername
- ) {
- if (expectLinked) {
- assertTrue("Account should be in the \"Linked\" list", provider.isLinked());
- assertTrue("Unlink button should be visible", provider.isUnlinkBtnVisible());
- assertFalse("Link button shouldn't be visible", provider.isLinkBtnVisible());
- }
- else {
- assertFalse("Account should be in the \"Unlinked\" list", provider.isLinked());
- assertFalse("Unlink button shouldn't be visible", provider.isUnlinkBtnVisible());
- assertTrue("Link button should be visible", provider.isLinkBtnVisible());
- }
-
- if (expectSocial) {
- assertTrue("Social badge should be visible", provider.hasSocialLoginBadge());
- assertTrue("Social icon should be visible", provider.hasSocialIcon());
- assertFalse("Default icon shouldn't be visible", provider.hasDefaultIcon());
- }
- else {
- assertFalse("Social badge shouldn't be visible", provider.hasSocialLoginBadge());
- assertFalse("Social icon shouldn't be visible", provider.hasSocialIcon());
- assertTrue("Default icon should be visible", provider.hasDefaultIcon());
- }
-
- assertEquals(expectedUsername, provider.getUsername());
- }
-
- private void assertProvidersCount() {
- assertEquals(2,
- linkedAccountsPage.getLinkedProvidersCount() + linkedAccountsPage.getUnlinkedProvidersCount());
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/MyResourcesTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/MyResourcesTest.java
deleted file mode 100644
index 6753c8f05a..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/MyResourcesTest.java
+++ /dev/null
@@ -1,316 +0,0 @@
-package org.keycloak.testsuite.ui.account3;
-
-import com.google.common.collect.Lists;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.After;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.keycloak.admin.client.resource.AuthorizationResource;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.authorization.client.AuthzClient;
-import org.keycloak.authorization.client.Configuration;
-import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.models.AccountRoles;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.representations.idm.authorization.PermissionTicketRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.MyResourcesPage;
-import org.keycloak.testsuite.util.ClientBuilder;
-import org.keycloak.testsuite.util.UserBuilder;
-import org.keycloak.util.JsonSerialization;
-import org.openqa.selenium.NoSuchElementException;
-
-import jakarta.ws.rs.core.Response;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static java.util.Collections.singletonList;
-import static org.hamcrest.core.StringEndsWith.endsWith;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.hamcrest.MatcherAssert.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;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class MyResourcesTest extends BaseAccountPageTest {
- private static final String[] userNames = new String[]{"alice", "jdoe"};
-
- @Page
- private MyResourcesPage myResourcesPage;
-
- private RealmRepresentation testRealm;
- private CloseableHttpClient httpClient;
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return myResourcesPage;
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- testRealm = testRealms.get(0);
- testRealm.setUserManagedAccessAllowed(true);
-
- testRealm.setUsers(Lists.asList("admin", userNames).stream().map(this::createUser).collect(Collectors.toList()));
-
- ClientRepresentation client = ClientBuilder.create()
- .clientId("my-resource-server")
- .authorizationServicesEnabled(true)
- .serviceAccountsEnabled(true)
- .secret("secret")
- .name("My Resource Server")
- .baseUrl("http://resourceserver.com")
- .directAccessGrants().build();
-
- testRealm.setClients(singletonList(client));
- }
-
- private UserRepresentation createUser(String userName) {
- return UserBuilder.create()
- .username(userName)
- .enabled(true)
- .password(PASSWORD)
- .role("account", AccountRoles.MANAGE_ACCOUNT)
- .build();
- }
-
- @After
- public void after() {
- if (httpClient != null) {
- try {
- httpClient.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- @Override
- public void afterAbstractKeycloakTestRealmImport() {
- ClientResource resourceServer = getResourceServer();
- AuthzClient authzClient = createAuthzClient(resourceServer.toRepresentation());
- AuthorizationResource authorization = resourceServer.authorization();
- ResourceRepresentation resource13 = null;
- for (int i = 1; i < 15; i++) {
- ResourceRepresentation resource = createResource(authzClient, authorization, i);
- if (i == 13) {
- resource13 = resource;
- }
-
- for (String scope : Arrays.asList("Scope A", "Scope B")) {
- createTicket(authzClient, i, resource, scope, userNames[i % userNames.length]);
- }
- }
-
- createTicket(authzClient, 13, resource13, "Scope A", "admin");
- }
-
- private void createTicket(AuthzClient authzClient, int i, ResourceRepresentation resource, String scope, String userName) {
- PermissionTicketRepresentation ticket = new PermissionTicketRepresentation();
-
- ticket.setGranted(!(i == 12 || i == 13));
- ticket.setOwner(resource.getOwner().getId());
- ticket.setRequesterName(userName);
- ticket.setResource(resource.getId());
- ticket.setScopeName(scope);
-
- authzClient.protection("jdoe", PASSWORD).permission().create(ticket);
- }
-
- private ResourceRepresentation createResource(AuthzClient authzClient, AuthorizationResource authorization, int i) {
- ResourceRepresentation resource = new ResourceRepresentation();
-
- resource.setOwnerManagedAccess(true);
-
- try {
- final byte[] content = new JWSInput(authzClient.obtainAccessToken("jdoe", PASSWORD).getToken()).getContent();
- final AccessToken accessToken = JsonSerialization.readValue(content, AccessToken.class);
- resource.setOwner(accessToken.getSubject());
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- resource.setName("Resource " + i);
- resource.setDisplayName("Display Name " + i);
- resource.setIconUri("Icon Uri " + i);
- resource.addScope("Scope A", "Scope B", "Scope C", "Scope D");
- resource.setUri("http://resourceServer.com/resources/" + i);
-
- try (Response response1 = authorization.resources().create(resource)) {
- resource.setId(response1.readEntity(ResourceRepresentation.class).getId());
- }
- return resource;
- }
-
- @Override
- public void addTestUser() {
- testUser = createUser("jdoe");
- }
-
- @Test
- public void shouldDisplayTheResources() {
- assertEquals(6, myResourcesPage.getResourcesListCount());
-
- assertEquals("Resource 0", myResourcesPage.getCellText("name", 0));
- assertEquals("Resource 1", myResourcesPage.getCellText("name", 1));
- assertEquals("My Resource Server", myResourcesPage.getCellText("client", 0));
- assertEquals("http://resourceserver.com/", myResourcesPage.getCellHref("client", 0));
- }
-
- @Test
- public void shouldShowMyResourcesAndUpdatePermissions() {
- final int row = 1;
- myResourcesPage.clickExpandButton(row);
- myResourcesPage.clickCollapseButton(row);
- myResourcesPage.clickExpandButton(row);
-
- assertEquals("Resource is shared with jdoe.", myResourcesPage.getSharedWith(row));
-
- myResourcesPage.clickEditButton(row);
- assertEquals("jdoe", myResourcesPage.getEditDialogUsername(0));
- myResourcesPage.removeAllPermissions();
-
- myResourcesPage.alert().assertSuccess();
- assertEquals("This resource is not shared.", myResourcesPage.getSharedWith(row));
- }
-
- @Test
- public void shouldShowMyResourcesAndRemoveShares() {
- final int row = 2;
- myResourcesPage.clickExpandButton(row);
-
- testModalDialog(() -> myResourcesPage.clickRemoveButton(row), () ->
- assertEquals("Resource is shared with alice.", myResourcesPage.getSharedWith(row)));
-
- myResourcesPage.alert().assertSuccess();
- assertEquals("This resource is not shared.", myResourcesPage.getSharedWith(row));
- }
-
- @Test
- public void shouldShowMyResourcesAndShare() {
- final int row = 3;
- myResourcesPage.clickExpandButton(row);
-
- assertEquals("Resource is shared with jdoe.", myResourcesPage.getSharedWith(row));
-
- myResourcesPage.clickShareButton(row);
- myResourcesPage.createShare("alice");
-
- myResourcesPage.alert().assertSuccess();
- assertThat(myResourcesPage.getSharedWith(row), endsWith("and 1 other users."));
- }
-
- @Test
- public void firstShouldRefreshOnRefreshButtonClick() {
- ClientResource resourceServer = getResourceServer();
- AuthzClient authzClient = createAuthzClient(resourceServer.toRepresentation());
- AuthorizationResource authorization = resourceServer.authorization();
-
- createResource(authzClient, authorization, 0);
-
- assertEquals("Resource 1", myResourcesPage.getCellText("name", 0));
- myResourcesPage.clickRefreshButton();
- assertEquals("Resource 0", myResourcesPage.getCellText("name", 0));
- }
-
- @Test
- public void shouldAllowRequestToShare() {
- final String resourceName = "Resource 12";
- assertEquals("1", myResourcesPage.getPendingRequestText(resourceName));
-
- switchUserSharedWithMeTab();
- assertFalse(myResourcesPage.containsResource(resourceName));
- login("jdoe");
-
- myResourcesPage.clickPendingRequest(resourceName);
- assertEquals("alice", myResourcesPage.getPendingRequestRequestor(0));
- final String permissions = myResourcesPage.getPendingRequestPermissions(0);
- assertTrue(permissions.contains("Scope A"));
- assertTrue(permissions.contains("Scope B"));
- myResourcesPage.acceptRequest(resourceName, 0);
-
- assertNoPendingRequest(resourceName);
- switchUserSharedWithMeTab();
-
- assertTrue(myResourcesPage.containsResource(resourceName));
- }
-
- @Test
- public void shouldDenyRequestToShare() {
- final String resourceName = "Resource 13";
-
- switchUserSharedWithMeTab();
- assertFalse(myResourcesPage.containsResource(resourceName));
- login("jdoe");
-
- myResourcesPage.clickNextPage();
- assertEquals("2", myResourcesPage.getPendingRequestText(resourceName));
- myResourcesPage.clickPendingRequest(resourceName);
- myResourcesPage.denyRequest(resourceName, 0);
-
- assertEquals("1", myResourcesPage.getPendingRequestText(resourceName));
-
- switchUserSharedWithMeTab();
- assertFalse(myResourcesPage.containsResource(resourceName));
- }
-
- @Test
- public void shouldNotHaveRequestToShareButton() {
- assertNoPendingRequest("Resource 0");
- assertNoPendingRequest("Resource 1");
- }
-
- private void assertNoPendingRequest(String resourceName) {
- try {
- myResourcesPage.getPendingRequestText(resourceName);
- fail("should not have a pending request button");
- } catch (NoSuchElementException e) {
- // success
- }
- }
-
- private void switchUserSharedWithMeTab() {
- login("alice");
- myResourcesPage.clickSharedWithMeTab();
- }
-
- private void login(String user) {
- myResourcesPage.clickSignOut();
- myResourcesPage.navigateTo();
- loginPage.form().login(createUser(user));
- }
-
- private AuthzClient createAuthzClient(ClientRepresentation client) {
- Map credentials = new HashMap<>();
-
- credentials.put("secret", "secret");
- httpClient = HttpClientBuilder.create().build();
-
- return AuthzClient
- .create(new Configuration(suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth",
- testRealm.getRealm(), client.getClientId(),
- credentials, httpClient));
- }
-
- private ClientResource getResourceServer() {
- ClientsResource clients = adminClient.realm(TEST).clients();
- return clients.get(clients.findByClientId("my-resource-server").get(0).getId());
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PermissionsTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PermissionsTest.java
deleted file mode 100644
index 9105fca464..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PermissionsTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2020 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.RoleScopeResource;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.testsuite.ui.account3.page.ForbiddenPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
-import org.keycloak.testsuite.ui.account3.page.WelcomeScreen;
-
-import java.util.List;
-
-import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
-
-/**
- * @author Vaclav Muzikar
- */
-public class PermissionsTest extends AbstractAccountTest {
- @Page
- private WelcomeScreen welcomeScreen;
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private SigningInPage signingInPage;
-
- @Page
- private ForbiddenPage forbiddenPage;
-
- private static final String DEFAULT_ROLE_NAME = "default-roles-" + TEST;
-
- @Test
- public void manageAccountRoleRequired() throws Exception {
- // remove realm level roles (no "default-roles-test") and any roles in the account client
- testUserResource().roles().realmLevel().remove(testUserResource().roles().realmLevel().listAll());
- String accountClientId = testRealmResource().clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId();
- RoleScopeResource roleScopes = testUserResource().roles().clientLevel(accountClientId);
- List roles = roleScopes.listAll();
- if (!roles.isEmpty()) {
- roleScopes.remove(roles);
- }
-
- welcomeScreen.header().clickLoginBtn();
- loginToAccount();
- welcomeScreen.assertCurrent(); // no forbidden at welcome screen yet
-
- welcomeScreen.clickPersonalInfoLink();
- forbiddenPage.assertCurrent();
-
- signingInPage.navigateToUsingSidebar();
- forbiddenPage.assertCurrent();
-
- // still possible to sign out
- forbiddenPage.header().clickLogoutBtn();
- welcomeScreen.assertCurrent();
- welcomeScreen.header().assertLoginBtnVisible(true);
- welcomeScreen.header().assertLogoutBtnVisible(false);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PersonalInfoTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PersonalInfoTest.java
deleted file mode 100644
index 2b9a987909..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/PersonalInfoTest.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * 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.account3;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.admin.Users.setPasswordFor;
-import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.forms.VerifyProfileTest;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-import org.keycloak.testsuite.util.UserBuilder;
-
-/**
- * @author Vaclav Muzikar
- */
-public class PersonalInfoTest extends BaseAccountPageTest {
- @Page
- private PersonalInfoPage personalInfoPage;
-
- private UserRepresentation testUser2;
-
- @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());
-
- VerifyProfileTest.enableUnmanagedAttributes(testRealmResource().users().userProfile());
- }
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return personalInfoPage;
- }
-
- @Test
- public void updateUserInfo() {
- setEditUsernameAllowed(true);
-
- assertTrue(personalInfoPage.valuesEqual(testUser));
- personalInfoPage.assertUsernameDisabled(false);
- personalInfoPage.assertSaveDisabled(false);
-
- personalInfoPage.setValues(testUser2, true);
- //assertEquals("test user", personalInfoPage.header().getToolbarLoggedInUser());
- assertTrue(personalInfoPage.valuesEqual(testUser2));
- personalInfoPage.assertSaveDisabled(false);
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertSuccess();
- personalInfoPage.assertSaveDisabled(false);
-
- personalInfoPage.navigateTo();
- personalInfoPage.valuesEqual(testUser2);
- //assertEquals("Václav Muzikář", personalInfoPage.header().getToolbarLoggedInUser());
-
- // change just first and last name
- testUser2.setFirstName("Another");
- testUser2.setLastName("Name");
- personalInfoPage.setValues(testUser2, true);
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertSuccess();
- personalInfoPage.navigateTo();
- personalInfoPage.valuesEqual(testUser2);
- //assertEquals("Another Name", personalInfoPage.header().getToolbarLoggedInUser());
- }
-
- @Test
- public void formValidationTest() {
- setEditUsernameAllowed(true);
-
- // clear username
- personalInfoPage.setUsername("");
- personalInfoPage.assertSaveDisabled(true);
- personalInfoPage.assertUsernameValid(false);
- personalInfoPage.setUsername("hsimpson");
- personalInfoPage.assertUsernameValid(true);
-
- // clear email
- personalInfoPage.setEmail("edewit@");
- personalInfoPage.assertEmailValid(false);
- personalInfoPage.setEmail("");
- personalInfoPage.assertEmailValid(false);
- personalInfoPage.setEmail("hsimpson@springfield.com");
- personalInfoPage.assertEmailValid(true);
-
- // clear first name
- personalInfoPage.setFirstName("");
- personalInfoPage.assertFirstNameValid(false);
- personalInfoPage.setFirstName("Homer");
- personalInfoPage.assertFirstNameValid(true);
-
- // clear last name
- personalInfoPage.setLastName("");
- personalInfoPage.assertLastNameValid(false);
- personalInfoPage.setLastName("Simpson");
- personalInfoPage.assertLastNameValid(true);
-
- // duplicity tests
- ApiUtil.createUserWithAdminClient(testRealmResource(), testUser2);
- // duplicate username
- personalInfoPage.setUsername(testUser2.getUsername());
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertDanger();
- // TODO assert actual error message and that the field is marked as invalid (KEYCLOAK-12102)
- personalInfoPage.setUsername(testUser.getUsername());
- // duplicate email
- personalInfoPage.setEmail(testUser2.getEmail());
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertDanger();
- // TODO assert actual error message and that the field is marked as invalid (KEYCLOAK-12102)
- // check no changes were saved
- personalInfoPage.navigateTo();
- personalInfoPage.valuesEqual(testUser);
- }
-
- @Test
- public void cancelForm() {
- setEditUsernameAllowed(false);
-
- personalInfoPage.setValues(testUser2, false);
- personalInfoPage.setEmail("hsimpson@springfield.com");
- personalInfoPage.clickCancel();
- personalInfoPage.valuesEqual(testUser2);
- }
-
- @Test
- public void disabledEditUsername() {
- setEditUsernameAllowed(false);
-
- personalInfoPage.assertUsernameDisabled(true);
- personalInfoPage.setValues(testUser2, false);
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertSuccess();
-
- testUser2.setUsername(testUser.getUsername()); // the username should remain the same
- personalInfoPage.navigateTo();
- personalInfoPage.valuesEqual(testUser2);
- }
-
- @Test
- public void clickLogoTest() {
- personalInfoPage.clickBrandLink();
- accountWelcomeScreen.assertCurrent();
- }
-
- @Ignore("Username is not included in the account console anymore, but it should be there.")
- @Test
- public void testNameInToolbar() {
- assertEquals("test user", personalInfoPage.header().getToolbarLoggedInUser());
-
- UserRepresentation user = new UserRepresentation();
- user.setUsername("edewit");
- user.setEnabled(true);
- setPasswordFor(user, "password");
- try {
- ApiUtil.removeUserByUsername(testRealmResource(), testUser.getUsername());
- personalInfoPage.navigateTo();
- ApiUtil.createUserWithAdminClient(testRealmResource(), user);
- loginPage.form().login(user);
-
- assertEquals("edewit", personalInfoPage.header().getToolbarLoggedInUser());
- } finally {
- ApiUtil.removeUserByUsername(testRealmResource(), user.getUsername());
- }
- }
-
- private void setEditUsernameAllowed(boolean value) {
- RealmRepresentation realm = testRealmResource().toRepresentation();
- realm.setEditUsernameAllowed(value);
- testRealmResource().update(realm);
- refreshPageAndWaitForLoad();
- }
-
- private void addUser(String username, String email) {
- UserRepresentation user = UserBuilder.create()
- .username(username)
- .enabled(true)
- .email(email)
- .firstName("first")
- .lastName("last")
- .build();
- RealmResource testRealm = adminClient.realm("test");
- ApiUtil.createUserAndResetPasswordWithAdminClient(testRealm, user, "password");
- }
-
- // KEYCLOAK-15634
- @Test
- public void updateProfileWithAttributePresent() {
-
- RealmResource testRealm = adminClient.realm("test");
- assertEquals(getAccountThemeName(), testRealm.toRepresentation().getAccountTheme());
-
- // Add a user and set a test attribute
- addUser("keycloak-15634","keycloak-15634@test.local");
- UserRepresentation userRepBefore = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- Map> userAttributes = new HashMap<>();
- userAttributes.put("testAttribute", Collections.singletonList("testValue"));
- userRepBefore.setAttributes(userAttributes);
- testRealm.users().get(userRepBefore.getId()).update(userRepBefore);
-
- // Check our test user is ok before updating profile with account v2
- UserRepresentation updatedUserRep = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- assertEquals("keycloak-15634@test.local", updatedUserRep.getEmail());
- assertEquals("testAttribute should be set", "testValue", updatedUserRep.getAttributes().get("testAttribute").get(0));
- assertFalse("locale attribute should not be set", updatedUserRep.getAttributes().containsKey("locale"));
-
- personalInfoPage.assertCurrent();
- personalInfoPage.header().clickLogoutBtn();
- personalInfoPage.navigateTo();
- loginPage.assertCurrent();
- loginPage.form().login("keycloak-15634","password");
- personalInfoPage.assertCurrent();
-
- // Trigger the JS involved in KEYCLOAK-15634
- assertEquals("keycloak-15634@test.local", personalInfoPage.getEmail());
- personalInfoPage.setEmail("keycloak-15634@domain.local");
- personalInfoPage.clickSave();
-
- // Check if updateProfile went well and if testAttribute is still there
- UserRepresentation userRepAfter = ApiUtil.findUserByUsername(testRealm,"keycloak-15634");
- assertEquals("keycloak-15634@domain.local", userRepAfter.getEmail());
- assertEquals("testAttribute should still be there","testValue", userRepAfter.getAttributes().get("testAttribute").get(0));
-
- ApiUtil.removeUserByUsername(testRealm, "keycloak-15634");
- }
-
- @Test
- // https://issues.redhat.com/browse/KEYCLOAK-16890
- // Stored personal info triggers attack via the display of user name in header.
- // If user name is left unsanitized, this test will fail with
- // org.openqa.selenium.UnhandledAlertException: unexpected alert open: {Alert text : XSS}
- public void storedXSSAttack() {
- personalInfoPage.navigateTo();
- testUser.setFirstName("");
- personalInfoPage.setValues(testUser, false);
- personalInfoPage.clickSave();
-
- personalInfoPage.header().clickLogoutBtn();
- accountWelcomeScreen.header().clickLoginBtn();
- loginPage.form().login(testUser);
- personalInfoPage.navigateTo();
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ReferrerTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ReferrerTest.java
deleted file mode 100644
index fbd5aeb24d..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/ReferrerTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Test;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-import org.keycloak.testsuite.ui.account3.page.WelcomeScreen;
-import org.keycloak.testsuite.ui.account3.page.fragment.AbstractHeader;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
-
-/**
- * @author Vaclav Muzikar
- */
-public class ReferrerTest extends AbstractAccountTest {
- public static final String FAKE_CLIENT_ID = "fake-client-name";
- public static final String REFERRER_LINK_TEXT = "Back to " + LOCALE_CLIENT_NAME_LOCALIZED;
- public static final String FAKE_CLIENT_URL_CONTEXT = "auth/non-existing-page/";
- public static final String FAKE_CLIENT_URL_FRAGMENT = "?foo=bar&bar=foo#anchor";
-
- @Page
- private WelcomeScreen welcomeScreen;
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation testRealm = testRealms.get(0);
-
- ClientRepresentation testClient = new ClientRepresentation();
- testClient.setClientId(FAKE_CLIENT_ID);
- testClient.setName(LOCALE_CLIENT_NAME);
-
- // Redirect URIs are no longer allowed to contain a fragment, so we
- // need the wildcard in order to use fragments in tests
- testClient.setRedirectUris(Collections.singletonList(getFakeClientUrl("*")));
-
- testClient.setEnabled(true);
-
- ClientRepresentation rootUrlClient = new ClientRepresentation();
- rootUrlClient.setClientId("test-client-with-root-url");
- rootUrlClient.setRootUrl(getFakeClientUrl("foo"));
- rootUrlClient.setBaseUrl("/bar");
- testClient.setRedirectUris(Collections.singletonList(getFakeClientUrl("*")));
- rootUrlClient.setEnabled(true);
-
- testRealm.setClients(Arrays.asList(testClient, rootUrlClient));
- testRealm.setAccountTheme(LOCALIZED_THEME_PREVIEW); // using localized custom theme for the fake client localized name
- }
-
- @Test
- // https://issues.redhat.com/browse/KEYCLOAK-17033
- // If the referrer is unescaped, this test will throw an exception.
- // org.openqa.selenium.UnhandledAlertException: unexpected alert open: {Alert text : XSS}
- public void reflectedXSSTest() {
- String attackUrl = getFakeClientUrl("'+alert('XSS')+'");
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, attackUrl);
-
- welcomeScreen.header().clickLoginBtn();
- loginToAccount();
- welcomeScreen.clickPersonalInfoLink();
- }
-
- @Test
- public void loggedInWelcomeScreenTest() {
- welcomeScreen.header().clickLoginBtn();
- loginToAccount();
-
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- welcomeScreen.header().assertLoginBtnVisible(false);
- welcomeScreen.header().assertLogoutBtnVisible(true);
-
- testReferrer(welcomeScreen.header(), true);
- }
-
- @Test
- public void loggedOutWelcomeScreenTest() {
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- welcomeScreen.header().assertLoginBtnVisible(true);
- welcomeScreen.header().assertLogoutBtnVisible(false);
-
- testReferrer(welcomeScreen.header(), true);
- }
-
- @Test
- public void loggedInPageTest() {
- welcomeScreen.header().clickLoginBtn();
- loginToAccount();
-
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- welcomeScreen.clickPersonalInfoLink();
-
- testReferrer(personalInfoPage.header(), true);
- }
-
- @Test
- public void loggedOutPageTest() {
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- welcomeScreen.clickPersonalInfoLink();
- loginToAccount();
-
- testReferrer(personalInfoPage.header(), true);
- }
-
- @Test
- public void badClientNameTest() {
- welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- testReferrer(welcomeScreen.header(), false);
-
- welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- welcomeScreen.clickPersonalInfoLink();
- loginToAccount();
- testReferrer(personalInfoPage.header(), false);
- }
-
- @Test
- public void badClientUriTest() {
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrlWithBadContext());
- testReferrer(welcomeScreen.header(), false);
-
- welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrlWithBadContext());
- welcomeScreen.clickPersonalInfoLink();
- loginToAccount();
- testReferrer(personalInfoPage.header(), false);
- }
-
- // Issue 16484
- @Test
- public void loggedInWithoutProvidedReferrerUrl() {
- welcomeScreen.header().clickLoginBtn();
- loginToAccount();
-
- welcomeScreen.navigateTo("test-client-with-root-url", null);
- welcomeScreen.header().assertLoginBtnVisible(false);
- welcomeScreen.header().assertLogoutBtnVisible(true);
-
- // referrer_uri parameter was not provided. So it should be set by Keycloak based on the client rootUrl and baseUrl
- assertEquals("Back to test-client-with-root-url", welcomeScreen.header().getReferrerLinkText());
- welcomeScreen.header().clickReferrerLink();
- assertCurrentUrlEquals(getFakeClientUrl("foo/bar"));
- }
-
- private void testReferrer(AbstractHeader header, boolean expectReferrerVisible) {
- if (expectReferrerVisible) {
- assertEquals(REFERRER_LINK_TEXT, header.getReferrerLinkText());
- header.clickReferrerLink();
- assertCurrentUrlEquals(getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
- }
- else {
- header.assertReferrerLinkVisible(false);
- }
- }
-
- private String getFakeClientUrl(String suffix) {
- // we need to use some page which host exists – Firefox is throwing exceptions like crazy if we try to load
- // a page on a non-existing host, like e.g. http://non-existing-server/
- // also we need to do this here as getAuthServerRoot is not ready when firing this class' constructor
- return getAuthServerRoot() + FAKE_CLIENT_URL_CONTEXT + suffix;
- }
-
- private String getFakeClientUrlWithBadContext() {
- // we need to use some page which host exists – Firefox is throwing exceptions like crazy if we try to load
- // a page on a non-existing host, like e.g. http://non-existing-server/
- // also we need to do this here as getAuthServerRoot is not ready when firing this class' constructor
- return getAuthServerRoot() + "bad/" + FAKE_CLIENT_URL_CONTEXT;
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SessionTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SessionTest.java
deleted file mode 100644
index b6d7c271c5..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SessionTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.ui.account3.page.DeviceActivityPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-
-import java.util.List;
-
-import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
-import static org.keycloak.testsuite.util.WaitUtils.pause;
-
-/**
- * @author Vaclav Muzikar
- */
-public class SessionTest extends AbstractAccountTest {
- public static final int SSO_SESSION_IDLE_TIMEOUT = 10;
- public static final int ACCESS_TOKEN_LIFESPAN = 10;
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private DeviceActivityPage deviceActivityPage;
-
- @Override
- public void addTestRealms(List testRealms) {
- super.addTestRealms(testRealms);
- RealmRepresentation realm = testRealms.get(0);
-
- // in seconds
- realm.setSsoSessionIdleTimeout(SSO_SESSION_IDLE_TIMEOUT);
- realm.setAccessTokenLifespan(ACCESS_TOKEN_LIFESPAN);
- }
-
- @Before
- public void beforeSessionTest() {
- personalInfoPage.navigateTo();
- loginToAccount();
- }
-
- @Test
- public void reactPageSsoTimeoutTest() {
- deviceActivityPage.navigateToUsingSidebar();
- deviceActivityPage.assertCurrent();
- personalInfoPage.navigateToUsingSidebar();
- personalInfoPage.assertCurrent();
-
- waitForSessionToExpire();
- deviceActivityPage.navigateToUsingSidebar();
- assertCurrentUrlStartsWithLoginUrlOf(accountWelcomeScreen);
- }
-
- @Test
- public void reactPageAsyncLogoutTest() {
- testRealmResource().logoutAll();
- deviceActivityPage.navigateToUsingSidebar();
- assertCurrentUrlStartsWithLoginUrlOf(accountWelcomeScreen);
- }
-
- @Test
- public void welcomeScreenSsoTimeoutTest() {
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.header().assertLoginBtnVisible(false);
- accountWelcomeScreen.header().assertLogoutBtnVisible(true);
-
- waitForSessionToExpire();
- refreshPageAndWaitForLoad();
- accountWelcomeScreen.header().assertLoginBtnVisible(true);
- accountWelcomeScreen.header().assertLogoutBtnVisible(false);
- }
-
- @Test
- public void welcomeScreenAsyncLogoutTest() {
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.header().assertLoginBtnVisible(false);
- accountWelcomeScreen.header().assertLogoutBtnVisible(true);
-
- testRealmResource().logoutAll();
- refreshPageAndWaitForLoad();
- accountWelcomeScreen.header().assertLoginBtnVisible(true);
- accountWelcomeScreen.header().assertLogoutBtnVisible(false);
- }
-
- private void waitForSessionToExpire() {
- // +3 to add some toleration
- log.info("Waiting for SSO session to expire");
- pause((SSO_SESSION_IDLE_TIMEOUT + 3) * 1000);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SigningInTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SigningInTest.java
deleted file mode 100644
index b2928b213e..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SigningInTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2020 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.credential.OTPCredentialModel;
-import org.keycloak.models.credential.PasswordCredentialModel;
-import org.keycloak.models.utils.Base32;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
-import org.keycloak.testsuite.admin.Users;
-import org.keycloak.testsuite.auth.page.login.OTPSetup;
-import org.keycloak.testsuite.auth.page.login.UpdatePassword;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
-import org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils;
-
-import java.time.LocalDateTime;
-
-import static java.util.Collections.emptyList;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.keycloak.models.UserModel.RequiredAction.CONFIGURE_TOTP;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
-import static org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils.assertUserCredential;
-import static org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils.testSetUpLink;
-import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
-import static org.keycloak.testsuite.util.WaitUtils.pause;
-
-/**
- * @author Vaclav Muzikar
- */
-public class SigningInTest extends BaseAccountPageTest {
- public static final String PASSWORD_LABEL = "My password";
-
- @Page
- private SigningInPage signingInPage;
-
- @Page
- private UpdatePassword updatePasswordPage;
-
- @Page
- private OTPSetup otpSetupPage;
-
- private SigningInPage.CredentialType passwordCredentialType;
- private SigningInPage.CredentialType otpCredentialType;
- private TimeBasedOTP otpGenerator;
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return signingInPage;
- }
-
- @Override
- public void setDefaultPageUriParameters() {
- super.setDefaultPageUriParameters();
- updatePasswordPage.setAuthRealm(TEST);
- otpSetupPage.setAuthRealm(TEST);
- }
-
- @Before
- public void beforeSigningInTest() {
- passwordCredentialType = signingInPage.getCredentialType(PasswordCredentialModel.TYPE);
- otpCredentialType = signingInPage.getCredentialType(OTPCredentialModel.TYPE);
-
- RealmRepresentation realm = testRealmResource().toRepresentation();
- otpGenerator = new TimeBasedOTP(realm.getOtpPolicyAlgorithm(), realm.getOtpPolicyDigits(), realm.getOtpPolicyPeriod(), 0);
- }
-
- @Test
- public void categoriesTest() {
- testContext.setTestRealmReps(emptyList()); // reimport realm after this test
-
- assertThat(signingInPage.getCategoriesCount(), is(2));
- assertThat(signingInPage.getCategoryTitle("basic-authentication"), is("Basic authentication"));
- assertThat(signingInPage.getCategoryTitle("two-factor"), is("Two-factor authentication"));
- }
-
- @Test
- public void updatePasswordTest() {
- SigningInPage.UserCredential passwordCred = passwordCredentialType.getUserCredential(
- testUserResource()
- .credentials()
- .get(0)
- .getId()
- );
-
- assertThat(passwordCredentialType.isSetUpLinkVisible(), is(false));
- assertThat(passwordCredentialType.isSetUp(), is(true));
- assertUserCredential(PASSWORD_LABEL, false, passwordCred);
-
- LocalDateTime previousCreatedAt = passwordCred.getCreatedAt();
- log.info("Waiting one minute to ensure createdAt will change");
- pause(60000);
-
- final String newPwd = "Keycloak is the best!";
- passwordCred.clickUpdateBtn();
- updatePasswordPage.assertCurrent();
- updatePasswordPage.updatePasswords(newPwd, newPwd);
- signingInPage.assertCurrent();
-
- assertUserCredential(PASSWORD_LABEL, false, passwordCred);
- assertThat(passwordCred.getCreatedAt(), is(not(previousCreatedAt)));
- }
-
- @Test
- public void updatePasswordTestForUserWithoutPassword() {
- // Remove password from the user through admin REST API
- String passwordId = testUserResource().credentials().get(0).getId();
- testUserResource().removeCredential(passwordId);
-
- // Refresh the page
- refreshPageAndWaitForLoad();
-
- // Test user doesn't have password set
- assertThat(passwordCredentialType.isSetUpLinkVisible(), is(true));
- assertThat(passwordCredentialType.isSetUp(), is(false));
-
- // Set password
- passwordCredentialType.clickSetUpLink();
- updatePasswordPage.assertCurrent();
- String originalPassword = Users.getPasswordOf(testUser);
- updatePasswordPage.updatePasswords(originalPassword, originalPassword);
- signingInPage.assertCurrent();
-
- // Credential set-up now
- assertThat(passwordCredentialType.isSetUpLinkVisible(), is(false));
- assertThat(passwordCredentialType.isSetUp(), is(true));
- SigningInPage.UserCredential passwordCred =
- passwordCredentialType.getUserCredential(testUserResource().credentials().get(0).getId());
- assertUserCredential(PASSWORD_LABEL, false, passwordCred);
- }
-
- @Test
- public void otpTest() {
- testContext.setTestRealmReps(emptyList());
-
- assertThat(otpCredentialType.isSetUp(), is(false));
- otpCredentialType.clickSetUpLink();
- otpSetupPage.cancel();
-
- signingInPage.assertCurrent();
- assertThat(otpCredentialType.isSetUp(), is(false));
- assertThat(otpCredentialType.getTitle(), is("authenticator application"));
-
- final String label1 = "OTP is secure";
- final String label2 = "OTP is inconvenient";
-
- SigningInPage.UserCredential otp1 = addOtpCredential(label1);
- assertThat(otpCredentialType.isSetUp(), is(true));
- assertThat(otpCredentialType.getUserCredentialsCount(), is(1));
- assertUserCredential(label1, true, otp1);
-
- SigningInPage.UserCredential otp2 = addOtpCredential(label2);
- assertThat(otpCredentialType.getUserCredentialsCount(), is(2));
- assertUserCredential(label2, true, otp2);
-
- assertThat("Set up link is not visible", otpCredentialType.isSetUpLinkVisible(), is(true));
- RequiredActionProviderRepresentation requiredAction = new RequiredActionProviderRepresentation();
- requiredAction.setEnabled(false);
- testRealmResource().flows().updateRequiredAction(CONFIGURE_TOTP.name(), requiredAction);
-
- refreshPageAndWaitForLoad();
-
- assertThat("Set up link for \"otp\" is visible", otpCredentialType.isSetUpLinkVisible(), is(false));
- assertThat("Not set up link for \"otp\" is visible", otpCredentialType.isNotSetUpLabelVisible(), is(false));
- assertThat("Title for \"otp\" is not visible", otpCredentialType.isTitleVisible(), is(true));
- assertThat(otpCredentialType.getUserCredentialsCount(), is(2));
-
- testRemoveCredential(otp1);
- }
-
- @Test
- public void setUpLinksTest() {
- testSetUpLink(testRealmResource(), otpCredentialType, CONFIGURE_TOTP.name());
- }
-
- private SigningInPage.UserCredential addOtpCredential(String label) {
- otpCredentialType.clickSetUpLink();
- otpSetupPage.assertCurrent();
- otpSetupPage.clickManualMode();
-
- String secret = new String(Base32.decode(otpSetupPage.getSecretKey()));
- String code = otpGenerator.generateTOTP(secret);
- otpSetupPage.setTotp(code);
- otpSetupPage.setUserLabel(label);
- otpSetupPage.submit();
- signingInPage.assertCurrent();
-
- return getNewestUserCredential(otpCredentialType);
- }
-
- private SigningInPage.UserCredential getNewestUserCredential(SigningInPage.CredentialType credentialType) {
- return SigningInPageUtils.getNewestUserCredential(testUserResource(), credentialType);
- }
-
- private void testRemoveCredential(SigningInPage.UserCredential userCredential) {
- SigningInPageUtils.testRemoveCredential(getAccountPage(), userCredential);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SmokeTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SmokeTest.java
deleted file mode 100644
index 7e456fc6e2..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/SmokeTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2019 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Test;
-import org.keycloak.testsuite.ui.account3.page.DeviceActivityPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-
-/**
- * Basic sanity check for Account Console
- *
- * @author Vaclav Muzikar
- */
-public class SmokeTest extends AbstractAccountTest {
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private DeviceActivityPage deviceActivityPage;
-
- @Test
- public void baseFunctionalityTest() {
- accountWelcomeScreen.assertCurrent();
- accountWelcomeScreen.clickPersonalInfoLink();
- loginToAccount();
- personalInfoPage.assertCurrent();
- deviceActivityPage.navigateToUsingSidebar();
- deviceActivityPage.assertCurrent();
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/UpdateEmailTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/UpdateEmailTest.java
deleted file mode 100644
index d849478896..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/UpdateEmailTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2021 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.account3;
-
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.common.Profile;
-import org.keycloak.events.Details;
-import org.keycloak.events.EventType;
-import org.keycloak.models.UserModel;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
-import org.keycloak.testsuite.auth.page.login.UpdateEmailPage;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-
-@EnableFeature(Profile.Feature.UPDATE_EMAIL)
-public class UpdateEmailTest extends BaseAccountPageTest {
-
- @Page
- private PersonalInfoPage personalInfoPage;
-
- @Page
- private UpdateEmailPage updateEmailPage;
-
- @Rule
- public AssertEvents events = new AssertEvents(this);
-
- @Override
- protected AbstractLoggedInPage getAccountPage() {
- return personalInfoPage;
- }
-
- @Before
- public void setup() {
- enableUpdateEmailRequiredAction();
- }
-
- @After
- public void clean() {
- disableUpdateEmailRequiredAction();
- disableRegistration();
- }
-
- @Test
- public void updateEmailLinkVisibleWithUpdateEmailActionEnabled() {
- refreshPageAndWaitForLoad();
- personalInfoPage.assertUpdateEmailLinkVisible(true);
- }
-
- @Test
- public void updateEmailLinkNotVisibleWithoutUpdateEmailActionEnabled() {
- disableUpdateEmailRequiredAction();
- refreshPageAndWaitForLoad();
- personalInfoPage.assertUpdateEmailLinkVisible(false);
- }
-
- @Test
- public void updateEmailLinkVisibleWithUpdateEmailActionEnabledAndRegistrationEmailAsUsernameAndEditUsernameNotAllowed() {
- enableRegistration(true, false);
- refreshPageAndWaitForLoad();
- personalInfoPage.assertUpdateEmailLinkVisible(false);
- }
-
- @Test
- public void updateUserInfoWithRegistrationEnabled() {
- enableRegistration(false, true);
- refreshPageAndWaitForLoad();
-
- assertTrue(personalInfoPage.valuesEqual(testUser));
- personalInfoPage.assertSaveDisabled(false);
-
- UserRepresentation newInfo = new UserRepresentation();
- newInfo.setUsername(testUser.getUsername());
- newInfo.setEmail(testUser.getEmail());
- newInfo.setFirstName("New First");
- newInfo.setLastName("New Last");
-
- personalInfoPage.setValues(newInfo, true);
- assertTrue(personalInfoPage.valuesEqual(newInfo));
- personalInfoPage.assertSaveDisabled(false);
- personalInfoPage.clickSave();
- personalInfoPage.alert().assertSuccess();
- personalInfoPage.assertSaveDisabled(false);
-
- personalInfoPage.navigateTo();
- personalInfoPage.valuesEqual(newInfo);
- }
-
- @Test
- public void aiaCancellationSucceeds() {
- refreshPageAndWaitForLoad();
- personalInfoPage.assertUpdateEmailLinkVisible(true);
- personalInfoPage.clickUpdateEmailLink();
- Assert.assertTrue(updateEmailPage.isCurrent());
- updateEmailPage.clickCancelAIA();
- Assert.assertTrue(personalInfoPage.isCurrent());
- }
-
- @Test
- public void updateEmailSucceeds() {
- personalInfoPage.navigateTo();
- personalInfoPage.assertUpdateEmailLinkVisible(true);
- personalInfoPage.clickUpdateEmailLink();
- Assert.assertTrue(updateEmailPage.isCurrent());
- updateEmailPage.changeEmail("new-email@example.org");
- events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.UPDATED_EMAIL, "new-email@example.org");
- Assert.assertEquals("new-email@example.org", testRealmResource().users().get(testUser.getId()).toRepresentation().getEmail());
- }
-
- private void disableUpdateEmailRequiredAction() {
- RequiredActionProviderRepresentation updateEmail = testRealmResource().flows().getRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL.name());
- updateEmail.setEnabled(false);
- testRealmResource().flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL.name(), updateEmail);
- }
-
- private void enableUpdateEmailRequiredAction() {
- RequiredActionProviderRepresentation updateEmail = testRealmResource().flows().getRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL.name());
- updateEmail.setEnabled(true);
- testRealmResource().flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL.name(), updateEmail);
- }
-
- private void enableRegistration(boolean emailAsUsername, boolean usernameEditionAllowed) {
- RealmRepresentation realmRepresentation = testRealmResource().toRepresentation();
- realmRepresentation.setRegistrationAllowed(true);
- realmRepresentation.setRegistrationEmailAsUsername(emailAsUsername);
- realmRepresentation.setEditUsernameAllowed(usernameEditionAllowed);
- testRealmResource().update(realmRepresentation);
- }
-
- private void disableRegistration() {
- RealmRepresentation realmRepresentation = testRealmResource().toRepresentation();
- realmRepresentation.setRegistrationAllowed(false);
- realmRepresentation.setRegistrationEmailAsUsername(false);
- realmRepresentation.setEditUsernameAllowed(false);
- testRealmResource().update(realmRepresentation);
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/WelcomeScreenTest.java b/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/WelcomeScreenTest.java
deleted file mode 100644
index e2fa4a1b05..0000000000
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/test/java/org/keycloak/testsuite/ui/account3/WelcomeScreenTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.account3;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Test;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.ui.account3.page.ApplicationsPage;
-import org.keycloak.testsuite.ui.account3.page.DeviceActivityPage;
-import org.keycloak.testsuite.ui.account3.page.LinkedAccountsPage;
-import org.keycloak.testsuite.ui.account3.page.MyResourcesPage;
-import org.keycloak.testsuite.ui.account3.page.PersonalInfoPage;
-
-import static org.junit.Assert.assertEquals;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
-
-/**
- * @author Vaclav Muzikar
- */
-public class WelcomeScreenTest extends AbstractAccountTest {
- @Page
- private PersonalInfoPage personalInfoPage;
- @Page
- private DeviceActivityPage deviceActivityPage;
- @Page
- private LinkedAccountsPage linkedAccountsPage;
- @Page
- private ApplicationsPage applicationsPage;
- @Page
- private MyResourcesPage myResourcesPage;
-
- @Test
- public void loginLogoutTest() {
- accountWelcomeScreen.assertCurrent();
- accountWelcomeScreen.header().assertLogoutBtnVisible(false);
- assertEquals("", accountWelcomeScreen.header().getToolbarLoggedInUser());
-
- // login
- accountWelcomeScreen.header().clickLoginBtn();
- loginToAccount();
- accountWelcomeScreen.assertCurrent();
- accountWelcomeScreen.header().assertLoginBtnVisible(false);
- assertEquals("test user", accountWelcomeScreen.header().getToolbarLoggedInUser());
-
- // try if we're really logged in
- personalInfoPage.navigateTo();
- personalInfoPage.assertCurrent();
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.assertCurrent();
-
- // logout
- accountWelcomeScreen.header().assertLoginBtnVisible(false);
- accountWelcomeScreen.header().clickLogoutBtn();
- accountWelcomeScreen.assertCurrent();
- accountWelcomeScreen.header().assertLogoutBtnVisible(false);
- accountWelcomeScreen.header().assertLoginBtnVisible(true);
- assertEquals("", accountWelcomeScreen.header().getToolbarLoggedInUser());
- personalInfoPage.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(personalInfoPage);
- }
-
- @Test
- public void personalInfoTest() {
- accountWelcomeScreen.clickPersonalInfoLink();
- loginToAccount();
- personalInfoPage.assertCurrent();
- }
-
- @Test
- public void clickLogoTest() {
- accountWelcomeScreen.clickLogoImage();
- accountWelcomeScreen.assertCurrent();
- }
-
- @Test
- public void accountSecurityTest() {
- // TODO rewrite this! (KEYCLOAK-12105)
-// // change password link
-// accountWelcomeScreen.accountSecurityCard().clickChangePassword();
-// loginToAccount();
-// changePasswordPage.assertCurrent();
-//
-// // authenticator link
-// accountWelcomeScreen.navigateTo();
-// accountWelcomeScreen.accountSecurityCard().clickAuthenticator();
-// authenticatorPage.assertCurrent();
-
- assertEquals("", accountWelcomeScreen.header().getToolbarLoggedInUser());
- // device activity link
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.clickDeviceActivityLink();
- loginToAccount();
- deviceActivityPage.assertCurrent();
-
- // linked accounts nav item (this doesn't test welcome page directly but the sidebar after login)
- personalInfoPage.navigateTo();
- personalInfoPage.sidebar().assertNavNotPresent(LinkedAccountsPage.LINKED_ACCOUNTS_ID);
-
- // linked accounts link
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.assertLinkedAccountsLinkVisible(false);
- // add simple IdP
- testRealmResource().identityProviders().create(createIdentityProviderRepresentation("test-idp", "google"));
- // test link appeared
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.clickLinkedAccountsLink();
- linkedAccountsPage.assertCurrent();
- // no need to remove the IdP
- }
-
- @Test
- public void applicationsTest() {
- accountWelcomeScreen.clickApplicationsLink();
- loginToAccount();
- applicationsPage.assertCurrent();
- }
-
- @Test
- public void resourcesTest() {
- accountWelcomeScreen.assertMyResourcesCardVisible(false);
-
- // set user managed access
- RealmRepresentation testRealm = testRealmResource().toRepresentation();
- testRealm.setUserManagedAccessAllowed(true);
- testRealmResource().update(testRealm);
-
- // test my resources appeared
- accountWelcomeScreen.navigateTo();
- accountWelcomeScreen.assertMyResourcesCardVisible(true);
- accountWelcomeScreen.clickMyResourcesLink();
- loginToAccount();
- myResourcesPage.assertCurrent();
- // no need to disable user managed access
- }
-}
diff --git a/testsuite/integration-arquillian/tests/other/pom.xml b/testsuite/integration-arquillian/tests/other/pom.xml
index ba2a61b713..0bd86fcd79 100644
--- a/testsuite/integration-arquillian/tests/other/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/pom.xml
@@ -151,7 +151,6 @@
webauthn
- base-ui
webauthn
diff --git a/testsuite/integration-arquillian/tests/other/webauthn/pom.xml b/testsuite/integration-arquillian/tests/other/webauthn/pom.xml
index 4d23a83daa..6a1eadde99 100644
--- a/testsuite/integration-arquillian/tests/other/webauthn/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/webauthn/pom.xml
@@ -23,11 +23,6 @@
-
- org.keycloak.testsuite
- integration-arquillian-tests-base-ui
- ${project.version}
-
org.jboss.arquillian.extension
arquillian-drone-bom
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractAccountPage.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractAccountPage.java
similarity index 96%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractAccountPage.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractAccountPage.java
index 7399832ad4..152eb27e04 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractAccountPage.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractAccountPage.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page;
+package org.keycloak.testsuite.webauthn.pages;
import org.keycloak.testsuite.auth.page.AuthRealm;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractLoggedInPage.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractLoggedInPage.java
similarity index 90%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractLoggedInPage.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractLoggedInPage.java
index e46b2e30da..06c0695d10 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/AbstractLoggedInPage.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/AbstractLoggedInPage.java
@@ -15,13 +15,13 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page;
+package org.keycloak.testsuite.webauthn.pages;
import org.jboss.arquillian.graphene.page.Page;
-import org.keycloak.testsuite.ui.account3.page.fragment.ContentAlert;
-import org.keycloak.testsuite.ui.account3.page.fragment.ContinueCancelModal;
-import org.keycloak.testsuite.ui.account3.page.fragment.LoggedInPageHeader;
-import org.keycloak.testsuite.ui.account3.page.fragment.Sidebar;
+import org.keycloak.testsuite.webauthn.pages.fragments.ContentAlert;
+import org.keycloak.testsuite.webauthn.pages.fragments.ContinueCancelModal;
+import org.keycloak.testsuite.webauthn.pages.fragments.LoggedInPageHeader;
+import org.keycloak.testsuite.webauthn.pages.fragments.Sidebar;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@@ -53,7 +53,7 @@ public abstract class AbstractLoggedInPage extends AbstractAccountPage {
@FindBy(id = "refresh-page")
private WebElement refreshPageBtn;
-
+
@FindBy(id = "brandLink")
private WebElement brandLink;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/SigningInPage.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/SigningInPage.java
similarity index 97%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/SigningInPage.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/SigningInPage.java
index e06a16eee2..5d5b29e40e 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/SigningInPage.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/SigningInPage.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page;
+package org.keycloak.testsuite.webauthn.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
@@ -212,8 +212,8 @@ public class SigningInPage extends AbstractLoggedInPage {
String lastCreateAtText = getTextFromItem(CREATED_AT);
return lastCreateAtText
- .substring(lastCreatedAtLabel.length(), lastCreateAtText.length() - 1) // remove label, drop last dot
- .trim();
+ .substring(lastCreatedAtLabel.length(), lastCreateAtText.length() - 1) // remove label, drop last dot
+ .trim();
}
public LocalDateTime getCreatedAt() {
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractFragmentWithMobileLayout.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractFragmentWithMobileLayout.java
similarity index 95%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractFragmentWithMobileLayout.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractFragmentWithMobileLayout.java
index cb1b233a42..3e66ccc0cf 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractFragmentWithMobileLayout.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractFragmentWithMobileLayout.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.openqa.selenium.WebDriver;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractHeader.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractHeader.java
similarity index 97%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractHeader.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractHeader.java
index 1b5d56faf8..178f4bbd10 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/AbstractHeader.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/AbstractHeader.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.openqa.selenium.WebElement;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContentAlert.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContentAlert.java
similarity index 98%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContentAlert.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContentAlert.java
index c0d4c0ead6..f96051bd70 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContentAlert.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContentAlert.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.jboss.arquillian.graphene.fragment.Root;
import org.openqa.selenium.By;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContinueCancelModal.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContinueCancelModal.java
similarity index 97%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContinueCancelModal.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContinueCancelModal.java
index 9589c782fb..01113ab2bd 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/ContinueCancelModal.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/ContinueCancelModal.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.openqa.selenium.WebDriver;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/LoggedInPageHeader.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/LoggedInPageHeader.java
similarity index 97%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/LoggedInPageHeader.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/LoggedInPageHeader.java
index 437b7fe032..a57c020f67 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/LoggedInPageHeader.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/LoggedInPageHeader.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/Sidebar.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/Sidebar.java
similarity index 98%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/Sidebar.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/Sidebar.java
index 555b9c6eed..9a49566f59 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/fragment/Sidebar.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/pages/fragments/Sidebar.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.fragment;
+package org.keycloak.testsuite.webauthn.pages.fragments;
import org.jboss.arquillian.graphene.fragment.Root;
import org.openqa.selenium.By;
diff --git a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/utils/SigningInPageUtils.java b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/utils/SigningInPageUtils.java
similarity index 96%
rename from testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/utils/SigningInPageUtils.java
rename to testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/utils/SigningInPageUtils.java
index 90bd3e86df..fc80cae901 100644
--- a/testsuite/integration-arquillian/tests/other/base-ui/src/main/java/org/keycloak/testsuite/ui/account3/page/utils/SigningInPageUtils.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/main/java/org/keycloak/testsuite/webauthn/utils/SigningInPageUtils.java
@@ -15,14 +15,14 @@
* limitations under the License.
*/
-package org.keycloak.testsuite.ui.account3.page.utils;
+package org.keycloak.testsuite.webauthn.utils;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
-import org.keycloak.testsuite.ui.account3.page.AbstractLoggedInPage;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
+import org.keycloak.testsuite.webauthn.pages.AbstractLoggedInPage;
+import org.keycloak.testsuite.webauthn.pages.SigningInPage;
import java.time.LocalDateTime;
import java.util.List;
diff --git a/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/AbstractWebAuthnAccountTest.java b/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/AbstractWebAuthnAccountTest.java
index 9fe3816f97..f0fe5dfa17 100644
--- a/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/AbstractWebAuthnAccountTest.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/AbstractWebAuthnAccountTest.java
@@ -33,8 +33,8 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
import org.keycloak.testsuite.AbstractAuthTest;
import org.keycloak.testsuite.page.AbstractPatternFlyAlert;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
-import org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils;
+import org.keycloak.testsuite.webauthn.pages.SigningInPage;
+import org.keycloak.testsuite.webauthn.utils.SigningInPageUtils;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
import org.keycloak.testsuite.util.FlowUtil;
import org.keycloak.testsuite.webauthn.AbstractWebAuthnVirtualTest;
diff --git a/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/WebAuthnSigningInTest.java b/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/WebAuthnSigningInTest.java
index c95d5762cd..a5ff46aa8c 100644
--- a/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/WebAuthnSigningInTest.java
+++ b/testsuite/integration-arquillian/tests/other/webauthn/src/test/java/org/keycloak/testsuite/webauthn/account/WebAuthnSigningInTest.java
@@ -26,7 +26,7 @@ import org.keycloak.authentication.requiredactions.WebAuthnRegisterFactory;
import org.keycloak.models.credential.WebAuthnCredentialModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
-import org.keycloak.testsuite.ui.account3.page.SigningInPage;
+import org.keycloak.testsuite.webauthn.pages.SigningInPage;
import org.keycloak.testsuite.webauthn.pages.WebAuthnAuthenticatorsList;
import org.keycloak.theme.DateTimeFormatterUtil;
@@ -49,8 +49,8 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
-import static org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils.assertUserCredential;
-import static org.keycloak.testsuite.ui.account3.page.utils.SigningInPageUtils.testSetUpLink;
+import static org.keycloak.testsuite.webauthn.utils.SigningInPageUtils.assertUserCredential;
+import static org.keycloak.testsuite.webauthn.utils.SigningInPageUtils.testSetUpLink;
import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;