keycloak-uncached

Merge pull request #3113 from vmuzikar/KEYCLOAK-3367 KEYCLOAK-3367

8/5/2016 4:44:52 AM

Details

diff --git a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
index 30de700..468f98e 100755
--- a/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
+++ b/testsuite/integration-arquillian/test-apps/js-console/src/main/webapp/index.html
@@ -29,6 +29,7 @@
     <button onclick="keycloak.register()">Register</button>
     <button onclick="refreshToken(9999)">Refresh Token</button>
     <button onclick="refreshToken(30)">Refresh Token (if <30s validity)</button>
+    <button onclick="showError()">Show Error Response</button>
     <button onclick="loadProfile()">Get Profile</button>
     <button onclick="loadUserInfo()">Get User Info</button>
     <button onclick="output(keycloak.tokenParsed)">Show Token</button>
@@ -108,6 +109,20 @@
         output(o);
     }
 
+    function showError() {
+        output("Error: " + getParameterByName("error") + "\n" + "Error description: " + getParameterByName("error_description"));
+    }
+
+    function getParameterByName(name, url) {
+        if (!url) url = window.location.href;
+        name = name.replace(/[\[\]]/g, "\\$&");
+        var regex = new RegExp("[?&#]" + name + "(=([^&#]*)|&|#|$)"),
+                results = regex.exec(url);
+        if (!results) return null;
+        if (!results[2]) return '';
+        return decodeURIComponent(results[2].replace(/\+/g, " "));
+    }
+
     function output(data) {
         if (typeof data === 'object') {
             data = JSON.stringify(data, null, '  ');
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
index fef0d11..2a57739 100755
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/JSConsoleTestApp.java
@@ -59,6 +59,8 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
     @FindBy(xpath = "//button[text() = 'Get Profile']")
     private WebElement getProfileButton;
 
+    @FindBy(xpath = "//button[text() = 'Show Error Response']")
+    private WebElement showErrorButton;
     @FindBy(xpath = "//button[text() = 'Show Token']")
     private WebElement showTokenButton;
     @FindBy(xpath = "//button[text() = 'Show Refresh Token']")
@@ -137,4 +139,8 @@ public class JSConsoleTestApp extends AbstractPageWithInjectedUrl {
     public WebElement getInitButtonElement() {
         return initButton;
     }
+
+    public void showErrorResponse() {
+        showErrorButton.click();
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
index 0e07157..c76747a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/PhotozClientAuthzTestApp.java
@@ -23,21 +23,27 @@ import org.keycloak.testsuite.auth.page.login.OIDCLogin;
 import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
 import org.keycloak.testsuite.page.Form;
 import org.keycloak.testsuite.pages.ConsentPage;
+import org.keycloak.testsuite.util.URLUtils;
 import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
 
 import java.net.URL;
 import java.util.List;
 
+import static org.keycloak.testsuite.util.WaitUtils.IMPLICIT_ELEMENT_WAIT_MILLIS;
 import static org.keycloak.testsuite.util.WaitUtils.pause;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
 
 /**
  * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ * @author Vaclav Muzikar <vmuzikar@redhat.com>
  */
 public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
 
     public static final String DEPLOYMENT_NAME = "photoz-html5-client";
+    public static final int WAIT_AFTER_OPERATION = 2000;
 
     @ArquillianResource
     @OperateOnDeployment(DEPLOYMENT_NAME)
@@ -49,14 +55,16 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     @Page
     protected ConsentPage consentPage;
 
+    @FindBy(xpath = "//a[@ng-click = 'Identity.logout()']")
+    WebElement signOutButton;
+
     public void createAlbum(String name) {
         navigateTo();
-        By id = By.id("create-album");
-        WaitUtils.waitUntilElement(id);
-        this.driver.findElement(id).click();
+        this.driver.findElement(By.id("create-album")).click();
         Form.setInputValue(this.driver.findElement(By.id("album.name")), name);
+        pause(200); // We need to wait a bit for the form to "accept" the input (otherwise it registers the input as empty)
         this.driver.findElement(By.id("save-album")).click();
-        pause(500);
+        pause(WAIT_AFTER_OPERATION);
     }
 
     @Override
@@ -65,76 +73,44 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     }
 
     public void deleteAlbum(String name) {
-        By id = By.id("delete-" + name);
-        WaitUtils.waitUntilElement(id);
-        this.driver.findElements(id).forEach(WebElement::click);
-        pause(500);
+        driver.findElements(By.xpath("//a[text()='" + name + "']/following-sibling::a[text()='X']")).forEach(WebElement::click);
+        pause(WAIT_AFTER_OPERATION);
     }
 
     public void navigateToAdminAlbum() {
-        this.driver.navigate().to(this.getInjectedUrl().toString() + "/#/admin/album");
-        pause(500);
+        URLUtils.navigateToUri(driver, toString() + "/#/admin/album", true);
+        driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
+        waitForPageToLoad(driver);
+        pause(WAIT_AFTER_OPERATION);
     }
 
     public void logOut() {
-        navigateTo();
-        By by = By.xpath("//a[text() = 'Sign Out']");
-        WaitUtils.waitUntilElement(by);
-        this.driver.findElement(by).click();
-        pause(500);
-    }
-
-    public void login(String username, String password) throws InterruptedException {
-        navigateTo();
-        Thread.sleep(2000);
-        if (this.driver.getCurrentUrl().startsWith(getInjectedUrl().toString())) {
-            Thread.sleep(2000);
-            logOut();
-            navigateTo();
-        }
-
-        Thread.sleep(2000);
-
-        this.loginPage.form().login(username, password);
-
-        // simple check if we are at the consent page, if so just click 'Yes'
-        if (this.consentPage.isCurrent()) {
-            consentPage.confirm();
-            Thread.sleep(2000);
-        }
+        signOutButton.click(); // Sometimes doesn't work in PhantomJS!
+        pause(WAIT_AFTER_OPERATION);
     }
 
-    public void loginWithScopes(String username, String password, String... scopes) throws Exception {
-        navigateTo();
-        Thread.sleep(2000);
-        if (this.driver.getCurrentUrl().startsWith(getInjectedUrl().toString())) {
-            Thread.sleep(2000);
-            logOut();
-            navigateTo();
-        }
-
-        Thread.sleep(2000);
-
-        StringBuilder scopesValue = new StringBuilder();
+    public void login(String username, String password, String... scopes) {
+        if (scopes.length > 0) {
+            StringBuilder scopesValue = new StringBuilder();
 
-        for (String scope : scopes) {
-            if (scopesValue.length() != 0) {
-                scopesValue.append(" ");
+            for (String scope : scopes) {
+                if (scopesValue.length() != 0) {
+                    scopesValue.append(" ");
+                }
+                scopesValue.append(scope);
             }
-            scopesValue.append(scope);
-        }
-
-        this.driver.navigate().to(this.driver.getCurrentUrl() + " " + scopesValue);
 
-        Thread.sleep(2000);
+            URLUtils.navigateToUri(driver, this.driver.getCurrentUrl() + " " + scopesValue, true);
+        }
 
         this.loginPage.form().login(username, password);
 
         // simple check if we are at the consent page, if so just click 'Yes'
         if (this.consentPage.isCurrent()) {
             consentPage.confirm();
-            Thread.sleep(2000);
         }
+
+        pause(WAIT_AFTER_OPERATION);
     }
 
     public boolean wasDenied() {
@@ -142,10 +118,20 @@ public class PhotozClientAuthzTestApp extends AbstractPageWithInjectedUrl {
     }
 
     public void viewAlbum(String name) throws InterruptedException {
-        Thread.sleep(2000);
-        By id = By.id("view-" + name);
-        WaitUtils.waitUntilElement(id);
-        this.driver.findElements(id).forEach(WebElement::click);
-        pause(500);
+        this.driver.findElement(By.xpath("//a[text() = '" + name + "']")).click();
+        waitForPageToLoad(driver);
+        driver.navigate().refresh(); // This is sometimes necessary for loading the new policy settings
+        pause(WAIT_AFTER_OPERATION);
+    }
+
+    @Override
+    public void navigateTo(boolean waitForMatch) {
+        super.navigateTo(waitForMatch);
+        pause(WAIT_AFTER_OPERATION);
+    }
+
+    @Override
+    public boolean isCurrent() {
+        return URLUtils.currentUrlStartWith(driver, toString());
     }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
index dcf3795..1147bc7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/URLUtils.java
@@ -40,8 +40,12 @@ public final class URLUtils {
         driver.navigate().to(uri);
 
         if (waitForMatch) {
+            // Possible login URL; this is to eliminate unnecessary wait when navigating to a secured page and being
+            // redirected to the login page
+            String loginUrl = "^[^\\?]+/auth/realms/[^/]+/(protocol|login-actions).+$";
+
             try {
-                (new WebDriverWait(driver, 3)).until(urlMatches("^" + Pattern.quote(uri) + ".*$"));
+                (new WebDriverWait(driver, 3)).until(or(urlMatches("^" + Pattern.quote(uri) + ".*$"), urlMatches(loginUrl)));
             } catch (TimeoutException e) {
                 log.info("new current URL doesn't start with desired URL");
             }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
index 4057d20..570c9e8 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
@@ -101,10 +101,7 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest {
     }
 
     public void deleteAllCookiesForTestRealm() {
-        // testRealmPage.navigateTo();
-        testRealmAccountPage.navigateTo();  // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative
-        log.debug("deleting cookies in test realm");
-        driver.manage().deleteAllCookies();
+        deleteAllCookiesForRealm(testRealmAccountPage);
     }
 
     public void listCookies() {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index ae0dcb6..2ee8f73 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -169,9 +169,13 @@ public abstract class AbstractKeycloakTest {
     }
 
     public void deleteAllCookiesForMasterRealm() {
+        deleteAllCookiesForRealm(accountPage);
+    }
+
+    protected void deleteAllCookiesForRealm(Account realmAccountPage) {
         // masterRealmPage.navigateTo();
-        accountPage.navigateTo(); // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative
-        log.debug("deleting cookies in master realm");
+        realmAccountPage.navigateTo(); // Because IE webdriver freezes when loading a JSON page (realm page), we need to use this alternative
+        log.info("deleting cookies in '" + realmAccountPage.getAuthRealm() + "' realm");
         driver.manage().deleteAllCookies();
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
index 7be3cbd..a91b26b 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java
@@ -268,14 +268,14 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
         jsConsoleTestAppPage.init();
 
         jsConsoleTestAppPage.logIn();
-        assertTrue(driver.getPageSource().contains("Implicit flow is disabled for the client"));
+        assertResponseError("Implicit flow is disabled for the client");
 
-        setImplicitFlowFroClient();
+        setImplicitFlowForClient();
 
         jsConsoleTestAppPage.navigateTo();
         jsConsoleTestAppPage.init();
         jsConsoleTestAppPage.logIn();
-        assertTrue(driver.getPageSource().contains("Standard flow is disabled for the client"));
+        assertResponseError("Standard flow is disabled for the client");
 
         logInAndInit("implicit");
 
@@ -284,19 +284,19 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
 
     @Test
     public void implicitFlowQueryTest() {
-        setImplicitFlowFroClient();
+        setImplicitFlowForClient();
 
         jsConsoleTestAppPage.navigateTo();
         jsConsoleTestAppPage.setFlow("implicit");
         jsConsoleTestAppPage.setResponseMode("query");
         jsConsoleTestAppPage.init();
         jsConsoleTestAppPage.logIn();
-        assertTrue(driver.getPageSource().contains("Invalid parameter: response_mode"));
+        assertResponseError("Response_mode 'query' not allowed");
     }
 
     @Test
     public void implicitFlowRefreshTokenTest() {
-        setImplicitFlowFroClient();
+        setImplicitFlowForClient();
 
         logInAndInit("implicit");
 
@@ -311,7 +311,7 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
         realm.setAccessTokenLifespanForImplicitFlow(5);
         testRealmResource().update(realm);
 
-        setImplicitFlowFroClient();
+        setImplicitFlowForClient();
 
         logInAndInit("implicit");
 
@@ -351,7 +351,7 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
         waitUntilElement(jsConsoleTestAppPage.getOutputElement()).text().contains("Init Success (Authenticated)");
     }
 
-    private void setImplicitFlowFroClient() {
+    private void setImplicitFlowForClient() {
         ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "js-console");
         ClientRepresentation client = clientResource.toRepresentation();
         client.setImplicitFlowEnabled(true);
@@ -373,4 +373,9 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl
         logInAndInit(flow, "user");
     }
 
+    private void assertResponseError(String errorDescription) {
+        jsConsoleTestAppPage.showErrorResponse();
+        assertTrue(jsConsoleTestAppPage.getOutputElement().getText().contains(errorDescription));
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java
index 4b78c05..3a0676e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractSAMLExampleAdapterTest.java
@@ -118,7 +118,7 @@ public abstract class AbstractSAMLExampleAdapterTest extends AbstractExampleAdap
         waitUntilElement(By.xpath("//body")).text().contains("Welcome to the Employee Tool,");
 
         samlRedirectSigExamplePage.logout();
-        waitUntilElement(By.xpath("//body")).text().contains("Logged out.");
+        URLAssert.assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage);
 
         samlRedirectSigExamplePage.navigateTo();
         URLAssert.assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
index 9a0fb26..66702a9 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozExampleAdapterTest.java
@@ -21,6 +21,7 @@ import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.AuthorizationResource;
 import org.keycloak.admin.client.resource.ClientResource;
@@ -47,10 +48,8 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -75,6 +74,17 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
     private PhotozClientAuthzTestApp clientPage;
 
     @Override
+    public void setDefaultPageUriParameters() {
+        super.setDefaultPageUriParameters();
+        testRealmPage.setAuthRealm(REALM_NAME);
+    }
+
+    @Before
+    public void beforePhotozExampleAdapterTest() {
+        deleteAllCookiesForClientPage();
+    }
+
+    @Override
     public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
         RealmRepresentation realm = loadRealm(new File(TEST_APPS_HOME_DIR + "/photoz/photoz-realm.json"));
 
@@ -104,7 +114,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum("Alice Family Album");
 
             List<ResourceRepresentation> resources = getAuthorizationResource().resources().resources();
@@ -123,10 +133,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
     public void testOnlyOwnerCanDeleteAlbum() throws Exception {
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum("Alice-Family-Album");
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
             this.clientPage.navigateToAdminAlbum();
 
             List<ResourceRepresentation> resources = getAuthorizationResource().resources().resources();
@@ -139,7 +149,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             }
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.deleteAlbum("Alice-Family-Album");
@@ -169,7 +179,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.navigateToAdminAlbum();
             assertTrue(this.clientPage.wasDenied());
         } finally {
@@ -182,7 +192,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
             this.clientPage.navigateToAdminAlbum();
             assertFalse(this.clientPage.wasDenied());
 
@@ -206,10 +216,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum("Alice Family Album");
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
             this.clientPage.navigateToAdminAlbum();
             assertFalse(this.clientPage.wasDenied());
 
@@ -269,10 +279,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum("Alice Family Album");
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
             this.clientPage.navigateToAdminAlbum();
             assertFalse(this.clientPage.wasDenied());
 
@@ -288,10 +298,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             }
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum("Alice Family Album");
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum("Alice Family Album");
             assertFalse(this.clientPage.wasDenied());
@@ -324,7 +334,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             assertFalse(this.clientPage.wasDenied());
 
             UsersResource usersResource = realmsResouce().realm(REALM_NAME).users();
@@ -347,10 +357,10 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
             roleResource.update(roleRepresentation);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             assertTrue(this.clientPage.wasDenied());
 
-            this.clientPage.loginWithScopes("alice", "alice", RESOURCE_SERVER_ID + "/manage-albums");
+            loginToClientPage("alice", "alice", RESOURCE_SERVER_ID + "/manage-albums");
             assertFalse(this.clientPage.wasDenied());
         } finally {
             this.deployer.undeploy(RESOURCE_SERVER_ID);
@@ -362,7 +372,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
 
             assertFalse(this.clientPage.wasDenied());
 
@@ -386,7 +396,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
             manageAlbumRole.update(roleRepresentation);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             assertTrue(this.clientPage.wasDenied());
 
             for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
@@ -405,7 +415,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             }
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             assertFalse(this.clientPage.wasDenied());
         } finally {
             this.deployer.undeploy(RESOURCE_SERVER_ID);
@@ -417,7 +427,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             String resourceName = "My Resource Instance";
             this.clientPage.createAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
@@ -431,7 +441,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
             this.clientPage.createAlbum(resourceName);
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum(resourceName);
@@ -441,7 +451,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
             this.clientPage.deleteAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
 
@@ -466,7 +476,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             });
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum(resourceName);
@@ -476,7 +486,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
             this.clientPage.deleteAlbum(resourceName);
             assertTrue(this.clientPage.wasDenied());
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.deleteAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
 
@@ -493,7 +503,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         try {
             this.deployer.deploy(RESOURCE_SERVER_ID);
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
 
             String resourceName = "My Resource Instance";
             this.clientPage.createAlbum(resourceName);
@@ -508,7 +518,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
 
             this.clientPage.createAlbum(resourceName);
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum(resourceName);
@@ -518,7 +528,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
             this.clientPage.deleteAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.createAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
 
@@ -544,7 +554,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             });
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum(resourceName);
@@ -561,7 +571,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
                 }
             });
 
-            this.clientPage.login("admin", "admin");
+            loginToClientPage("admin", "admin");
 
             this.clientPage.navigateToAdminAlbum();
             this.clientPage.viewAlbum(resourceName);
@@ -571,7 +581,7 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
             this.clientPage.deleteAlbum(resourceName);
             assertTrue(this.clientPage.wasDenied());
 
-            this.clientPage.login("alice", "alice");
+            loginToClientPage("alice", "alice");
             this.clientPage.deleteAlbum(resourceName);
             assertFalse(this.clientPage.wasDenied());
             List<ResourceRepresentation> resources = resourcesResource.resources();
@@ -601,4 +611,17 @@ public abstract class AbstractPhotozExampleAdapterTest extends AbstractExampleAd
         ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
         return clients.get(resourceServer.getId());
     }
+
+    private void deleteAllCookiesForClientPage() {
+        clientPage.navigateTo();
+        driver.manage().deleteAllCookies();
+    }
+    
+    private void loginToClientPage(String username, String password, String... scopes) {
+        // We need to log out by deleting cookies because the log out button sometimes doesn't work in PhantomJS
+        deleteAllCookiesForClientPage();
+        deleteAllCookiesForTestRealm();
+        clientPage.navigateTo();
+        clientPage.login(username, password, scopes);
+    }
 }
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
index 5191e55..083867f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java
@@ -21,6 +21,7 @@ import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
@@ -118,6 +119,13 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
         return servletDeployment(TokenMinTTLPage.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, TokenMinTTLServlet.class, ErrorServlet.class);
     }
 
+    @Before
+    public void beforeDemoServletsAdapterTest() {
+        // Delete all cookies from token-min-ttl page to be sure we are logged out
+        tokenMinTTLPage.navigateTo();
+        driver.manage().deleteAllCookies();
+    }
+
     @Test
     public void testCustomerPortalWithSubsystemSettings() {
         customerPortalSubsystem.navigateTo();