keycloak-memoizeit

Changes

pom.xml 19(+6 -13)

testsuite/pom.xml 13(+3 -10)

Details

pom.xml 19(+6 -13)

diff --git a/pom.xml b/pom.xml
index c4a3486..8966893 100755
--- a/pom.xml
+++ b/pom.xml
@@ -242,20 +242,13 @@
   				<version>1.1.1.Final</version>
   				<type>pom</type>
   				<scope>import</scope>
-			</dependency>			
+			</dependency>		
+				
 			<dependency>
-				<groupId>org.jboss.arquillian.extension</groupId>
-				<artifactId>arquillian-drone-bom</artifactId>
-				<version>1.2.0.Beta1</version>
-				<type>pom</type>
-				<scope>import</scope>
-			</dependency>
-			<dependency>
-				<groupId>org.jboss.arquillian.graphene</groupId>
-				<artifactId>graphene-webdriver</artifactId>
-				<type>pom</type>
-				<version>2.0.0.Beta1</version>
-			</dependency>
+				<groupId>org.seleniumhq.selenium</groupId>
+				<artifactId>selenium-java</artifactId>
+				<version>2.26.0</version>
+  			</dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
index a0996ab..0c106d0 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
@@ -35,6 +35,7 @@ import org.keycloak.services.models.UserModel.RequiredAction;
 import org.picketlink.idm.model.sample.Realm;
 
 import javax.imageio.spi.ServiceRegistry;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
@@ -127,7 +128,7 @@ public class FormFlows {
         while (itr.hasNext()) {
             FormService provider = itr.next();
             if (provider.getId().equals("FormServiceId"))
-                return Response.status(200).entity(provider.process(template, formDataBean)).build();
+                return Response.status(200).type(MediaType.TEXT_HTML).entity(provider.process(template, formDataBean)).build();
         }
 
         return Response.status(200).entity("form provider not found").build();

testsuite/pom.xml 13(+3 -10)

diff --git a/testsuite/pom.xml b/testsuite/pom.xml
index 784b613..973b7a3 100755
--- a/testsuite/pom.xml
+++ b/testsuite/pom.xml
@@ -119,17 +119,10 @@
 			<scope>test</scope>
 		</dependency>
 		<dependency>
-			<groupId>org.jboss.arquillian.extension</groupId>
-			<artifactId>arquillian-drone-webdriver-depchain</artifactId>
-			<type>pom</type>
+			<groupId>org.seleniumhq.selenium</groupId>
+			<artifactId>selenium-java</artifactId>
 			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.jboss.arquillian.graphene</groupId>
-			<artifactId>graphene-webdriver</artifactId>
-			<type>pom</type>
-			<scope>test</scope>
-		</dependency>
+  		</dependency>
 		<dependency>
 			<groupId>org.jboss.shrinkwrap.resolver</groupId>
 			<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/AbstractDroneTest.java b/testsuite/src/test/java/org/keycloak/testsuite/AbstractDroneTest.java
index 0da9787..e261ab0 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/AbstractDroneTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/AbstractDroneTest.java
@@ -22,13 +22,15 @@
 package org.keycloak.testsuite;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.After;
+import org.junit.Rule;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.Driver;
+import org.keycloak.testsuite.rule.Page;
+import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
 /**
@@ -46,11 +48,14 @@ public abstract class AbstractDroneTest {
         return Deployments.deployment();
     }
 
+    @Rule
+    public WebRule webRule = new WebRule(this);
+
     @Page
     protected AppPage appPage;
 
-    @Drone
-    protected WebDriver browser;
+    @Driver
+    protected WebDriver driver;
 
     @Page
     protected LoginPage loginPage;
@@ -64,7 +69,7 @@ public abstract class AbstractDroneTest {
         if (appPage.isCurrent()) {
             appPage.logout();
         }
-        browser.manage().deleteAllCookies();
+        driver.manage().deleteAllCookies();
     }
 
 }
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/AccountTest.java b/testsuite/src/test/java/org/keycloak/testsuite/AccountTest.java
index 6321031..8301e51 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/AccountTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/AccountTest.java
@@ -21,13 +21,13 @@
  */
 package org.keycloak.testsuite;
 
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.ChangePasswordPage;
 import org.keycloak.testsuite.pages.UpdateProfilePage;
+import org.keycloak.testsuite.rule.Page;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/LoginTest.java b/testsuite/src/test/java/org/keycloak/testsuite/LoginTest.java
index 2291484..ecd65fe 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/LoginTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/LoginTest.java
@@ -56,7 +56,6 @@ public class LoginTest extends AbstractDroneTest {
     public void loginSuccess() {
         appPage.open();
 
-        Assert.assertTrue(loginPage.isCurrent());
         loginPage.login("bburke@redhat.com", "password");
         
         Assert.assertTrue(appPage.isCurrent());
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/AppPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/AppPage.java
index f747896..18cc3ae 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/AppPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/AppPage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class AppPage {
 
     private static String PATH = Constants.APP_ROOT + "/user.jsp";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "logout")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/ChangePasswordPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/ChangePasswordPage.java
index f655f4b..4d7c4cb 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/ChangePasswordPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/ChangePasswordPage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class ChangePasswordPage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account/password";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "password")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
index 1c7c062..5a16097 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class LoginConfigTotpPage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account/totp";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "totpSecret")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
index c639bdd..8477863 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
@@ -1,13 +1,13 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 public class LoginPage {
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "username")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
index 7bd9836..14da7d4 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordResetPage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class LoginPasswordResetPage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account/password";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "username")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
index 2a19f0c..7136a2c 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginPasswordUpdatePage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class LoginPasswordUpdatePage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account/password";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "password-new")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
index 8c839ee..18b6423 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
@@ -1,13 +1,13 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 public class LoginTotpPage {
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "totp")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
index 2f37961..73950f3 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
@@ -1,13 +1,13 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 public class LoginUpdateProfilePage {
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "firstName")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
index 88ebbfa..6012a56 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
@@ -1,13 +1,13 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
 public class RegisterPage {
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "name")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/TotpPage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/TotpPage.java
index f01e812..53474c1 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/TotpPage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/TotpPage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class TotpPage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account/totp";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "totpSecret")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/pages/UpdateProfilePage.java b/testsuite/src/test/java/org/keycloak/testsuite/pages/UpdateProfilePage.java
index 94feb0e..e6dbfcb 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/pages/UpdateProfilePage.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/pages/UpdateProfilePage.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.pages;
 
-import org.jboss.arquillian.drone.api.annotation.Drone;
 import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.rule.Driver;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -10,7 +10,7 @@ public class UpdateProfilePage {
 
     private static String PATH = Constants.AUTH_SERVER_ROOT + "/rest/realms/demo/account";
 
-    @Drone
+    @Driver
     private WebDriver browser;
 
     @FindBy(id = "firstName")
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionEmailVerificationTest.java b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionEmailVerificationTest.java
index 134a6b1..738e681 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionEmailVerificationTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionEmailVerificationTest.java
@@ -29,8 +29,6 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -42,6 +40,10 @@ import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.Driver;
+import org.keycloak.testsuite.rule.GreenMailRule;
+import org.keycloak.testsuite.rule.Page;
+import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
 /**
@@ -66,11 +68,14 @@ public class RequiredActionEmailVerificationTest {
                 .addAsWebInfResource("web-properties-email-verfication.xml", "web.xml");
     }
 
+    @Rule
+    public WebRule webRule = new WebRule(this);
+
     @Page
     protected AppPage appPage;
 
-    @Drone
-    protected WebDriver browser;
+    @Driver
+    protected WebDriver driver;
 
     @Page
     protected LoginPage loginPage;
@@ -96,7 +101,7 @@ public class RequiredActionEmailVerificationTest {
         loginPage.register();
         registerPage.register("name", "email", "verifyEmail", "password", "password");
 
-        Assert.assertTrue(browser.getPageSource().contains("Verify email"));
+        Assert.assertTrue(driver.getPageSource().contains("Verify email"));
 
         MimeMessage message = greenMail.getReceivedMessages()[0];
 
@@ -108,7 +113,7 @@ public class RequiredActionEmailVerificationTest {
 
         String verificationUrl = m.group(1);
 
-        browser.navigate().to(verificationUrl.trim());
+        driver.navigate().to(verificationUrl.trim());
 
         Assert.assertTrue(appPage.isCurrent());
         Assert.assertEquals("verifyEmail", appPage.getUser());
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionMultipleActionsTest.java b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionMultipleActionsTest.java
index eaa8ced..147e29b 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionMultipleActionsTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionMultipleActionsTest.java
@@ -22,7 +22,6 @@
 package org.keycloak.testsuite;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -33,6 +32,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
 import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
+import org.keycloak.testsuite.rule.GreenMailRule;
+import org.keycloak.testsuite.rule.Page;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionResetPasswordTest.java b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionResetPasswordTest.java
index 0f369a7..c9ea42b 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionResetPasswordTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionResetPasswordTest.java
@@ -22,7 +22,6 @@
 package org.keycloak.testsuite;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -31,6 +30,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
+import org.keycloak.testsuite.rule.GreenMailRule;
+import org.keycloak.testsuite.rule.Page;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionTotpSetupTest.java b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionTotpSetupTest.java
index 0d667ee..88f86b1 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionTotpSetupTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionTotpSetupTest.java
@@ -24,19 +24,21 @@ package org.keycloak.testsuite;
 import java.net.MalformedURLException;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.drone.api.annotation.Drone;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.LoginConfigTotpPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.Driver;
+import org.keycloak.testsuite.rule.Page;
+import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 import org.picketlink.idm.credential.util.TimeBasedOTP;
 
@@ -56,11 +58,14 @@ public class RequiredActionTotpSetupTest {
         return Deployments.deployment().addAsResource("testrealm-totp.json", "META-INF/testrealm.json");
     }
 
+    @Rule
+    public WebRule webRule = new WebRule(this);
+
     @Page
     protected AppPage appPage;
 
-    @Drone
-    protected WebDriver browser;
+    @Driver
+    protected WebDriver driver;
 
     @Page
     protected LoginConfigTotpPage totpPage;
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionUpdateProfileTest.java b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionUpdateProfileTest.java
index 74ae20a..6520152 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionUpdateProfileTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/RequiredActionUpdateProfileTest.java
@@ -22,7 +22,6 @@
 package org.keycloak.testsuite;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -31,6 +30,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
+import org.keycloak.testsuite.rule.GreenMailRule;
+import org.keycloak.testsuite.rule.Page;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/ResetPasswordTest.java b/testsuite/src/test/java/org/keycloak/testsuite/ResetPasswordTest.java
index 755061e..f220853 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/ResetPasswordTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/ResetPasswordTest.java
@@ -27,7 +27,6 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -37,6 +36,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.LoginPasswordResetPage;
 import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
+import org.keycloak.testsuite.rule.GreenMailRule;
+import org.keycloak.testsuite.rule.Page;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -80,7 +81,7 @@ public class ResetPasswordTest extends AbstractDroneTest {
         String body = (String) message.getContent();
         String changePasswordUrl = body.split("\n")[0];
 
-        browser.navigate().to(changePasswordUrl.trim());
+        driver.navigate().to(changePasswordUrl.trim());
 
         Assert.assertTrue(updatePasswordPage.isCurrent());
 
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/rule/Driver.java b/testsuite/src/test/java/org/keycloak/testsuite/rule/Driver.java
new file mode 100644
index 0000000..5b7d1d9
--- /dev/null
+++ b/testsuite/src/test/java/org/keycloak/testsuite/rule/Driver.java
@@ -0,0 +1,12 @@
+package org.keycloak.testsuite.rule;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Driver {
+
+}
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/rule/Page.java b/testsuite/src/test/java/org/keycloak/testsuite/rule/Page.java
new file mode 100644
index 0000000..c3009ee
--- /dev/null
+++ b/testsuite/src/test/java/org/keycloak/testsuite/rule/Page.java
@@ -0,0 +1,12 @@
+package org.keycloak.testsuite.rule;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Page {
+
+}
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/rule/WebRule.java b/testsuite/src/test/java/org/keycloak/testsuite/rule/WebRule.java
new file mode 100644
index 0000000..1adcfa2
--- /dev/null
+++ b/testsuite/src/test/java/org/keycloak/testsuite/rule/WebRule.java
@@ -0,0 +1,109 @@
+package org.keycloak.testsuite.rule;
+
+import java.lang.reflect.Field;
+
+import org.junit.rules.ExternalResource;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.support.PageFactory;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+
+public class WebRule extends ExternalResource {
+
+    private WebDriver driver;
+    private Object test;
+
+    public WebRule(Object test) {
+        this.test = test;
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        String browser = "htmlunit";
+        if (System.getProperty("browser") != null) {
+            browser = System.getProperty("browser");
+        }
+
+        if (browser.equals("htmlunit")) {
+            HtmlUnitDriver d = new HtmlUnitDriver();
+            d.getWebClient().setCssEnabled(false);
+            driver = d;
+        } else if (browser.equals("chrome")) {
+            driver = new ChromeDriver();
+        } else if (browser.equals("firefox")) {
+            driver = new FirefoxDriver();
+        } else {
+            throw new RuntimeException("Unsupported browser " + browser);
+        }
+
+        initDriver(test);
+        initPages(test);
+    }
+
+    protected void initDriver(Object o) {
+        Class<?> c = o.getClass();
+        while (c != null) {
+            for (Field f : c.getDeclaredFields()) {
+                if (f.getAnnotation(Driver.class) != null) {
+                    set(f, o, driver);
+                }
+            }
+
+            c = c.getSuperclass();
+        }
+    }
+
+    protected void initPages(Object o) {
+        Class<?> c = o.getClass();
+        while (c != null) {
+            for (Field f : c.getDeclaredFields()) {
+                if (f.getAnnotation(Page.class) != null) {
+                    set(f, o, getPage(f.getType()));
+                }
+            }
+
+            c = c.getSuperclass();
+        }
+    }
+
+    protected void set(Field f, Object o, Object v) {
+        f.setAccessible(true);
+        try {
+            f.set(o, v);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public WebDriver getDriver() {
+        return driver;
+    }
+
+    public <T> T getPage(Class<T> pageClass) {
+        try {
+            T instance = pageClass.newInstance();
+            initDriver(instance);
+            PageFactory.initElements(driver, instance);
+            return instance;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void after() {
+        driver.close();
+    }
+
+    public class HtmlUnitDriver extends org.openqa.selenium.htmlunit.HtmlUnitDriver {
+        
+        @Override
+        public WebClient getWebClient() {
+            return super.getWebClient();
+        }
+        
+    }
+    
+}
diff --git a/testsuite/src/test/java/org/keycloak/testsuite/TotpTest.java b/testsuite/src/test/java/org/keycloak/testsuite/TotpTest.java
index 8f1ad0f..91e2d70 100644
--- a/testsuite/src/test/java/org/keycloak/testsuite/TotpTest.java
+++ b/testsuite/src/test/java/org/keycloak/testsuite/TotpTest.java
@@ -23,7 +23,6 @@ package org.keycloak.testsuite;
 
 import java.net.MalformedURLException;
 
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.junit.Arquillian;
 import org.junit.Assert;
 import org.junit.Before;
@@ -31,6 +30,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.keycloak.testsuite.pages.LoginTotpPage;
 import org.keycloak.testsuite.pages.TotpPage;
+import org.keycloak.testsuite.rule.Page;
 import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 /**
@@ -109,7 +109,7 @@ public class TotpTest extends AbstractDroneTest {
 
         totpPage.configure(totp.generate(totpPage.getTotpSecret()));
 
-        Assert.assertTrue(browser.getPageSource().contains("Google Authenticator enabled"));
+        Assert.assertTrue(driver.getPageSource().contains("Google Authenticator enabled"));
     }
 
 }