keycloak-uncached
Merge pull request #4414 from vmuzikar/KEYCLOAK-5229-dep-update KEYCLOAK-5229 …
Changes
testsuite/integration-arquillian/pom.xml 12(+6 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java 8(+2 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java 12(+8 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java 19(+7 -12)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java 31(+16 -15)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java 6(+4 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Dropdown.java 3(+2 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java 12(+6 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java 26(+7 -19)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPage.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppServerWelcomePage.java 12(+6 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/DroneUtils.java 41(+8 -33)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java 5(+1 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java 35(+32 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java 67(+32 -35)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java 55(+37 -18)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzFunctionalAdapterTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java 9(+3 -6)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java 10(+4 -6)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java 4(+1 -3)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java 8(+4 -4)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java 8(+4 -4)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java 4(+3 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java 6(+3 -3)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/RequiredActions.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java 22(+17 -5)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java 18(+9 -9)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java 2(+2 -0)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java 18(+8 -10)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java 18(+9 -9)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java 10(+5 -5)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java 20(+11 -9)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java 6(+3 -3)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java 2(+1 -1)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java 4(+2 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java 8(+4 -4)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java 2(+0 -2)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/LoginEventsTest.java 6(+3 -3)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/realm/LoginSettingsTest.java 9(+6 -3)
Details
diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md
index 3098a35..6c1a07c 100644
--- a/testsuite/integration-arquillian/HOW-TO-RUN.md
+++ b/testsuite/integration-arquillian/HOW-TO-RUN.md
@@ -336,9 +336,15 @@ To run the tests run:
  
 #### Mozilla Firefox
 * **Supported version:** [latest ESR](https://www.mozilla.org/en-US/firefox/organizations/) (Extended Support Release)
-* **Driver download required:** no
+* **Driver download required:** no (using the old legacy Firefox driver)
 * **Run with:** `-Dbrowser=firefox`; optionally you can specify `-Dfirefox_binary=path/to/firefox/binary`
 
+#### Mozilla Firefox with GeckoDriver
+You can also use Firefox automation with modern Marionette protocol and GeckoDriver. However, this is **highly experimental** and the testsuite may not work as expected.
+* **Supported version:** as latest as possible (Firefox has better support for Marionette with each version released)
+* **Driver download required:** [GeckoDriver](https://github.com/mozilla/geckodriver/releases)
+* **Run with:** `-Dbrowser=firefox -DfirefoxLegacyDriver=false -Dwebdriver.gecko.driver=path/to/geckodriver`
+
 #### Google Chrome
 * **Supported version:** latest stable
 * **Driver download required:** [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) which corresponds with your version of the browser
@@ -346,9 +352,12 @@ To run the tests run:
 
 #### Internet Explorer
 * **Supported version:** 11
-* **Driver download required:** [Internet Explorer Driver Server](http://www.seleniumhq.org/download/); recommended version [2.53.1 32-bit](http://selenium-release.storage.googleapis.com/2.53/IEDriverServer_Win32_2.53.1.zip)
+* **Driver download required:** [Internet Explorer Driver Server](http://www.seleniumhq.org/download/); recommended version [3.5.1 32-bit](http://selenium-release.storage.googleapis.com/3.5/IEDriverServer_Win32_3.5.1.zip)
 * **Run with:** `-Dbrowser=internetExplorer -Dwebdriver.ie.driver=path/to/IEDriverServer.exe`
- 
+
+#### Automatic driver downloads
+You can rely on automatic driver downloads which is provided by [Arquillian Drone](http://arquillian.org/arquillian-extension-drone/#_automatic_download). To do so just omit the `-Dwebdriver.{browser}.driver` CLI argument when running the tests.
+
 ## Run X.509 tests
 
 To run the X.509 client certificate authentication tests:
                testsuite/integration-arquillian/pom.xml 12(+6 -6)
diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
index 78a7648..e2f300c 100644
--- a/testsuite/integration-arquillian/pom.xml
+++ b/testsuite/integration-arquillian/pom.xml
@@ -41,14 +41,14 @@
         <app.server.java.home>${java.home}</app.server.java.home>
 
         <!--component versions-->
-        <arquillian-core.version>1.1.11.Final</arquillian-core.version>
-        <selenium.version>2.53.0</selenium.version>
-        <arquillian-drone.version>2.0.1.Final</arquillian-drone.version>
-        <arquillian-graphene.version>2.1.0.Alpha3</arquillian-graphene.version>
+        <arquillian-core.version>1.1.13.Final</arquillian-core.version>
+        <selenium.version>3.5.1</selenium.version>
+        <arquillian-drone.version>2.4.0</arquillian-drone.version>
+        <arquillian-graphene.version>2.3.1</arquillian-graphene.version>
         <arquillian-wildfly-container.version>2.1.0.Beta1</arquillian-wildfly-container.version>
         <arquillian-wls-container.version>1.0.1.Final</arquillian-wls-container.version>
-        <arquillian-infinispan-container.version>1.2.0.Alpha2</arquillian-infinispan-container.version>
-        <version.shrinkwrap.resolvers>2.2.2</version.shrinkwrap.resolvers>
+        <arquillian-infinispan-container.version>1.2.0.Beta2</arquillian-infinispan-container.version>
+        <version.shrinkwrap.resolvers>2.2.6</version.shrinkwrap.resolvers>
         <undertow-embedded.version>1.0.0.Alpha2</undertow-embedded.version>
 
         <!--migration properties-->
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
index 4d11f93..32cc58f 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
@@ -93,9 +93,9 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     }
 
     public void navigateToAdminAlbum() {
-        URLUtils.navigateToUri(driver, toString() + "/#/admin/album", true);
+        URLUtils.navigateToUri(toString() + "/#/admin/album", true);
         driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         pause(WAIT_AFTER_OPERATION);
     }
 
@@ -136,7 +136,7 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
                 scopesValue.append(scope);
             }
 
-            URLUtils.navigateToUri(driver, this.driver.getCurrentUrl() + " " + scopesValue, true);
+            URLUtils.navigateToUri(this.driver.getCurrentUrl() + " " + scopesValue, true);
         }
 
         this.loginPage.form().login(username, password);
@@ -155,7 +155,7 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
 
     public void viewAlbum(String name) throws InterruptedException {
         this.driver.findElement(By.xpath("//a[text() = '" + name + "']")).click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
         pause(WAIT_AFTER_OPERATION);
     }
@@ -172,6 +172,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
 
     @Override
     public boolean isCurrent() {
-        return URLUtils.currentUrlStartWith(driver, toString());
+        return URLUtils.currentUrlStartWith(toString());
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
index 33dc8c2..4671ccb 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
@@ -17,18 +17,17 @@
 
 package org.keycloak.testsuite.arquillian;
 
-import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
 import org.jboss.arquillian.container.osgi.OSGiApplicationArchiveProcessor;
+import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
 import org.jboss.arquillian.container.test.impl.enricher.resource.URLResourceProvider;
 import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
 import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator;
 import org.jboss.arquillian.core.spi.LoadableExtension;
 import org.jboss.arquillian.drone.spi.Configurator;
-import org.jboss.arquillian.drone.spi.Instantiator;
-import org.jboss.arquillian.drone.webdriver.factory.HtmlUnitDriverFactory;
 import org.jboss.arquillian.drone.webdriver.factory.WebDriverFactory;
 import org.jboss.arquillian.graphene.location.ContainerCustomizableURLResourceProvider;
 import org.jboss.arquillian.graphene.location.CustomizableURLResourceProvider;
+import org.jboss.arquillian.test.spi.TestEnricher;
 import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
 import org.jboss.arquillian.test.spi.execution.TestExecutionDecider;
 import org.keycloak.testsuite.arquillian.h2.H2TestEnricher;
@@ -43,9 +42,7 @@ import org.keycloak.testsuite.arquillian.provider.TestContextProvider;
 import org.keycloak.testsuite.arquillian.provider.URLProvider;
 import org.keycloak.testsuite.drone.HtmlUnitScreenshots;
 import org.keycloak.testsuite.drone.KeycloakDronePostSetup;
-import org.keycloak.testsuite.drone.KeycloakHtmlUnitInstantiator;
 import org.keycloak.testsuite.drone.KeycloakWebDriverConfigurator;
-import org.jboss.arquillian.test.spi.TestEnricher;
 
 /**
  *
@@ -83,7 +80,6 @@ public class KeycloakArquillianExtension implements LoadableExtension {
 
         builder
                 .override(Configurator.class, WebDriverFactory.class, KeycloakWebDriverConfigurator.class)
-                .override(Instantiator.class, HtmlUnitDriverFactory.class, KeycloakHtmlUnitInstantiator.class)
                 .observer(HtmlUnitScreenshots.class)
                 .observer(KeycloakDronePostSetup.class);
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
index 0e55060..bb1b330 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
@@ -83,7 +83,7 @@ public class AccountFields extends Form {
     }
 
     public void waitForUsernameInputNotPresent() {
-        waitUntilElementIsNotPresent(driver, usernameInput);
+        waitUntilElementIsNotPresent(usernameInput);
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
index 59c5026..5f5da8c 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
@@ -24,6 +24,7 @@ import org.openqa.selenium.support.FindBy;
 
 import javax.ws.rs.core.UriBuilder;
 
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
@@ -77,6 +78,7 @@ public class AccountManagement extends AuthRealm implements PageWithLogOutAction
 
     public void signOut() {
         signOutLink.click();
+        waitForPageToLoad();
     }
     
     @Override
@@ -86,34 +88,36 @@ public class AccountManagement extends AuthRealm implements PageWithLogOutAction
     
     public void account() {
         accountLink.click();
+        waitForPageToLoad();
     }
 
     public void password() {
         passwordLink.click();
+        waitForPageToLoad();
     }
 
     public void authenticator() {
         authenticatorLink.click();
+        waitForPageToLoad();
     }
 
     public void sessions() {
         sessionsLink.click();
+        waitForPageToLoad();
     }
 
     public void applications() {
         applicationsLink.click();
+        waitForPageToLoad();
     }
 
     public void save() {
         save.click();
+        waitForPageToLoad();
     }
 
 //    public RealmResource realmResource() {
 //        return keycloak().realm(getAuthRealm());
 //    }
 
-    public void waitForAccountLinkPresent() {
-        waitUntilElement(accountLink, "account link should be present").is().present();
-    }
-
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
index 9a38cf6..ff2a570 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
@@ -25,7 +25,7 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 import static org.keycloak.testsuite.admin.Users.getPasswordOf;
-import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElementIsNotPresent;
 
@@ -76,28 +76,24 @@ public class LoginForm extends Form {
     }
 
     public void register() {
-        registerLink.click();
-        waitForPageToLoad(driver);
+        clickLink(registerLink);
     }
 
     public void login() {
         labelPassword.click(); // This is a nasty trick for IE; As IE was "moving the cursor" towards the login button
                                // it opened the internationalization menu (when present) and then clicked
                                // one of the languages instead of the Login button
-        loginButton.click();
-        waitForPageToLoad(driver);
+        clickLink(loginButton);
     }
 
     public void forgotPassword() {
-        forgottenPassword.click();
-        waitForPageToLoad(driver);
+        clickLink(forgottenPassword);
     }
 
     public void rememberMe(boolean value) {
         boolean selected = rememberMe.isSelected();
         if ((value && !selected) || !value && selected) {
             rememberMe.click();
-            waitForPageToLoad(driver);
         }
     }
 
@@ -111,7 +107,7 @@ public class LoginForm extends Form {
     }
 
     public void waitForRegisterLinkNotPresent() {
-        waitUntilElementIsNotPresent(driver, registerLink);
+        waitUntilElementIsNotPresent(registerLink);
     }
 
     public void waitForResetPasswordLinkNotPresent() {
@@ -123,7 +119,7 @@ public class LoginForm extends Form {
     }
 
     public void waitForRememberMeNotPresent() {
-        waitUntilElementIsNotPresent(driver, rememberMe);
+        waitUntilElementIsNotPresent(rememberMe);
     }
 
     public void waitForLoginButtonPresent() {
@@ -157,8 +153,7 @@ public class LoginForm extends Form {
         }
         
         public void submit() {
-            submit.click();
-            waitForPageToLoad(driver);
+            clickLink(submit);
         }
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java
index a732c47..9adb530 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/TermsAndConditions.java
@@ -37,16 +37,16 @@ public class TermsAndConditions extends LoginActions {
     
     @Override
     public boolean isCurrent() {
-        return UIUtils.currentTitleEquals(driver, "Terms and Conditions");
+        return UIUtils.currentTitleEquals("Terms and Conditions");
     }
 
     public void acceptTerms() {
         acceptButton.click();
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
     }
     public void declineTerms() {
         declineButton.click();
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
     }
 
     public String getAcceptButtonText() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java
index 3c4dda8..c29b160 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java
@@ -16,23 +16,24 @@
  */
 package org.keycloak.testsuite.console.page.fragment;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
 import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.graphene.fragment.Root;
-import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.JavascriptExecutor;
 import org.openqa.selenium.Keys;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.FindBy;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -44,7 +45,7 @@ public abstract class AbstractMultipleSelect2<R> {
     @Drone
     private WebDriver driver;
 
-    @FindBy(xpath = ".//input[contains(@class,'select2-input')]")
+    @FindBy(xpath = "//input[contains(@class,'select2-focused')]")
     private WebElement search;
 
     @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
@@ -76,17 +77,17 @@ public abstract class AbstractMultipleSelect2<R> {
     }
 
     public void select(R value) {
+        pause(500);
         root.click();
-        WaitUtils.pause(500);
+        pause(500);
 
         String id = identity().apply(value);
 
-        Actions actions = new Actions(driver);
-        actions.sendKeys(id).perform();
-        WaitUtils.pause(500);
+        search.sendKeys(id);
+        waitForPageToLoad();
 
         if (result.isEmpty()) {
-            actions.sendKeys(Keys.ESCAPE).perform();
+            search.sendKeys(Keys.ESCAPE);
             return;
         }
 
@@ -137,7 +138,7 @@ public abstract class AbstractMultipleSelect2<R> {
                 WebElement element = selected.findElement(By.xpath(".//a[contains(@class,'select2-search-choice-close')]"));
                 JavascriptExecutor executor = (JavascriptExecutor) driver;
                 executor.executeScript("arguments[0].click();", element);
-                WaitUtils.pause(500);
+                pause(500);
                 return true;
             }
             return false;
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
index 4f128cd..9906b13 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
@@ -25,6 +25,7 @@ import org.openqa.selenium.support.FindBy;
 
 import java.util.List;
 
+import static org.keycloak.testsuite.util.WaitUtils.pause;
 import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
 import static org.openqa.selenium.By.xpath;
 
@@ -59,12 +60,12 @@ public class DataTable {
 
     public void clickHeaderButton(String buttonText) {
         header.findElement(By.xpath(".//button[text()='" + buttonText + "']")).click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void clickHeaderLink(String linkText) {
         header.findElement(By.linkText(linkText)).click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public WebElement body() {
@@ -72,6 +73,7 @@ public class DataTable {
     }
 
     public List<WebElement> rows() {
+        pause(500); // wait a bit to ensure the table is no more changing
         return rows;
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Dropdown.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Dropdown.java
index e5081e6..6c5d4e1 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Dropdown.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Dropdown.java
@@ -6,6 +6,7 @@ import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 
+import static org.keycloak.testsuite.util.URLUtils.navigateToUri;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
@@ -27,6 +28,6 @@ public class Dropdown {
     public void selectByText(String text) {
         waitUntilElement(dropDownRoot).is().present();
         WebElement element = dropDownRoot.findElement(By.xpath("./ul/li/a[text()='" + text + "']"));
-        driver.navigate().to(element.getAttribute("href"));
+        navigateToUri(element.getAttribute("href"), true); // TODO: move cursor to show the menu and then click the menu item
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
index 9639749..2d3b7f6 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
@@ -52,21 +52,21 @@ public class ModalDialog {
     private WebElement message;
 
     public void ok() {
-        waitForModalFadeIn(driver);
+        waitForModalFadeIn();
         okButton.click();
-        waitForModalFadeOut(driver);
+        waitForModalFadeOut();
     }
     
     public void confirmDeletion() {
-        waitForModalFadeIn(driver);
+        waitForModalFadeIn();
         deleteButton.click();
-        waitForModalFadeOut(driver);
+        waitForModalFadeOut();
     }
 
     public void cancel() {
-        waitForModalFadeIn(driver);
+        waitForModalFadeIn();
         cancelButton.click();
-        waitForModalFadeOut(driver);
+        waitForModalFadeOut();
     }
 
     public void setName(String name) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
index ccb6817..5c57758 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
@@ -17,12 +17,8 @@
 package org.keycloak.testsuite.console.page.fragment;
 
 import org.jboss.arquillian.graphene.fragment.Root;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
-
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+import org.openqa.selenium.support.FindBy;
 
 /**
  *
@@ -33,26 +29,18 @@ public class OnOffSwitch {
     @Root
     private WebElement root;
 
-    @ArquillianResource
-    private Actions actions;
-
-    public OnOffSwitch() {
-    }
+    @FindBy(tagName = "input")
+    private WebElement inputTag;
 
-    public OnOffSwitch(WebElement root, Actions actions) {
-        this.root = root;
-        this.actions = actions;
-    }
+    @FindBy(tagName = "label")
+    private WebElement labelTag;
 
     public boolean isOn() {
-        waitUntilElement(root).is().present();
-        return root.findElement(By.tagName("input")).isSelected();
+        return inputTag.isSelected();
     }
 
     private void click() {
-        waitUntilElement(root).is().present();
-        actions.moveToElement(root.findElement(By.tagName("label")))
-                .click().build().perform();
+        labelTag.click();
     }
 
     public void toggle() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java
index 59f1021..4778da6 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java
@@ -51,7 +51,7 @@ public abstract class AbstractAlert {
     }
 
     protected boolean checkAlertType(String type) {
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
         try {
             (new WebDriverWait(driver, 1)).until(ExpectedConditions.attributeContains(root, "class", "alert-" + type));
         }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPage.java
index 4d002fc..34daa16 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPage.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractPage.java
@@ -95,11 +95,11 @@ public abstract class AbstractPage {
     }
 
     public void navigateTo(boolean waitForMatch) {
-        URLUtils.navigateToUri(driver, buildUri().toASCIIString(), waitForMatch);
+        URLUtils.navigateToUri(buildUri().toASCIIString(), waitForMatch);
     }
 
     public boolean isCurrent() {
-        return URLUtils.currentUrlEqual(driver, toString());
+        return URLUtils.currentUrlEqual(toString());
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
index 6af4998..6eab0c7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
@@ -47,7 +47,7 @@ public class Form {
     public void save() {
 //        guardAjax(save).click();
         save.click();
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
     }
 
     public void cancel() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppServerWelcomePage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppServerWelcomePage.java
index d7056ee..de8bc09 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppServerWelcomePage.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppServerWelcomePage.java
@@ -50,29 +50,29 @@ public class AppServerWelcomePage extends AppServerContextRoot {
 
     public void navigateToConsole() {
         WaitUtils.pause(2000);
-        URLUtils.navigateToUri(driver, getInjectedUrl().toString() + "/console", true);
-        waitForPageToLoad(driver);
+        URLUtils.navigateToUri(getInjectedUrl().toString() + "/console", true);
+        waitForPageToLoad();
     }
 
     public void login(String username, String password) {
         loginPage.form().waitForLoginButtonPresent();
         loginPage.form().login(username, password);
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void navigateToAccessControl() {
         accessControlLink.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void navigateManageProfile() {
         manageProfileLink.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void logout() {
         logoutLink.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public boolean isLoginPage() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
index e577758..f4c9819 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
@@ -19,7 +19,6 @@ package org.keycloak.testsuite.util;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -50,7 +49,6 @@ import org.keycloak.representations.IDToken;
 import org.keycloak.representations.RefreshToken;
 import org.keycloak.representations.idm.KeysMetadataRepresentation;
 import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
-import org.keycloak.testsuite.arquillian.SuiteContext;
 import org.keycloak.util.BasicAuthHelper;
 import org.keycloak.util.JsonSerialization;
 import org.keycloak.util.TokenUtil;
@@ -60,7 +58,6 @@ import org.openqa.selenium.WebDriver;
 
 import javax.ws.rs.core.UriBuilder;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
@@ -204,7 +201,7 @@ public class OAuthClient {
     }
 
     public void fillLoginForm(String username, String password) {
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
         String src = driver.getPageSource();
         try {
             driver.findElement(By.id("username")).sendKeys(username);
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
index ec54244..84cd7c8 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/UIUtils.java
@@ -1,12 +1,14 @@
 package org.keycloak.testsuite.util;
 
 import org.openqa.selenium.TimeoutException;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.ui.ExpectedConditions;
 import org.openqa.selenium.support.ui.Select;
 import org.openqa.selenium.support.ui.WebDriverWait;
 
+import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+
 /**
  * @author Vaclav Muzikar <vmuzikar@redhat.com>
  */
@@ -21,13 +23,40 @@ public final class UIUtils {
         return false;
     }
 
-    public static boolean currentTitleEquals(WebDriver driver, String url) {
+    public static boolean currentTitleEquals(String url) {
         try {
-            (new WebDriverWait(driver, 5)).until(ExpectedConditions.titleIs(url));
+            (new WebDriverWait(getCurrentDriver(), 5)).until(ExpectedConditions.titleIs(url));
         }
         catch (TimeoutException e) {
             return false;
         }
         return true;
     }
+
+    /**
+     * Safely performs an operation which is expected to cause a page reload, e.g. a link click.
+     * This ensures the page will be fully loaded after the operation.
+     * This is intended for use in UI tests only.
+     *
+     * @param operation
+     */
+    public static void performOperationWithPageReload(Runnable operation) {
+        operation.run();
+        waitForPageToLoad();
+    }
+
+    public static void clickLink(WebElement element) {
+        performOperationWithPageReload(element::click);
+    }
+
+    /**
+     * Navigates to a link directly instead of clicking on it.
+     * Some browsers are sometimes having problems with clicking on links, so this should be used only in that cases,
+     * i.e. only when clicking directly doesn't work
+     *
+     * @param element
+     */
+    public static void navigateToLink(WebElement element) {
+        URLUtils.navigateToUri(element.getAttribute("href"), true);
+    }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
index ea7d72c..e3985c5 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
@@ -10,8 +10,9 @@ import org.openqa.selenium.support.ui.WebDriverWait;
 
 import java.util.regex.Pattern;
 
+import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
 import static org.openqa.selenium.support.ui.ExpectedConditions.not;
-import static org.openqa.selenium.support.ui.ExpectedConditions.or;
 import static org.openqa.selenium.support.ui.ExpectedConditions.urlMatches;
 import static org.openqa.selenium.support.ui.ExpectedConditions.urlToBe;
 
@@ -20,12 +21,15 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.urlToBe;
  */
 public final class URLUtils {
 
-    public static void navigateToUri(WebDriver driver, String uri, boolean waitForMatch) {
-        navigateToUri(driver, uri, waitForMatch, true);
+    private static Logger log = Logger.getLogger(URLUtils.class);
+
+    public static void navigateToUri(String uri, boolean waitForMatch) {
+        navigateToUri(uri, waitForMatch, true);
     }
 
-    private static void navigateToUri(WebDriver driver, String uri, boolean waitForMatch, boolean enableIEWorkaround) {
-        Logger log = Logger.getLogger(URLUtils.class);
+    // TODO: remove waitForMatch
+    private static void navigateToUri(String uri, boolean waitForMatch, boolean enableIEWorkaround) {
+        WebDriver driver = getCurrentDriver();
 
         log.info("starting navigation");
 
@@ -34,27 +38,20 @@ public final class URLUtils {
         if (driver instanceof InternetExplorerDriver && driver.getCurrentUrl().equals(uri)) {
             log.info("IE workaround: target URL equals current URL - refreshing the page");
             driver.navigate().refresh();
+            waitForPageToLoad();
         }
 
-        WaitUtils.waitForPageToLoad(driver);
-
         log.info("current URL:  " + driver.getCurrentUrl());
         log.info("navigating to " + uri);
-        driver.navigate().to(uri);
-
-        if (waitForMatch) {
-            // Possible login URL; this is to eliminate unnecessary wait when navigating to a secured page and being
-            // redirected to the login page
-            String loginUrl = "^[^\\?]+/auth/realms/[^/]+/(protocol|login-actions).+$";
-
-            try {
-                (new WebDriverWait(driver, 3)).until(or(urlMatches("^" + Pattern.quote(uri) + ".*$"), urlMatches(loginUrl)));
-            } catch (TimeoutException e) {
-                log.info("new current URL doesn't start with desired URL");
-            }
+        if (driver.getCurrentUrl().equals(uri)) { // Some browsers won't do anything if navigating to the same URL; this "fixes" it
+            log.info("target URL equals current URL - refreshing the page");
+            driver.navigate().refresh();
+        }
+        else {
+            driver.navigate().to(uri);
         }
 
-        WaitUtils.waitForPageToLoad(driver);
+        waitForPageToLoad();
 
         log.info("new current URL:  " + driver.getCurrentUrl());
 
@@ -65,45 +62,45 @@ public final class URLUtils {
                 && (driver.getCurrentUrl().matches("^[^#]+/#state=[^#/&]+&code=[^#/&]+$")
                 ||  driver.getCurrentUrl().matches("^.+/auth/admin/[^/]+/console/$"))) {
             log.info("IE workaround: reloading the page after deleting the cookies...");
-            navigateToUri(driver, uri, waitForMatch, false);
+            navigateToUri(uri, waitForMatch, false);
         }
         else {
             log.info("navigation complete");
         }
     }
 
-    public static boolean currentUrlEqual(WebDriver driver, String url) {
-        return urlCheck(driver, urlToBe(url));
+    public static boolean currentUrlEqual(String url) {
+        return urlCheck(urlToBe(url));
     }
 
-    public static boolean currentUrlDoesntEqual(WebDriver driver, String url) {
-        return urlCheck(driver, not(urlToBe(url)));
+    public static boolean currentUrlDoesntEqual(String url) {
+        return urlCheck(not(urlToBe(url)));
     }
 
-    public static boolean currentUrlStartWith(WebDriver driver, String url) {
-        return urlCheck(driver, urlMatches("^" + Pattern.quote(url) + ".*$"));
+    public static boolean currentUrlStartWith(String url) {
+        return urlCheck(urlMatches("^" + Pattern.quote(url) + ".*$"));
     }
 
-    public static boolean currentUrlDoesntStartWith(WebDriver driver, String url) {
-        return urlCheck(driver, urlMatches("^(?!" + Pattern.quote(url) + ").+$"));
+    public static boolean currentUrlDoesntStartWith(String url) {
+        return urlCheck(urlMatches("^(?!" + Pattern.quote(url) + ").+$"));
     }
 
-    private static boolean urlCheck(WebDriver driver, ExpectedCondition condition) {
-        return urlCheck(driver, condition, false);
+    private static boolean urlCheck(ExpectedCondition condition) {
+        return urlCheck(condition, false);
     }
 
-    private static boolean urlCheck(WebDriver driver, ExpectedCondition condition, boolean secondTry) {
-        Logger log = Logger.getLogger(URLUtils.class);
+    private static boolean urlCheck(ExpectedCondition condition, boolean secondTry) {
+        WebDriver driver = getCurrentDriver();
 
         try {
-            (new WebDriverWait(driver, 1, 100)).until(condition);
+            (new WebDriverWait(driver, 5, 100)).until(condition);
         }
         catch (TimeoutException e) {
             if (driver instanceof InternetExplorerDriver && !secondTry) {
                 // IE WebDriver has sometimes invalid current URL
                 log.info("IE workaround: checking URL failed at first attempt - refreshing the page and trying one more time...");
                 driver.navigate().refresh();
-                urlCheck(driver, condition, true);
+                urlCheck(condition, true);
             }
             else {
                 return false;
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
index 216e2ca..30ec1a8 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
@@ -21,17 +21,18 @@ import org.openqa.selenium.By;
 import org.openqa.selenium.TimeoutException;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
+import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+import org.openqa.selenium.support.ui.FluentWait;
 import org.openqa.selenium.support.ui.WebDriverWait;
 
 import java.util.Collections;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import static org.jboss.arquillian.graphene.Graphene.waitGui;
-import static org.openqa.selenium.support.ui.ExpectedConditions.invisibilityOfAllElements;
-import static org.openqa.selenium.support.ui.ExpectedConditions.javaScriptThrowsNoExceptions;
-import static org.openqa.selenium.support.ui.ExpectedConditions.not;
-import static org.openqa.selenium.support.ui.ExpectedConditions.urlContains;
+import static org.keycloak.testsuite.util.DroneUtils.getCurrentDriver;
+import static org.openqa.selenium.support.ui.ExpectedConditions.*;
 
 /**
  *
@@ -64,13 +65,14 @@ public final class WaitUtils {
         return waitGui().until(failMessage).element(element);
     }
 
-    public static void waitUntilElementIsNotPresent(WebDriver driver, By locator) {
-        waitUntilElementIsNotPresent(driver, driver.findElement(locator));
+    public static void waitUntilElementIsNotPresent(By locator) {
+        waitUntilElement(locator).is().not().present();
     }
 
-    public static void waitUntilElementIsNotPresent(WebDriver driver, WebElement element) {
-        (new WebDriverWait(driver, IMPLICIT_ELEMENT_WAIT_MILLIS))
-                .until(invisibilityOfAllElements(Collections.singletonList(element)));
+    public static void waitUntilElementIsNotPresent(WebElement element) {
+        waitUntilElement(element).is().not().present();
+//        (new WebDriverWait(driver, IMPLICIT_ELEMENT_WAIT_MILLIS))
+//                .until(invisibilityOfAllElements(Collections.singletonList(element)));
     }
 
     public static void pause(long millis) {
@@ -89,15 +91,32 @@ public final class WaitUtils {
      * Waits for page to finish any pending redirects, REST API requests etc.
      * Because Keycloak's Admin Console is a single-page application, we need to
      * take extra steps to ensure the page is fully loaded
-     *
-     * @param driver
      */
-    public static void waitForPageToLoad(WebDriver driver) {
-        WebDriverWait wait = new WebDriverWait(driver, PAGELOAD_TIMEOUT_MILLIS / 1000);
+    public static void waitForPageToLoad() {
+        WebDriver driver = getCurrentDriver();
 
-        try {
-            wait.until(not(urlContains("redirect_fragment")));
+        if (driver instanceof HtmlUnitDriver) {
+            return; // not needed
+        }
+
+        // Ensure the URL is "stable", i.e. is not changing anymore; if it'd changing, some redirects are probably still in progress
+        for (int maxRedirects = 2; maxRedirects > 0; maxRedirects--) {
+            String currentUrl = driver.getCurrentUrl();
+            FluentWait<WebDriver> wait = new FluentWait<>(driver).withTimeout(250, TimeUnit.MILLISECONDS);
+            try {
+                wait.until(not(urlToBe(currentUrl)));
+            }
+            catch (TimeoutException e) {
+                break; // URL has not changed recently - ok, the URL is stable and page is current
+            }
+            if (maxRedirects == 1) {
+                log.warn("URL seems unstable! (Some redirect are probably still in progress)");
+            }
+        }
 
+        WebDriverWait wait = new WebDriverWait(getCurrentDriver(), PAGELOAD_TIMEOUT_MILLIS / 1000);
+
+        try {
             // Checks if the document is ready and asks AngularJS, if present, whether there are any REST API requests
             // in progress
             wait.until(javaScriptThrowsNoExceptions(
@@ -112,12 +131,12 @@ public final class WaitUtils {
         }
     }
 
-    public static void waitForModalFadeIn(WebDriver driver) {
+    public static void waitForModalFadeIn() {
         pause(500); // TODO: Find out how to do in more 'elegant' way, e.g. like in the waitForModalFadeOut
     }
 
-    public static void waitForModalFadeOut(WebDriver driver) {
-        waitUntilElementIsNotPresent(driver, By.className("modal-backdrop"));
+    public static void waitForModalFadeOut() {
+        waitUntilElementIsNotPresent(By.className("modal-backdrop"));
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzFunctionalAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzFunctionalAdapterTest.java
index 49158fa..a46f8f1 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzFunctionalAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzFunctionalAdapterTest.java
@@ -207,7 +207,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testAccessPublicResource() throws Exception {
         performTests(() -> {
             driver.navigate().to(getResourceServerUrl() + "/public-html.html");
-            WaitUtils.waitForPageToLoad(driver);
+            WaitUtils.waitForPageToLoad();
             assertTrue(hasText("This is public resource that should be accessible without login."));
         });
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java
index f95fe7f..ace5807 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractClientInitiatedAccountLinkTest.java
@@ -48,7 +48,6 @@ import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
 import org.keycloak.testsuite.pages.ErrorPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
-import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
 import org.keycloak.testsuite.util.OAuthClient;
 import org.keycloak.testsuite.util.WaitUtils;
 import org.keycloak.util.JsonSerialization;
@@ -61,8 +60,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
 import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS;
@@ -545,7 +542,7 @@ public abstract class AbstractClientInitiatedAccountLinkTest extends AbstractSer
 
         // Login to account mgmt first
         profilePage.open(CHILD_IDP);
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
 
         Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
         loginPage.login("child", "password");
@@ -590,7 +587,7 @@ public abstract class AbstractClientInitiatedAccountLinkTest extends AbstractSer
 
         // Login to account mgmt first
         profilePage.open(CHILD_IDP);
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
 
         Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
         loginPage.login("child", "password");
@@ -624,7 +621,7 @@ public abstract class AbstractClientInitiatedAccountLinkTest extends AbstractSer
 
     private void navigateTo(String uri) {
         driver.navigate().to(uri);
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
     }
 
     
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
index f7a9335..721c89e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
@@ -53,8 +53,6 @@ import org.keycloak.testsuite.util.*;
 import org.keycloak.testsuite.util.URLUtils;
 import org.keycloak.util.BasicAuthHelper;
 
-import org.openqa.selenium.By;
-
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.client.Entity;
@@ -197,7 +195,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
         assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
         testRealmLoginPage.form().login("bburke@redhat.com", "password");
         assertCurrentUrlEquals(driver, inputPortal + "/secured/post");
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         String pageSource = driver.getPageSource();
         assertThat(pageSource, containsString("parameter=hello"));
 
@@ -564,7 +562,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
 
         // Test I need to reauthenticate with prompt=login
         String appUri = tokenMinTTLPage.getUriBuilder().queryParam(OIDCLoginProtocol.PROMPT_PARAM, OIDCLoginProtocol.PROMPT_VALUE_LOGIN).build().toString();
-        URLUtils.navigateToUri(driver, appUri, true);
+        URLUtils.navigateToUri(appUri, true);
         assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
         testRealmLoginPage.form().login("bburke@redhat.com", "password");
         AccessToken token = tokenMinTTLPage.getAccessToken();
@@ -624,7 +622,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
         oAuthGrantPage.accept();
 
         String pageSource = driver.getPageSource();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         assertThat(pageSource, containsString("Bill Burke"));
         assertThat(pageSource, containsString("Stian Thorgersen"));
 
@@ -682,7 +680,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
 
         testRealmLoginPage.form().login("bburke@redhat.com", "password");
 
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         String pageSource = driver.getPageSource();
         assertThat(pageSource, containsString("Bill Burke"));
         assertThat(pageSource, containsString("Stian Thorgersen"));
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
index b62ba31..a2b2634 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
@@ -397,7 +397,7 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
 
     private void checkLoggedOut(AbstractPage page, Login loginPage) {
         page.navigateTo();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         assertCurrentUrlStartsWith(loginPage);
     }
 
@@ -950,7 +950,7 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
         assertCurrentUrlStartsWith(testRealmSAMLPostLoginPage);
         testRealmSAMLPostLoginPage.form().login("bburke", "password");
         assertCurrentUrlStartsWith(employeeServletPage);
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
         String pageSource = driver.getPageSource();
         assertThat(pageSource, containsString("Relay state: " + SamlSPFacade.RELAY_STATE));
         assertThat(pageSource, not(containsString("SAML response: null")));
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java
index 3868fb5..3a87cdc 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java
@@ -17,7 +17,6 @@
 package org.keycloak.testsuite.adapter.servlet.cluster;
 
 import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.*;
 import org.keycloak.testsuite.Retry;
 import org.keycloak.testsuite.adapter.page.EmployeeServletDistributable;
@@ -57,7 +56,6 @@ import org.openqa.selenium.support.ui.WebDriverWait;
 
 import static org.hamcrest.Matchers.*;
 import static org.junit.Assert.assertThat;
-import static org.keycloak.testsuite.AbstractAuthTest.createUserRepresentation;
 import static org.keycloak.testsuite.admin.Users.setPasswordFor;
 import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getNearestSuperclassWithAnnotation;
 import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
@@ -223,7 +221,7 @@ public abstract class AbstractSAMLAdapterClusterTest extends AbstractServletsAda
 
     protected void checkLoggedOut(AbstractPage page, AuthRealm loginPage) {
         page.navigateTo();
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
         assertCurrentUrlStartsWith(loginPage);
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java
index 096fb76..547d039 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java
@@ -225,10 +225,10 @@ public class SocialLoginTest extends AbstractKeycloakTest {
 
         // Just to be sure there's no redirect in progress
         WaitUtils.pause(3000);
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
 
         // Only when there's not active session for the social provider, i.e. login is required
-        if (URLUtils.currentUrlDoesntStartWith(driver, getAuthServerRoot().toASCIIString())) {
+        if (URLUtils.currentUrlDoesntStartWith(getAuthServerRoot().toASCIIString())) {
             log.infof("current URL: %s", driver.getCurrentUrl());
             log.infof("performing log in to '%s' ...", currentTestProvider.id());
             AbstractSocialLoginPage loginPage = Graphene.createPageFragment(currentTestProvider.pageObjectClazz(), driver.findElement(By.tagName("html")));
@@ -240,7 +240,7 @@ public class SocialLoginTest extends AbstractKeycloakTest {
     }
 
     private void assertAccount() {
-        assertTrue(URLUtils.currentUrlStartWith(driver, accountPage.toString())); // Sometimes after login the URL ends with /# or similar
+        assertTrue(URLUtils.currentUrlStartWith(accountPage.toString())); // Sometimes after login the URL ends with /# or similar
 
         assertEquals(getConfig("profile.firstName"), accountPage.getFirstName());
         assertEquals(getConfig("profile.lastName"), accountPage.getLastName());
@@ -248,7 +248,7 @@ public class SocialLoginTest extends AbstractKeycloakTest {
     }
 
     private void assertUpdateProfile(boolean firstName, boolean lastName, boolean email) {
-        assertTrue(URLUtils.currentUrlDoesntStartWith(driver, accountPage.toString()));
+        assertTrue(URLUtils.currentUrlDoesntStartWith(accountPage.toString()));
 
         if (firstName) {
             assertTrue(updateAccountPage.fields().getFirstName().isEmpty());
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
index 90ee6ce..2fd0cb6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
@@ -53,12 +53,12 @@ public class URLAssert {
     public static void assertCurrentUrlEquals(WebDriver driver, final AbstractPage page) {
         String expected = page.toString();
         assertTrue("Expected URL: " + expected + "; actual: " + driver.getCurrentUrl(),
-                currentUrlEqual(driver, page.toString()));
+                currentUrlEqual(page.toString()));
     }
 
     public static void assertCurrentUrlEquals(WebDriver driver, final String url) {
         assertTrue("Expected URL: " + url + "; actual: " + driver.getCurrentUrl(),
-                currentUrlEqual(driver, url));
+                currentUrlEqual(url));
     }
 
     public static void assertCurrentUrlStartsWith(AbstractPage page) {
@@ -67,7 +67,7 @@ public class URLAssert {
 
     public static void assertCurrentUrlStartsWith(WebDriver driver, final String url) {
         assertTrue("URL expected to begin with:" + url + "; actual URL: " + driver.getCurrentUrl(),
-                currentUrlStartWith(driver, url));
+                currentUrlStartWith(url));
     }
 
     public static void assertCurrentUrlDoesntStartWith(AbstractPage page) {
@@ -76,7 +76,7 @@ public class URLAssert {
 
     public static void assertCurrentUrlDoesntStartWith(WebDriver driver, final String url) {
         assertTrue("URL expected NOT to begin with:" + url + "; actual URL: " + driver.getCurrentUrl(),
-                currentUrlDoesntStartWith(driver, url));
+                currentUrlDoesntStartWith(url));
     }
 
     public static void assertCurrentUrlStartsWithLoginUrlOf(PageWithLoginUrl page) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
index acf153c..f3b3a69 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -24,10 +24,22 @@
 	
     <extension qualifier="webdriver">
         <property name="browser">${browser}</property>
+        <property name="downloadBinaries">${webdriverDownloadBinaries}</property>
+
+        <!-- htmlunit -->
         <property name="htmlUnit.version">${htmlUnitBrowserVersion}</property>
+        <property name="htmlUnitWebClientOptions">cssEnabled=false;historyPageCacheLimit=1</property>
+
+        <!-- phantomjs -->
+        <property name="phantomjs.cli.args">${phantomjs.cli.args} --ssl-certificates-path=${client.certificate.ca.path} --ssl-client-certificate-file=${client.certificate.file} --ssl-client-key-file=${client.key.file} --ssl-client-key-passphrase=${client.key.passphrase}</property>
+
+        <!-- firefox -->
         <property name="firefox_binary">${firefox_binary}</property>
+        <property name="firefoxLogLevel">OFF</property>
+        <property name="firefoxLegacy">${firefoxLegacyDriver}</property>
+
+        <!-- chrome -->
         <property name="chromeArguments">${chromeArguments}</property>
-        <property name="phantomjs.cli.args">${phantomjs.cli.args} --ssl-certificates-path=${client.certificate.ca.path} --ssl-client-certificate-file=${client.certificate.file} --ssl-client-key-file=${client.key.file} --ssl-client-key-passphrase=${client.key.passphrase}</property>
     </extension>
     
     <extension qualifier="graphene">
                diff --git a/testsuite/integration-arquillian/tests/other/console/pom.xml b/testsuite/integration-arquillian/tests/other/console/pom.xml
index 003e24c..796e939 100644
--- a/testsuite/integration-arquillian/tests/other/console/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/console/pom.xml
@@ -33,6 +33,7 @@
 
     <properties>
         <keycloak.theme.dir>${auth.server.home}/themes</keycloak.theme.dir>
+        <supportedBrowsers>firefox|chrome|internetExplorer</supportedBrowsers>
     </properties>
 
     <build>
@@ -55,6 +56,27 @@
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireProperty>
+                                    <property>browser</property>
+                                    <message>Browser property must be set!</message>
+                                    <regex>${supportedBrowsers}</regex>
+                                    <regexMessage>Unsupported browser "${browser}"! Only the following are supported: ${supportedBrowsers}</regexMessage>
+                                </requireProperty>
+                            </rules>
+                            <fail>true</fail>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
         <pluginManagement>
             <plugins>
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java
index 262a834..6e410ad 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/Flows.java
@@ -8,6 +8,8 @@ import org.openqa.selenium.support.ui.Select;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
+
 /**
  * @author tkyjovsk
  * @author mhajas
@@ -61,7 +63,7 @@ public class Flows extends Authentication {
     }
 
     public void selectFlowOption(FlowOption option) {
-        flowSelect.selectByVisibleText(option.getName());
+        performOperationWithPageReload(() -> flowSelect.selectByVisibleText(option.getName()));
     }
 
     public String getFlowSelectValue() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
index 8f8073c..02ad49e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
@@ -36,7 +36,7 @@ public class PasswordPolicy extends Authentication {
         addPolicySelect.selectByVisibleText(policy.getName());
         if (value != null) {setPolicyValue(policy, value);}
         primaryButton.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
 
@@ -53,7 +53,7 @@ public class PasswordPolicy extends Authentication {
         if (primaryButton.isEnabled()) {
             primaryButton.click();
         }
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void editPolicy(Type policy, int value) {
@@ -65,7 +65,7 @@ public class PasswordPolicy extends Authentication {
         if (primaryButton.isEnabled()) {
             primaryButton.click();
         }
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     private void setPolicyValue(Type policy, String value) {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/RequiredActions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/RequiredActions.java
index 09f5f1c..f9c4ede 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/RequiredActions.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/authentication/RequiredActions.java
@@ -33,7 +33,7 @@ public class RequiredActions extends Authentication {
 
         WebElement checkbox = requiredActionTable.findElement(By.id(id));
 
-        if (checkbox.isSelected() != value) {
+        if (checkbox.isEnabled() && checkbox.isSelected() != value) {
             checkbox.click();
         }
     }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java
index 5510d7e..391e1e6 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java
@@ -16,6 +16,7 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization;
 
+import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.graphene.fragment.Root;
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.testsuite.console.page.clients.Client;
@@ -23,9 +24,12 @@ import org.keycloak.testsuite.console.page.clients.authorization.permission.Perm
 import org.keycloak.testsuite.console.page.clients.authorization.policy.Policies;
 import org.keycloak.testsuite.console.page.clients.authorization.resource.Resources;
 import org.keycloak.testsuite.console.page.clients.authorization.scope.Scopes;
+import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
+import static org.keycloak.testsuite.util.UIUtils.navigateToLink;
+
 /**
  *
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -97,6 +101,9 @@ public class Authorization extends Client {
         @Root
         private WebElement root;
 
+        @Drone
+        private WebDriver driver;
+
         @FindBy(linkText = "Settings")
         private WebElement settingsLink;
 
@@ -113,23 +120,28 @@ public class Authorization extends Client {
         private WebElement policiesLink;
 
         public void settings() {
-            settingsLink.click();
+            //clickLink(settingsLink);
+            navigateToLink(settingsLink); // for some reason, GeckoDriver is currently having problems clicking on those tabs
         }
 
         public void resources() {
-            resourcesLink.click();
+            //clickLink(resourcesLink);
+            navigateToLink(resourcesLink);
         }
 
         private void scopes() {
-            scopesLink.click();
+            //clickLink(scopesLink);
+            navigateToLink(scopesLink);
         }
 
         private void permissions() {
-            permissionsLink.click();
+            //clickLink(permissionsLink);
+            navigateToLink(permissionsLink);
         }
 
         private void policies() {
-            policiesLink.click();
+            //clickLink(policiesLink);
+            navigateToLink(policiesLink);
         }
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
index de9c13c..f861c85 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
@@ -16,8 +16,6 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.permission;
 
-import static org.openqa.selenium.By.tagName;
-
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
@@ -25,13 +23,15 @@ import org.keycloak.representations.idm.authorization.ResourcePermissionRepresen
 import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
 import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.URLUtils;
 import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+import static org.openqa.selenium.By.tagName;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -73,8 +73,8 @@ public class Permissions extends Form {
         for (WebElement row : permissions().rows()) {
             PolicyRepresentation actual = permissions().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
                 String type = representation.getType();
 
                 if ("resource".equals(type)) {
@@ -92,8 +92,8 @@ public class Permissions extends Form {
         for (WebElement row : permissions().rows()) {
             PolicyRepresentation actual = permissions().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
                 String type = actual.getType();
                 if ("resource".equals(type)) {
                     return (P) resourcePermission;
@@ -109,8 +109,8 @@ public class Permissions extends Form {
         for (WebElement row : permissions().rows()) {
             PolicyRepresentation actual = permissions().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
 
                 String type = actual.getType();
 
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
index 389a214..d063f6c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/GroupPolicyForm.java
@@ -16,6 +16,7 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import static org.openqa.selenium.By.tagName;
 
 import java.util.ArrayList;
@@ -93,6 +94,7 @@ public class GroupPolicyForm extends Form {
             String groupName = path.substring(path.lastIndexOf('/') + 1);
             WebElement element = driver.findElement(By.xpath("//span[text()='" + groupName + "']"));
             element.click();
+            waitUntilElement(selectGroupButton).is().enabled();
             selectGroupButton.click();
             driver.findElements(By.xpath("(//table[@id='selected-groups'])/tbody/tr")).stream()
                     .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
index a42e12e..79c6957 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
@@ -16,8 +16,6 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
-import static org.openqa.selenium.By.tagName;
-
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
@@ -30,13 +28,15 @@ import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
 import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
 import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.URLUtils;
-import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
+import static org.openqa.selenium.By.tagName;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -79,7 +79,7 @@ public class Policies extends Form {
     public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
         String type = expected.getType();
 
-        createSelect.selectByValue(type);
+        performOperationWithPageReload(() -> createSelect.selectByValue(type));
 
         if ("role".equals(type)) {
             rolePolicy.form().populate((RolePolicyRepresentation) expected);
@@ -104,7 +104,6 @@ public class Policies extends Form {
             return (P) clientPolicy;
         } else if ("group".equals(type)) {
             groupPolicy.form().populate((GroupPolicyRepresentation) expected);
-            groupPolicy.form().save();
             return (P) groupPolicy;
         }
 
@@ -115,8 +114,7 @@ public class Policies extends Form {
         for (WebElement row : policies().rows()) {
             PolicyRepresentation actual = policies().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
                 String type = representation.getType();
 
                 if ("role".equals(type)) {
@@ -146,7 +144,7 @@ public class Policies extends Form {
         for (WebElement row : policies().rows()) {
             PolicyRepresentation actual = policies().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
+                clickLink(row.findElements(tagName("a")).get(0));
                 String type = actual.getType();
                 if ("role".equals(type)) {
                     return (P) rolePolicy;
@@ -174,7 +172,7 @@ public class Policies extends Form {
         for (WebElement row : policies().rows()) {
             PolicyRepresentation actual = policies().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
+                clickLink(row.findElements(tagName("a")).get(0));
 
                 String type = actual.getType();
 
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
index 0ba43f1..3b02288 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RulePolicyForm.java
@@ -77,7 +77,7 @@ public class RulePolicyForm extends Form {
         setInputValue(artifactVersion, expected.getArtifactVersion());
 
         resolveModuleButton.click();
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
 
         moduleName.selectByVisibleText(expected.getModuleName());
         WaitUtils.pause(1000);
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
index 199be95..d079ce6 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
@@ -16,17 +16,17 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.resource;
 
-import static org.openqa.selenium.By.tagName;
-
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.URLUtils;
 import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+import static org.openqa.selenium.By.tagName;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -54,8 +54,8 @@ public class Resources extends Form {
         for (WebElement row : resources().rows()) {
             ResourceRepresentation actual = resources().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
                 resource.form().populate(representation);
                 return;
             }
@@ -66,8 +66,8 @@ public class Resources extends Form {
         for (WebElement row : resources().rows()) {
             ResourceRepresentation actual = resources().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
                 resource.form().delete();
                 return;
             }
@@ -89,8 +89,8 @@ public class Resources extends Form {
         for (WebElement row : resources().rows()) {
             ResourceRepresentation actual = resources().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
-                WaitUtils.waitForPageToLoad(driver);
+                clickLink(row.findElements(tagName("a")).get(0));
+                WaitUtils.waitForPageToLoad();
                 return resource;
             }
         }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
index 3974e35..7324996 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
@@ -16,16 +16,16 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.scope;
 
-import static org.openqa.selenium.By.tagName;
-
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.ScopeRepresentation;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.URLUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+import static org.openqa.selenium.By.tagName;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -53,7 +53,7 @@ public class Scopes extends Form {
         for (WebElement row : scopes().rows()) {
             ScopeRepresentation actual = scopes().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
+                clickLink(row.findElements(tagName("a")).get(0));
                 scope.form().populate(representation);
             }
         }
@@ -63,7 +63,7 @@ public class Scopes extends Form {
         for (WebElement row : scopes().rows()) {
             ScopeRepresentation actual = scopes().toRepresentation(row);
             if (actual.getName().equalsIgnoreCase(name)) {
-                URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
+                clickLink(row.findElements(tagName("a")).get(0));
                 scope.form().delete();
             }
         }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
index 39999ba..619a065 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
@@ -6,6 +6,8 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 import static org.keycloak.testsuite.console.page.fragment.Breadcrumb.BREADCRUMB_XPATH;
+import static org.keycloak.testsuite.util.UIUtils.clickLink;
+
 import org.openqa.selenium.NoSuchElementException;
 
 /**
@@ -44,7 +46,7 @@ public class Client extends Clients {
     private WebElement deleteIcon;
     
     public void delete() {
-        deleteIcon.click();
+        clickLink(deleteIcon);
         modalDialog.confirmDeletion();
     }
 
@@ -80,35 +82,35 @@ public class Client extends Clients {
         private WebElement authorizationLink;
 
         public void settings() {
-            settingsLink.click();
+            clickLink(settingsLink);
         }
 
         public void roles() {
-            rolesLink.click();
+            clickLink(rolesLink);
         }
 
         public void mappers() {
-            mappersLink.click();
+            clickLink(mappersLink);
         }
 
         public void scope() {
-            scopeLink.click();
+            clickLink(scopeLink);
         }
 
         public void revocation() {
-            revocationLink.click();
+            clickLink(revocationLink);
         }
 
         public void sessions() {
-            sessionsLink.click();
+            clickLink(sessionsLink);
         }
 
         public void installation() {
-            installationLink.click();
+            clickLink(installationLink);
         }
 
         public void authorization() {
-            authorizationLink.click();
+            clickLink(authorizationLink);
         }
         
         public boolean isServiceAccountRolesDisplayed() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java
index 3ec2773..b29de62 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java
@@ -57,18 +57,18 @@ public class ClientCredentialsForm extends Form {
     public void regenerateSecret() {
         waitUntilElement(regenerateSecretButton).is().visible();
         regenerateSecretButton.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void regenerateRegistrationAccessToken() {
         waitUntilElement(regenerateRegistrationAccessTokenButton).is().visible();
         regenerateRegistrationAccessTokenButton.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 
     public void generateNewKeysAndCert() {
         waitUntilElement(generateNewKeysAndCert).is().visible();
         generateNewKeysAndCert.click();
-        waitForPageToLoad(driver);
+        waitForPageToLoad();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java
index fbd415a..2458931 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java
@@ -41,7 +41,7 @@ public class ClientInstallationForm extends Form {
 
     public void setConfigFormat(String value) {
         configFormatsSelect.selectByVisibleText(value);
-        WaitUtils.waitForPageToLoad(driver);
+        WaitUtils.waitForPageToLoad();
     }
     
     public String getTextareaContent() {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java
index a4b3107..c43dfe0 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java
@@ -116,7 +116,7 @@ public class CreateClientMappersForm extends Form {
             }
             WaitUtils.pause(1000);
             selectRealmRoleButton.click();
-            WaitUtils.waitForModalFadeOut(driver);
+            WaitUtils.waitForModalFadeOut();
         }
         
         public void selectClientRole(String clientName, String roleName) {
@@ -126,7 +126,7 @@ public class CreateClientMappersForm extends Form {
             }
             WaitUtils.pause(1000);
             selectClientRoleButton.click();
-            WaitUtils.waitForModalFadeOut(driver);
+            WaitUtils.waitForModalFadeOut();
         }
     }
     
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
index 4232289..ca1fa9e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
@@ -79,18 +79,18 @@ public class Users extends AdminConsoleRealm {
         }
 
         public void clickUser(String username) {
-            URLUtils.navigateToUri(driver, getRowByUsername(username).findElement(By.xpath("./td[position()=1]/a")).getAttribute("href"), true);
-            waitForPageToLoad(driver);
+            URLUtils.navigateToUri(getRowByUsername(username).findElement(By.xpath("./td[position()=1]/a")).getAttribute("href"), true);
+            waitForPageToLoad();
         }
 
         public void editUser(String username) {
             clickRowActionButton(getRowByUsername(username), EDIT);
-            waitForPageToLoad(driver);
+            waitForPageToLoad();
         }
 
         public void impersonateUser(String username) {
             clickRowActionButton(getRowByUsername(username), IMPERSONATE);
-            waitForPageToLoad(driver);
+            waitForPageToLoad();
         }
 
         public void deleteUser(String username) {
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
index b879e18..d0c9068 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
@@ -22,10 +22,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.Assert;
-import org.keycloak.testsuite.auth.page.AuthRealm;
 import org.keycloak.testsuite.auth.page.login.Registration;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
-import org.keycloak.testsuite.console.page.AdminConsoleRealm;
 import org.keycloak.testsuite.console.page.authentication.RequiredActions;
 import org.keycloak.testsuite.console.page.realm.LoginSettings;
 import org.openqa.selenium.By;
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/LoginEventsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/LoginEventsTest.java
index 7a12f61..24b7a08 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/LoginEventsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/LoginEventsTest.java
@@ -62,7 +62,7 @@ public class LoginEventsTest extends AbstractConsoleTest {
         resultList.get(0).findElement(By.xpath("//td[text()='LOGIN']"));
         resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
         resultList.get(0).findElement(By.xpath("//td[text()='Client']/../td[text()='security-admin-console']"));
-        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1']"));
+        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1' or text()='0:0:0:0:0:0:0:1']"));
 
         loginEventsPage.table().reset();
         loginEventsPage.table().filterForm().addEventType("LOGOUT");
@@ -73,7 +73,7 @@ public class LoginEventsTest extends AbstractConsoleTest {
         assertEquals(1, resultList.size());
         resultList.get(0).findElement(By.xpath("//td[text()='LOGOUT']"));
         resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
-        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1']"));
+        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1' or text()='0:0:0:0:0:0:0:1']"));
 
         loginEventsPage.table().reset();
         loginEventsPage.table().filterForm().addEventType("LOGIN_ERROR");
@@ -86,7 +86,7 @@ public class LoginEventsTest extends AbstractConsoleTest {
         resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
         resultList.get(0).findElement(By.xpath("//td[text()='Client']/../td[text()='security-admin-console']"));
         resultList.get(0).findElement(By.xpath("//td[text()='Error']/../td[text()='invalid_user_credentials']"));
-        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1']"));
+        resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1' or text()='0:0:0:0:0:0:0:1']"));
 
 
     }
                diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/realm/LoginSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/realm/LoginSettingsTest.java
index 9495cde..d92b493 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/realm/LoginSettingsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/realm/LoginSettingsTest.java
@@ -42,6 +42,7 @@ import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWit
 import static org.keycloak.testsuite.admin.Users.setPasswordFor;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
 
 /**
  *
@@ -136,15 +137,16 @@ public class LoginSettingsTest extends AbstractRealmTest {
         log.info("edit username");
         testAccountPage.navigateTo();
         testRealmLoginPage.form().login(testUser);
-        testAccountPage.waitForAccountLinkPresent();
+        assertCurrentUrlStartsWith(testAccountPage);
         testAccountPage.setUsername(NEW_USERNAME);
         testAccountPage.save();
         testAccountPage.signOut();
         log.debug("edited");
         
         log.info("log in with edited username");
+        assertCurrentUrlStartsWithLoginUrlOf(testAccountPage);
         testRealmLoginPage.form().login(NEW_USERNAME, PASSWORD);
-        testAccountPage.waitForAccountLinkPresent();
+        assertCurrentUrlStartsWith(testAccountPage);
         log.debug("user is logged in with edited username");
         
         log.info("disabling edit username");
@@ -202,6 +204,7 @@ public class LoginSettingsTest extends AbstractRealmTest {
         testAccountPage.navigateTo();
         testRealmLoginPage.form().rememberMe(true);
         testRealmLoginPage.form().login(testUser);
+        assertCurrentUrlStartsWith(testAccountPage);
         
         assertTrue("Cookie KEYCLOAK_REMEMBER_ME should be present.", getCookieNames().contains("KEYCLOAK_REMEMBER_ME"));
         
@@ -265,7 +268,7 @@ public class LoginSettingsTest extends AbstractRealmTest {
         log.info("log in as new user");
         testAccountPage.navigateTo();        
         testRealmLoginPage.form().login(newUser);
-        testAccountPage.waitForAccountLinkPresent();
+        assertCurrentUrlStartsWith(testAccountPage);
                 
         log.info("verified verify email is disabled");
         
                diff --git a/testsuite/integration-arquillian/tests/other/nodejs_adapter/src/main/java/org/keycloak/testsuite/adapter/nodejs/page/NodejsExamplePage.java b/testsuite/integration-arquillian/tests/other/nodejs_adapter/src/main/java/org/keycloak/testsuite/adapter/nodejs/page/NodejsExamplePage.java
index 0c223f4..0feb8ec 100644
--- a/testsuite/integration-arquillian/tests/other/nodejs_adapter/src/main/java/org/keycloak/testsuite/adapter/nodejs/page/NodejsExamplePage.java
+++ b/testsuite/integration-arquillian/tests/other/nodejs_adapter/src/main/java/org/keycloak/testsuite/adapter/nodejs/page/NodejsExamplePage.java
@@ -50,11 +50,11 @@ public class NodejsExamplePage extends AbstractNodejsExamplePage {
 
     public boolean isOnLoginSecuredPage() {
         UriBuilder uriBuilder = createUriBuilder().path("login");
-        return URLUtils.currentUrlEqual(driver, uriBuilder.build().toASCIIString());
+        return URLUtils.currentUrlEqual(uriBuilder.build().toASCIIString());
     }
 
     @Override
     public boolean isCurrent() {
-        return URLUtils.currentUrlStartWith(driver, toString());
+        return URLUtils.currentUrlStartWith(toString());
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 324f726..4a8fb3e 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -93,9 +93,12 @@
         <examples.home>${project.build.directory}/examples</examples.home>
 
         <browser>htmlUnit</browser>
+        <webdriverDownloadBinaries>true</webdriverDownloadBinaries>
         <htmlUnitBrowserVersion>chrome</htmlUnitBrowserVersion>
-        <firefox_binary>/usr/bin/firefox</firefox_binary>
         <phantomjs.cli.args>--ignore-ssl-errors=true --web-security=false</phantomjs.cli.args>
+        <firefox_binary>/usr/bin/firefox</firefox_binary>
+        <firefoxLegacyDriver>true</firefoxLegacyDriver>
+        <chromeArguments/>
 
         <frontend.console.output>true</frontend.console.output>
         <backends.console.output>true</backends.console.output>
@@ -252,8 +255,13 @@
 
                             <browser>${browser}</browser>
                             <htmlUnitBrowserVersion>${htmlUnitBrowserVersion}</htmlUnitBrowserVersion>
+                            <webdriverDownloadBinaries>${webdriverDownloadBinaries}</webdriverDownloadBinaries>
+
                             <firefox_binary>${firefox_binary}</firefox_binary>
                             <phantomjs.cli.args>${phantomjs.cli.args}</phantomjs.cli.args>
+                            <chromeArguments>${chromeArguments}</chromeArguments>
+
+                            <firefoxLegacyDriver>${firefoxLegacyDriver}</firefoxLegacyDriver>
 
                             <project.version>${project.version}</project.version>
                             <migration.project.version>${migration.project.version}</migration.project.version>
@@ -313,6 +321,12 @@
             <groupId>org.jboss.arquillian.container</groupId>
             <artifactId>arquillian-container-osgi</artifactId>
             <version>2.1.0.CR18</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
@@ -986,10 +1000,19 @@
                             <groupId>org.apache.commons</groupId>
                             <artifactId>commons-io</artifactId>
                         </exclusion>
+                        <exclusion>
+                            <groupId>com.google.guava</groupId>
+                            <artifactId>guava</artifactId>
+                        </exclusion>
                     </exclusions>
                 </dependency>
 
                 <dependency>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>httpclient</artifactId>
+                    <version>4.5.3</version>
+                </dependency>
+                <dependency>
                     <groupId>jfree</groupId>
                     <artifactId>jfreechart</artifactId>
                     <version>1.0.13</version>
@@ -1067,6 +1090,12 @@
                     <groupId>org.keycloak</groupId>
                     <artifactId>keycloak-dependencies-server-all</artifactId>
                     <type>pom</type>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>com.google.guava</groupId>
+                            <artifactId>guava</artifactId>
+                        </exclusion>
+                    </exclusions>
                 </dependency>
 
                 <dependency>
@@ -1184,6 +1213,18 @@
                 </dependency>
 
             </dependencies>
+
+            <dependencyManagement>
+                <dependencies>
+                    <!-- we need to specify the correct version because of conflict in arquillian-drone-webdriver-depchain -->
+                    <dependency>
+                        <groupId>org.seleniumhq.selenium</groupId>
+                        <artifactId>htmlunit-driver</artifactId>
+                        <version>2.27</version>
+                    </dependency>
+                </dependencies>
+            </dependencyManagement>
+
             <build>
                 <plugins>
                     <plugin>