keycloak-aplcache

Changes

Details

diff --git a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js
index eb760a9..d175bfd 100755
--- a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js
+++ b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js
@@ -113,7 +113,7 @@ module.controller('GlobalCtrl', function($scope, $http) {
     };
 
     $scope.loadVersion = function() {
-        $http.get(getAuthServerUrl() + "/auth/version").success(function(data) {
+        $http.get(getAppServerUrl("localhost-db") + "/cors-database/products/k_version").success(function(data) {
             $scope.version = angular.fromJson(data);
         });
     };
diff --git a/testsuite/integration-arquillian/test-apps/servlet-authz/keycloak-cache-lifespan-authz-service.json b/testsuite/integration-arquillian/test-apps/servlet-authz/keycloak-cache-lifespan-authz-service.json
index d4b4af7..7c73876 100644
--- a/testsuite/integration-arquillian/test-apps/servlet-authz/keycloak-cache-lifespan-authz-service.json
+++ b/testsuite/integration-arquillian/test-apps/servlet-authz/keycloak-cache-lifespan-authz-service.json
@@ -11,7 +11,7 @@
   "policy-enforcer": {
     "on-deny-redirect-to" : "/servlet-authz-app/accessDenied.jsp",
     "path-cache": {
-      "lifespan": 5000,
+      "lifespan": 10000,
       "max-entries": 1000
     },
     "paths": [
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 90a6692..8232506 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
@@ -17,14 +17,17 @@
 package org.keycloak.testsuite.adapter.page;
 
 import org.jboss.arquillian.container.test.api.OperateOnDeployment;
+import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.keycloak.testsuite.auth.page.login.OIDCLogin;
 import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
 import org.keycloak.testsuite.page.Form;
 import org.keycloak.testsuite.pages.ConsentPage;
+import org.keycloak.testsuite.util.JavascriptBrowser;
 import org.keycloak.testsuite.util.URLUtils;
 import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -49,25 +52,36 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     @OperateOnDeployment(DEPLOYMENT_NAME)
     private URL url;
 
+    @Drone
+    @JavascriptBrowser
+    protected WebDriver driver;
+
     @Page
+    @JavascriptBrowser
     protected OIDCLogin loginPage;
 
     @Page
+    @JavascriptBrowser
     protected ConsentPage consentPage;
 
     @FindBy(xpath = "//a[@ng-click = 'Identity.logout()']")
+    @JavascriptBrowser
     private WebElement signOutButton;
     
     @FindBy(id = "entitlement")
+    @JavascriptBrowser
     private WebElement entitlement;
     
     @FindBy(id = "entitlements")
+    @JavascriptBrowser
     private WebElement entitlements;
 
     @FindBy(id = "get-all-resources")
+    @JavascriptBrowser
     private WebElement viewAllAlbums;
 
     @FindBy(id = "output")
+    @JavascriptBrowser
     private WebElement output;
 
     public void createAlbum(String name) {
@@ -91,7 +105,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
         WebElement albumNameInput = driver.findElement(By.id("album.name"));
         waitUntilElement(albumNameInput).is().present();
         Form.setInputValue(albumNameInput, name);
-        pause(200); // We need to wait a bit for the form to "accept" the input (otherwise it registers the input as empty)
         waitUntilElement(albumNameInput).attribute(Form.VALUE).contains(name);
         WebElement button = driver.findElement(By.id(buttonId));
         waitUntilElement(button).is().clickable();
@@ -142,9 +155,10 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     }
 
     public void logOut() {
+        navigateTo();
         waitUntilElement(signOutButton).is().clickable(); // Sometimes doesn't work in PhantomJS!
         signOutButton.click();
-        pause(WAIT_AFTER_OPERATION);
+        this.loginPage.form().waitForLoginButtonPresent();
     }
     
     public void requestEntitlement() {
@@ -166,14 +180,6 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     public void login(String username, String password, String... scopes) throws InterruptedException {
         String currentUrl = this.driver.getCurrentUrl();
 
-        if (currentUrl.startsWith(getInjectedUrl().toString())) {
-            Thread.sleep(1000);
-            logOut();
-            navigateTo();
-        }
-
-        Thread.sleep(1000);
-
         if (scopes.length > 0) {
             StringBuilder scopesValue = new StringBuilder();
 
@@ -186,19 +192,25 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
 
             scopesValue.append(" openid");
 
-            int scopeIndex = currentUrl.indexOf("scope");
 
-            if (scopeIndex != -1) {
-                StringBuilder url = new StringBuilder(currentUrl);
+            StringBuilder urlWithScopeParam = new StringBuilder(currentUrl);
 
-                url.delete(scopeIndex, currentUrl.indexOf('&', scopeIndex));
+            int scopeIndex = currentUrl.indexOf("scope");
 
-                url.append("&").append("scope=").append(scopesValue);
+            if (scopeIndex != -1) {
+                // Remove scope param from url
+                urlWithScopeParam.delete(scopeIndex, currentUrl.indexOf('&', scopeIndex));
+                // Add scope param to the end of query
+                urlWithScopeParam.append("&").append("scope=");
+            }
 
-                currentUrl = url.toString();
+            if (!currentUrl.contains("?")) {
+                urlWithScopeParam.append("?scope=");
             }
 
-            URLUtils.navigateToUri(currentUrl + " " + scopesValue, true);
+            urlWithScopeParam.append(scopesValue);
+
+            URLUtils.navigateToUri(urlWithScopeParam.toString(), true);
         }
 
         this.loginPage.form().login(username, password);
@@ -207,7 +219,7 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
         try {
             if (!isCurrent()) {
                 // simple check if we are at the consent page, if so just click 'Yes'
-                if (this.consentPage.isCurrent()) {
+                if (this.consentPage.isCurrent(driver)) {
                     consentPage.confirm();
                 }
             }
@@ -222,6 +234,10 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
         waitUntilElement(output).text().contains("You can not access");
     }
 
+    private void waitForNotDenial() {
+        waitUntilElement(output).text().not().contains("You can not access");
+    }
+
     public void viewAllAlbums() {
         viewAllAlbums.click();
         pause(WAIT_AFTER_OPERATION);
@@ -232,8 +248,12 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
         waitUntilElement(viewalbum).is().clickable();
         viewalbum.click();
         waitForPageToLoad();
-        if (shouldBeDenied) waitForDenial();
         driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
+        if (shouldBeDenied) {
+            waitForDenial();
+        } else {
+            waitForNotDenial();
+        }
         waitForPageToLoad();
         pause(WAIT_AFTER_OPERATION);
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
index 3abfcfd..5a9e84f 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
@@ -17,6 +17,7 @@
 
 package org.keycloak.testsuite.pages;
 
+import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -41,7 +42,11 @@ public class ConsentPage extends AbstractPage {
 
     @Override
     public boolean isCurrent() {
-        return PageUtils.getPageTitle(driver).contains("Grant Access to ");
+        return isCurrent(driver);
+    }
+
+    public boolean isCurrent(WebDriver driver1) {
+        return PageUtils.getPageTitle(driver1).contains("Grant Access to ");
     }
 
     @Override
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index f762715..482ab32 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -18,24 +18,6 @@ package org.keycloak.testsuite;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.BeforeClass;
-import org.keycloak.common.util.KeycloakUriBuilder;
-import org.keycloak.common.util.Time;
-import org.keycloak.testsuite.arquillian.KcArquillian;
-import org.keycloak.testsuite.arquillian.TestContext;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeoutException;
-
-import javax.ws.rs.NotFoundException;
 import org.jboss.arquillian.container.test.api.RunAsClient;
 import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.jboss.arquillian.graphene.page.Page;
@@ -43,6 +25,7 @@ import org.jboss.arquillian.test.api.ArquillianResource;
 import org.jboss.logging.Logger;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.runner.RunWith;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.AuthenticationManagementResource;
@@ -50,12 +33,16 @@ import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.admin.client.resource.RealmsResource;
 import org.keycloak.admin.client.resource.UserResource;
 import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.common.util.KeycloakUriBuilder;
+import org.keycloak.common.util.Time;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.admin.ApiUtil;
 import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
+import org.keycloak.testsuite.arquillian.KcArquillian;
 import org.keycloak.testsuite.arquillian.SuiteContext;
+import org.keycloak.testsuite.arquillian.TestContext;
 import org.keycloak.testsuite.auth.page.AuthRealm;
 import org.keycloak.testsuite.auth.page.AuthServer;
 import org.keycloak.testsuite.auth.page.AuthServerContextRoot;
@@ -66,6 +53,7 @@ import org.keycloak.testsuite.auth.page.login.UpdatePassword;
 import org.keycloak.testsuite.client.KeycloakTestingClient;
 import org.keycloak.testsuite.util.AdminClientUtil;
 import org.keycloak.testsuite.util.DroneUtils;
+import org.keycloak.testsuite.util.JavascriptBrowser;
 import org.keycloak.testsuite.util.OAuthClient;
 import org.keycloak.testsuite.util.TestCleanup;
 import org.keycloak.testsuite.util.TestEventsLogger;
@@ -82,6 +70,18 @@ import org.wildfly.extras.creaper.core.online.operations.OperationException;
 import org.wildfly.extras.creaper.core.online.operations.Operations;
 import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
 
+import javax.ws.rs.NotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
 import static org.keycloak.testsuite.admin.Users.setPasswordFor;
 import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
 import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
@@ -116,6 +116,15 @@ public abstract class AbstractKeycloakTest {
     @Drone
     protected WebDriver driver;
 
+    // Javascript browser needed KEYCLOAK-4703
+    @Drone
+    @JavascriptBrowser
+    protected WebDriver jsDriver;
+
+    @Page
+    @JavascriptBrowser
+    protected OIDCLogin jsDriverTestRealmLoginPage;
+
     @Page
     protected AuthServerContextRoot authServerContextRootPage;
     @Page
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractBaseServletAuthzAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractBaseServletAuthzAdapterTest.java
index 03abbb2..4b8c19a 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractBaseServletAuthzAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractBaseServletAuthzAdapterTest.java
@@ -16,20 +16,6 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertFalse;
-import static org.keycloak.testsuite.util.IOUtil.loadJson;
-import static org.keycloak.testsuite.util.IOUtil.loadRealm;
-import static org.keycloak.testsuite.util.WaitUtils.pause;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-import javax.ws.rs.core.Response;
-
 import org.jboss.arquillian.container.test.api.Deployer;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.junit.BeforeClass;
@@ -47,6 +33,20 @@ import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.keycloak.testsuite.util.IOUtil.loadJson;
+import static org.keycloak.testsuite.util.IOUtil.loadRealm;
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -142,8 +142,12 @@ public abstract class AbstractBaseServletAuthzAdapterTest extends AbstractExampl
         WaitUtils.waitUntilElement(By.xpath("//a[text() = 'Dynamic Menu']"));
     }
 
-    protected boolean wasDenied() {
-        return this.driver.getPageSource().contains("You can not access this resource.");
+    protected void assertWasDenied() {
+        waitUntilElement(By.tagName("body")).text().contains("You can not access this resource.");
+    }
+
+    protected void assertWasNotDenied() {
+        waitUntilElement(By.tagName("body")).text().not().contains("You can not access this resource.");
     }
 
     protected URL getResourceServerUrl() {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPermissiveModeAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPermissiveModeAdapterTest.java
index 052150c..63385b3 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPermissiveModeAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPermissiveModeAdapterTest.java
@@ -16,14 +16,14 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertTrue;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
 
 import java.io.File;
 import java.io.IOException;
 
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
+import static org.junit.Assert.assertTrue;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -50,7 +50,7 @@ public abstract class AbstractPermissiveModeAdapterTest extends AbstractBaseServ
             }
 
             driver.navigate().to(getResourceServerUrl() + "/protected/admin");
-            assertTrue(wasDenied());
+            assertWasDenied();
         });
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
index 8947376..3a2e759 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
@@ -16,36 +16,13 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.util.IOUtil.loadJson;
-import static org.keycloak.testsuite.util.IOUtil.loadRealm;
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.LaxRedirectStrategy;
-
 import org.jboss.arquillian.container.test.api.Deployer;
-import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -67,7 +44,32 @@ import org.keycloak.representations.idm.authorization.ResourceServerRepresentati
 import org.keycloak.testsuite.ProfileAssume;
 import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
 import org.keycloak.testsuite.adapter.page.PhotozClientAuthzTestApp;
+import org.keycloak.testsuite.util.DroneUtils;
+import org.keycloak.testsuite.util.JavascriptBrowser;
 import org.keycloak.util.JsonSerialization;
+import org.openqa.selenium.NoSuchElementException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.keycloak.testsuite.util.IOUtil.loadJson;
+import static org.keycloak.testsuite.util.IOUtil.loadRealm;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -82,6 +84,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
     private Deployer deployer;
 
     @Page
+    @JavascriptBrowser
     private PhotozClientAuthzTestApp clientPage;
 
     @Override
@@ -95,6 +98,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
     @Before
     public void beforePhotozExampleAdapterTest() throws Exception {
+        DroneUtils.addWebDriver(jsDriver);
         deleteAllCookiesForClientPage();
         this.deployer.deploy(RESOURCE_SERVER_ID);
         
@@ -107,6 +111,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
     @After
     public void afterPhotozExampleAdapterTest() {
         this.deployer.undeploy(RESOURCE_SERVER_ID);
+        DroneUtils.removeWebDriver();
     }
 
     @Override
@@ -421,7 +426,6 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
         clientPage.createAlbum(resourceName);
 
-        clientPage.logOut();
         loginToClientPage("admin", "admin");
 
         clientPage.navigateToAdminAlbum(false);
@@ -559,10 +563,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         loginToClientPage("admin", "admin");
 
         clientPage.requestEntitlements();
-        assertTrue(driver.getPageSource().contains("admin:manage"));
+        assertTrue(jsDriver.getPageSource().contains("admin:manage"));
 
         clientPage.requestEntitlement();
-        String pageSource = driver.getPageSource();
+        String pageSource = jsDriver.getPageSource();
         assertTrue(pageSource.contains("album:view"));
         assertTrue(pageSource.contains("album:delete"));
     }
@@ -671,14 +675,38 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
     }
 
     private void deleteAllCookiesForClientPage() {
-        driver.manage().deleteAllCookies();
+        jsDriver.manage().deleteAllCookies();
     }
 
     private void loginToClientPage(String username, String password, String... scopes) throws InterruptedException {
         log.debugf("--logging in as {0} with password: {1}; scopes: {2}", username, password, Arrays.toString(scopes));
-        // We need to log out by deleting cookies because the log out button sometimes doesn't work in PhantomJS
-        deleteAllCookiesForTestRealm();
+
+        clientPage.navigateTo();
+        if (jsDriver.getCurrentUrl().startsWith(clientPage.toString())) {
+            try {
+                clientPage.logOut();
+            } catch (NoSuchElementException ex) {
+                if ("phantomjs".equals(System.getProperty("js.browser"))) {
+                    // PhantomJS is broken, it can't logout using sign out button sometimes, we have to clean sessions and remove cookies
+                    adminClient.realm(REALM_NAME).logoutAll();
+
+                    jsDriverTestRealmLoginPage.navigateTo();
+                    driver.manage().deleteAllCookies();
+
+                    clientPage.navigateTo();
+                    driver.manage().deleteAllCookies();
+
+                    clientPage.navigateTo();
+                    // Check for correct logout
+                    this.jsDriverTestRealmLoginPage.form().waitForLoginButtonPresent();
+                } else {
+                    throw ex;
+                }
+            }
+        }
+
         clientPage.navigateTo();
+        waitForPageToLoad();
         clientPage.login(username, password, scopes);
     }
 }
\ No newline at end of file
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 35c936b..98c06cb 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
@@ -16,14 +16,6 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.ws.rs.core.Response;
-
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ClientPoliciesResource;
 import org.keycloak.admin.client.resource.RealmResource;
@@ -40,6 +32,13 @@ import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
 import org.keycloak.testsuite.util.WaitUtils;
 
+import javax.ws.rs.core.Response;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -58,7 +57,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
         }, () -> {
             login("jdoe", "jdoe");
             driver.navigate().to(getResourceServerUrl().toString() + "/enforcing/resource");
-            assertTrue(wasDenied());
+            assertWasDenied();
         });
     }
 
@@ -66,7 +65,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testRegularUserPermissions() throws Exception {
         performTests(() -> {
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
             assertTrue(hasLink("User Premium"));
             assertTrue(hasLink("Administration"));
             assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
@@ -79,10 +78,10 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             assertFalse(hasText("Do administration thing"));
 
             navigateToUserPremiumPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             navigateToAdminPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
         });
     }
 
@@ -90,7 +89,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testUserPremiumPermissions() throws Exception {
         performTests(() -> {
             login("jdoe", "jdoe");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
             assertTrue(hasLink("User Premium"));
             assertTrue(hasLink("Administration"));
             assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
@@ -103,10 +102,10 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             assertFalse(hasText("Do administration thing"));
 
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             navigateToAdminPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
         });
     }
 
@@ -114,7 +113,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testAdminPermissions() throws Exception {
         performTests(() -> {
             login("admin", "admin");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
             assertTrue(hasLink("User Premium"));
             assertTrue(hasLink("Administration"));
             assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
@@ -127,10 +126,10 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             assertFalse(hasText("Do  user premium thing"));
 
             navigateToUserPremiumPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             navigateToAdminPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
 
@@ -138,24 +137,24 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testGrantPremiumAccessToUser() throws Exception {
         performTests(() -> {
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             navigateToUserPremiumPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             updatePermissionPolicies("Premium Resource Permission", "Any User Policy");
 
             login("alice", "alice");
 
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             updatePermissionPolicies("Premium Resource Permission", "Only Premium User Policy");
 
             login("alice", "alice");
 
             navigateToUserPremiumPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             createUserPolicy("Temporary Premium Access Policy", "alice");
 
@@ -164,7 +163,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             login("alice", "alice");
 
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
 
@@ -174,7 +173,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             login("jdoe", "jdoe");
 
             navigateToAdminPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             RealmResource realmResource = realmsResouce().realm(REALM_NAME);
             UsersResource usersResource = realmResource.users();
@@ -190,7 +189,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             login("jdoe", "jdoe");
 
             navigateToAdminPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
     
@@ -209,7 +208,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
         performTests(() -> {
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             RolesResource rolesResource = getClientResource(RESOURCE_SERVER_ID).roles();
 
@@ -230,7 +229,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
 
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             policy.getRoles().clear();
             policy.addRole("user_premium", false);
@@ -240,7 +239,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
 
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             UsersResource users = realmsResouce().realm(REALM_NAME).users();
             UserRepresentation user = users.search("jdoe").get(0);
@@ -251,7 +250,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
 
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             policy.getRoles().clear();
             policy.addRole("user_premium", false);
@@ -261,13 +260,13 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
 
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             roleScopeResource.remove(Arrays.asList(requiredRole));
 
             login("jdoe", "jdoe");
             navigateToUserPremiumPage();
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
 
@@ -275,7 +274,7 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
     public void testOnlySpecificClient() throws Exception {
         performTests(() -> {
             login("jdoe", "jdoe");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             ClientPolicyRepresentation policy = new ClientPolicyRepresentation();
 
@@ -290,13 +289,13 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
             updatePermissionPolicies("Protected Resource Permission", policy.getName());
 
             login("jdoe", "jdoe");
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             policy.addClient("servlet-authz-app");
             policyResource.findById(policy.getId()).update(policy);
 
             login("jdoe", "jdoe");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzLazyLoadPathsAdapterTest.java
index fb68580..a3316e6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzLazyLoadPathsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletAuthzLazyLoadPathsAdapterTest.java
@@ -16,15 +16,13 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertFalse;
-
-import java.io.File;
-import java.io.IOException;
-
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -40,7 +38,7 @@ public abstract class AbstractServletAuthzLazyLoadPathsAdapterTest extends Abstr
     public void testPathPEPDisabled() {
         performTests(() -> {
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             navigateTo();
             getLink("PEP Disabled").click();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheDisabledAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheDisabledAdapterTest.java
index 8bc641a..1bdbd42 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheDisabledAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheDisabledAdapterTest.java
@@ -16,18 +16,15 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Test;
 import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -43,10 +40,10 @@ public abstract class AbstractServletCacheDisabledAdapterTest extends AbstractSe
     public void testCreateNewResource() {
         performTests(() -> {
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             ResourceRepresentation resource = new ResourceRepresentation();
 
@@ -64,10 +61,10 @@ public abstract class AbstractServletCacheDisabledAdapterTest extends AbstractSe
             permission = getAuthorizationResource().permissions().resource().create(permission).readEntity(ResourcePermissionRepresentation.class);
 
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertTrue(wasDenied());
+            assertWasDenied();
 
             permission = getAuthorizationResource().permissions().resource().findById(permission.getId()).toRepresentation();
 
@@ -77,10 +74,10 @@ public abstract class AbstractServletCacheDisabledAdapterTest extends AbstractSe
             getAuthorizationResource().permissions().resource().findById(permission.getId()).update(permission);
 
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
         });
     }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheLifespanAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheLifespanAdapterTest.java
index 6477cd4..5d5d6f7 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheLifespanAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractServletCacheLifespanAdapterTest.java
@@ -16,18 +16,15 @@
  */
 package org.keycloak.testsuite.adapter.example.authorization;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Test;
 import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
 import org.keycloak.representations.idm.authorization.ResourceRepresentation;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
  */
@@ -43,10 +40,10 @@ public abstract class AbstractServletCacheLifespanAdapterTest extends AbstractSe
     public void testCreateNewResourceWaitExpiration() {
         performTests(() -> {
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             ResourceRepresentation resource = new ResourceRepresentation();
 
@@ -64,18 +61,21 @@ public abstract class AbstractServletCacheLifespanAdapterTest extends AbstractSe
             permission = getAuthorizationResource().permissions().resource().create(permission).readEntity(ResourcePermissionRepresentation.class);
 
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
-            Thread.sleep(5000);
+            //Thread.sleep(5000);
+            setTimeOffset(10000);
 
             login("alice", "alice");
-            assertFalse(wasDenied());
+            assertWasNotDenied();
 
             this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
-            assertTrue(wasDenied());
+            assertWasDenied();
+
+            resetTimeOffset();
         });
     }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java
index 83a34c7..03a2b71 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/AbstractCorsExampleAdapterTest.java
@@ -20,24 +20,28 @@ package org.keycloak.testsuite.adapter.example.cors;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jetbrains.annotations.Nullable;
 import org.junit.AfterClass;
 import org.junit.Test;
-import org.keycloak.representations.VersionRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
 import org.keycloak.testsuite.adapter.page.AngularCorsProductTestApp;
 import org.keycloak.testsuite.adapter.page.CorsDatabaseServiceTestApp;
 import org.keycloak.testsuite.auth.page.account.Account;
+import org.keycloak.testsuite.util.JavascriptBrowser;
+import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
 
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.WebTarget;
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
+import static junit.framework.TestCase.assertNotNull;
 import static org.keycloak.testsuite.util.IOUtil.loadRealm;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
@@ -50,10 +54,12 @@ public abstract class AbstractCorsExampleAdapterTest extends AbstractExampleAdap
     private static String hostBackup;
 
     @Page
-    private AngularCorsProductTestApp angularCorsProductPage;
+    @JavascriptBrowser
+    private AngularCorsProductTestApp jsDriverAngularCorsProductPage;
 
     @Page
-    private Account testRealmAccount;
+    @JavascriptBrowser
+    private Account jsDriverTestRealmAccount;
 
     @Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME)
     private static WebArchive angularCorsProductExample() throws IOException {
@@ -79,50 +85,69 @@ public abstract class AbstractCorsExampleAdapterTest extends AbstractExampleAdap
     @Override
     public void setDefaultPageUriParameters() {
         super.setDefaultPageUriParameters();
-        testRealmPage.setAuthRealm(CORS);
-        testRealmLoginPage.setAuthRealm(CORS);
-        testRealmAccount.setAuthRealm(CORS);
+        jsDriverTestRealmLoginPage.setAuthRealm(CORS);
+        jsDriverTestRealmAccount.setAuthRealm(CORS);
     }
 
     @Test
     public void angularCorsProductTest() {
-        angularCorsProductPage.navigateTo();
-        testRealmLoginPage.form().login("bburke@redhat.com", "password");
-
-        assertCurrentUrlStartsWith(angularCorsProductPage);
-        angularCorsProductPage.reloadData();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("iphone");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("ipad");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("ipod");
-        waitUntilElement(angularCorsProductPage.getHeaders()).text().contains("\"x-custom1\":\"some-value\"");
-
-        angularCorsProductPage.loadRoles();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("user");
-
-        angularCorsProductPage.addRole();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("stuff");
-
-        angularCorsProductPage.deleteRole();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().not().contains("stuff");
-
-        angularCorsProductPage.loadAvailableSocialProviders();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("twitter");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("google");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("linkedin");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("facebook");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("stackoverflow");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("github");
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("microsoft");
-
-        angularCorsProductPage.loadPublicRealmInfo();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("Realm name: cors");
-
-        Client client = ClientBuilder.newClient();
-        WebTarget target = client.target(authServerPage.createUriBuilder()).path("version");
-        VersionRepresentation version = target.request().get(VersionRepresentation.class);
-
-        angularCorsProductPage.loadVersion();
-        waitUntilElement(angularCorsProductPage.getOutput()).text().contains("Keycloak version: " + version.getVersion());
+        jsDriverAngularCorsProductPage.navigateTo();
+        jsDriverTestRealmLoginPage.form().login("bburke@redhat.com", "password");
+
+        assertCurrentUrlStartsWith(jsDriverAngularCorsProductPage);
+        jsDriverAngularCorsProductPage.reloadData();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("iphone");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("ipad");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("ipod");
+        waitUntilElement(jsDriverAngularCorsProductPage.getHeaders()).text().contains("\"x-custom1\":\"some-value\"");
+
+        jsDriverAngularCorsProductPage.loadRoles();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("user");
+
+        jsDriverAngularCorsProductPage.addRole();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("stuff");
+
+        jsDriverAngularCorsProductPage.deleteRole();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().not().contains("stuff");
+
+        jsDriverAngularCorsProductPage.loadAvailableSocialProviders();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("twitter");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("google");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("linkedin");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("facebook");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("stackoverflow");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("github");
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("microsoft");
+
+        jsDriverAngularCorsProductPage.loadPublicRealmInfo();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("Realm name: cors");
+
+        String serverVersion = getAuthServerVersion();
+        assertNotNull(serverVersion);
+
+        jsDriverAngularCorsProductPage.navigateTo();
+        waitForPageToLoad();
+
+        jsDriverAngularCorsProductPage.loadVersion();
+        waitUntilElement(jsDriverAngularCorsProductPage.getOutput()).text().contains("Keycloak version: " + serverVersion);
+    }
+
+    @Nullable
+    private String getAuthServerVersion() {
+        jsDriver.navigate().to(suiteContext.getAuthServerInfo().getContextRoot().toString() +
+                "/auth/admin/master/console/#/server-info");
+        jsDriverTestRealmLoginPage.form().login("admin", "admin");
+
+        WaitUtils.waitUntilElement(By.tagName("body")).is().visible();
+        Pattern pattern = Pattern.compile("<td [^>]+>Server Version</td>" +
+                "\\s+<td [^>]+>([^<]+)</td>");
+        Matcher matcher = pattern.matcher(jsDriver.getPageSource());
+
+        if (matcher.find()) {
+            return matcher.group(1);
+        }
+
+        return null;
     }
 
     @AfterClass
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
index fabedb8..e42e4b0 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
@@ -1,7 +1,5 @@
 package org.keycloak.testsuite.adapter.javascript;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.page.Page;
 import org.junit.Before;
 import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.representations.idm.ClientRepresentation;
@@ -11,7 +9,6 @@ import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.AbstractAuthTest;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.auth.page.login.OIDCLogin;
 import org.keycloak.testsuite.util.ClientBuilder;
 import org.keycloak.testsuite.util.JavascriptBrowser;
 import org.keycloak.testsuite.util.RealmBuilder;
@@ -49,16 +46,8 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest {
     public static int TOKEN_LIFESPAN_LEEWAY = 3; // seconds
 
 
-    @Drone
-    @JavascriptBrowser
-    protected WebDriver jsDriver;
-
     protected JavascriptExecutor jsExecutor;
 
-    @Page
-    @JavascriptBrowser
-    protected OIDCLogin testRealmLoginPage;
-
     @FindBy(id = "output")
     @JavascriptBrowser
     protected WebElement outputArea;
@@ -147,7 +136,7 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest {
 
     protected void assertOnLoginPage(WebDriver driver1, Object output, WebElement events) {
         waitUntilElement(By.tagName("body")).is().present();
-        assertCurrentUrlStartsWith(testRealmLoginPage, driver1);
+        assertCurrentUrlStartsWith(jsDriverTestRealmLoginPage, driver1);
     }
 
     public void assertOutputWebElementContains(String value, WebDriver driver1, Object output, WebElement events) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
index 4102a14..1232e45 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
@@ -35,7 +35,6 @@ import java.util.Map;
 import static java.lang.Math.toIntExact;
 import static org.hamcrest.CoreMatchers.both;
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.lessThan;
@@ -76,12 +75,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
     public void setDefaultEnvironment() {
         testAppUrl = authServerContextRootPage + JAVASCRIPT_URL + "/index.html";
 
-        testRealmLoginPage.setAuthRealm(REALM_NAME);
+        jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
         oAuthGrantPage.setAuthRealm(REALM_NAME);
         applicationsPage.setAuthRealm(REALM_NAME);
 
         jsDriver.navigate().to(testAppUrl);
-        testExecutor = JavascriptTestExecutor.create(jsDriver, testRealmLoginPage);
+        testExecutor = JavascriptTestExecutor.create(jsDriver, jsDriverTestRealmLoginPage);
 
         waitUntilElement(outputArea).is().present();
         assertCurrentUrlStartsWith(testAppUrl, jsDriver);
@@ -401,7 +400,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
 
         testAppUrl = authServerContextRootPage + JAVASCRIPT_SPACE_URL + "/index.html";
         jsDriver.navigate().to(testAppUrl);
-        testRealmLoginPage.setAuthRealm(SPACE_REALM_NAME);
+        jsDriverTestRealmLoginPage.setAuthRealm(SPACE_REALM_NAME);
 
         testExecutor.configure(configuration)
                 .init(defaultArguments(), this::assertInitNotAuth)
@@ -412,7 +411,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
 
         // Clean
         adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build());
-        testRealmLoginPage.setAuthRealm(REALM_NAME);
+        jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
     }
 
     @Test
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 5fdec57..6a7986a 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
@@ -16,21 +16,6 @@
  */
 package org.keycloak.testsuite.adapter.servlet;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.http.client.utils.URLEncodedUtils;
 import org.apache.http.conn.params.ConnManagerParams;
@@ -41,11 +26,9 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.openqa.selenium.Cookie;
-
 import org.keycloak.OAuth2Constants;
-import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.adapters.OIDCAuthenticationError;
+import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.common.util.Time;
 import org.keycloak.constants.AdapterConstants;
 import org.keycloak.events.Details;
@@ -87,6 +70,7 @@ import org.keycloak.testsuite.util.URLUtils;
 import org.keycloak.testsuite.util.WaitUtils;
 import org.keycloak.util.BasicAuthHelper;
 import org.openqa.selenium.By;
+import org.openqa.selenium.Cookie;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
@@ -96,6 +80,20 @@ import javax.ws.rs.core.Form;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.containsString;
@@ -635,15 +633,15 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
 
     @Test
     public void testVersion() {
-        driver.navigate().to(suiteContext.getAuthServerInfo().getContextRoot().toString() +
+        jsDriver.navigate().to(suiteContext.getAuthServerInfo().getContextRoot().toString() +
                 "/auth/admin/master/console/#/server-info");
-        testRealmLoginPage.form().login("admin", "admin");
+        jsDriverTestRealmLoginPage.form().login("admin", "admin");
 
         WaitUtils.waitUntilElement(By.tagName("body")).is().visible();
 
         Pattern pattern = Pattern.compile("<td [^>]+>Server Version</td>" +
                 "\\s+<td [^>]+>([^<]+)</td>");
-        Matcher matcher = pattern.matcher(driver.getPageSource());
+        Matcher matcher = pattern.matcher(jsDriver.getPageSource());
         String serverVersion = null;
         if (matcher.find()) {
             serverVersion = matcher.group(1);
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 e45dc60..4426da2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -56,9 +56,22 @@
 
     <extension qualifier="webdriver-javascriptbrowser">
         <property name="browser">${js.browser}</property>
+        <property name="downloadBinaries">${webdriverDownloadBinaries}</property>
+        <property name="githubUsername">${github.username}</property>
+        <property name="githubToken">${github.secretToken}</property>
+        <property name="ieDriverArch">${ieDriverArch}</property>
+
+        <!-- htmlunit -->
         <property name="htmlUnit.version">${htmlUnitBrowserVersion}</property>
+        <property name="htmlUnitWebClientOptions">cssEnabled=false;historyPageCacheLimit=1</property>
+
+        <!-- firefox -->
         <property name="firefox_binary">${firefox_binary}</property>
-        <property name="chromeDriverBinary">${webdriver.chrome.driver}</property>
+        <property name="firefoxLogLevel">OFF</property>
+        <property name="firefoxLegacy">${firefoxLegacyDriver}</property>
+
+        <!-- chrome -->
+        <property name="chromeBinary">${chromeBinary}</property>
         <property name="chromeArguments">${js.chromeArguments}</property>
     </extension>
 
diff --git a/testsuite/integration-arquillian/tests/other/adapters/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
index 3aa97f1..6dcc259 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
@@ -96,10 +96,6 @@
         <examples.basedir>${main.basedir}/examples</examples.basedir>
         <exclude.test>-</exclude.test>
         <exclude.cors.tests>**/cors/*Test.java</exclude.cors.tests>
-
-        <!-- Use phantomjs as default browser for adapters, since javascript doesn't work correctly on htmlUnit (KEYCLOAK-4703) -->
-        <browser>phantomjs</browser>
-
     </properties>
 
     <modules>