keycloak-aplcache

Changes

testsuite/integration-arquillian/README_old.md 189(+0 -189)

testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainersTestEnricher.java 362(+0 -362)

Details

diff --git a/testsuite/integration-arquillian/README.md b/testsuite/integration-arquillian/README.md
index 7620d98..5f7f831 100644
--- a/testsuite/integration-arquillian/README.md
+++ b/testsuite/integration-arquillian/README.md
@@ -1,61 +1,166 @@
-# Keycloak Integration Testsuite with Arquillian
+# Keycloak Arquillian Integration Testsuite
 
-## Structure
+## Container Lifecycles
 
-```
-integration-arquillian
-│
-├──servers  (submodules enabled via profiles)
-│  ├──wildfly
-│  └──eap6
-│
-└──tests
-   ├──base
-   └──adapters  (submodules enabled via profiles, all depend on base)
-      ├──wildfly
-      ├──wildfly-relative  (needs servers/wildfly)
-      ├──wildfly8
-      ├──as7
-      ├──tomcat
-      └──karaf
+### Keycloak Auth Server
 
-```
+There is only one instance of Keycloak server running during a single test run.
+It is automatically started by Arquillian on the `BeforeSuite` event and stopped `AfterSuite`.
+
+The type of container can be determined by property `-Dauth.server.container`. Default value is `auth-server-undertow`, 
+other options are: `auth-server-wildfly` and `auth-server-eap7`. The values correspond to Arquillian *container qualifiers* in `arquillian.xml` config file.
+
+**Note 1:** For the non-default options it's necessary to build a corresponding server module prior to running any of the test modules.
+This can be done by building the server module directly (from `servers/wildfly`/`servers/eap7`), 
+or by activating `auth-server-wildfly`/`auth-server-eap7` profile when building from the top level module.
+(The profiles will also set the proper value of the `auth.server.container` property.)
+
+**Note 2:** Most server-side configurations are done during the build of the server module
+and included in the output artifact - which is then consumed by the test modules( if a corresponding profile is activated).
+To reflect a change in server config in the test (e.g. a datasource) it's necessary to rebuild the server module after each change.
+
+### Migration
+
+Migration tests can be enabled by setting `-Dmigrated.auth.server.container` property or activating a corresponding profile.
+When enabled, the `AuthServerTestEnricher` class will start/stop the selected *migrated* instance 
+even **before** the *current* auth server instance is started.
+
+### App Servers
+
+Lifecycle of application server is always tied to a particular TestClass.
+
+Each *adapter* test class is annotated by `@AppServerContainer("app-server-*")` annotation 
+that links it to a particular Arquillian container in `arquillian.xml`.
+The `AppServerTestEnricher` then ensures the server is started before and stopped after all tests methods in the class.
+In case the `@AppServerContainer` annotation has no value it's assumed that the application container 
+is the same as the auth server container (a relative adapter test scenario).
+
+Adapter tests are separated into submodules because different app containers require different configurations 
+(installation of adapter libs, etc.).
+Container entries of app servers are not present in the main `arquillian.xml` in the `base` module.
+Each adapter submodule adds it's own entry before it runs the tests.
+
+## SuiteContext and TestContext
+
+These objects are injected into `AbstractKeycloakTest` class so they can be used everywhere.
+They can be used to get information about the tested containers, and to store information that won't survive across test classes or test methods.
+(Arquillian creates a new instance of test class for each test method run, so all data in the fields is always lost.)
+
+## REST Testing
+
+The `AbstractKeycloakTest` has an initialized instance of AdminClient. Subclasses can use it to access any REST subresources.
+
+## UI Testing
+
+### Page Objects
+
+Page Objects are used by tests to access and operate on UI. 
+They can be injected using annotation `@Page` provided by the *Arquillian Graphene* extension.
+
+The base class for all page objects used throughout this Arquillian testsuite is `AbstractPage`, and it's subclass `AbstractPageWithInjectedUrl`.
 
-## General Concepts
+For the page objects for the *adapter test apps* the URLs are injected automatically by Arquillian depending on actual URL of the deployed app/example.
 
-The testsuite supports **multiple server runtimes** for the Keycloak server.
-The **default is Undertow** which is the fastest and easiest option, and runs in the same JVM as the tests.
+For the pages under the `/auth` context the URL is only injected to the `AuthServerContextRoot` page object, 
+and the URL hierarchy is modeled by the class inheritance hierarchy (subclasses/extending of `AuthServerContextRoot`).
 
-Other options are **Wildfly 9** and **EAP 6**. These have some additional requirements and limitations:
-1. The selected server module must be built before any tests can be run. 
-All server-side configuration is done during this build (e.g. datasource configuration).
-Once server artifact is built the tests modules can unpack it via `maven-dependency-plugin` into their working directory before running.
-2. Before the selected server module can be built the `keycloak/distribution` module also needs to be built.
 
-### Server Runtimes
+### Browsers
 
-TODO: explain why separate module, list config options, note on migration modules
+The default browser for UI testing is `phantomjs` which is used for fast "headless" testing.
+Other browsers can be selected with the `-Dbrowser` property, for example `firefox`.
+See Arquillian Graphene documentation for more details.
+
+
+## Test Modules
 
 ### Base Testsuite
 
-login flows + account management
+The base testsuite contains custom Arquillian extensions and most functional tests.
+The other test modules depend on this module.
 
-admin ui
+### Admin Console UI Tests
 
-abstract adapter tests
+Tests for Keycloak Admin Console are located in a separate module `tests/other/console` 
+and are **disabled** by default. Can be enabled by `-Pconsole-ui-tests`.
 
 ### Adapter Tests
 
-test servlets: demo, session
+Adapter tests are located in submodules of the `tests/other/adapters` module.
+
+They are **disabled** by default; they can be enabled by corresponding profiles.
+Multiple profiles can be enabled for a single test execution.
+
+#### Types of adapter tests
+
+1. Using *custom test servlets*
+2. Using *example demo apps* from `keycloak/examples` modules.
+
+#### Relative vs Non-relative scenario
+
+The test suite can handle both types.
+It automatically modifies imported test realms and deployments' adapter configs based on scenario type.
+
+| Scenario | Description | Realm config (server side) | Adapter config (client side) |
+| --- | --- | --- | --- |
+| **Relative** | auth server == app server | client `baseUrl`, `adminUrl` and `redirect-uris` can be relative | `auth-server-url` can be relative |
+| **Non-relative** | auth server != app server  | client `baseUrl`, `adminUrl` and `redirect-uris` need to include FQDN of the app server | `auth-server-url` needs to include FQDN of the auth server|
+
+
+
+#### Adapter Libs Mode
 
-examples
+1. **Provided** - By container, e.g. as a subsystem. **Default.**
+2. **Bundled** - In the deployed war in `/WEB-INF/libs`. Enable with `-Dadapter.libs.bundled`. *Wildfly only*.
+
+#### Adapter Config Mode
+
+1. ~~**Provided** - In `standalone.xml` using `secure-deployment`. *Wildfly only.*~~ WIP
+2. **Bundled** - In the deployed war in `/WEB-INF/keycloak.json`. **Default.**
+
+
+## Maven Modules Structure
+
+```
+integration-arquillian
+│
+├──servers
+│  ├──wildfly   (activated by -Pauth-server-wildfly)
+│  └──eap7      (activated by -Pauth-server-eap7)
+│
+└──tests   (common settings for all test modules)
+   ├──base    (custom ARQ extensions + base functional tests)
+   └──other   (common settings for all modules dependent on base)
+      │
+      ├──adapters         (common settings for all adapter submodules)
+      │  ├──wildfly           (activated by -Papp-server-wildfly)
+      │  ├──wildfly-relative  (activated by -Papp-server-wildfly-relative,auth-server-wildfly)
+      │  ├──...
+      │  ├──tomcat            (activated by -Papp-server-tomcat)
+      │  └──karaf             (activated by -Papp-server-karaf)
+      │
+      ├──console          (activated by -Pconsole-ui-tests)
+      ├──mod_auth_mellon  (activated by -Pmod_auth_mellon)
+      └──...
+```
 
-## Running the Tests
+## Custom Arquillian Extensions
 
-### Undertow
+Custom extensions are registered in `META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension`.
 
-### Wildfly or EAP 6
+### MultipleContainersExtension
+ * Replaces Arquillian's default container handling.
+ * Allows to manage multiple container instances of different types within a single test run.
+ * Allows to skip loading disabled containers based on `enabled` config property in `arquillian.xml`.
 
-### Adapters
+### KeycloakArquillianExtension
+ * `AuthServerTestEnricher` - Handles lifecycle of auth server and migrated auth server.
+ * `AppServerTestEnricher` - Handles lifecycles of app servers.
+ * `CustomUndertowContainer` - Custom container controller for JAX-RS-enabled Undertow with Keycloak Server.
+ * `DeploymentArchiveProcessor` - Modifies adapter configs before test apps are deployed.
+ * `DeploymentTargetModifier` - Ensures all test app deployments are targeted at app server containers.
+ * `URLProvider` - Fixes URLs injected by Arquillian Graphene which contain value `127.0.0.1` instead of required `localhost`.
+ 
+### CustomKarafContainerExtension
 
-### Supported Browsers
\ No newline at end of file
+Extension for executing karaf commands after container is started. Used for installation of bundles (test apps and adapter libs).
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java
new file mode 100644
index 0000000..9289593
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java
@@ -0,0 +1,207 @@
+package org.keycloak.testsuite.arquillian;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.jboss.arquillian.container.spi.event.container.BeforeDeploy;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.core.api.Instance;
+import org.jboss.arquillian.core.api.InstanceProducer;
+import org.jboss.arquillian.core.api.annotation.Inject;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.test.spi.annotation.ClassScoped;
+import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
+import org.jboss.logging.Logger;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerQualifier;
+import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
+import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
+import static org.keycloak.testsuite.util.IOUtil.execCommand;
+import org.keycloak.testsuite.util.LogChecker;
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class AppServerTestEnricher {
+
+    protected final Logger log = Logger.getLogger(this.getClass());
+
+    @Inject
+    @ClassScoped
+    private InstanceProducer<TestContext> testContextProducer;
+    private TestContext testContext;
+
+    public static String getAppServerQualifier(Class testClass) {
+        Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class);
+
+        String appServerQ = (annotatedClass == null ? null
+                : annotatedClass.getAnnotation(AppServerContainer.class).value());
+
+        return appServerQ == null || appServerQ.isEmpty()
+                ? getAuthServerQualifier() // app server == auth server
+                : appServerQ;
+    }
+
+    public static String getAppServerContextRoot() {
+        return getAppServerContextRoot(0);
+    }
+
+    public static String getAppServerContextRoot(int clusterPortOffset) {
+        int httpPort = Integer.parseInt(System.getProperty("app.server.http.port")); // property must be set
+        int httpsPort = Integer.parseInt(System.getProperty("app.server.https.port")); // property must be set
+        boolean sslRequired = Boolean.parseBoolean(System.getProperty("app.server.ssl.required"));
+
+        return sslRequired
+                ? "https://localhost:" + (httpsPort + clusterPortOffset)
+                : "http://localhost:" + (httpPort + clusterPortOffset);
+    }
+
+    public void updateTestContextWithAppServerInfo(@Observes(precedence = 1) BeforeClass event) {
+        testContext = testContextProducer.get();
+        String appServerQualifier = getAppServerQualifier(testContext.getTestClass());
+        for (ContainerInfo container : testContext.getSuiteContext().getContainers()) {
+            if (container.getQualifier().equals(appServerQualifier)) {
+                testContext.setAppServerInfo(updateWithAppServerInfo(container));
+            }
+        }
+        // validate app server
+        if (appServerQualifier != null && testContext.getAppServerInfo() == null) {
+            throw new RuntimeException(String.format("No app server container matching '%s' was activated. Check if defined and enabled in arquillian.xml.", appServerQualifier));
+        }
+        log.info("\n\n" + testContext);
+    }
+
+    private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo) {
+        return updateWithAppServerInfo(appServerInfo, 0);
+    }
+
+    private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo, int clusterPortOffset) {
+        try {
+
+            String appServerContextRootStr = isRelative(testContext.getTestClass())
+                    ? getAuthServerContextRoot(clusterPortOffset)
+                    : getAppServerContextRoot(clusterPortOffset);
+
+            appServerInfo.setContextRoot(new URL(appServerContextRootStr));
+
+        } catch (MalformedURLException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return appServerInfo;
+    }
+
+    @Inject
+    private Instance<ContainerController> containerConrollerInstance;
+
+    public void startAppServer(@Observes(precedence = -1) BeforeClass event) throws MalformedURLException, InterruptedException, IOException {
+        if (testContext.isAdapterTest()) {
+            ContainerController controller = containerConrollerInstance.get();
+            if (!controller.isStarted(testContext.getAppServerInfo().getQualifier())) {
+                controller.start(testContext.getAppServerInfo().getQualifier());
+            }
+        }
+    }
+
+    public void installAdapterLibs(@Observes BeforeDeploy event) {
+        log.debug("BEFORE DEPLOY - INSTALL ADAPTER LIBS");
+        if (testContext.isAdapterTest()) {
+            // install adapter libs on JBoss-based container via CLI
+            if (testContext.getAppServerInfo().isJBossBased()) {
+                try {
+                    installAdapterLibsUsingJBossCLIClient(testContext.getAppServerInfo());
+                } catch (InterruptedException | IOException ex) {
+                    throw new RuntimeException("Failed to install adapter libs.", ex);
+                }
+            }
+        }
+    }
+
+    private void installAdapterLibsUsingJBossCLIClient(ContainerInfo appServerInfo) throws InterruptedException, IOException {
+        if (!appServerInfo.isAdapterLibsInstalled()) {
+
+            if (!appServerInfo.isJBossBased()) {
+                throw new IllegalArgumentException("App server must be JBoss-based to run jboss-cli-client.");
+            }
+
+            String jbossHomePath = appServerInfo.getProperties().get("jbossHome");
+
+            File bin = new File(jbossHomePath + "/bin");
+            
+            File clientJar = new File(jbossHomePath + "/bin/client/jboss-cli-client.jar");
+            if (!clientJar.exists()) {
+                clientJar = new File(jbossHomePath + "/bin/client/jboss-client.jar"); // AS7
+            }
+            if (!clientJar.exists()) {
+                throw new IOException("JBoss CLI client JAR not found.");
+            }
+            
+            String command = "java -jar " + clientJar.getAbsolutePath();
+            String adapterScript = "adapter-install.cli";
+            String samlAdapterScript = "adapter-install-saml.cli";
+            String managementPort = appServerInfo.getProperties().get("managementPort");
+
+            String controllerArg = " --controller=localhost:" + managementPort;
+            if (new File(bin, adapterScript).exists()) {
+                log.info("Installing adapter to app server via cli script");
+                execCommand(command + " --connect --file=" + adapterScript + controllerArg, bin);
+            }
+            if (new File(bin, samlAdapterScript).exists()) {
+                log.info("Installing saml adapter to app server via cli script");
+                execCommand(command + " --connect --file=" + samlAdapterScript + controllerArg, bin);
+            }
+            if (new File(bin, adapterScript).exists() || new File(bin, samlAdapterScript).exists()) {
+                log.info("Restarting container");
+                execCommand(command + " --connect --command=reload" + controllerArg, bin);
+                log.info("Container restarted");
+                pause(5000);
+                LogChecker.checkJBossServerLog(jbossHomePath);
+            }
+
+            appServerInfo.setAdapterLibsInstalled(true);
+        }
+    }
+
+    /**
+     *
+     * @param testClass
+     * @param annotationClass
+     * @return testClass or the nearest superclass of testClass annotated with
+     * annotationClass
+     */
+    public static Class getNearestSuperclassWithAnnotation(Class testClass, Class annotationClass) {
+        return testClass.isAnnotationPresent(annotationClass) ? testClass
+                : (testClass.getSuperclass().equals(Object.class) ? null // stop recursion
+                        : getNearestSuperclassWithAnnotation(testClass.getSuperclass(), annotationClass)); // continue recursion
+    }
+
+    public static boolean hasAppServerContainerAnnotation(Class testClass) {
+        return getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class) != null;
+    }
+
+    public static boolean isRelative(Class testClass) {
+        return getAppServerQualifier(testClass).equals(getAuthServerQualifier());
+    }
+
+    public static String getAdapterLibsLocationProperty(Class testClass) {
+        Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AdapterLibsLocationProperty.class);
+        return (annotatedClass == null ? null
+                : annotatedClass.getAnnotation(AdapterLibsLocationProperty.class).value());
+    }
+
+    public static boolean isWildflyAppServer(Class testClass) {
+        return getAppServerQualifier(testClass).contains("wildfly");
+    }
+
+    public static boolean isTomcatAppServer(Class testClass) {
+        return getAppServerQualifier(testClass).contains("tomcat");
+    }
+
+    public static boolean isOSGiAppServer(Class testClass) {
+        String q = getAppServerQualifier(testClass);
+        return q.contains("karaf") || q.contains("fuse");
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java
new file mode 100644
index 0000000..5000e3b
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.arquillian;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.jboss.arquillian.container.spi.Container;
+import org.jboss.arquillian.container.spi.ContainerRegistry;
+import org.jboss.arquillian.container.spi.event.StartContainer;
+import org.jboss.arquillian.container.spi.event.StartSuiteContainers;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.core.api.Event;
+import org.jboss.arquillian.core.api.Instance;
+import org.jboss.arquillian.core.api.InstanceProducer;
+import org.jboss.arquillian.core.api.annotation.Inject;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.test.spi.annotation.ClassScoped;
+import org.jboss.arquillian.test.spi.annotation.SuiteScoped;
+import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
+import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
+import org.jboss.logging.Logger;
+import org.keycloak.testsuite.util.LogChecker;
+
+/**
+ *
+ * @author tkyjovsk
+ * @author vramik
+ */
+public class AuthServerTestEnricher {
+
+    protected final Logger log = Logger.getLogger(this.getClass());
+
+    @Inject
+    private Instance<ContainerRegistry> containerRegistry;
+
+    @Inject
+    private Instance<ContainerController> containerController;
+
+    @Inject
+    private Event<StartContainer> startContainerEvent;
+
+    private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container";
+    private static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow";
+
+    private static final String MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY = "migrated.auth.server.container";
+
+    @Inject
+    @SuiteScoped
+    private InstanceProducer<SuiteContext> suiteContextProducer;
+    private SuiteContext suiteContext;
+
+    @Inject
+    @ClassScoped
+    private InstanceProducer<TestContext> testContextProducer;
+
+    public static String getAuthServerQualifier() {
+        return System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT);
+    }
+
+    public static String getMigratedAuthServerQualifier() {
+        return System.getProperty(MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY); // == null if migration not enabled
+    }
+
+    public static String getAuthServerContextRoot() {
+        return getAuthServerContextRoot(0);
+    }
+
+    public static String getAuthServerContextRoot(int clusterPortOffset) {
+        int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set
+        int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set
+        boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));
+
+        return sslRequired
+                ? "https://localhost:" + (httpsPort + clusterPortOffset)
+                : "http://localhost:" + (httpPort + clusterPortOffset);
+    }
+
+    public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event) {
+
+        Set<ContainerInfo> containers = new LinkedHashSet<>();
+        for (Container c : containerRegistry.get().getContainers()) {
+            containers.add(new ContainerInfo(c));
+        }
+
+        suiteContext = new SuiteContext(containers);
+
+        String authServerQualifier = getAuthServerQualifier();
+        String migratedAuthServerQualifier = getMigratedAuthServerQualifier();
+
+        // init authServerInfo and authServerBackendsInfo
+        if (authServerQualifier.startsWith("auth-server-")) {
+
+            boolean authServerCluster = authServerQualifier.endsWith("-cluster");
+
+            String authServerType = authServerQualifier.replaceAll("^auth-server-", "").replaceAll("-cluster$", "");
+            String authServerFrontend = authServerCluster
+                    ? "auth-server-" + authServerType + "-balancer" // in cluster mode the load-balancer container serves as auth server frontend
+                    : authServerQualifier; // single-node mode
+            String authServerBackend = "auth-server-" + authServerType + "-backend";
+            int backends = 0;
+            for (ContainerInfo container : suiteContext.getContainers()) {
+                // frontend
+                if (container.getQualifier().equals(authServerFrontend)) {
+                    updateWithAuthServerInfo(container);
+                    suiteContext.setAuthServerInfo(container);
+                }
+                // backends
+                if (container.getQualifier().startsWith(authServerBackend)) {
+                    updateWithAuthServerInfo(container, ++backends);
+                    suiteContext.getAuthServerBackendsInfo().add(container);
+                }
+            }
+
+            // validate auth server setup
+            if (suiteContext.getAuthServerInfo() == null) {
+                throw new RuntimeException(String.format("No auth server activated. A container matching '%s' needs to be enabled in arquillian.xml.", authServerFrontend));
+            }
+            if (authServerCluster && !suiteContext.getAuthServerBackendsInfo().isEmpty()) {
+                throw new RuntimeException(String.format("No cluster backend nodes activated. Containers matching '%sN' need to be enabled in arquillian.xml.", authServerBackend));
+            }
+
+        } else {
+            throw new IllegalArgumentException(String.format("Value of %s should start with 'auth-server-' prefix.", AUTH_SERVER_CONTAINER_PROPERTY));
+        }
+
+        if (migratedAuthServerQualifier != null) {
+            // init migratedAuthServerInfo
+            if (migratedAuthServerQualifier.startsWith("migrated-auth-server-")) {
+                for (ContainerInfo container : suiteContext.getContainers()) {
+                    // migrated auth server
+                    if (container.getQualifier().equals(migratedAuthServerQualifier)) {
+                        updateWithAuthServerInfo(container);
+                        suiteContext.setMigratedAuthServerInfo(container);
+                    }
+                }
+            } else {
+                throw new IllegalArgumentException(String.format("Value of %s should start with 'migrated-auth-server-' prefix.", MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY));
+            }
+            // validate setup
+            if (suiteContext.getMigratedAuthServerInfo() == null) {
+                throw new RuntimeException(String.format("Migration test was enabled but no auth server from which to migrate was activated. "
+                        + "A container matching '%s' needs to be enabled in arquillian.xml.", migratedAuthServerQualifier));
+            }
+        }
+
+        suiteContextProducer.set(suiteContext);
+        log.info("\n\n" + suiteContext);
+    }
+
+    private ContainerInfo updateWithAuthServerInfo(ContainerInfo authServerInfo) {
+        return updateWithAuthServerInfo(authServerInfo, 0);
+    }
+
+    private ContainerInfo updateWithAuthServerInfo(ContainerInfo authServerInfo, int clusterPortOffset) {
+        try {
+            authServerInfo.setContextRoot(new URL(getAuthServerContextRoot(clusterPortOffset)));
+        } catch (MalformedURLException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return authServerInfo;
+    }
+
+    public void startMigratedContainer(@Observes(precedence = 2) StartSuiteContainers event) {
+        if (suiteContext.isAuthServerMigrationEnabled()) {
+            log.info("\n\n### Starting keycloak " + System.getProperty("version", "- previous") + " ###\n");
+            startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer()));
+        }
+    }
+
+    public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) {
+        if (suiteContext.isAuthServerMigrationEnabled()) {
+            containerController.get().stop(suiteContext.getAuthServerInfo().getQualifier());
+        }
+    }
+
+    public void checkServerLogs(@Observes(precedence = -1) BeforeSuite event) throws IOException, InterruptedException {
+        boolean checkLog = System.getProperty("auth.server.log.check", "true").equals("true");
+        if (checkLog && suiteContext.getAuthServerInfo().isJBossBased()) {
+            String jbossHomePath = suiteContext.getAuthServerInfo().getProperties().get("jbossHome");
+            LogChecker.checkJBossServerLog(jbossHomePath);
+        }
+    }
+
+    public void initializeTestContext(@Observes(precedence = 2) BeforeClass event) {
+        TestContext testContext = new TestContext(suiteContext, event.getTestClass().getJavaClass());
+        testContextProducer.set(testContext);
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java
new file mode 100644
index 0000000..a6bcdc5
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java
@@ -0,0 +1,95 @@
+package org.keycloak.testsuite.arquillian;
+
+import java.net.URL;
+import java.util.Map;
+import java.util.Objects;
+import org.jboss.arquillian.container.spi.Container;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class ContainerInfo {
+
+    private URL contextRoot;
+    private Container arquillianContainer;
+    private boolean adapterLibsInstalled;
+
+    public ContainerInfo(Container arquillianContainer) {
+        if (arquillianContainer == null) {
+            throw new IllegalArgumentException();
+        }
+        this.arquillianContainer = arquillianContainer;
+    }
+
+    public Container getArquillianContainer() {
+        return arquillianContainer;
+    }
+
+    public Map<String, String> getProperties() {
+        return getArquillianContainer().getContainerConfiguration().getContainerProperties();
+    }
+
+    public String getQualifier() {
+        return getArquillianContainer().getName();
+    }
+
+    public URL getContextRoot() {
+        return contextRoot;
+    }
+
+    public void setContextRoot(URL contextRoot) {
+        this.contextRoot = contextRoot;
+    }
+
+    public boolean isAS7() {
+        return getQualifier().toLowerCase().contains("as7");
+    }
+
+    public boolean isWildfly() {
+        return getQualifier().toLowerCase().contains("wildfly");
+    }
+
+    public boolean isEAP() {
+        return getQualifier().toLowerCase().contains("eap");
+    }
+
+    public boolean isJBossBased() {
+        return isAS7() || isWildfly() || isEAP();
+    }
+
+    @Override
+    public String toString() {
+        return getQualifier();
+    }
+
+    public boolean isAdapterLibsInstalled() {
+        return adapterLibsInstalled;
+    }
+
+    public void setAdapterLibsInstalled(boolean adapterLibsInstalled) {
+        this.adapterLibsInstalled = adapterLibsInstalled;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 97 * hash + Objects.hashCode(this.arquillianContainer);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ContainerInfo other = (ContainerInfo) obj;
+        return Objects.equals(
+                this.arquillianContainer.getContainerConfiguration().getContainerName(),
+                other.arquillianContainer.getContainerConfiguration().getContainerName());
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java
index 74e20c1..e4a8ab2 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java
@@ -37,8 +37,12 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAdapterLibsLocationProperty;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.hasAppServerContainerAnnotation;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isRelative;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isTomcatAppServer;
 
-import static org.keycloak.testsuite.arquillian.ContainersTestEnricher.*;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.*;
 import static org.keycloak.testsuite.util.IOUtil.*;
 
 ;
@@ -66,7 +70,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
         log.info("Processing archive " + archive.getName());
 //        if (isAdapterTest(testClass)) {
         modifyAdapterConfigs(archive, testClass);
-        attachKeycloakLibs(archive, testClass);
+        attachAdapterLibs(archive, testClass);
         modifyWebXml(archive, testClass);
 //        } else {
 //            log.info(testClass.getJavaClass().getSimpleName() + " is not an AdapterTest");
@@ -89,21 +93,21 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
     protected void modifyAdapterConfig(Archive<?> archive, String adapterConfigPath, boolean relative) {
         if (archive.contains(adapterConfigPath)) {
             log.info("Modifying adapter config " + adapterConfigPath + " in " + archive.getName());
-            if (adapterConfigPath.equals(SAML_ADAPTER_CONFIG_PATH)) {
+            if (adapterConfigPath.equals(SAML_ADAPTER_CONFIG_PATH)) { // SAML adapter config
                 log.info("Modyfying saml adapter config in " + archive.getName());
 
                 Document doc = loadXML(archive.get("WEB-INF/keycloak-saml.xml").getAsset().openStream());
                 if (authServerSslRequired) {
-                    modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.https.port", null));
+                    modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.https.port"));
                     modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "http", "https");
-                    modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.https.port", null));
+                    modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.https.port"));
                     modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "http", "https");
-                    modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.https.port", null));
+                    modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.https.port"));
                     modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "http", "https");
                 } else {
-                    modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.http.port", null));
-                    modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.http.port", null));
-                    modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.http.port", null));
+                    modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.http.port"));
+                    modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.http.port"));
+                    modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.http.port"));
                 }
 
                 try {
@@ -112,7 +116,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
                     log.error("Can't transform document to String");
                     throw new RuntimeException(e);
                 }
-            } else {
+            } else { // OIDC adapter config
                 try {
                     BaseAdapterConfig adapterConfig = loadJson(archive.get(adapterConfigPath)
                             .getAsset().openStream(), BaseAdapterConfig.class);
@@ -122,7 +126,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
                         adapterConfig.setAuthServerUrl("/auth");
 //                ac.setRealmKey(null); // TODO verify if realm key is required for relative scneario
                     } else {
-                        adapterConfig.setAuthServerUrl(getAuthServerContextRootFromSystemProperty() + "/auth");
+                        adapterConfig.setAuthServerUrl(getAuthServerContextRoot() + "/auth");
                         adapterConfig.setRealmKey(REALM_KEY);
                     }
                     
@@ -140,7 +144,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
         }
     }
 
-    protected void attachKeycloakLibs(Archive<?> archive, TestClass testClass) {
+    protected void attachAdapterLibs(Archive<?> archive, TestClass testClass) {
         AdapterLibsMode adapterType = AdapterLibsMode.getByType(System.getProperty("adapter.libs.mode",
                 AdapterLibsMode.PROVIDED.getType()));
         log.info("Adapter type: " + adapterType);
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
index b45d50f..b867c7c 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
@@ -23,7 +23,7 @@ import org.jboss.arquillian.container.spi.client.deployment.TargetDescription;
 import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
 import org.jboss.arquillian.test.spi.TestClass;
 import org.jboss.logging.Logger;
-import static org.keycloak.testsuite.arquillian.ContainersTestEnricher.*;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAppServerQualifier;
 
 /**
  * Changes target container for all Arquillian deployments based on value of
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 621483c..7154b8a 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
@@ -47,7 +47,8 @@ public class KeycloakArquillianExtension implements LoadableExtension {
         builder
                 .service(DeploymentScenarioGenerator.class, DeploymentTargetModifier.class)
                 .service(ApplicationArchiveProcessor.class, DeploymentArchiveProcessor.class)
-                .observer(ContainersTestEnricher.class);
+                .observer(AuthServerTestEnricher.class)
+                .observer(AppServerTestEnricher.class);
 
         builder
                 .service(DeployableContainer.class, CustomUndertowContainer.class);
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
index f883f64..301fc86 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
@@ -33,6 +33,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashSet;
 import java.util.Set;
+import org.keycloak.testsuite.arquillian.SuiteContext;
 
 public class URLProvider extends URLResourceProvider {
 
@@ -44,6 +45,8 @@ public class URLProvider extends URLResourceProvider {
     private final boolean appServerSslRequired = Boolean.parseBoolean(System.getProperty("app.server.ssl.required"));
 
     @Inject
+    Instance<SuiteContext> suiteContext;
+    @Inject
     Instance<TestContext> testContext;
 
     private static final Set<String> fixedUrls = new HashSet<>();
@@ -97,10 +100,10 @@ public class URLProvider extends URLResourceProvider {
         // inject context roots if annotation present
         for (Annotation a : qualifiers) {
             if (AuthServerContext.class.isAssignableFrom(a.annotationType())) {
-                return testContext.get().getAuthServerContextRoot();
+                return suiteContext.get().getAuthServerInfo().getContextRoot();
             }
             if (AppServerContext.class.isAssignableFrom(a.annotationType())) {
-                return testContext.get().getAppServerContextRoot();
+                return testContext.get().getAppServerInfo().getContextRoot();
             }
         }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
index fb91a7b..c4bd23b 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
@@ -14,11 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.arquillian;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import static org.keycloak.testsuite.util.MailServerConfiguration.*;
 
 /**
@@ -27,10 +29,18 @@ import static org.keycloak.testsuite.util.MailServerConfiguration.*;
  */
 public final class SuiteContext {
 
+    private final Set<ContainerInfo> container;
+
+    private ContainerInfo authServerInfo;
+    private final List<ContainerInfo> authServerBackendsInfo = new ArrayList<>();
+
+    private ContainerInfo migratedAuthServerInfo;
+
     private boolean adminPasswordUpdated;
     private final Map<String, String> smtpServer = new HashMap<>();
-    
-    public SuiteContext() {
+
+    public SuiteContext(Set<ContainerInfo> arquillianContainers) {
+        this.container = arquillianContainers;
         this.adminPasswordUpdated = false;
         smtpServer.put("from", FROM);
         smtpServer.put("host", HOST);
@@ -48,4 +58,44 @@ public final class SuiteContext {
     public Map<String, String> getSmtpServer() {
         return smtpServer;
     }
+
+    public ContainerInfo getAuthServerInfo() {
+        return authServerInfo;
+    }
+
+    public void setAuthServerInfo(ContainerInfo authServerInfo) {
+        this.authServerInfo = authServerInfo;
+    }
+
+    public List<ContainerInfo> getAuthServerBackendsInfo() {
+        return authServerBackendsInfo;
+    }
+
+    public ContainerInfo getMigratedAuthServerInfo() {
+        return migratedAuthServerInfo;
+    }
+
+    public void setMigratedAuthServerInfo(ContainerInfo migratedAuthServerInfo) {
+        this.migratedAuthServerInfo = migratedAuthServerInfo;
+    }
+
+    public boolean isAuthServerCluster() {
+        return !authServerBackendsInfo.isEmpty();
+    }
+
+    public boolean isAuthServerMigrationEnabled() {
+        return migratedAuthServerInfo != null;
+    }
+
+    public Set<ContainerInfo> getContainers() {
+        return container;
+    }
+
+    @Override
+    public String toString() {
+        return "SUITE CONTEXT:\n"
+                + "Auth server: " + authServerInfo.getQualifier() + "\n"
+                +(isAuthServerCluster() ? "Auth server cluster: " + getAuthServerBackendsInfo().size() + " nodes+\n" : "");
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
index b4c67ef..673bc7c 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
@@ -14,10 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.arquillian;
 
-import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  *
@@ -25,43 +25,67 @@ import java.net.URL;
  */
 public final class TestContext {
 
-    private URL authServerContextRoot;
-    private URL appServerContextRoot;
+    private final SuiteContext suiteContext;
+
+    private final Class testClass;
+
+    private ContainerInfo appServerInfo;
+    private final List<ContainerInfo> appServerBackendsInfo = new ArrayList<>();
 
     private boolean adminLoggedIn;
 
-    public TestContext() {
+    public TestContext(SuiteContext suiteContext, Class testClass) {
+        this.suiteContext = suiteContext;
+        this.testClass = testClass;
         this.adminLoggedIn = false;
     }
 
-    public TestContext(URL authServerContextRoot, URL appServerContextRoot) {
-        this();
-        this.authServerContextRoot = authServerContextRoot;
-        this.appServerContextRoot = appServerContextRoot;
+    public boolean isAdminLoggedIn() {
+        return adminLoggedIn;
     }
 
-    public URL getAuthServerContextRoot() {
-        return authServerContextRoot;
+    public void setAdminLoggedIn(boolean adminLoggedIn) {
+        this.adminLoggedIn = adminLoggedIn;
     }
 
-    public URL getAppServerContextRoot() {
-        return appServerContextRoot;
+    public ContainerInfo getAppServerInfo() {
+        return appServerInfo;
     }
 
-    public boolean isAdminLoggedIn() {
-        return adminLoggedIn;
+    public void setAppServerInfo(ContainerInfo appServerInfo) {
+        this.appServerInfo = appServerInfo;
     }
 
-    public void setAdminLoggedIn(boolean adminLoggedIn) {
-        this.adminLoggedIn = adminLoggedIn;
+    public List<ContainerInfo> getAppServerBackendsInfo() {
+        return appServerBackendsInfo;
+    }
+
+    public Class getTestClass() {
+        return testClass;
+    }
+
+    public boolean isAdapterTest() {
+        return appServerInfo != null;
+    }
+
+    public boolean isRelativeAdapterTest() {
+        return isAdapterTest()
+                && appServerInfo.getQualifier().equals(
+                        suiteContext.getAuthServerInfo().getQualifier()); // app server == auth server
+    }
+
+    public boolean isClusteredAdapterTest() {
+        return isAdapterTest() && !appServerBackendsInfo.isEmpty();
     }
 
-    public void setAuthServerContextRoot(URL authServerContextRoot) {
-        this.authServerContextRoot = authServerContextRoot;
+    public SuiteContext getSuiteContext() {
+        return suiteContext;
     }
 
-    public void setAppServerContextRoot(URL appServerContextRoot) {
-        this.appServerContextRoot = appServerContextRoot;
+    @Override
+    public String toString() {
+        return "TEST CONTEXT: " + getTestClass().getCanonicalName() + "\n"
+                + (isAdapterTest() ? "App server container: " + getAppServerInfo() + "\n" : "");
     }
 
 }
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 4661df8..ba45448 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
@@ -101,9 +101,9 @@ public class AccountManagement extends AuthRealm {
         save.click();
     }
 
-    public RealmResource realmResource() {
-        return keycloak().realm(getAuthRealm());
-    }
+//    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/AuthServer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
index 7dae6b6..14f1e26 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
@@ -41,11 +41,11 @@ public class AuthServer extends AuthServerContextRoot {
         return uri.getScheme() + "://" + uri.getAuthority() + "/auth";
     }
 
-    @ArquillianResource
-    protected Keycloak keycloak;
-
-    public Keycloak keycloak() {
-        return keycloak;
-    }
+//    @ArquillianResource
+//    protected Keycloak keycloak;
+//
+//    public Keycloak keycloak() {
+//        return keycloak;
+//    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
index 081b1d4..fa42371 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
@@ -59,9 +59,9 @@ public class AdminConsoleRealm extends AdminConsoleRealmsRoot {
         return configureMenu;
     }
 
-    public RealmResource realmResource() {
-        return realmsResource().realm(getConsoleRealm());
-    }
+//    public RealmResource realmResource() {
+//        return realmsResource().realm(getConsoleRealm());
+//    }
 
     public class ConfigureMenu {
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
index 5e3048f..467dc21 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
@@ -59,8 +59,8 @@ public class AdminConsoleRealmsRoot extends AdminConsole {
     @FindBy(css = "realm-selector")
     protected RealmSelector realmSelector;
 
-    public RealmsResource realmsResource() {
-        return keycloak.realms();
-    }
+//    public RealmsResource realmsResource() {
+//        return keycloak.realms();
+//    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
index 36c692b..23103d3 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.util;
 
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -33,6 +32,8 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import java.io.*;
+import java.util.concurrent.TimeUnit;
+import org.jboss.logging.Logger;
 
 /**
  *
@@ -40,6 +41,8 @@ import java.io.*;
  */
 public class IOUtil {
 
+    private static final Logger log = Logger.getLogger(IOUtil.class);
+
     public static <T> T loadJson(InputStream is, Class<T> type) {
         try {
             return JsonSerialization.readValue(is, type);
@@ -71,7 +74,7 @@ public class IOUtil {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             return dBuilder.parse(is);
-        } catch (ParserConfigurationException|SAXException|IOException e) {
+        } catch (ParserConfigurationException | SAXException | IOException e) {
             throw new RuntimeException(e);
         }
     }
@@ -99,4 +102,36 @@ public class IOUtil {
         }
         node.setTextContent(node.getTextContent().replace(regex, replacement));
     }
+
+    public static void execCommand(String command, File dir) throws IOException, InterruptedException {
+        Process process = Runtime.getRuntime().exec(command, null, dir);
+        if (process.waitFor(10, TimeUnit.SECONDS)) {
+            if (process.exitValue() != 0) {
+                getOutput("ERROR", process.getErrorStream());
+                throw new RuntimeException("Adapter installation failed. Process exitValue: "
+                        + process.exitValue());
+            }
+            getOutput("OUTPUT", process.getInputStream());
+            log.debug("process.isAlive(): " + process.isAlive());
+        } else {
+            if (process.isAlive()) {
+                process.destroyForcibly();
+            }
+            throw new RuntimeException("Timeout after 10 seconds.");
+        }
+    }
+
+    public static void getOutput(String type, InputStream is) throws IOException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        StringBuilder builder = new StringBuilder();
+        builder.append("<").append(type).append(">");
+        System.out.println(builder);
+        builder = new StringBuilder();
+        while (reader.ready()) {
+            System.out.println(reader.readLine());
+        }
+        builder.append("</").append(type).append(">");
+        System.out.println(builder);
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java
new file mode 100644
index 0000000..8e16b34
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java
@@ -0,0 +1,37 @@
+package org.keycloak.testsuite.util;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ * @author vramik
+ * @author tkyjovsk
+ */
+public class LogChecker {
+
+    private static final Logger log = Logger.getLogger(LogChecker.class);
+
+    public static void checkServerLog(File logFile) throws IOException {
+        log.info(String.format("Checking server log: '%s'", logFile.getAbsolutePath()));
+        String logContent = FileUtils.readFileToString(logFile);
+
+        boolean containsError
+                = logContent.contains("ERROR")
+                || logContent.contains("SEVERE")
+                || logContent.contains("Exception ");
+
+        //There is expected string "Exception" in server log: Adding provider 
+        //singleton org.keycloak.services.resources.ModelExceptionMapper
+        if (containsError) {
+            throw new RuntimeException(String.format("Server log file contains ERROR: '%s'", logFile.getPath()));
+        }
+    }
+
+    public static void checkJBossServerLog(String jbossHome) throws IOException {
+        checkServerLog(new File(jbossHome + "/standalone/log/server.log"));
+    }
+
+}
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 9d3040f..92dc9c5 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
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite;
 
 import org.keycloak.testsuite.arquillian.TestContext;
@@ -33,9 +32,12 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.RealmsResource;
+import org.keycloak.models.Constants;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import static org.keycloak.testsuite.admin.Users.setPasswordFor;
+import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
 import org.keycloak.testsuite.arquillian.SuiteContext;
 import org.keycloak.testsuite.auth.page.WelcomePage;
 import org.keycloak.testsuite.util.OAuthClient;
@@ -66,11 +68,9 @@ public abstract class AbstractKeycloakTest {
 
     @ArquillianResource
     protected TestContext testContext;
-    
-    @ArquillianResource
+
     protected Keycloak adminClient;
 
-    @ArquillianResource
     protected OAuthClient oauthClient;
 
     protected List<RealmRepresentation> testRealmReps;
@@ -100,6 +100,11 @@ public abstract class AbstractKeycloakTest {
 
     @Before
     public void beforeAbstractKeycloakTest() {
+        adminClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
+                MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
+        oauthClient = new OAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
+
+        
         adminUser = createAdminUserRepresentation();
 
         setDefaultPageUriParameters();
@@ -195,5 +200,9 @@ public abstract class AbstractKeycloakTest {
     public void removeRealm(RealmRepresentation realm) {
         adminClient.realms().realm(realm.getRealm()).remove();
     }
+    
+    public RealmsResource realmsResouce() {
+        return adminClient.realms();
+    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
index fa115af..a9ed805 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
@@ -25,7 +25,6 @@ import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.AbstractAuthTest;
 import org.keycloak.testsuite.adapter.page.AppServerContextRoot;
-import org.keycloak.testsuite.arquillian.ContainersTestEnricher;
 import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
 
 import java.io.IOException;
@@ -78,7 +77,7 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
     public abstract void addAdapterTestRealms(List<RealmRepresentation> testRealms);
 
     public boolean isRelative() {
-        return ContainersTestEnricher.isRelative(this.getClass());
+        return testContext.isRelativeAdapterTest();
     }
 
     protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String replacement) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
index fc572a1..c7085b3 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.client;
 
 import org.junit.After;
@@ -46,7 +45,7 @@ public abstract class AbstractClientRegistrationTest extends AbstractKeycloakTes
 
     @Before
     public void before() throws Exception {
-        reg = ClientRegistration.create().url(testContext.getAuthServerContextRoot() + "/auth", "test").build();
+        reg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", "test").build();
     }
 
     @After
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
index 55a9475..4272025 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.client;
 
 import org.junit.Before;
@@ -87,7 +86,7 @@ public class AdapterInstallationConfigTest extends AbstractClientRegistrationTes
         AdapterConfig config = reg.getAdapterConfig(client.getClientId());
         assertNotNull(config);
 
-        assertEquals(testContext.getAuthServerContextRoot() + "/auth", config.getAuthServerUrl());
+        assertEquals(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", config.getAuthServerUrl());
         assertEquals("test", config.getRealm());
 
         assertEquals(1, config.getCredentials().size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java
new file mode 100644
index 0000000..27053ae
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java
@@ -0,0 +1,34 @@
+package org.keycloak.testsuite;
+
+import java.util.List;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class ContainersTest extends AbstractKeycloakTest {
+
+    @ArquillianResource
+    ContainerController controller;
+
+    @Override
+    public void addTestRealms(List<RealmRepresentation> testRealms) {
+    }
+
+    
+    @Test
+    public void testAuthServer() {
+
+        log.info("AUTH SERVER should be started.");
+        assertTrue(controller.isStarted(AuthServerTestEnricher.getAuthServerQualifier()));
+        
+    }
+
+}
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 8c8f9b2..555f3ce 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -1,19 +1,19 @@
 <!--
-  ~ Copyright 2016 Red Hat, Inc. and/or its affiliates
-  ~ and other contributors as indicated by the @author tags.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~ http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
+~ Copyright 2016 Red Hat, Inc. and/or its affiliates
+~ and other contributors as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~ http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
 
 <arquillian xmlns="http://jboss.org/schema/arquillian"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -44,10 +44,73 @@
         <property name="deploymentExportPath">target/deployments</property>
     </engine>
     
-    <!-- PREVIOUS VERSIONS KEYCLOAK FOR MIGRATION TESTS -->
-    <!-- IT HAS TO BE LISTED ABOWE KEYCLOAK AUTH SERVERS -->
+    <!-- KEYCLOAK AUTH SERVERS -->
+    
+    <container qualifier="auth-server-undertow" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.undertow}</property>
+            <property name="bindAddress">localhost</property>
+            <property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.CustomUndertowContainer</property>
+            <property name="bindHttpPort">${auth.server.http.port}</property>
+        </configuration>
+    </container>
+    
+    <container qualifier="auth-server-wildfly" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.wildfly}</property>
+            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+            <property name="jbossHome">${keycloak.home}</property>
+            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
+            <property name="managementPort">${auth.server.management.port}</property>
+            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+        </configuration>
+    </container>
+    
+    <group qualifier="auth-server-wildfly-cluster">
+        <container qualifier="auth-server-wildfly-balancer" mode="suite" >
+            <configuration>
+                <property name="enabled">${auth.server.wildfly.cluster}</property>
+                <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+                <property name="jbossHome">${wildfly.home}</property>
+                <property name="javaVmArguments">
+                    -Djboss.socket.binding.port-offset=${auth.server.port.offset} 
+                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
+                    ${adapter.test.props}
+                </property>
+                <property name="managementPort">${auth.server.management.port}</property>
+                <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            </configuration>
+        </container>
+        <container qualifier="auth-server-wildfly-backend1" mode="manual" >
+            <configuration>
+                <property name="enabled">${auth.server.wildfly.cluster}</property>
+                <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+                <property name="jbossHome">${keycloak.backend1.home}</property>
+                <property name="javaVmArguments">
+                    -Djboss.socket.binding.port-offset=${auth.server.backend1.port.offset} 
+                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
+                    ${adapter.test.props}
+                </property>
+                <property name="managementPort">${auth.server.backend1.management.port}</property>
+                <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            </configuration>
+        </container>
+    </group>
+    
+    <container qualifier="auth-server-eap7" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.eap7}</property>
+            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+            <property name="jbossHome">${keycloak.home}</property>
+            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
+            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            <property name="managementPort">${auth.server.management.port}</property>
+        </configuration>
+    </container>
+
+    <!-- PREVIOUS VERSIONS OF KEYCLOAK FOR MIGRATION TESTS -->
     
-    <container qualifier="keycloak-1.6.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc16" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc16}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -66,7 +129,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.5.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc15" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc15}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -85,7 +148,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.4.0.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc14" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc14}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -96,7 +159,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.3.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc13" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc13}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -107,7 +170,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.2.0.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc12" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc12}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -118,37 +181,12 @@
         </configuration>
     </container>
     
-    <!-- KEYCLOAK AUTH SERVERS -->
-    
-    <container qualifier="auth-server-undertow" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.undertow}</property>
-            <property name="bindAddress">localhost</property>
-            <property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.CustomUndertowContainer</property>
-            <property name="bindHttpPort">${auth.server.http.port}</property>
-        </configuration>
-    </container>
-    
-    <container qualifier="auth-server-wildfly" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.wildfly}</property>
-            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
-            <property name="jbossHome">${keycloak.home}</property>
-            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
-            <property name="managementPort">${auth.server.management.port}</property>
-            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
-        </configuration>
-    </container>
-    
-    <container qualifier="auth-server-eap7" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.eap7}</property>
-            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
-            <property name="jbossHome">${keycloak.home}</property>
-            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
-            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
-            <property name="managementPort">${auth.server.management.port}</property>
-        </configuration>
-    </container>
+    <!--
     
+     APP SERVER CONTAINERS ARE ADDED BY XSL TRANSFORMATIONS IN ADAPTER TEST SUBMODULES 
+     The configuration of various application containers had to be split into multiple 
+     maven submodules: tests/other/adapters, which are activated on demand by profiles.
+     
+    -->
+
 </arquillian>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
index 74228e2..4db057f 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
@@ -287,13 +287,6 @@
         </profile>
         
         <profile>
-            <id>auth-server-wildfly</id>
-            <modules>
-                <module>wildfly-relative</module>
-            </modules>
-        </profile>
-        
-        <profile>
             <id>app-server-eap6</id>
             <modules>
                 <module>eap6</module>
@@ -312,6 +305,12 @@
             </modules>
         </profile>
         <profile>
+            <id>app-server-wildfly-relative</id>
+            <modules>
+                <module>wildfly-relative</module>
+            </modules>
+        </profile>
+        <profile>
             <id>app-server-wildfly8</id>
             <modules>
                 <module>wildfly8</module>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/wildfly-relative/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/wildfly-relative/pom.xml
index 871e825..983e815 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/wildfly-relative/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/wildfly-relative/pom.xml
@@ -1,20 +1,20 @@
 <?xml version="1.0"?>
 <!--
-  ~ Copyright 2016 Red Hat, Inc. and/or its affiliates
-  ~ and other contributors as indicated by the @author tags.
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~ http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
+~ Copyright 2016 Red Hat, Inc. and/or its affiliates
+~ and other contributors as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~ http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
 
 <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
@@ -54,7 +54,39 @@
         </dependency>
     </dependencies>
     
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-enforcer-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>enforce-auth-server-wildfly-profile</id>
+                            <goals>
+                                <goal>enforce</goal>
+                            </goals>
+                            <configuration>
+                                <rules>
+                                    <requireActiveProfile>
+                                        <profiles>auth-server-wildfly</profiles>
+                                    </requireActiveProfile>
+                                </rules>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    
     <profiles>
+        
+        <profile>
+            <id>auth-server-wildfly</id>
+            <!--dummy profile for the enforcer plugin to work-->
+        </profile>
+        
         <profile>
             <id>adapter-libs-bundled</id>
             <activation>    
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 bb70843..864ebee 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
@@ -108,8 +108,6 @@ public class Client extends Clients {
 
     }
 
-    public ClientResource clientResource() {
-        return clientsResource().get(getId());
-    }
+
 
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
index 58fac4d..945e72f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
@@ -126,8 +126,4 @@ public class Clients extends AdminConsoleRealm {
         }
     }
 
-    public ClientsResource clientsResource() {
-        return realmResource().clients();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
index 3542af2..67bbf52 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
@@ -22,9 +22,5 @@ public class ClientRoles extends Client {
     public RolesTable roles() {
         return table;
     }
-    
-    public RolesResource rolesResource() {
-        return clientResource().roles();
-    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
index 275ddf4..f3f91a7 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
@@ -92,8 +92,4 @@ public class IdentityProviderSettings extends AdminConsoleRealm {
         return rows;
     }
     
-    public IdentityProvidersResource identityProviders() {
-        return realmResource().identityProviders();
-    }
-    
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
index 910e470..6c86255 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
@@ -35,8 +35,4 @@ public class Roles extends AdminConsoleRealm {
 
     }
 
-    public RolesResource rolesResource() {
-        return realmResource().roles();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
index fba2adb..7cea05c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
@@ -1,6 +1,5 @@
 package org.keycloak.testsuite.console.page.users;
 
-import org.keycloak.admin.client.resource.UserResource;
 import org.keycloak.testsuite.console.page.fragment.Breadcrumb;
 import static org.keycloak.testsuite.console.page.fragment.Breadcrumb.BREADCRUMB_XPATH;
 import org.openqa.selenium.WebElement;
@@ -76,8 +75,4 @@ public class User extends Users {
 
     }
     
-    public UserResource userResource() {
-        return usersResource().get(getId());
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
index 3a05b68..32c6bac 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
@@ -20,9 +20,5 @@ public class UserRoleMappings extends User {
     public UserRoleMappingsForm form() {
         return form;
     }
-    
-    public RoleMappingResource roleMappingResource() {
-        return userResource().roles();
-    }
 
 }
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 d5ffcb5..9e083a7 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
@@ -22,7 +22,6 @@ import org.openqa.selenium.support.FindBy;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.UserRepresentation;
 
 import org.keycloak.testsuite.console.page.AdminConsoleRealm;
@@ -135,8 +134,4 @@ public class Users extends AdminConsoleRealm {
 
     }
     
-    public UsersResource usersResource() {
-        return realmResource().users();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
index eb2fb5b..633b550 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
@@ -17,7 +17,6 @@
  */
 package org.keycloak.testsuite.console;
 
-import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
index 0847294..f646675 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
@@ -8,6 +8,8 @@ import java.util.Map;
 import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertEquals;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.admin.client.resource.ClientsResource;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import static org.keycloak.testsuite.auth.page.login.OIDCLogin.OIDC;
@@ -50,7 +52,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
 
     public final String TEST_CLIENT_ID = "test-client";
     public final String TEST_REDIRECT_URIS = "http://example.test/app/*";
-    
+
     @Page
     protected Clients clientsPage;
     @Page
@@ -87,12 +89,12 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         client.setConsentRequired(false);
         return client;
     }
-    
+
     public static ClientRepresentation createOidcClientRep(OidcAccessType accessType, String clientId, String... redirectUris) {
         ClientRepresentation client = createClientRep(clientId);
-       
+
         client.setProtocol(OIDC);
-        
+
         switch (accessType) {
             case BEARER_ONLY:
                 client.setBearerOnly(true);
@@ -116,24 +118,24 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return client;
     }
-    
+
     public static ClientRepresentation createSamlClientRep(String clinetId) {
         ClientRepresentation client = createClientRep(clinetId);
-        
+
         client.setProtocol(SAML);
-        
+
         client.setFrontchannelLogout(true);
         client.setAttributes(getSAMLAttributes());
-        
+
         return client;
     }
-    
+
     private static void setRedirectUris(ClientRepresentation client, String... redirectUris) {
         List<String> redirectUrisList = new ArrayList<>();
         redirectUrisList.addAll(Arrays.asList(redirectUris));
         client.setRedirectUris(redirectUrisList);
     }
-    
+
     protected static void setExpectedWebOrigins(ClientRepresentation client) {
         List<String> webOrigins = new ArrayList<>();
         for (String redirectUri : client.getRedirectUris()) {
@@ -143,7 +145,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         client.setWebOrigins(webOrigins);
     }
-    
+
     public ClientRepresentation findClientByClientId(String clientId) {
         ClientRepresentation found = null;
         for (ClientRepresentation clientRepresentation : testRealmResource().clients().findAll()) {
@@ -154,7 +156,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return found;
     }
-    
+
     public void assertClientSettingsEqual(ClientRepresentation c1, ClientRepresentation c2) {
         assertEqualsStringAttributes(c1.getClientId(), c2.getClientId());
         assertEqualsStringAttributes(c1.getName(), c2.getName());
@@ -174,38 +176,37 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
             }
             assertEqualsBooleanAttributes(c1.isSurrogateAuthRequired(), c2.isSurrogateAuthRequired());
             assertEqualsBooleanAttributes(c1.isServiceAccountsEnabled(), c2.isServiceAccountsEnabled());
-        }
-        else if (c1.getProtocol().equals(SAML)) {
+        } else if (c1.getProtocol().equals(SAML)) {
             assertEqualsBooleanAttributes(c1.isFrontchannelLogout(), c2.isFrontchannelLogout());
         }
     }
-    
+
     public void assertClientSamlAttributes(Map<String, String> expected, Map<String, String> actual) {
         for (String key : expected.keySet()) {
             assertEquals("Expected attribute " + key, expected.get(key), actual.get(key));
         }
     }
-    
+
     protected static Map<String, String> getSAMLAttributes() {
         Map<String, String> attributes = new HashMap<>();
         attributes.put(SAML_ASSERTION_SIGNATURE, "true");
         attributes.put(SAML_AUTHNSTATEMENT, "false");
-	attributes.put(SAML_CLIENT_SIGNATURE,	"true");
-	attributes.put(SAML_ENCRYPT, "true");
-	attributes.put(SAML_FORCE_POST_BINDING, "true");
-	attributes.put(SAML_MULTIVALUED_ROLES, "false");
-	attributes.put(SAML_SERVER_SIGNATURE,	"true");
-	attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA512");
-	attributes.put(SAML_ASSERTION_CONSUMER_URL_POST, "http://example0.test");
-	attributes.put(SAML_ASSERTION_CONSUMER_URL_REDIRECT, "http://example1.test");
-	attributes.put(SAML_FORCE_NAME_ID_FORMAT, "true");
-	attributes.put(SAML_NAME_ID_FORMAT, "email");
-	attributes.put(SAML_SIGNATURE_CANONICALIZATION_METHOD, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
-	attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_POST, "http://example2.test");
-	attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT, "http://example3.test");
+        attributes.put(SAML_CLIENT_SIGNATURE, "true");
+        attributes.put(SAML_ENCRYPT, "true");
+        attributes.put(SAML_FORCE_POST_BINDING, "true");
+        attributes.put(SAML_MULTIVALUED_ROLES, "false");
+        attributes.put(SAML_SERVER_SIGNATURE, "true");
+        attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA512");
+        attributes.put(SAML_ASSERTION_CONSUMER_URL_POST, "http://example0.test");
+        attributes.put(SAML_ASSERTION_CONSUMER_URL_REDIRECT, "http://example1.test");
+        attributes.put(SAML_FORCE_NAME_ID_FORMAT, "true");
+        attributes.put(SAML_NAME_ID_FORMAT, "email");
+        attributes.put(SAML_SIGNATURE_CANONICALIZATION_METHOD, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
+        attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_POST, "http://example2.test");
+        attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT, "http://example3.test");
         return attributes;
     }
-    
+
     public ProtocolMapperRepresentation findClientMapperByName(String clientId, String mapperName) {
         ProtocolMapperRepresentation found = null;
         for (ProtocolMapperRepresentation mapper : testRealmResource().clients().get(clientId).getProtocolMappers().getMappers()) {
@@ -215,4 +216,13 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return found;
     }
+
+    public ClientsResource clientsResource() {
+        return testRealmResource().clients();
+    }
+
+    public ClientResource clientResource(String id) {
+        return clientsResource().get(id);
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
index d3aa64f..14fff17 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
@@ -153,11 +153,11 @@ public class ClientSettingsTest extends AbstractClientTest {
         c.setPublicClient(true);
         c.setBearerOnly(true);
 
-        Response r = clientsPage.clientsResource().create(c);
+        Response r = clientsResource().create(c);
         r.close();
         clientSettingsPage.setId(getCreatedId(r));
 
-        c = clientSettingsPage.clientResource().toRepresentation();
+        c = clientResource(clientSettingsPage.getId()).toRepresentation();
         assertTrue(c.isBearerOnly());
         assertTrue(c.isPublicClient());
     }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
index c257564..ddbaa8c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
@@ -18,6 +18,7 @@ import javax.ws.rs.core.Response;
 import java.util.List;
 
 import static org.junit.Assert.assertEquals;
+import org.keycloak.admin.client.resource.ClientsResource;
 import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL;
 
 
@@ -50,12 +51,12 @@ public class AdminEventsTest extends AbstractConsoleTest {
     @Test
     public void clientsAdminEventsTest() {
         newClient = AbstractClientTest.createOidcClientRep(CONFIDENTIAL, "test_client", "http://example.test/test_client/*");
-        Response response = clientsPage.clientsResource().create(newClient);
+        Response response = clientsResource().create(newClient);
         String id = ApiUtil.getCreatedId(response);
         response.close();
         newClient.setClientId("test_client2");
-        clientsPage.clientsResource().get(id).update(newClient);
-        clientsPage.clientsResource().get(id).remove();
+        clientsResource().get(id).update(newClient);
+        clientsResource().get(id).remove();
 
         adminEventsPage.navigateTo();
         adminEventsPage.table().filter();
@@ -85,4 +86,8 @@ public class AdminEventsTest extends AbstractConsoleTest {
         resultList.get(0).findElement(By.xpath("//td[text()='DELETE']"));
         resultList.get(0).findElement(By.xpath("//td[text()='clients/" + id + "']"));
     }
+    
+    public ClientsResource clientsResource() {
+        return testRealmResource().clients();
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
index 701e798..cb66b8f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
@@ -2,6 +2,7 @@ package org.keycloak.testsuite.console.roles;
 
 import org.jboss.arquillian.graphene.page.Page;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.RoleMappingResource;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
 import org.keycloak.testsuite.console.page.roles.Roles;
 import org.keycloak.testsuite.console.page.users.User;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
index 67baad2..202d004 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
@@ -4,6 +4,7 @@ import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.junit.Test;
+import org.keycloak.admin.client.resource.RolesResource;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
@@ -31,7 +32,7 @@ public class DefaultRolesTest extends AbstractRolesTest {
     public void beforeDefaultRolesTest() {
         // create a role via admin client
         defaultRoleRep = new RoleRepresentation("default-role", "", false);
-        rolesPage.rolesResource().create(defaultRoleRep);
+        rolesResource().create(defaultRoleRep);
 
         defaultRolesPage.navigateTo();
         // navigate to default roles page
@@ -58,4 +59,8 @@ public class DefaultRolesTest extends AbstractRolesTest {
         assertTrue(userRolesPage.form().isAssignedRole(defaultRoleName));
     }
 
+    public RolesResource rolesResource() {
+        return testRealmResource().roles();
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
index 3ddf899..585080d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
@@ -2,6 +2,8 @@ package org.keycloak.testsuite.console.users;
 
 import org.jboss.arquillian.graphene.page.Page;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
 import org.keycloak.testsuite.console.page.users.CreateUser;
@@ -35,5 +37,13 @@ public abstract class AbstractUserTest extends AbstractConsoleTest {
         createUserPage.form().setValues(user);
         createUserPage.form().save();
     }
-
+    
+    public UsersResource usersResource() {
+        return testRealmResource().users();
+    }
+    
+    public UserResource userResource(String id) {
+        return usersResource().get(id);
+    }
+    
 }