keycloak-aplcache

Changes

pom.xml 2(+2 -0)

Details

pom.xml 2(+2 -0)

diff --git a/pom.xml b/pom.xml
index 21142fa..5ba74c6 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1311,6 +1311,7 @@
             <id>distribution</id>
             <modules>
                 <module>distribution</module>
+                <module>testsuite/integration-arquillian</module>
             </modules>
         </profile>
         <profile>
@@ -1318,6 +1319,7 @@
             <modules>
                 <module>docbook</module>
                 <module>distribution</module>
+                <module>testsuite/integration-arquillian</module>
             </modules>
             <build>
                 <plugins>
diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
new file mode 100644
index 0000000..2435a1a
--- /dev/null
+++ b/testsuite/integration-arquillian/pom.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<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">
+    <parent>
+        <artifactId>keycloak-testsuite-pom</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Final-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>arquillian-integration</artifactId>
+    <name>KeyCloak Admin UI TestSuite</name>
+
+    <properties>
+        <browser>phantomjs</browser>
+		
+        <arquillian-core.version>1.1.5.Final</arquillian-core.version>
+        <selenium.version>2.45.0</selenium.version>
+        <arquillian-drone.version>1.3.1.Final</arquillian-drone.version>
+        <arquillian-phantomjs.version>1.1.4.Final</arquillian-phantomjs.version>
+        <arquillian-graphene.version>2.0.3.Final</arquillian-graphene.version>
+        <arquillian-wildfly-container.version>8.1.0.Final</arquillian-wildfly-container.version>
+        
+        <!-- Used in profile "wildfly-8-remote".
+        Set to "false" if admin password has already been updated after first login. -->
+        <firstAdminLogin>true</firstAdminLogin>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.jboss.arquillian.selenium</groupId>
+                <artifactId>selenium-bom</artifactId>
+                <version>${selenium.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.arquillian</groupId>
+                <artifactId>arquillian-bom</artifactId>
+                <version>${arquillian-core.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.arquillian.extension</groupId>
+                <artifactId>arquillian-drone-bom</artifactId>
+                <version>${arquillian-drone.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.wildfly</groupId>
+                <artifactId>wildfly-arquillian-container-remote</artifactId>
+                <version>${arquillian-wildfly-container.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.wildfly</groupId>
+                <artifactId>wildfly-arquillian-container-managed</artifactId>
+                <version>${arquillian-wildfly-container.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.arquillian.junit</groupId>
+            <artifactId>arquillian-junit-container</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.arquillian.graphene</groupId>
+            <artifactId>graphene-webdriver</artifactId>
+            <version>${arquillian-graphene.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.arquillian.extension</groupId>
+            <artifactId>arquillian-phantom-driver</artifactId>
+            <version>${arquillian-phantomjs.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>wildfly-8-remote</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.wildfly</groupId>
+                    <artifactId>wildfly-arquillian-container-remote</artifactId>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <shouldDeploy>false</shouldDeploy>
+                                <arquillian.launch>wildfly-8-remote</arquillian.launch>
+                                <browser>${browser}</browser>
+                                <firstAdminLogin>${first.login}</firstAdminLogin>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+		
+        <profile>
+            <id>wildfly-8-managed</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.wildfly</groupId>
+                    <artifactId>wildfly-arquillian-container-managed</artifactId>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <properties>
+                <install.directory>${project.build.directory}/install</install.directory>
+                <jbossHome>${install.directory}/keycloak-${project.version}</jbossHome>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <version>2.10</version>
+                        <executions>
+                            <execution>
+                                <id>unpack</id>
+                                <phase>process-test-resources</phase>
+                                <goals>
+                                    <goal>unpack</goal>
+                                </goals>
+                                <configuration>
+                                    <artifactItems>
+                                        <artifactItem>
+                                            <groupId>org.keycloak</groupId>
+                                            <artifactId>keycloak-server-dist</artifactId>
+                                            <version>${project.version}</version>
+                                            <type>zip</type>
+                                            <overWrite>false</overWrite>
+                                        </artifactItem>
+                                    </artifactItems>
+                                    <outputDirectory>${install.directory}</outputDirectory>
+                                    <overWriteReleases>false</overWriteReleases>
+                                    <overWriteSnapshots>true</overWriteSnapshots>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <shouldDeploy>false</shouldDeploy>
+                                <arquillian.launch>wildfly-8-managed</arquillian.launch>
+                                <browser>${browser}</browser>
+                                <jbossHome>${jbossHome}</jbossHome>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/testsuite/integration-arquillian/README.md b/testsuite/integration-arquillian/README.md
new file mode 100644
index 0000000..a81701d
--- /dev/null
+++ b/testsuite/integration-arquillian/README.md
@@ -0,0 +1,21 @@
+Testing admin console with Arquillian
+=====================================
+
+There are currently two ways of running the tests with help of Arquillian.
+
+Remote mode
+----------
+
+Just simply typle `mvn verify` and you are all set. This requires the instance of Wildfly with embedded Keycloak to be already running.
+
+Managed mode
+------------
+
+You need to pass two arguments to Maven, first is location of your Wildfly server with embedded Keycloak and the other is name of the profile.
+
+    mvn verify -Pwildfly-8-managed -DjbossHome=/your/server/location
+
+Browser
+-------
+
+There are currently two supported browsers - PhantomJS and Firefox. PhantomJS is the default one, in order to use Firefox just specify `-Dbrowser=firefox` parameter in the Maven command. 
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractKeyCloakTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractKeyCloakTest.java
new file mode 100644
index 0000000..aa1be23
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractKeyCloakTest.java
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui;
+
+import java.util.concurrent.TimeUnit;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.After;
+import org.junit.Before;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+
+/**
+ *
+ * @author Petr Mensik
+ * @param <P>
+ */
+public abstract class AbstractKeyCloakTest<P extends AbstractPage> extends AbstractTest {
+	
+    @Page
+    protected P page;
+	
+	@Before
+	public void before() {
+        driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
+		driver.manage().window().maximize();
+		loginAsAdmin();
+	}
+	
+	@After
+	public void after() {
+		logOut();
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractTest.java
new file mode 100644
index 0000000..b05331e
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/AbstractTest.java
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.jboss.arquillian.graphene.page.Page;
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.runner.RunWith;
+import org.keycloak.testsuite.ui.fragment.Navigation;
+import org.keycloak.testsuite.ui.fragment.MenuPage;
+import org.keycloak.testsuite.ui.page.LoginPage;
+import org.keycloak.testsuite.ui.page.account.PasswordPage;
+import static org.keycloak.testsuite.ui.util.Constants.ADMIN_PSSWD;
+
+import static org.keycloak.testsuite.ui.util.URL.BASE_URL;
+import org.openqa.selenium.WebDriver;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+@RunWith(Arquillian.class)
+public abstract class AbstractTest {
+
+    private static boolean firstAdminLogin = Boolean.parseBoolean(
+            System.getProperty("firstAdminLogin", "true"));
+
+    @Page
+    protected LoginPage loginPage;
+
+    @Page
+    protected PasswordPage passwordPage;
+
+    @Page
+    protected MenuPage menuPage;
+
+    @Page
+    protected Navigation navigation;
+
+    @Drone
+    protected WebDriver driver;
+
+    public void logOut() {
+        menuPage.logOut();
+    }
+
+    public void loginAsAdmin() {
+        driver.get(BASE_URL);
+        loginPage.loginAsAdmin();
+        if (firstAdminLogin) {
+            passwordPage.confirmNewPassword(ADMIN_PSSWD);
+            passwordPage.submit();
+            firstAdminLogin = false;
+        }
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/CreateRealm.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/CreateRealm.java
new file mode 100644
index 0000000..bae764f
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/CreateRealm.java
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import static org.openqa.selenium.By.id;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class CreateRealm {
+	
+	@FindBy(css = ".btn-primary")
+	private WebElement primaryButton;
+	
+	@Drone
+	private WebDriver driver;
+	
+	public void importRealm(String filePath) {
+		driver.findElement(id("import-file")).sendKeys(filePath);
+		primaryButton.click();
+	}
+	
+	public void createRealm(String name, boolean on) {
+		driver.findElement(id("name")).sendKeys(name);
+		primaryButton.click();
+	}
+	
+	public void createRealm(String name) {
+		createRealm(name, true);
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/FlashMessage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/FlashMessage.java
new file mode 100644
index 0000000..33a84af
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/FlashMessage.java
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import static org.jboss.arquillian.graphene.Graphene.waitGui;
+import org.jboss.arquillian.graphene.fragment.Root;
+
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+import org.openqa.selenium.WebElement;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class FlashMessage {
+
+    @Root
+    private WebElement root;
+
+    public boolean isSuccess() {
+		waitGui().until("Flash message should be success")
+			.element(root)
+			.attribute("class")
+			.contains("success");
+		return root.getAttribute("class").contains("success");
+    }
+
+    public boolean isError() {
+		waitGui().until("Flash message should be error")
+			.element(root)
+			.attribute("class")
+			.contains("error");
+        return root.getAttribute("class").contains("error");
+    }
+
+    public boolean isDanger() {
+		waitGui().until("Flash message should be danger")
+			.element(root)
+			.attribute("class")
+			.contains("danger");
+		return root.getAttribute("class").contains("danger"); 
+	}
+
+    public String getText() {
+        return root.getText();
+    }
+
+    public void waitUntilPresent() {
+		waitGuiForElement(root, "Flash message should be visible.");
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/MenuPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/MenuPage.java
new file mode 100644
index 0000000..2f53658
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/MenuPage.java
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import java.util.List;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+import org.openqa.selenium.By;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class MenuPage {
+
+	private static final String MENU_LOCATOR = "ul[class='dropdown-menu']";
+	
+    @FindBy(css = MENU_LOCATOR)
+	private List<WebElement> menuList;
+	
+    @FindBy(css = ".dropdown-toggle")
+    private List<WebElement> toggle;
+
+    public void logOut() {
+		clickOnMenuElement(Menu.USER, "Sign Out");
+	}
+    
+    public void goToAccountManagement() {
+		clickOnMenuElement(Menu.USER, "Manage Account");
+	}
+	
+	public void switchRealm(String realmName) {
+		clickOnMenuElement(Menu.REALM, realmName);
+	}
+	
+	public String getCurrentRealm() {
+		waitGuiForElement(By.cssSelector(MENU_LOCATOR));
+		return toggle.get(1).getText();
+	}
+
+	private void clickOnMenuElement(Menu menuType, String linkText) {
+		int menuOrder = 0;
+		switch(menuType) {
+			case REALM: menuOrder = 1; break;
+			case USER: menuOrder = 0; break;
+		}
+		waitGuiForElement(By.cssSelector(MENU_LOCATOR));
+        if (!menuList.get(menuOrder).isDisplayed()) 
+			toggle.get(menuOrder).click();
+        for (WebElement item : menuList.get(menuOrder).findElements(By.cssSelector(MENU_LOCATOR + " a"))) {
+            if (item.getText().contains(linkText)) {
+                item.click();
+                return;
+            }
+        }
+        throw new RuntimeException("Could not find menu item containing \"" + linkText + "\"");
+    }
+	
+	private enum Menu {
+		USER, REALM
+	}
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java
new file mode 100644
index 0000000..4175c45
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java
@@ -0,0 +1,157 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import static org.jboss.arquillian.graphene.Graphene.waitModel;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class Navigation {
+	
+	@Drone
+	private WebDriver driver;
+
+    @FindByJQuery("a:contains('Settings')")
+    private WebElement settingsLink;
+
+    @FindByJQuery("a:contains('Users')")
+    private WebElement usersLink;
+
+    @FindByJQuery("a:contains('Roles')")
+    private WebElement rolesLink;
+
+    @FindByJQuery("a:contains('Clients')")
+    private WebElement clientsLink;
+
+    @FindByJQuery("a:contains('OAuth')")
+    private WebElement oauthLink;
+
+    @FindByJQuery("a:contains('Tokens')")
+    private WebElement tokensLink;
+	
+	@FindByJQuery("a:contains('Sessions')")
+    private WebElement sessionLink;
+
+    @FindByJQuery("a:contains('Security Defenses')")
+    private WebElement securityLink;
+
+    @FindByJQuery("a:contains('Events')")
+    private WebElement eventsLink;
+	
+	@FindByJQuery("a:contains('Login')")
+    private WebElement loginLink;
+
+    @FindByJQuery("a:contains('Themes')")
+    private WebElement themesLink;
+
+	@FindByJQuery("a:contains('Role Mappings')")
+    private WebElement usersRoleMappings;
+	
+	@FindByJQuery("a:contains('Add Realm')")
+    private WebElement addRealm;
+	
+	@FindByJQuery("a:contains('Credentials')")
+    private WebElement credentials;
+	
+	@FindByJQuery("a:contains('Attributes')")
+    private WebElement attributes;
+	
+    @FindBy(css = "div h1")
+    private WebElement currentHeader;
+
+	public void selectRealm(String realmName) {
+		driver.findElement(By.linkText(realmName)).click();
+	}
+	
+    public void settings() {
+        openPage(settingsLink, "Settings");
+    }
+
+    public void users() {
+        openPage(usersLink, "Users");
+    }
+
+    public void roles() {
+        openPage(rolesLink, "Roles");
+    }
+
+    public void clients() {
+        openPage(clientsLink, "Clients");
+    }
+	
+    public void oauth() {
+        openPage(oauthLink, "OAuth Clients");
+    }
+
+    public void tokens() {
+        openPage(tokensLink, "Settings");
+    }
+	
+	public void sessions() {
+		openPage(sessionLink, "Sessions");
+	}
+
+    public void security() {
+        openPage(securityLink, "Settings");
+    }
+
+    public void events() {
+        openPage(eventsLink, "Events");
+    }
+	
+	public void login() {
+		openPage(loginLink, "Settings");
+	}
+
+    public void themes() { 
+		openPage(themesLink, "Settings"); 
+	}
+
+    public void roleMappings() {
+		openPage(usersRoleMappings, "User");
+	}
+	
+	public void addRealm() {
+		openPage(addRealm, "Add Realm");
+	}
+	
+	public void credentials() {
+		openPage(credentials, "Settings");
+	}
+	
+	public void attributes() {
+		openPage(attributes, "Attributes");
+	}
+
+    private void openPage(WebElement page, String headerText) {
+        waitGuiForElement(page);
+        page.click();
+        waitModel().until().element(currentHeader).text().contains(headerText);
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/OnOffSwitch.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/OnOffSwitch.java
new file mode 100644
index 0000000..3fc3a90
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/OnOffSwitch.java
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import org.jboss.arquillian.graphene.fragment.Root;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+
+public class OnOffSwitch {
+
+	@Root
+	private WebElement root;
+	
+	@ArquillianResource
+	private Actions actions;
+	
+	public boolean isEnabled() {
+		return root.findElement(By.tagName("input")).isSelected();
+	}
+	
+	private void click() {
+		actions.moveToElement(root.findElements(By.tagName("span")).get(0))
+				.click().build().perform();
+	}
+	
+	public void toggle() {
+		click();
+	}
+	
+	public void enable() {
+		if(!isEnabled()) {
+			click();
+		}
+	}
+	
+	public void disable() {
+		if(isEnabled()) {
+			click();
+		}
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/PickList.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/PickList.java
new file mode 100644
index 0000000..7711585
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/PickList.java
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.fragment;
+
+import org.jboss.arquillian.graphene.fragment.Root;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+
+public class PickList {
+
+    @Root
+    private WebElement root;
+
+    private Select firstSelect;
+    private Select secondSelect;
+    
+    @FindBy(className = "kc-icon-arrow-right")
+    private WebElement rightArrow;
+    
+    @FindBy(className = "kc-icon-arrow-left")
+    private WebElement leftArrow;
+    
+    public void addItems(String... values) {
+        for(String value : values) {
+            firstSelect.selectByVisibleText(value);
+        }
+        rightArrow.click();
+    }
+    
+    public void setFirstSelect(By locator) {
+        firstSelect = new Select(root.findElement(locator));
+    }
+    
+    public void setSecondSelect(By locator) {
+        secondSelect = new Select(root.findElement(locator));
+    }
+    
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Account.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Account.java
new file mode 100644
index 0000000..f2a2ef0
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Account.java
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class Account {
+
+    private String username;
+
+    private String email;
+
+    private String lastName;
+
+    private String firstName;
+
+    public Account(String username, String email, String lastName, String firstName) {
+        this.username = username;
+        this.email = email;
+        this.lastName = lastName;
+        this.firstName = firstName;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Account account = (Account) o;
+
+        if (email != null ? !email.equals(account.email) : account.email != null) return false;
+        if (firstName != null ? !firstName.equals(account.firstName) : account.firstName != null) return false;
+        if (lastName != null ? !lastName.equals(account.lastName) : account.lastName != null) return false;
+        if (username != null ? !username.equals(account.username) : account.username != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = username != null ? username.hashCode() : 0;
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
+        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Client.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Client.java
new file mode 100644
index 0000000..5172f8f
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Client.java
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class Client {
+
+	private String clientId;
+    private String name;
+    private boolean enabled;
+    private String accessType;
+    private String uri;
+
+	public Client(String clientId, String uri) {
+		this.name = clientId;
+		this.clientId = clientId;		
+		this.uri = uri;
+		this.enabled = true;
+	}
+	
+    public Client(String clientId, String name, String uri) {
+        this.clientId = clientId;
+		this.uri = uri;
+        this.enabled = true;
+        this.name = name;
+    }
+
+    public Client() {
+    }
+
+    public Client(String name, String uri, String accessType, boolean enabled) {
+        this.name = name;
+        this.uri = uri;
+        this.accessType = accessType;
+        this.enabled = enabled;
+    }
+
+    public String getName() { return name; }
+
+    public void setName(String name) { this.name = name; }
+
+    public boolean isEnabled() { return enabled; }
+
+    public void setEnabled(boolean enabled) { this.enabled = enabled; }
+
+    public String getAccessType() { return accessType; }
+
+    public void setAccessType(String accessType) { this.accessType = accessType; }
+
+    public String getUri() { return uri; }
+
+    public void setUri(String uri) { this.uri = uri; }
+
+	public String getClientId() {
+		return clientId;
+	}
+
+	public void setClientId(String clientId) {
+		this.clientId = clientId;
+	}
+	
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Client that = (Client) o;
+
+        if (enabled != that.enabled) return false;
+        if (accessType != null ? !accessType.equals(that.accessType) : that.accessType != null) return false;
+        if (!name.equals(that.name)) return false;
+        if (!uri.equals(that.uri)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + (enabled ? 1 : 0);
+        result = 31 * result + (accessType != null ? accessType.hashCode() : 0);
+        result = 31 * result + uri.hashCode();
+        return result;
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/PasswordPolicy.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/PasswordPolicy.java
new file mode 100644
index 0000000..6d2c651
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/PasswordPolicy.java
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public enum PasswordPolicy {
+
+	HASH_ITERATIONS("Hash Iterations"), LENGTH("Length"), DIGITS("Digits"), LOWER_CASE("Lower Case"), 
+	UPPER_CASE("Upper Case"), SPECIAL_CHARS("Special Chars");
+	
+	private String name;
+
+	private PasswordPolicy(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Provider.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Provider.java
new file mode 100644
index 0000000..869eec2
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Provider.java
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class Provider {
+
+	public SocialProvider providerName;
+	public String key;
+	public String secret;
+
+	public Provider() {
+	}
+
+	public Provider(SocialProvider providerName, String key, String secret) {
+		this.providerName = providerName;
+		this.key = key;
+		this.secret = secret;
+	}
+	
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Role.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Role.java
new file mode 100644
index 0000000..efe6178
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Role.java
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class Role {
+
+    private String name;
+    private boolean composite;
+    private String description;
+
+    public Role() {
+    }
+
+    public Role(String name) {
+        this(name, false, "");
+    }
+    
+    public Role(String name, boolean composite) {
+        this(name, composite, "");
+    }
+    
+    public Role(String name, boolean composite, String description) {
+        this.name = name;
+        this.composite = composite;
+        this.description = description;
+    }
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public boolean isComposite() {
+		return composite;
+	}
+
+	public void setComposite(boolean composite) {
+		this.composite = composite;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/SocialProvider.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/SocialProvider.java
new file mode 100644
index 0000000..cb13d68
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/SocialProvider.java
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public enum SocialProvider {
+	
+	FACEBOOK("Facebook"), GITHUB("Github"), GOOGLE("Google"), TWITTER("Twitter");
+	
+	private String name;
+
+	private SocialProvider(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+	
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Theme.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Theme.java
new file mode 100644
index 0000000..0578449
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/Theme.java
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public enum Theme {
+    
+    BASE("base"), KEYCLOAK("keycloak"), PATTERNFLY("patternfly");
+    
+    private final String name;
+    
+    private Theme(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/User.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/User.java
new file mode 100644
index 0000000..e4be9f5
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/User.java
@@ -0,0 +1,146 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class User {
+
+    private String userName;
+	
+	private String password;
+
+    private String email;
+
+    private String firstName;
+
+    private String lastName;
+
+    private boolean userEnabled;
+
+    private boolean emailVerified;
+
+    private String requiredUserActions;
+
+    public User() {
+        this.userEnabled = true;
+        this.emailVerified = false;
+    }
+
+    public User(String userName) {
+		this();
+		this.userName = userName;
+    }
+	
+	public User(String userName, String password) {
+		this(userName);
+		this.password = password;
+    }
+
+    public User(String userName, String password, String email) {
+		this(userName, password);
+		this.email = email;
+    }
+
+    public User(String userName, String password, String email, String firstName, String lastName) {
+		this(userName, password, email);
+		this.firstName = firstName;
+        this.lastName = lastName;
+    }
+
+    public User(String userName, String password, String email, String firstName, String lastName, boolean userEnabled, boolean emailVerified, String requiredUserActions) {
+		this(userName, password, email, firstName, lastName);
+		this.requiredUserActions = requiredUserActions;
+    }
+	
+	public User(User user) {
+		this(user.userName, user.password, user.email, user.firstName, user.lastName,
+				user.userEnabled, user.emailVerified, user.requiredUserActions);
+	}
+
+    public String getUserName() { return userName; }
+
+    public void setUserName(String userName) { this.userName = userName; }
+
+    public String getEmail() { return email; }
+
+    public void setEmail(String email) { this.email = email; }
+
+    public String getFirstName() { return firstName; }
+
+    public void setFirstName(String firstName) { this.firstName = firstName; }
+
+    public String getLastName() { return lastName; }
+
+    public void setLastName(String lastName) { this.lastName = lastName; }
+
+    public boolean isUserEnabled() { return userEnabled; }
+
+    public void setUserEnabled(boolean userEnabled) { this.userEnabled = userEnabled; }
+
+    public boolean isEmailVerified() { return emailVerified; }
+
+    public void setEmailVerified(boolean emailVerified) { this.emailVerified = emailVerified; }
+
+    public String getRequiredUserActions() { return requiredUserActions; }
+
+    public void setRequiredUserActions(String requiredUserActions) { this.requiredUserActions = requiredUserActions; }
+
+	public String getPassword() {
+		return password;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+	
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        User user = (User) o;
+
+        if (emailVerified != user.emailVerified) return false;
+        if (userEnabled != user.userEnabled) return false;
+        if (email != null ? !email.equals(user.email) : user.email != null) return false;
+        if (firstName != null ? !firstName.equals(user.firstName) : user.firstName != null) return false;
+        if (lastName != null ? !lastName.equals(user.lastName) : user.lastName != null) return false;
+        if (requiredUserActions != null ? !requiredUserActions.equals(user.requiredUserActions) : user.requiredUserActions != null)
+            return false;
+        if (!userName.equals(user.userName)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = userName.hashCode();
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
+        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
+        result = 31 * result + (userEnabled ? 1 : 0);
+        result = 31 * result + (emailVerified ? 1 : 0);
+        result = 31 * result + (requiredUserActions != null ? requiredUserActions.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/UserAction.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/UserAction.java
new file mode 100644
index 0000000..bf6a396
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/model/UserAction.java
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.model;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public enum UserAction {
+
+	UPDATE_PASSWORD("Update Password"), VERIFY_EMAIL("Verify Email"), UPDATE_PROFILE("Update Profile"), CONFIGURE_TOTP("Configure Totp");
+	
+	private final String actionName;
+
+	private UserAction(String actionName) {
+		this.actionName = actionName;
+	}
+
+	public String getActionName() {
+		return actionName;
+	}
+	
+	
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/AbstractPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/AbstractPage.java
new file mode 100644
index 0000000..8251ab2
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/AbstractPage.java
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.ui.page;
+
+import java.util.List;
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.keycloak.testsuite.ui.util.Constants;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class AbstractPage {
+
+    @Drone
+    protected WebDriver driver;
+	
+	@FindBy(css = ".btn-danger")
+	protected WebElement dangerButton;
+	
+	//@FindByJQuery(".btn-primary:visible")
+    @FindBy(css = ".btn-primary")
+    protected WebElement primaryButton;
+	
+	    @FindBy(css = ".btn-primary")
+    protected List<WebElement> primaryButtons;
+
+	
+	@FindBy(css = ".ng-binding.btn.btn-danger")
+	protected WebElement deleteConfirmationButton;
+	
+    public void goToPage(String page) {
+        driver.get(String.format(page, Constants.CURRENT_REALM));
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/AccountPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/AccountPage.java
new file mode 100644
index 0000000..0c8ab50
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/AccountPage.java
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.account;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.keycloak.testsuite.ui.model.Account;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class AccountPage extends AbstractPage {
+
+    @FindBy(id = "username")
+    private WebElement username;
+
+    @FindBy(id = "email")
+    private WebElement email;
+
+    @FindBy(id = "lastName")
+    private WebElement lastName;
+
+    @FindBy(id = "firstName")
+    private WebElement firstName;
+
+    @FindByJQuery("button[value='Save']")
+    private WebElement save;
+	
+	@FindByJQuery(".nav li:eq(0) a")
+    private WebElement keyclockConsole;
+
+    @FindByJQuery(".nav li:eq(1) a")
+    private WebElement signOutLink;
+
+    @FindByJQuery(".bs-sidebar ul li:eq(0) a")
+    private WebElement accountLink;
+
+    @FindByJQuery(".bs-sidebar ul li:eq(1) a")
+    private WebElement passwordLink;
+
+    @FindByJQuery(".bs-sidebar ul li:eq(2) a")
+    private WebElement authenticatorLink;
+
+    @FindByJQuery(".bs-sidebar ul li:eq(3) a")
+    private WebElement sessionsLink;
+
+
+    public Account getAccount() {
+        return new Account(username.getAttribute("value"), email.getAttribute("value"), lastName.getAttribute("value"), firstName.getAttribute("value"));
+    }
+
+    public void setAccount(Account account) {
+        email.clear();
+        email.sendKeys(account.getEmail());
+        lastName.clear();
+        lastName.sendKeys(account.getLastName());
+        firstName.clear();
+        firstName.sendKeys(account.getFirstName());
+    }
+
+    public void save() {
+        save.click();
+    }
+	
+	 public void keycloakConsole() {
+        keyclockConsole.click();
+    }
+
+    public void signOut() {
+        signOutLink.click();
+    }
+
+    public void account() {
+        accountLink.click();
+    }
+
+    public void password() {
+        passwordLink.click();
+    }
+
+    public void authenticator() {
+        authenticatorLink.click();
+    }
+
+    public void sessions() {
+        sessionsLink.click();
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/PasswordPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/PasswordPage.java
new file mode 100644
index 0000000..b0a3e9d
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/account/PasswordPage.java
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.account;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class PasswordPage {
+
+    @FindBy(id = "password")
+    private WebElement passwordInput;
+
+    @FindBy(id = "password-new")
+    private WebElement newPasswordInput;
+
+    @FindBy(id = "password-confirm")
+    private WebElement confirmInput;
+
+    @FindByJQuery("button[value='Save']")
+    private WebElement save;
+
+    @FindBy(xpath = "//input[@value='Submit']")
+    private WebElement submit; // on "update password" page, after first login
+
+    public void setPassword(String oldPassword, String newPassword) {
+        passwordInput.clear();
+        passwordInput.sendKeys(oldPassword);
+        confirmNewPassword(newPassword);
+    }
+    
+    public void confirmNewPassword(String newPassword) {
+        newPasswordInput.clear();
+        newPasswordInput.sendKeys(newPassword);
+        confirmInput.clear();
+        confirmInput.sendKeys(newPassword);
+    }
+    
+    public void setOldPasswordField(String oldPassword) {
+        passwordInput.clear();
+        passwordInput.sendKeys(oldPassword);
+    }
+
+    public void setNewPasswordField(String newPassword) {
+        newPasswordInput.clear();
+        newPasswordInput.sendKeys(newPassword);
+    }
+
+    public void setConfirmField(String confirmPassword) {
+        confirmInput.clear();
+        confirmInput.sendKeys(confirmPassword);
+    }
+
+    public void save() {
+        save.click();
+    }
+
+    public void submit() {
+        submit.click();
+    }
+    
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/LoginPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/LoginPage.java
new file mode 100644
index 0000000..06ef63e
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/LoginPage.java
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page;
+
+import static org.keycloak.testsuite.ui.util.Constants.ADMIN_PSSWD;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class LoginPage extends AbstractPage {
+
+    @FindBy(id = "username")
+    private WebElement usernameInput;
+    
+    @FindBy(id = "password")
+    private WebElement passwordInput;
+
+    @FindBy(linkText = "Register")
+    private WebElement registerLink;
+
+	@FindBy(id = "kc-header")
+	private WebElement loginPageHeader;
+
+	public void login(String username, String password) {
+		waitGuiForElement(usernameInput, "Login form should be visible");
+        usernameInput.sendKeys(username);
+        passwordInput.sendKeys(password);
+        passwordInput.submit();
+    }
+    
+    public void loginAsAdmin() {
+        login("admin", ADMIN_PSSWD);
+    }
+
+    public void goToUserRegistration() {
+        waitGuiForElement(usernameInput, "Login form should be visible");
+        registerLink.click();
+    }
+	
+	public String getLoginPageHeaderText() {
+		return loginPageHeader.getText();
+	}
+	
+	public WebElement getLoginPageHeader() {
+		return loginPageHeader;
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/RegisterPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/RegisterPage.java
new file mode 100644
index 0000000..1c3ad33
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/RegisterPage.java
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page;
+
+import org.keycloak.testsuite.ui.model.User;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class RegisterPage extends AbstractPage {
+
+    @FindBy(id = "username")
+    private WebElement usernameInput;
+
+    @FindBy(id = "email")
+    private WebElement emailInput;
+
+    @FindBy(id = "firstName")
+    private WebElement firstNameInput;
+
+    @FindBy(id = "lastName")
+    private WebElement lastNameInput;
+
+    @FindBy(id = "password")
+    private WebElement passwordInput;
+
+    @FindBy(id = "password-confirm")
+    private WebElement passwordConfirmInput;
+
+    @FindBy(css = "span.kc-feedback-text")
+    private WebElement feedbackError;
+	
+	@FindBy(css = "div[id='kc-form-options'] span a")
+	private WebElement backToLoginForm;
+
+	public void registerNewUser(User user) {
+		registerNewUser(user, user.getPassword());
+	}
+	
+    public void registerNewUser(User user, String confirmPassword) {
+        driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
+        waitGuiForElement(passwordConfirmInput, "Register form should be visible");
+        clearAndType(usernameInput, user.getUserName());
+        clearAndType(firstNameInput, user.getFirstName());
+        clearAndType(lastNameInput, user.getLastName());
+        clearAndType(emailInput, user.getEmail());
+        clearAndType(passwordInput, user.getPassword());
+        clearAndType(passwordConfirmInput, confirmPassword);
+        primaryButton.click();
+    }
+
+    public void clearAndType(WebElement webElement, String text) {
+            webElement.clear();
+            webElement.sendKeys(text);
+    }
+
+    public boolean isInvalidEmail() {
+        waitGuiForElement(feedbackError, "Feedback message should be visible");
+        return feedbackError.getText().equals("Invalid email address.");
+    }
+
+    public boolean isAttributeSpecified(String attribute) {
+        waitGuiForElement(feedbackError, "Feedback message should be visible");
+        return !feedbackError.getText().contains("Please specify " + attribute + ".");
+    }
+
+    public boolean isPasswordSame() {
+        waitGuiForElement(feedbackError, "Feedback message should be visible");
+        return !feedbackError.getText().equals("Password confirmation doesn't match.");
+    }
+	
+	public void backToLoginPage() {
+		backToLoginForm.click();
+	}
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/session/SessionsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/session/SessionsPage.java
new file mode 100644
index 0000000..d714a64
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/session/SessionsPage.java
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.session;
+
+import org.keycloak.testsuite.ui.page.AbstractPage;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class SessionsPage extends AbstractPage {
+
+	public void logoutAllSessions() {
+		primaryButton.click();
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ClientPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ClientPage.java
new file mode 100644
index 0000000..890c7e5
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ClientPage.java
@@ -0,0 +1,129 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.keycloak.testsuite.ui.model.Client;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jboss.arquillian.graphene.findby.ByJQuery;
+
+import static org.junit.Assert.assertEquals;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitAjaxForElement;
+import static org.openqa.selenium.By.cssSelector;
+import static org.openqa.selenium.By.linkText;
+import static org.openqa.selenium.By.tagName;
+
+/**
+ *
+ * @author Filip Kisss
+ */
+public class ClientPage extends AbstractPage {
+
+	@FindBy(id = "clientId")
+	private WebElement clientId;
+
+	@FindBy(id = "name")
+	private WebElement nameInput;
+
+	@FindBy(id = "")
+	private WebElement enabledSwitchToggle;
+
+	@FindBy(id = "accessType")
+	private WebElement accessTypeDropDownMenu;
+
+	@FindBy(id = "newRedirectUri")
+	private WebElement redirectUriInput;
+
+	@FindBy(css = "table[class*='table']")
+	private WebElement dataTable;
+
+	@FindBy(css = "input[class*='search']")
+	private WebElement searchInput;
+
+	public void addClient(Client client) {
+		primaryButton.click();
+		waitAjaxForElement(clientId);
+		clientId.sendKeys(client.getClientId());
+		nameInput.sendKeys(client.getName());
+		if (!client.isEnabled()) {
+			enabledSwitchToggle.click();
+		}
+		accessTypeDropDownMenu.sendKeys(client.getAccessType());
+		redirectUriInput.sendKeys(client.getUri());
+		primaryButton.click();
+	}
+
+	public void addUri(String uri) {
+		redirectUriInput.sendKeys(uri);
+	}
+
+	public void removeUri(Client client) {
+	}
+
+	public void confirmAddClient() {
+		primaryButton.click();
+	}
+
+	public void deleteClient(String clientName) {
+		searchInput.sendKeys(clientName);
+		driver.findElement(linkText(clientName)).click();
+		waitAjaxForElement(dangerButton);
+		dangerButton.click();
+		waitAjaxForElement(deleteConfirmationButton);
+		deleteConfirmationButton.click();
+	}
+
+	public Client findClient(String clientName) {
+		waitAjaxForElement(searchInput);
+		searchInput.sendKeys(clientName);
+		List<Client> clients = getAllRows();
+		if (clients.isEmpty()) {
+			return null;
+
+		} else {
+			assertEquals(1, clients.size());
+			return clients.get(0);
+		}
+	}
+
+	private List<Client> getAllRows() {
+		List<Client> rows = new ArrayList<Client>();
+		List<WebElement> allRows = dataTable.findElements(cssSelector("tbody tr"));
+		if (allRows.size() > 1) {
+			for (WebElement rowElement : allRows) {
+				if (rowElement.isDisplayed()) {
+					Client client = new Client();
+					List<WebElement> tds = rowElement.findElements(tagName("td"));
+					client.setClientId(tds.get(0).getText());
+					client.setUri(tds.get(2).getText());
+					rows.add(client);
+				}
+			}
+		}
+		return rows;
+	}
+
+	public void goToCreateClient() {
+		driver.findElements(ByJQuery.selector(".btn.btn-primary")).get(0).click();
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/CredentialsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/CredentialsPage.java
new file mode 100644
index 0000000..a0455f5
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/CredentialsPage.java
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import java.util.List;
+import org.jboss.arquillian.graphene.findby.ByJQuery;
+import org.keycloak.testsuite.ui.model.PasswordPolicy;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+/**
+ *
+ * @author Petr Mensik
+ */
+public class CredentialsPage extends AbstractPage {
+	
+	@FindBy(tagName = "select")
+	private Select addPolicySelect;
+	
+	@FindBy(css = "tr.ng-scope")
+	private List<WebElement> allRows;
+	
+	public void addPolicy(PasswordPolicy policy, int value) {
+		addPolicySelect.selectByVisibleText(policy.getName());
+		setPolicyValue(policy, value);
+		primaryButton.click();
+	}
+	
+	public void removePolicy(PasswordPolicy policy) {
+		int policyInputLocation = findPolicy(policy);
+		allRows.get(policyInputLocation).findElements(By.tagName("i")).get(0).click();
+		primaryButton.click();
+	}
+	
+	public void editPolicy(PasswordPolicy policy, int value) {
+		setPolicyValue(policy, value);
+		primaryButton.click();
+	}
+	
+	private void setPolicyValue(PasswordPolicy policy, int value) {
+		int policyInputLocation = findPolicy(policy);
+		allRows.get(policyInputLocation).findElement(By.tagName("input")).sendKeys(String.valueOf(value));
+	}
+	
+	private int findPolicy(PasswordPolicy policy) {
+		for (int i = 0; i < allRows.size(); i++) {
+			String policyName = allRows.get(i).findElement(ByJQuery.selector("td:eq(0)")).getText();
+			if(policyName.equals(policy.getName()))
+				return i;
+		}
+		return 0;
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/DefaultRolesPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/DefaultRolesPage.java
new file mode 100644
index 0000000..d76ede6
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/DefaultRolesPage.java
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.keycloak.testsuite.ui.fragment.PickList;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.keycloak.testsuite.ui.model.Role;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class DefaultRolesPage extends AbstractPage {
+    
+    @FindBy(id = "")
+    private PickList realmDefaultRoles;
+    
+    @FindBy(id = "")
+    private PickList applicationDefaultRoles;
+    
+    @FindBy(id = "applications")
+    private Select applicationsSelect;
+    
+    public void addDefaultRealmRoles(String... roles) {
+        realmDefaultRoles.addItems(roles);
+    }
+    
+    public void addDefaultRealmRoles(Role... roles) {
+        List<String> roleList = new ArrayList<String>();
+        for(Role role : roles) {
+            roleList.add(role.getName());
+        }
+        addDefaultRealmRoles(((String []) roleList.toArray()));
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/GeneralSettingsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/GeneralSettingsPage.java
new file mode 100644
index 0000000..bfab15d
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/GeneralSettingsPage.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.keycloak.testsuite.ui.model.Theme;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+
+public class GeneralSettingsPage extends AbstractPage {
+
+    @FindBy(id = "name")
+    private WebElement realmName;
+    
+    @FindBy(id = "enabled")
+    private WebElement realmEnabled;
+    
+    @FindBy(id = "updateProfileOnInitialSocialLogin")
+    private WebElement updateProfileOnInitialSocialLogin;
+    
+    @FindBy(id = "passwordCredentialGrantAllowed")
+    private WebElement passwordCredentialGrantAllowed;
+    
+    @FindBy(id = "loginTheme")
+    private Select loginThemeSelect;
+    
+    @FindBy(id = "accountTheme")
+    private Select accountThemeSelect;
+    
+    @FindBy(id = "adminTheme")
+    private Select adminThemeSelect;
+    
+    @FindBy(id = "emailTheme")
+    private Select emailThemeSelect;
+    
+    @FindBy(className = "btn btn-primary btn-lg")
+    private WebElement saveButton;
+    
+    public void saveSettings() {
+        saveButton.click();
+    }
+    
+    public void selectLoginTheme(Theme theme) {
+        loginThemeSelect.selectByVisibleText(theme.getName());
+    }
+    
+    public void selecAccountTheme(Theme theme) {
+        accountThemeSelect.selectByVisibleText(theme.getName());
+    }
+    
+    public void selectAdminTheme(Theme theme) {
+        adminThemeSelect.selectByVisibleText(theme.getName());
+    }
+    
+    public void selectEmailTheme(Theme theme) {
+        emailThemeSelect.selectByVisibleText(theme.getName());
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/LoginSettingsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/LoginSettingsPage.java
new file mode 100644
index 0000000..84049dc
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/LoginSettingsPage.java
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.keycloak.testsuite.ui.fragment.OnOffSwitch;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class LoginSettingsPage extends AbstractPage {
+
+	@FindByJQuery("div[class='onoffswitch']:eq(0)")
+	private OnOffSwitch registrationAllowed;
+
+	@FindByJQuery("div[class='onoffswitch']:eq(1)")
+	private OnOffSwitch resetPasswordAllowed;
+		
+	@FindByJQuery("div[class='onoffswitch']:eq(2)")
+	private OnOffSwitch rememberMeEnabled;
+
+	@FindByJQuery("div[class='onoffswitch']:eq(3)")
+	private OnOffSwitch verifyEmailEnabled;
+
+	@FindByJQuery("div[class='onoffswitch']:eq(4)")
+	private OnOffSwitch directGrantApiEnabled;
+
+	@FindByJQuery("div[class='onoffswitch']:eq(5)")
+	private OnOffSwitch requireSsl;
+	
+	public boolean isUserRegistrationAllowed() {
+		return registrationAllowed.isEnabled();
+	}
+	
+	public void enableUserRegistration() {
+		registrationAllowed.enable();
+		primaryButton.click();
+	}
+	
+	public void disableUserRegistration() {
+		registrationAllowed.disable();
+		primaryButton.click();
+	}
+	
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/RolesPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/RolesPage.java
new file mode 100644
index 0000000..1ddaca5
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/RolesPage.java
@@ -0,0 +1,112 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import java.util.ArrayList;
+import java.util.List;
+import static org.junit.Assert.assertEquals;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.keycloak.testsuite.ui.model.Role;
+import static org.openqa.selenium.By.cssSelector;
+import static org.openqa.selenium.By.linkText;
+import static org.openqa.selenium.By.tagName;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.*;
+/**
+ *
+ * @author Petr Mensik
+ */
+public class RolesPage extends AbstractPage {
+
+    @FindBy(css = "input[class*='search']")
+    private WebElement searchInput;
+
+    @FindBy(css = "table[class*='table']")
+    private WebElement dataTable;
+
+    @FindBy(id = "name")
+    private WebElement nameInput;
+
+    @FindBy(id = "description")
+    private WebElement descriptionInput;
+
+    @FindBy(id = "compositeSwitch")
+    private WebElement compositeSwitchToggle;
+	
+
+    public boolean isRoleComposite(String roleName) {
+        return findRole(roleName).isComposite();
+    }
+
+    public void addRole(Role role) {
+		primaryButton.click();
+		waitAjaxForElement(nameInput);
+        nameInput.sendKeys(role.getName());
+        if (role.isComposite()) {
+            compositeSwitchToggle.click();
+        }
+        descriptionInput.sendKeys(role.getDescription());
+		primaryButton.click();
+	}
+
+    public Role findRole(String roleName) {
+        searchInput.sendKeys(roleName);
+        List<Role> roles = getAllRows();
+        assertEquals(1, roles.size());
+        return roles.get(0);
+    }
+
+    public void editRole(Role role) {
+        driver.findElement(linkText(role.getName())).click();
+        waitAjaxForElement(nameInput);
+        nameInput.sendKeys(role.getName());
+        if (role.isComposite()) {
+            compositeSwitchToggle.click();
+        }
+        descriptionInput.sendKeys(role.getDescription());
+		primaryButton.click();
+	}
+
+    public void deleteRole(Role role) {
+        driver.findElement(linkText(role.getName())).click();
+        waitAjaxForElement(dangerButton);
+		dangerButton.click();
+		deleteConfirmationButton.click();
+    }
+	
+	public void deleteRole(String name) {
+		deleteRole(new Role(name));
+	}
+
+    private List<Role> getAllRows() {
+        List<Role> rows = new ArrayList<Role>();
+        for (WebElement rowElement : dataTable.findElements(cssSelector("tbody tr"))) {
+            Role role = new Role();
+            List<WebElement> tds = rowElement.findElements(tagName("td"));
+            if(!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
+                role.setName(tds.get(0).getText());
+                role.setComposite(Boolean.valueOf(tds.get(1).getText()));
+                role.setDescription(tds.get(2).getText());
+                rows.add(role);
+            }
+        }
+        return rows;
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SecurityPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SecurityPage.java
new file mode 100644
index 0000000..13d6a07
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SecurityPage.java
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.keycloak.testsuite.ui.fragment.OnOffSwitch;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.keycloak.testsuite.ui.util.SeleniumUtils;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class SecurityPage extends AbstractPage {
+
+    @FindByJQuery("a:contains('Brute Force Detection')")
+    private WebElement bruteForceProtectionLink;
+
+    @FindByJQuery("div[class='onoffswitch']")
+    private OnOffSwitch protectionEnabled;
+
+    @FindBy(id = "failureFactor")
+    private WebElement failureFactorInput;
+
+    @FindBy(id = "waitIncrement")
+    private WebElement waitIncrementInput;
+
+    @FindBy(id = "waitIncrementUnit")
+    private Select waitIncrementSelect;
+
+    @FindBy(id = "quickLoginCheckMilliSeconds")
+    private WebElement quickLoginCheckInput;
+
+    @FindBy(id = "minimumQuickLoginWait")
+    private WebElement minQuickLoginWaitInput;
+
+    @FindBy(id = "minimumQuickLoginWaitUnit")
+    private Select minQuickLoginWaitSelect;
+
+    @FindBy(id = "maxFailureWait")
+    private WebElement maxWaitInput;
+
+    @FindBy(id = "maxFailureWaitUnit")
+    private Select maxWaitSelect;
+
+    @FindBy(id = "maxDeltaTime")
+    private WebElement failureResetTimeInput;
+
+    @FindBy(id = "maxDeltaTimeUnit")
+    private Select failureResetTimeSelect;
+
+    public void goToAndEnableBruteForceProtectionTab() {
+        SeleniumUtils.waitGuiForElement(bruteForceProtectionLink);
+        bruteForceProtectionLink.click();
+        if(!protectionEnabled.isEnabled()){
+            protectionEnabled.enable();
+        }
+    }
+
+    public void setFailureFactorInput(String value){
+        failureFactorInput.clear();
+        failureFactorInput.sendKeys(value);
+    }
+
+    public void setWaitIncrementInput(String value){
+        waitIncrementInput.clear();
+        waitIncrementInput.sendKeys(value);
+    }
+
+    public void setQuickLoginCheckInput(String value){
+        quickLoginCheckInput.clear();
+        quickLoginCheckInput.sendKeys(value);
+    }
+
+    public void setMinQuickLoginWaitInput(String value){
+        minQuickLoginWaitInput.clear();
+        minQuickLoginWaitInput.sendKeys(value);
+    }
+
+    public void setMaxWaitInput(String value){
+        maxWaitInput.clear();
+        maxWaitInput.sendKeys(value);
+    }
+
+    public void setFailureResetTimeInput(String value){
+        failureResetTimeInput.clear();
+        failureResetTimeInput.sendKeys(value);
+    }
+
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SocialSettingsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SocialSettingsPage.java
new file mode 100644
index 0000000..ef38396
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/SocialSettingsPage.java
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import static org.junit.Assert.assertNotNull;
+import org.keycloak.testsuite.ui.model.Provider;
+import org.keycloak.testsuite.ui.model.SocialProvider;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import static org.openqa.selenium.By.tagName;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class SocialSettingsPage extends AbstractPage {
+	
+	@FindBy(tagName = "select")
+	private Select newProviderSelect;
+	
+	@FindByJQuery("input[class*='form-control']:eq(1)")
+	private WebElement providerKey;
+	
+	@FindByJQuery("input[class*='form-control']:eq(2)")
+	private WebElement providerSecret;
+	
+	@FindBy(tagName = "tbody")
+	private WebElement providersTable;
+	
+	public void addNewProvider(Provider provider) {
+		newProviderSelect.selectByVisibleText(provider.providerName.getName());
+		providerKey.sendKeys(provider.key);
+		providerSecret.sendKeys(provider.secret);
+		primaryButton.click();
+	}
+	
+	public void editProvider(SocialProvider oldProvider, Provider newProvider) {
+		Provider p = find(oldProvider);
+		assertNotNull("Provider should have been found", p);
+		System.out.println(p.providerName);
+	}
+	
+	public Provider find(SocialProvider provider){
+		List<Provider> list = getAllRows();
+		for(Provider p : list) {
+			if(p.providerName == provider) {
+				return p;
+			} 
+		}
+		return null;
+	}
+	
+	private List<Provider> getAllRows() {
+        List<Provider> rows = new ArrayList<Provider>();
+        for (WebElement rowElement : providersTable.findElements(tagName("tr"))) {
+            Provider provider = new Provider();
+            List<WebElement> tds = rowElement.findElements(tagName("td"));
+            if(!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
+                provider.providerName = SocialProvider.valueOf(tds.get(0).getText());
+                provider.key = tds.get(1).getText();
+                provider.secret = tds.get(2).getText();
+                rows.add(provider);
+            }
+        }
+        return rows;
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ThemesSettingsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ThemesSettingsPage.java
new file mode 100644
index 0000000..d311d4d
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/ThemesSettingsPage.java
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElementNotPresent;
+import org.openqa.selenium.By;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class ThemesSettingsPage extends AbstractPage {
+
+    @FindBy(css = "#loginTheme")
+    private Select loginThemeSelect;
+
+    @FindBy(css = "#accountTheme")
+    private Select accountThemeSelect;
+
+    @FindBy(css = "#adminTheme")
+    private Select adminConsoleThemeSelect;
+
+    @FindBy(css = "#emailTheme")
+    private Select emailThemeSelect;
+
+    @FindBy(css = "link[href*='login/keycloak/css/login.css']")
+    private WebElement keycloakTheme;
+
+    public void changeLoginTheme(String themeName){
+		waitGuiForElement(By.id("loginTheme"));
+        loginThemeSelect.selectByVisibleText(themeName);
+    }
+
+    public void changeAccountTheme(String themeName){
+        accountThemeSelect.selectByVisibleText(themeName);
+    }
+
+    public void changeAdminConsoleTheme(String themeName){
+        adminConsoleThemeSelect.selectByVisibleText(themeName);
+    }
+
+    public void changeEmailTheme(String themeName){
+        emailThemeSelect.selectByVisibleText(themeName);
+    }
+
+    public void verifyBaseTheme(){
+        waitGuiForElementNotPresent(keycloakTheme);
+    }
+
+    public void verifyKeycloakTheme(){
+        waitGuiForElement(keycloakTheme);
+    }
+
+    public void saveTheme() {
+        primaryButton.click();
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/TokensPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/TokensPage.java
new file mode 100644
index 0000000..fc8d433
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/TokensPage.java
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import java.util.concurrent.TimeUnit;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+import static java.lang.String.valueOf;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+import static org.apache.commons.lang3.text.WordUtils.capitalize;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class TokensPage extends AbstractPage {
+	
+	@FindBy(id = "ssoSessionIdleTimeout")
+	private WebElement sessionTimeout;
+	
+	@FindBy(name = "ssoSessionIdleTimeoutUnit")
+	private Select sessionTimeoutUnit;
+	
+	@FindBy(id = "ssoSessionMaxLifespan")
+	private WebElement sessionLifespanTimeout;
+	
+	@FindBy(name = "ssoSessionMaxLifespanUnit")
+	private Select sessionLifespanTimeoutUnit;
+
+	public void setSessionTimeout(int timeout, TimeUnit unit) {
+		setTimeout(sessionTimeoutUnit, sessionTimeout, timeout, unit);
+	}
+	
+	public void setSessionTimeoutLifespan(int time, TimeUnit unit) {
+		setTimeout(sessionLifespanTimeoutUnit, sessionLifespanTimeout, time, unit);
+	}
+	
+	private void setTimeout(Select timeoutElement, WebElement unitElement,
+			int timeout, TimeUnit unit) {
+		waitGuiForElement(sessionTimeout);
+		timeoutElement.selectByValue(capitalize(unit.name().toLowerCase()));
+		unitElement.clear();
+		unitElement.sendKeys(valueOf(timeout));
+		primaryButton.click();
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/UserPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/UserPage.java
new file mode 100644
index 0000000..18450b4
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/UserPage.java
@@ -0,0 +1,195 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.page.settings;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.keycloak.testsuite.ui.model.User;
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import org.keycloak.testsuite.ui.model.UserAction;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitAjaxForElement;
+import static org.openqa.selenium.By.*;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class UserPage extends AbstractPage {
+
+	@FindBy(id = "username")
+	private WebElement usernameInput;
+
+	@FindBy(id = "email")
+	private WebElement emailInput;
+
+	@FindBy(id = "firstName")
+	private WebElement firstNameInput;
+
+	@FindBy(id = "lastName")
+	private WebElement lastNameInput;
+
+	@FindBy(id = "emailVerified")
+	private WebElement emailVerifiedSwitchToggle;
+
+	@FindBy(css = "label[for='userEnabled']")
+	private WebElement userEnabledSwitchToggle;
+
+	@FindBy(css = "input[class*='select2-input']")
+	private WebElement requiredUserActionsInput;
+
+	@FindByJQuery(".select2-offscreen")
+	private Select actionsSelect;
+
+	@FindBy(id = "password")
+	private WebElement password;
+
+	@FindBy(id = "confirmPassword")
+	private WebElement confirmPassword;
+
+	@FindBy(css = "input[class*='search']")
+	private WebElement searchInput;
+
+	@FindBy(css = "table[class*='table']")
+	private WebElement dataTable;
+
+	@FindByJQuery("button[kc-cancel] ")
+	private WebElement cancel;
+	
+	@FindBy(css = "div[class='input-group-addon'] i")
+	private WebElement searchButton;
+
+	public void addUser(User user) {
+		primaryButtons.get(1).click();
+		waitAjaxForElement(usernameInput);
+		usernameInput.sendKeys(user.getUserName());
+		emailInput.sendKeys(user.getEmail());
+		firstNameInput.sendKeys(user.getFirstName());
+		lastNameInput.sendKeys(user.getLastName());
+		if (!user.isUserEnabled()) {
+			userEnabledSwitchToggle.click();
+		}
+		if (user.isEmailVerified()) {
+			emailVerifiedSwitchToggle.click();
+		}
+//		requiredUserActionsInput.sendKeys(user.getRequiredUserActions());
+		primaryButton.click();
+	}
+
+	public void addPasswordForUser(User user) {
+		password.sendKeys(user.getPassword());
+		confirmPassword.sendKeys(user.getPassword());
+		dangerButton.click();
+		waitAjaxForElement(deleteConfirmationButton);
+		deleteConfirmationButton.click();
+	}
+
+	public User findUser(String username) {
+		waitAjaxForElement(searchInput);
+		searchInput.sendKeys(username);
+		searchButton.click();
+		List<User> users = getAllRows();
+		if (users.isEmpty()) {
+			return null;
+
+		} else {
+			assertEquals(1, users.size());
+			return users.get(0);
+		}
+	}
+
+	public void editUser(User user) {
+		goToUser(user);
+		waitAjaxForElement(usernameInput);
+		usernameInput.sendKeys(user.getUserName());
+		emailInput.sendKeys(user.getEmail());
+		if (!user.isUserEnabled()) {
+			userEnabledSwitchToggle.click();
+		}
+		if (user.isEmailVerified()) {
+			emailVerifiedSwitchToggle.click();
+		}
+		requiredUserActionsInput.sendKeys(user.getRequiredUserActions());
+		primaryButton.click();
+	}
+
+	public void deleteUser(String username) {
+		searchInput.sendKeys(username);
+		searchButton.click();
+		driver.findElement(linkText(username)).click();
+		waitAjaxForElement(dangerButton);
+		dangerButton.click();
+		waitAjaxForElement(deleteConfirmationButton);
+		deleteConfirmationButton.click();
+	}
+
+	public void cancel() {
+		cancel.click();
+	}
+
+	public void showAllUsers() {
+		primaryButtons.get(0).click();
+	}
+
+	public void goToUser(User user) {
+		dataTable.findElement(linkText(user.getUserName())).click();
+	}
+
+	public void goToUser(String name) {
+		goToUser(new User(name));
+	}
+
+	public void addAction(UserAction action) {
+		actionsSelect.selectByValue(action.name());
+		primaryButton.click();
+	}
+
+	public void removeAction(UserAction action) {
+		actionsSelect.deselectByValue(action.name());
+		primaryButton.click();
+	}
+
+	private List<User> getAllRows() {
+		List<User> users = new ArrayList<User>();
+		List<WebElement> rows = dataTable.findElements(cssSelector("tbody tr"));
+		if (rows.size() > 1) {
+			for (WebElement rowElement : rows) {
+				if (rowElement.isDisplayed()) {
+					User user = new User();
+					List<WebElement> tds = rowElement.findElements(tagName("td"));
+					if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
+						user.setUserName(tds.get(0).getText());
+						user.setLastName(tds.get(1).getText());
+						user.setFirstName(tds.get(2).getText());
+						user.setEmail(tds.get(3).getText());
+						users.add(user);
+					}
+				}
+			}	
+		}
+		return users;
+	}
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/account/AccountManagementTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/account/AccountManagementTest.java
new file mode 100644
index 0000000..537fee3
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/account/AccountManagementTest.java
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.account;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.keycloak.testsuite.ui.util.Constants.ADMIN_PSSWD;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.Account;
+import org.keycloak.testsuite.ui.page.account.AccountPage;
+import org.keycloak.testsuite.ui.page.account.PasswordPage;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class AccountManagementTest extends AbstractKeyCloakTest<AccountPage> {
+
+	@FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+	
+    @Page
+    private AccountPage accountPage;
+
+    @Page
+    private PasswordPage passwordPage;
+	
+    private static final String USERNAME = "admin";
+    private static final String NEW_PASSWORD = "newpassword";
+    private static final String WRONG_PASSWORD = "wrongpassword";
+
+	@Before
+	public void beforeAccountTest() {
+		menuPage.goToAccountManagement();
+	}
+	
+	@After
+	public void afterAccountTest() {
+		accountPage.keycloakConsole();
+	}
+	
+	@Test
+    public void passwordPageValidationTest() {
+	    page.password();
+        passwordPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isError());
+
+        passwordPage.setPassword(WRONG_PASSWORD, NEW_PASSWORD);
+        passwordPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isError());
+
+        passwordPage.setOldPasswordField(ADMIN_PSSWD);
+        passwordPage.setNewPasswordField("something");
+        passwordPage.setConfirmField("something else");
+        passwordPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isError());
+    }
+
+    @Test
+    public void changePasswordTest() {
+        page.password();
+        passwordPage.setPassword(ADMIN_PSSWD, NEW_PASSWORD);
+        passwordPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        page.signOut();
+        loginPage.login(USERNAME, NEW_PASSWORD);
+        page.password();
+        passwordPage.setPassword(NEW_PASSWORD, ADMIN_PSSWD);
+        passwordPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+    }
+
+    @Test
+    public void accountPageTest() {
+        page.account();
+        Account adminAccount = accountPage.getAccount();
+        assertEquals(adminAccount.getUsername(), USERNAME);
+        adminAccount.setEmail("a@b");
+        adminAccount.setFirstName("John");
+        adminAccount.setLastName("Smith");
+        accountPage.setAccount(adminAccount);
+        accountPage.save();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+
+        page.signOut();
+        loginPage.login(USERNAME, ADMIN_PSSWD);
+
+        page.account();
+        assertEquals(adminAccount, accountPage.getAccount());
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/client/AddNewClientTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/client/AddNewClientTest.java
new file mode 100644
index 0000000..8e0cb19
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/client/AddNewClientTest.java
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.client;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.Client;
+import org.keycloak.testsuite.ui.page.settings.ClientPage;
+
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class AddNewClientTest extends AbstractKeyCloakTest<ClientPage> {
+
+    @FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+	
+	@Before
+	public void beforeClientTest() {
+		navigation.clients();
+		page.goToCreateClient();
+	}
+
+    @Test
+    public void addNewClientTest() {
+        Client newClient = new Client("testClient1", "http://example.com/*");
+        page.addClient(newClient);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        navigation.clients();
+
+        page.deleteClient(newClient.getName());
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        assertNull(page.findClient(newClient.getName()));
+    }
+
+    @Test
+    public void addNewClientWithBlankNameTest() {
+        Client newClient = new Client("", "http://example.com/*");
+        page.addClient(newClient);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+    }
+
+    @Test
+    public void addNewClientWithBlankUriTest() {
+        Client newClient = new Client("testClient2", "");
+        page.addClient(newClient);
+        page.confirmAddClient();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+
+        page.addUri("http://testUri.com/*");
+        page.confirmAddClient();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+
+        navigation.clients();
+        page.deleteClient(newClient.getName());
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        assertNull(page.findClient(newClient.getName()));
+    }
+
+    @Test
+    public void addNewClientWithTwoUriTest() {
+        Client newClient = new Client("testClient3", "");
+        page.addClient(newClient);
+        page.confirmAddClient();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+
+        page.addUri("http://testUri.com/*");
+        page.addUri("http://example.com/*");
+
+        page.confirmAddClient();
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+
+        navigation.clients();
+        page.deleteClient(newClient.getName());
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        assertNull(page.findClient(newClient.getName()));
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java
new file mode 100644
index 0000000..7bcd681
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java
@@ -0,0 +1,94 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.keycloak.testsuite.ui.test.role;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.page.settings.RolesPage;
+import org.keycloak.testsuite.ui.model.Role;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.page.settings.UserPage;
+import static org.openqa.selenium.By.id;
+import org.openqa.selenium.support.ui.Select;
+
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class AddNewRoleTest extends AbstractKeyCloakTest<RolesPage> {
+	
+	@Page
+	private UserPage userPage;
+	
+	@FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+	
+	@Before
+	public void beforeTestAddNewRole() {
+		navigation.roles();
+	}
+	
+    @Test
+    public void testAddNewRole() {
+        Role role = new Role("role1");
+        page.addRole(role);
+		flashMessage.waitUntilPresent();
+		assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+		navigation.roles();
+        assertEquals("role1", page.findRole(role.getName()).getName());
+        page.deleteRole(role);
+    }
+    
+	@Ignore
+    @Test
+    public void testAddNewRoleWithLongName() {
+        String name = "hjewr89y1894yh98(*&*&$jhjkashd)*(&y8934h*&@#hjkahsdj";
+        page.addRole(new Role(name));
+        assertNotNull(page.findRole(name));
+        navigation.roles();
+        page.deleteRole(name);
+    }
+    
+    @Test
+    public void testAddExistingRole() {
+        Role role = new Role("role2");
+        page.addRole(role);
+		flashMessage.waitUntilPresent();
+		assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        navigation.roles();
+        page.addRole(role);
+		flashMessage.waitUntilPresent();
+		assertTrue(flashMessage.getText(), flashMessage.isDanger());
+        navigation.roles();
+        page.deleteRole(role);
+    }
+	
+	@Test
+	public void testRoleIsAvailableForUsers() {
+		Role role = new Role("User role");
+		page.addRole(role);
+		flashMessage.waitUntilPresent();
+		assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+		navigation.users();
+		userPage.showAllUsers();
+		userPage.goToUser("admin");
+		navigation.roleMappings();
+		Select rolesSelect = new Select(driver.findElement(id("available")));
+		assertEquals("User role should be present in admin role mapping", 
+				role.getName(), rolesSelect.getOptions().get(0).getText());
+		navigation.roles();	
+		page.deleteRole(role);
+	}
+    
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/SessionsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/SessionsTest.java
new file mode 100644
index 0000000..41c04c0
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/SessionsTest.java
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.session;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.page.session.SessionsPage;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class SessionsTest extends AbstractKeyCloakTest<SessionsPage> {
+	
+	@Before
+	public void beforeSessionTest() {
+		navigation.sessions();
+	}
+	
+	@Test
+	public void testLogoutAllSessions() {
+		page.logoutAllSessions();
+		waitGuiForElement(loginPage.getLoginPageHeader(), "Home page should be visible after logout");
+		loginPage.loginAsAdmin();
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/TokensTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/TokensTest.java
new file mode 100644
index 0000000..ba1c2e6
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/session/TokensTest.java
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.session;
+
+import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.page.settings.TokensPage;
+
+import static org.jboss.arquillian.graphene.Graphene.waitModel;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class TokensTest extends AbstractKeyCloakTest<TokensPage> {
+
+	private static final int TIMEOUT = 10;
+	private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
+	
+	@Before
+	public void beforeTokensTest() {
+		navigation.tokens();
+	}
+	
+	@Test
+	public void testTimeoutForRealmSession() throws InterruptedException {
+		page.setSessionTimeout(TIMEOUT, TIME_UNIT);
+		TIME_UNIT.sleep(TIMEOUT + 2); //add 2 secs to timeout
+		driver.navigate().refresh();
+		waitGuiForElement(loginPage.getLoginPageHeader(), "Home page should be visible after session timeout");
+		loginPage.loginAsAdmin();
+		page.setSessionTimeout(30, TimeUnit.MINUTES);
+	}
+	
+	@Test
+	public void testLifespanOfRealmSession() {
+		page.setSessionTimeoutLifespan(TIMEOUT, TIME_UNIT);
+		logOut();
+		loginAsAdmin();
+		waitModel().withTimeout(TIMEOUT + 2, TIME_UNIT) //adds 2 seconds to the timeout
+				.pollingEvery(1, TIME_UNIT)
+				.until("Home page should be visible after session timeout")
+				.element(loginPage.getLoginPageHeader())
+				.is()
+				.present();
+		loginPage.loginAsAdmin();
+		navigation.tokens();
+		page.setSessionTimeoutLifespan(10, TimeUnit.HOURS);
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/CredentialsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/CredentialsTest.java
new file mode 100644
index 0000000..f016db1
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/CredentialsTest.java
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.model.PasswordPolicy;
+import org.keycloak.testsuite.ui.page.settings.CredentialsPage;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class CredentialsTest extends AbstractKeyCloakTest<CredentialsPage> {
+	
+	@Before
+	public void beforeCredentialsTest() {
+		navigation.credentials();
+	}
+	
+	@Test
+	public void testDigitsNumber() {
+		page.addPolicy(PasswordPolicy.HASH_ITERATIONS, 5);
+		page.removePolicy(PasswordPolicy.DIGITS);
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SecuritySettingsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SecuritySettingsTest.java
new file mode 100644
index 0000000..b748bd6
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SecuritySettingsTest.java
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.settings;
+
+import org.junit.Test;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.page.settings.SecurityPage;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class SecuritySettingsTest extends AbstractKeyCloakTest<SecurityPage>{
+
+    @Test
+    public void securitySettingsTest() {
+        navigation.security();
+        page.goToAndEnableBruteForceProtectionTab();
+        //TODO:
+
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SocialSettingsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SocialSettingsTest.java
new file mode 100644
index 0000000..71ecc4e
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/SocialSettingsTest.java
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.settings;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import static  org.junit.Assert.*;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.page.settings.SocialSettingsPage;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.Provider;
+import org.keycloak.testsuite.ui.model.SocialProvider;
+import org.keycloak.testsuite.ui.util.URL;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class SocialSettingsTest extends AbstractKeyCloakTest<SocialSettingsPage> {
+	
+	@FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+	
+//	@Test
+	public void testAddNewProvider() {
+		page.addNewProvider(new Provider(SocialProvider.FACEBOOK, "klic", "secret"));
+		flashMessage.waitUntilPresent();
+		assertTrue("Success message should be displayed", flashMessage.isSuccess());
+	}
+	
+//	@Test(expected = NoSuchElementException.class)
+	public void testDuplicitProvider() {
+		page.addNewProvider(new Provider(SocialProvider.FACEBOOK, "a", "b"));
+	}
+	
+//	@Test
+	public void testEditProvider() {
+		page.goToPage(URL.SETTINGS_SOCIAL);
+		page.editProvider(SocialProvider.FACEBOOK, new Provider(SocialProvider.FACEBOOK, "abc", "def"));
+	}
+	
+//	@Test
+	public void testDeleteProvider() {
+		
+	}
+	
+	@Test
+	public void testAddMultipleProviders() {
+	}
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/ThemesSettingsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/ThemesSettingsTest.java
new file mode 100644
index 0000000..c4686ff
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/settings/ThemesSettingsTest.java
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.model.Theme;
+import org.keycloak.testsuite.ui.page.settings.ThemesSettingsPage;
+
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class ThemesSettingsTest extends AbstractKeyCloakTest<ThemesSettingsPage> {
+
+    @Before
+    public void beforeThemeTest() {
+        navigation.themes();
+    }
+
+    @Test
+    public void changeLoginThemeTest() {
+        page.changeLoginTheme(Theme.BASE.getName());
+        page.saveTheme();
+        logOut();
+        page.verifyBaseTheme();
+
+        loginAsAdmin();
+        navigation.themes();
+        page.changeLoginTheme(Theme.KEYCLOAK.getName());
+        page.saveTheme();
+        logOut();
+        page.verifyKeycloakTheme();
+
+        loginAsAdmin();
+    }
+
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java
new file mode 100644
index 0000000..5694c51
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java
@@ -0,0 +1,116 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.user;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.User;
+import org.keycloak.testsuite.ui.page.settings.UserPage;
+
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import static org.keycloak.testsuite.ui.util.Users.TEST_USER1;
+
+/**
+ *
+ * @author Filip Kiss
+ */
+public class AddNewUserTest extends AbstractKeyCloakTest<UserPage> {
+
+    @FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+
+	@Before
+	public void beforeAddNewUserTest() {
+		navigation.users();
+	}
+	
+    @Test
+    public void addUserWithInvalidEmailTest() {
+        String testUsername = "testUserInvEmail";
+        String invalidEmail = "user.redhat.com";
+        User testUser = new User(testUsername, "pass", invalidEmail);
+        page.addUser(testUser);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+        navigation.users();
+        assertNull(page.findUser(testUsername));
+    }
+
+    @Test
+    public void addUserWithNoUsernameTest() {
+        User testUser = new User();
+        page.addUser(testUser);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+    }
+
+	@Ignore
+	@Test
+    public void addUserWithLongNameTest() {
+        String longUserName = "thisisthelongestnameeveranditcannotbeusedwhencreatingnewuserinkeycloak";
+        User testUser = new User(longUserName);
+        navigation.users();
+        page.addUser(testUser);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+        assertNull(page.findUser(testUser.getUserName()));
+    }
+
+    @Test
+    public void addDuplicatedUser() {
+        String testUsername = "test_duplicated_user";
+        User testUser = new User(testUsername);
+        page.addUser(testUser);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+		navigation.users();
+        assertNotNull(page.findUser(testUsername));
+
+        User testUser2 = new User(testUsername);
+        page.addUser(testUser2);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isDanger());
+		navigation.users();
+        page.deleteUser(testUsername);
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        assertNull(page.findUser(testUser2.getUserName()));
+    }
+
+    @Test
+    public void addDisabledUser() {
+        page.addUser(TEST_USER1);
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+		navigation.users();
+        page.deleteUser(TEST_USER1.getUserName());
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+        assertNull(page.findUser(TEST_USER1.getUserName()));
+    }
+
+    
+
+
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java
new file mode 100644
index 0000000..834ba25
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.test.user;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.After;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.User;
+import org.keycloak.testsuite.ui.page.RegisterPage;
+import org.keycloak.testsuite.ui.page.settings.UserPage;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.page.settings.LoginSettingsPage;
+import static org.keycloak.testsuite.ui.util.Users.*;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class RegisterNewUserTest extends AbstractKeyCloakTest<RegisterPage> {
+
+    @Page
+    private UserPage userPage;
+
+	@Page
+	private LoginSettingsPage loginSettingsPage;
+	
+    @FindByJQuery(".alert")
+    private FlashMessage flashMessage;
+	
+	@Before
+	public void beforeUserRegistration() {
+		navigation.settings();
+		navigation.login();
+		loginSettingsPage.enableUserRegistration();
+		logOut();
+		loginPage.goToUserRegistration();
+	}
+	
+	@After
+	public void afterUserRegistration() {
+		navigation.settings();
+		navigation.login();
+		loginSettingsPage.disableUserRegistration();
+	}
+
+    @Test
+    public void registerNewUserTest() {
+        page.registerNewUser(TEST_USER1);
+		logOut();
+        loginAsAdmin();
+        navigation.users();
+        userPage.deleteUser(TEST_USER1.getUserName());
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+    }
+
+
+    @Test
+    public void registerNewUserWithWrongEmail() {
+        User testUser = new User(TEST_USER1);
+		testUser.setEmail("newUser.redhat.com");
+        page.registerNewUser(testUser);
+        assertTrue(page.isInvalidEmail());
+		page.backToLoginPage();
+        loginAsAdmin();
+        navigation.users();
+        assertNull(userPage.findUser(testUser.getUserName()));
+    }
+
+    @Test
+    public void registerNewUserWithWrongAttributes() {
+		User testUser = new User();
+		
+        page.registerNewUser(testUser);
+        assertFalse(page.isAttributeSpecified("first name"));
+		testUser.setFirstName("name");
+        page.registerNewUser(testUser);
+        assertFalse(page.isAttributeSpecified("last name"));
+		testUser.setLastName("surname");
+        page.registerNewUser(testUser);
+        assertFalse(page.isAttributeSpecified("email"));
+		testUser.setEmail("mail@redhat.com");
+        page.registerNewUser(testUser);
+        assertFalse(page.isAttributeSpecified("username"));
+		testUser.setUserName("user");
+        page.registerNewUser(testUser);
+        assertFalse(page.isAttributeSpecified("password"));
+		testUser.setPassword("password");
+        page.registerNewUser(testUser);
+		logOut();
+		loginAsAdmin();
+        navigation.users();
+        userPage.deleteUser(TEST_USER1.getUserName());
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+    }
+
+    @Test
+    public void registerNewUserWithNotMatchingPasswords() {
+        page.registerNewUser(TEST_USER1, "psswd");
+        assertFalse(page.isPasswordSame());
+        page.registerNewUser(TEST_USER1);
+		logOut();
+        loginAsAdmin();
+        navigation.users();
+        userPage.deleteUser(TEST_USER1.getUserName());
+        flashMessage.waitUntilPresent();
+        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+    }
+
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Constants.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Constants.java
new file mode 100644
index 0000000..3bdde85
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Constants.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.util;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public final class Constants {
+
+    private Constants() {
+    }
+    
+    public static String CURRENT_REALM = "master";
+    
+    public static final String ADMIN_PSSWD = "admin";
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/SeleniumUtils.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/SeleniumUtils.java
new file mode 100644
index 0000000..15a4ee5
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/SeleniumUtils.java
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.util;
+
+import static org.jboss.arquillian.graphene.Graphene.waitAjax;
+import static org.jboss.arquillian.graphene.Graphene.waitGui;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public final class SeleniumUtils {
+
+    private SeleniumUtils() {
+    }
+
+    public static void waitAjaxForElement(By element) {
+        waitAjax().until()
+                .element(element)
+                .is()
+                .present();
+    }
+
+    public static void waitAjaxForElement(WebElement element) {
+        waitAjax().until()
+                .element(element)
+                .is()
+                .present();
+    }
+
+    public static void waitGuiForElement(By element, String message) {
+		waitGui().until(message)
+                .element(element)
+                .is()
+                .present();
+	}
+
+    public static void waitGuiForElement(By element) {
+		waitGuiForElement(element, null);
+	}
+
+    public static void waitGuiForElement(WebElement element) {
+		waitGuiForElement(element, null);
+	}
+
+	public static void waitGuiForElement(WebElement element, String message) {
+        waitGui().until(message)
+                .element(element)
+                .is()
+                .present();
+    }
+
+    public static void waitGuiForElementNotPresent(WebElement element) {
+        waitGui().until()
+                .element(element)
+                .is()
+                .not()
+                .present();
+    }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/URL.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/URL.java
new file mode 100644
index 0000000..ffde485
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/URL.java
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.util;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public class URL {
+    
+    public static final String BASE_URL = "http://localhost:8080/auth/admin/master/console/index.html";
+    
+    public static String SETTINGS_GENERAL_SETTINGS = BASE_URL + "#/realms/%s";
+    public static String SETTINGS_ROLES = BASE_URL + "#/realms/%s/roles";
+    public static String SETTINGS_LOGIN = BASE_URL + "#/realms/%s/login-settings";
+    public static String SETTINGS_SOCIAL = BASE_URL + "#/realms/%s/social-settings";
+    
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Users.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Users.java
new file mode 100644
index 0000000..77a6b5f
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/util/Users.java
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.ui.util;
+
+import org.keycloak.testsuite.ui.model.User;
+
+/**
+ *
+ * @author Petr Mensik
+ */
+public final class Users {
+
+	private Users() {
+	}
+	
+	public static final User ADMIN = new User("admin", "admin");
+	public static final User EMPTY_USER = new User();
+	public static final User TEST_USER1 = new User("user", "password", "user@redhat.com", "user", "test");
+	
+}
diff --git a/testsuite/integration-arquillian/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..91393a9
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/resources/arquillian.xml
@@ -0,0 +1,23 @@
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+			xsi:schemaLocation="http://jboss.org/schema/arquillian
+        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+
+	<container qualifier="wildfly-8-remote">
+		<protocol type="jmx-as7">
+			<property name="executionType">REMOTE</property>
+		</protocol>
+	</container>
+	
+	<container qualifier="wildfly-8-managed">
+		<configuration>
+			<property name="jbossHome">${jbossHome}</property>
+			<property name="serverConfig">standalone.xml</property>
+		</configuration>
+	</container>
+    
+	<extension qualifier="webdriver">
+		<property name="browser">${browser}</property>
+	</extension>
+</arquillian>