keycloak-aplcache

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/authorization/AbstractPolicyRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/authorization/AbstractPolicyRepresentation.java
index 6d19a84..ddac66d 100644
--- a/core/src/main/java/org/keycloak/representations/idm/authorization/AbstractPolicyRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/authorization/AbstractPolicyRepresentation.java
@@ -118,6 +118,10 @@ public class AbstractPolicyRepresentation {
         return scopes;
     }
 
+    public void setScopes(Set<String> scopes) {
+        this.scopes = scopes;
+    }
+
     public void addScope(String... id) {
         if (this.scopes == null) {
             this.scopes = new HashSet<>();
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java
new file mode 100644
index 0000000..3c4dda8
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AbstractMultipleSelect2.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.fragment;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.jboss.arquillian.graphene.fragment.Root;
+import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public abstract class AbstractMultipleSelect2<R> {
+
+    @Root
+    private WebElement root;
+
+    @Drone
+    private WebDriver driver;
+
+    @FindBy(xpath = ".//input[contains(@class,'select2-input')]")
+    private WebElement search;
+
+    @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
+    private List<WebElement> result;
+
+    public void update(Set<R> values) {
+        Set<R> selection = getSelected();
+
+        for (R value : values) {
+            if (!selection.contains(value)) {
+                select(value);
+            }
+        }
+
+        for (R selected : selection) {
+            boolean isSelected = false;
+
+            for (R value : values) {
+                if (selected.equals(value)) {
+                    isSelected = true;
+                    break;
+                }
+            }
+
+            if (!isSelected) {
+                deselect(selected);
+            }
+        }
+    }
+
+    public void select(R value) {
+        root.click();
+        WaitUtils.pause(500);
+
+        String id = identity().apply(value);
+
+        Actions actions = new Actions(driver);
+        actions.sendKeys(id).perform();
+        WaitUtils.pause(500);
+
+        if (result.isEmpty()) {
+            actions.sendKeys(Keys.ESCAPE).perform();
+            return;
+        }
+
+        for (WebElement result : result) {
+            if (result.getText().equalsIgnoreCase(id)) {
+                result.click();
+                return;
+            }
+        }
+    }
+
+    protected abstract Function<R, String> identity();
+
+    public Set<R> getSelected() {
+        Set<R> values = new HashSet<>();
+
+        for (WebElement selected : getSelectedElements()) {
+            R value = representation().apply(selected);
+
+            if (value != null) {
+                values.add(value);
+            }
+        }
+
+        return values;
+    }
+
+    protected abstract List<WebElement> getSelectedElements();
+
+    protected abstract Function<WebElement, R> representation();
+
+    public void deselect(R value) {
+        onDeselect(value);
+    }
+
+    protected void onDeselect(R value) {
+        for (WebElement selected : getSelectedElements()) {
+            if (deselect().apply(selected, value)) {
+                return;
+            }
+        }
+    }
+
+    protected BiFunction<WebElement, R, Boolean> deselect() {
+        return (selected, value) -> {
+            WebElement selection = selected.findElements(By.tagName("div")).get(0);
+            if (identity().apply(value).equals(selection.getText())) {
+                WebElement element = selected.findElement(By.xpath(".//a[contains(@class,'select2-search-choice-close')]"));
+                JavascriptExecutor executor = (JavascriptExecutor) driver;
+                executor.executeScript("arguments[0].click();", element);
+                WaitUtils.pause(500);
+                return true;
+            }
+            return false;
+        };
+    }
+
+    protected WebElement getRoot() {
+        return root;
+    }
+
+    protected WebDriver getDriver() {
+        return driver;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/MultipleStringSelect2.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/MultipleStringSelect2.java
new file mode 100644
index 0000000..89582c8
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/MultipleStringSelect2.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.fragment;
+
+import java.util.List;
+import java.util.function.Function;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class MultipleStringSelect2 extends AbstractMultipleSelect2<String> {
+
+    @Override
+    protected Function<String, String> identity() {
+        return r -> r.toString();
+    }
+
+    @Override
+    protected List<WebElement> getSelectedElements() {
+        return getRoot().findElements(By.xpath(".//li[contains(@class,'select2-search-choice')]"));
+    }
+
+    @Override
+    protected Function<WebElement, String> representation() {
+        return webElement -> {
+            List<WebElement> element = webElement.findElements(By.tagName("div"));
+
+            if (element.isEmpty()) {
+                return null;
+            }
+
+            String value = element.get(0).getText();
+
+            return "".equals(value) ? null : value;
+        };
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/SingleStringSelect2.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/SingleStringSelect2.java
new file mode 100644
index 0000000..6621622
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/SingleStringSelect2.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.fragment;
+
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebElement;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class SingleStringSelect2 extends AbstractMultipleSelect2<String> {
+
+    @Override
+    protected Function<String, String> identity() {
+        return r -> r.toString();
+    }
+
+    @Override
+    protected List<WebElement> getSelectedElements() {
+        return getRoot().findElements(By.xpath(".//span[contains(@class,'select2-chosen')]"));
+    }
+
+    @Override
+    protected Function<WebElement, String> representation() {
+        return webElement -> {
+            String value = webElement.getText();
+            return "".equals(value) ? null : value;
+        };
+    }
+
+    @Override
+    protected BiFunction<WebElement, String, Boolean> deselect() {
+        return (selected, value) -> {
+            if (identity().apply(value).equals(selected.getText())) {
+                WebElement element = selected.findElement(By.xpath(".//a[contains(@class,'select2-search-choice-close')]"));
+                JavascriptExecutor executor = (JavascriptExecutor) getDriver();
+                executor.executeScript("arguments[0].click();", element);
+                WaitUtils.pause(500);
+                return true;
+            }
+            return false;
+        };
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
index 9900247..a6c9527 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
@@ -22,6 +22,7 @@ import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
 import org.keycloak.representations.idm.authorization.PolicyRepresentation;
 import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
 import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
 import org.keycloak.testsuite.page.Form;
 import org.keycloak.testsuite.util.WaitUtils;
@@ -43,6 +44,9 @@ public class Permissions extends Form {
     @Page
     private ResourcePermission resourcePermission;
 
+    @Page
+    private ScopePermission scopePermission;
+
     public PermissionsTable permissions() {
         return table;
     }
@@ -57,7 +61,9 @@ public class Permissions extends Form {
             resourcePermission.form().save();
             return (P) resourcePermission;
         } else if ("scope".equals(type)) {
-            return null;
+            scopePermission.form().populate((ScopePermissionRepresentation) expected);
+            scopePermission.form().save();
+            return (P) scopePermission;
         }
 
         return null;
@@ -73,6 +79,8 @@ public class Permissions extends Form {
 
                 if ("resource".equals(type)) {
                     resourcePermission.form().populate((ResourcePermissionRepresentation) representation);
+                } else if ("scope".equals(type)) {
+                    scopePermission.form().populate((ScopePermissionRepresentation) representation);
                 }
 
                 return;
@@ -89,6 +97,8 @@ public class Permissions extends Form {
                 String type = actual.getType();
                 if ("resource".equals(type)) {
                     return (P) resourcePermission;
+                } else if ("scope".equals(type)) {
+                    return (P) scopePermission;
                 }
             }
         }
@@ -106,6 +116,8 @@ public class Permissions extends Form {
 
                 if ("resource".equals(type)) {
                     resourcePermission.form().delete();
+                } else if ("scope".equals(type)) {
+                    scopePermission.form().delete();
                 }
 
                 return;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
index 87facb3..cf39523 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
@@ -16,22 +16,12 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.permission;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.jboss.arquillian.graphene.fragment.Root;
 import org.keycloak.representations.idm.authorization.DecisionStrategy;
 import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
+import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
 import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.openqa.selenium.By;
-import org.openqa.selenium.JavascriptExecutor;
-import org.openqa.selenium.Keys;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
@@ -62,10 +52,10 @@ public class ResourcePermissionForm extends Form {
     private WebElement confirmDelete;
 
     @FindBy(id = "s2id_policies")
-    private PolicyInput policyInput;
+    private MultipleStringSelect2 policySelect;
 
     @FindBy(id = "s2id_resources")
-    private ResourceInput resourceInput;
+    private MultipleStringSelect2 resourceSelect;
 
     public void populate(ResourcePermissionRepresentation expected) {
         setInputValue(name, expected.getName());
@@ -78,56 +68,10 @@ public class ResourcePermissionForm extends Form {
             setInputValue(resourceType, expected.getResourceType());
         } else {
             resourceTypeSwitch.setOn(false);
-            Set<String> selectedResources = resourceInput.getSelected();
-            Set<String> resources = expected.getResources();
-
-            for (String resource : resources) {
-                if (!selectedResources.contains(resource)) {
-                    resourceInput.select(resource);
-                }
-            }
-
-            for (String selected : selectedResources) {
-                boolean isSelected = false;
-
-                for (String resource : resources) {
-                    if (selected.equals(resource)) {
-                        isSelected = true;
-                        break;
-                    }
-                }
-
-                if (!isSelected) {
-                    resourceInput.unSelect(selected, driver);
-                }
-            }
+            resourceSelect.update(expected.getResources());
         }
 
-        Set<String> selectedPolicies = policyInput.getSelected();
-        Set<String> policies = expected.getPolicies();
-
-        for (String policy : policies) {
-            if (!selectedPolicies.contains(policy)) {
-                policyInput.select(policy, driver);
-            }
-        }
-
-        for (String selected : selectedPolicies) {
-            boolean isSelected = false;
-
-            for (String policy : policies) {
-                if (selected.equals(policy)) {
-                    isSelected = true;
-                    break;
-                }
-            }
-
-            if (!isSelected) {
-                policyInput.unSelect(selected, driver);
-            }
-        }
-
-        WaitUtils.pause(1000);
+        policySelect.update(expected.getPolicies());
 
         save();
     }
@@ -143,122 +87,15 @@ public class ResourcePermissionForm extends Form {
         representation.setName(getInputValue(name));
         representation.setDescription(getInputValue(description));
         representation.setDecisionStrategy(DecisionStrategy.valueOf(decisionStrategy.getFirstSelectedOption().getText().toUpperCase()));
-        representation.setPolicies(policyInput.getSelected());
-        representation.setResources(resourceInput.getSelected());
-
-        return representation;
-    }
-
-    public class PolicyInput {
-
-        @Root
-        private WebElement root;
-
-        @FindBy(xpath = "//input[contains(@class,'select2-input')]")
-        private WebElement search;
-
-        @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
-        private List<WebElement> result;
-
-        @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
-        private List<WebElement> selection;
-
-        public void select(String name, WebDriver driver) {
-            root.click();
-            WaitUtils.pause(1000);
+        representation.setPolicies(policySelect.getSelected());
+        String inputValue = getInputValue(resourceType);
 
-            Actions actions = new Actions(driver);
-
-            actions.sendKeys(name).perform();
-            WaitUtils.pause(1000);
-
-            if (result.isEmpty()) {
-                actions.sendKeys(Keys.ESCAPE).perform();
-                return;
-            }
-            for (WebElement result : result) {
-                if (result.getText().equalsIgnoreCase(name)) {
-                    result.click();
-                    return;
-                }
-            }
-        }
-
-        public Set<String> getSelected() {
-            HashSet<String> values = new HashSet<>();
-
-            for (WebElement selected : selection) {
-                values.add(selected.findElements(By.tagName("div")).get(0).getText());
-            }
-
-            return values;
+        if (!"".equals(inputValue)) {
+            representation.setResourceType(inputValue);
         }
 
-        public void unSelect(String name, WebDriver driver) {
-            for (WebElement selected : selection) {
-                WebElement selection = selected.findElements(By.tagName("div")).get(0);
-                if (name.equals(selection.getText())) {
-                    WebElement element = selection.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
-                    JavascriptExecutor executor = (JavascriptExecutor) driver;
-                    executor.executeScript("arguments[0].click();", element);
-                    WaitUtils.pause(1000);
-                    return;
-                }
-            }
-        }
-    }
-
-    public class ResourceInput {
-
-        @Root
-        private WebElement root;
-
-        @FindBy(xpath = "//input[contains(@class,'select2-input')]")
-        private WebElement search;
+        representation.setResources(resourceSelect.getSelected());
 
-        @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
-        private List<WebElement> result;
-
-        @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
-        private List<WebElement> selection;
-
-        public void select(String name) {
-            root.click();
-            WaitUtils.pause(1000);
-            setInputValue(search, name);
-            WaitUtils.pause(1000);
-            if (result.isEmpty()) {
-                search.sendKeys(Keys.ESCAPE);
-                return;
-            }
-            for (WebElement result : result) {
-                if (result.getText().equalsIgnoreCase(name)) {
-                    result.click();
-                    return;
-                }
-            }
-        }
-
-        public Set<String> getSelected() {
-            HashSet<String> values = new HashSet<>();
-
-            for (WebElement selected : selection) {
-                values.add(selected.findElements(By.tagName("div")).get(0).getText());
-            }
-
-            return values;
-        }
-
-        public void unSelect(String name, WebDriver driver) {
-            for (WebElement selected : selection) {
-                if (name.equals(selected.findElements(By.tagName("div")).get(0).getText())) {
-                    WebElement element = selected.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
-                    JavascriptExecutor executor = (JavascriptExecutor) driver;
-                    executor.executeScript("arguments[0].click();", element);
-                    WaitUtils.pause(1000);
-                    return;
-                }
-            }
-        }
+        return representation;
     }
 }
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java
new file mode 100644
index 0000000..5b392ad
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.clients.authorization.permission;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class ScopePermission implements PolicyTypeUI {
+
+    @Page
+    private ScopePermissionForm form;
+
+    public ScopePermissionForm form() {
+        return form;
+    }
+
+    public ScopePermissionRepresentation toRepresentation() {
+        return form.toRepresentation();
+    }
+
+    public void update(ScopePermissionRepresentation expected) {
+        form().populate(expected);
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java
new file mode 100644
index 0000000..f16cd5c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.clients.authorization.permission;
+
+import java.util.Set;
+import java.util.function.Function;
+
+import org.keycloak.representations.idm.authorization.DecisionStrategy;
+import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
+import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
+import org.keycloak.testsuite.console.page.fragment.SingleStringSelect2;
+import org.keycloak.testsuite.page.Form;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class ScopePermissionForm extends Form {
+
+    @FindBy(id = "name")
+    private WebElement name;
+
+    @FindBy(id = "description")
+    private WebElement description;
+
+    @FindBy(id = "decisionStrategy")
+    private Select decisionStrategy;
+
+    @FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
+    private WebElement deleteButton;
+
+    @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
+    private WebElement confirmDelete;
+
+    @FindBy(id = "s2id_policies")
+    private MultipleStringSelect2 policySelect;
+
+    @FindBy(id = "s2id_scopes")
+    private MultipleStringSelect2 scopeSelect;
+
+    @FindBy(id = "s2id_resourceScopes")
+    private MultipleStringSelect2 resourceScopeSelect;
+
+    @FindBy(id = "s2id_resources")
+    private ResourceSelect resourceSelect;
+
+    public void populate(ScopePermissionRepresentation expected) {
+        setInputValue(name, expected.getName());
+        setInputValue(description, expected.getDescription());
+        decisionStrategy.selectByValue(expected.getDecisionStrategy().name());
+
+        Set<String> resources = expected.getResources();
+
+        if (resources != null && !resources.isEmpty()) {
+            resourceSelect.update(resources);
+            resourceScopeSelect.update(expected.getScopes());
+        } else {
+            scopeSelect.update(expected.getScopes());
+        }
+
+        policySelect.update(expected.getPolicies());
+
+        save();
+    }
+
+    public void delete() {
+        deleteButton.click();
+        confirmDelete.click();
+    }
+
+    public ScopePermissionRepresentation toRepresentation() {
+        ScopePermissionRepresentation representation = new ScopePermissionRepresentation();
+
+        representation.setName(getInputValue(name));
+        representation.setDescription(getInputValue(description));
+        representation.setDecisionStrategy(DecisionStrategy.valueOf(decisionStrategy.getFirstSelectedOption().getText().toUpperCase()));
+        representation.setPolicies(policySelect.getSelected());
+        representation.setResources(resourceSelect.getSelected());
+        representation.setScopes(scopeSelect.getSelected());
+        representation.getScopes().addAll(resourceScopeSelect.getSelected());
+
+        return representation;
+    }
+
+    public class ResourceSelect extends SingleStringSelect2 {
+        @Override
+        protected Function<WebElement, String> representation() {
+            return super.representation().andThen(s -> "".equals(s) || s.contains("Any resource...") ? null : s);
+        }
+    }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
index c1d5f21..5e7170d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
@@ -16,21 +16,13 @@
  */
 package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
-import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
-import org.jboss.arquillian.graphene.fragment.Root;
 import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
 import org.keycloak.representations.idm.authorization.Logic;
+import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.openqa.selenium.By;
-import org.openqa.selenium.JavascriptExecutor;
-import org.openqa.selenium.Keys;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
@@ -52,7 +44,7 @@ public class AggregatePolicyForm extends Form {
     private WebElement deleteButton;
 
     @FindBy(id = "s2id_policies")
-    private PolicyInput policyInput;
+    private MultipleStringSelect2 policySelect;
 
     @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
     private WebElement confirmDelete;
@@ -62,12 +54,12 @@ public class AggregatePolicyForm extends Form {
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
 
-        Set<String> selectedPolicies = policyInput.getSelected();
+        Set<String> selectedPolicies = policySelect.getSelected();
         Set<String> policies = expected.getPolicies();
 
         for (String policy : policies) {
             if (!selectedPolicies.contains(policy)) {
-                policyInput.select(policy, driver);
+                policySelect.select(policy);
             }
         }
 
@@ -82,7 +74,7 @@ public class AggregatePolicyForm extends Form {
             }
 
             if (!isSelected) {
-                policyInput.unSelect(selected, driver);
+                policySelect.deselect(selected);
             }
         }
 
@@ -100,66 +92,8 @@ public class AggregatePolicyForm extends Form {
         representation.setName(getInputValue(name));
         representation.setDescription(getInputValue(description));
         representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
-        representation.setPolicies(policyInput.getSelected());
+        representation.setPolicies(policySelect.getSelected());
 
         return representation;
     }
-
-    public class PolicyInput {
-
-        @Root
-        private WebElement root;
-
-        @FindBy(xpath = "//input[contains(@class,'select2-input')]")
-        private WebElement search;
-
-        @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
-        private List<WebElement> result;
-
-        @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
-        private List<WebElement> selection;
-
-        public void select(String name, WebDriver driver) {
-            root.click();
-            WaitUtils.pause(1000);
-
-            Actions actions = new Actions(driver);
-
-            actions.sendKeys(name).perform();
-            WaitUtils.pause(1000);
-
-            if (result.isEmpty()) {
-                actions.sendKeys(Keys.ESCAPE).perform();
-                return;
-            }
-            for (WebElement result : result) {
-                if (result.getText().equalsIgnoreCase(name)) {
-                    result.click();
-                    return;
-                }
-            }
-        }
-
-        public Set<String> getSelected() {
-            HashSet<String> values = new HashSet<>();
-
-            for (WebElement selected : selection) {
-                values.add(selected.findElements(By.tagName("div")).get(0).getText());
-            }
-
-            return values;
-        }
-
-        public void unSelect(String name, WebDriver driver) {
-            for (WebElement selected : selection) {
-                if (name.equals(selected.findElements(By.tagName("div")).get(0).getText())) {
-                    WebElement element = selected.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
-                    JavascriptExecutor executor = (JavascriptExecutor) driver;
-                    executor.executeScript("arguments[0].click();", element);
-                    WaitUtils.pause(1000);
-                    return;
-                }
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
index 29ae535..8b6f114 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/RolePolicyForm.java
@@ -18,21 +18,19 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
 import static org.openqa.selenium.By.tagName;
 
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import org.jboss.arquillian.graphene.fragment.Root;
 import org.keycloak.representations.idm.authorization.Logic;
 import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.testsuite.console.page.fragment.AbstractMultipleSelect2;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
-import org.openqa.selenium.Keys;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
@@ -54,13 +52,13 @@ public class RolePolicyForm extends Form {
     private WebElement deleteButton;
 
     @FindBy(id = "s2id_roles")
-    private RolesInput realmRolesInput;
+    private RoleMultipleSelect2 realmRoleSelect;
 
     @FindBy(id = "clients")
     private Select clientsSelect;
 
     @FindBy(id = "s2id_clientRoles")
-    private ClientRolesInput clientRolesInput;
+    private ClientRoleSelect clientRoleSelect;
 
     @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
     private WebElement confirmDelete;
@@ -78,16 +76,16 @@ public class RolePolicyForm extends Form {
             if (clientRole) {
                 String[] parts = role.getId().split("/");
                 clientsSelect.selectByVisibleText(parts[0]);
-                clientRolesInput.select(parts[1], driver);
-                clientRolesInput.setRequired(parts[1], role);
+                clientRoleSelect.select(role);
+                clientRoleSelect.setRequired(role);
             } else {
-                realmRolesInput.select(role.getId(), driver);
-                realmRolesInput.setRequired(role.getId(), role);
+                realmRoleSelect.select(role);
+                realmRoleSelect.setRequired(role);
             }
         }
 
-        unSelect(roles, realmRolesInput.getSelected());
-        unSelect(roles, clientRolesInput.getSelected());
+        unSelect(roles, realmRoleSelect.getSelected());
+        unSelect(roles, clientRoleSelect.getSelected());
 
         save();
     }
@@ -107,9 +105,9 @@ public class RolePolicyForm extends Form {
                 boolean clientRole = selected.getId().indexOf('/') != -1;
 
                 if (clientRole) {
-                    clientRolesInput.unSelect(selected.getId().split("/")[1], driver);
+                    clientRoleSelect.deselect(selected);
                 } else {
-                    realmRolesInput.unSelect(selected.getId(), driver);
+                    realmRoleSelect.deselect(selected);
                 }
             }
         }
@@ -127,144 +125,58 @@ public class RolePolicyForm extends Form {
         representation.setDescription(getInputValue(description));
         representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
 
-        Set<RolePolicyRepresentation.RoleDefinition> roles = realmRolesInput.getSelected();
+        Set<RolePolicyRepresentation.RoleDefinition> roles = realmRoleSelect.getSelected();
 
-        roles.addAll(clientRolesInput.getSelected());
+        roles.addAll(clientRoleSelect.getSelected());
 
         representation.setRoles(roles);
 
         return representation;
     }
 
-    public class RolesInput extends AbstractRolesInput {
-        @Override
-        protected RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds) {
-            RolePolicyRepresentation.RoleDefinition selectedRole = new RolePolicyRepresentation.RoleDefinition();
-            selectedRole.setId(tds.get(0).getText());
-            selectedRole.setRequired(tds.get(1).findElement(By.tagName("input")).isSelected());
-            return selectedRole;
-        }
-
-        @Override
-        protected WebElement getRemoveButton(List<WebElement> tds) {
-            return tds.get(2);
-        }
-
-        @Override
-        protected List<WebElement> getSelectedElements() {
-            return root.findElements(By.xpath("(//table[@id='selected-realm-roles'])/tbody/tr"));
-        }
-
-        @Override
-        protected WebElement getRequiredColumn(List<WebElement> tds) {
-            return tds.get(1);
-        }
-    }
-
-    public class ClientRolesInput extends AbstractRolesInput {
-        @Override
-        protected WebElement getRemoveButton(List<WebElement> tds) {
-            return tds.get(3);
-        }
+    public class RoleMultipleSelect2 extends AbstractMultipleSelect2<RolePolicyRepresentation.RoleDefinition> {
 
         @Override
-        protected RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds) {
-            RolePolicyRepresentation.RoleDefinition selectedRole = new RolePolicyRepresentation.RoleDefinition();
-            selectedRole.setId(tds.get(1).getText() + "/" + tds.get(0).getText());
-            selectedRole.setRequired(tds.get(2).findElement(By.tagName("input")).isSelected());
-            return selectedRole;
+        protected Function<RolePolicyRepresentation.RoleDefinition, String> identity() {
+            return role -> {
+                String id = role.getId();
+                return id.indexOf('/') != -1 ? id.split("/")[1] : id;
+            };
         }
 
         @Override
         protected List<WebElement> getSelectedElements() {
-            return root.findElements(By.xpath("(//table[@id='selected-client-roles'])/tbody/tr"));
+            return getRoot().findElements(By.xpath("(//table[@id='selected-realm-roles'])/tbody/tr")).stream()
+                    .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
+                    .collect(Collectors.toList());
         }
 
         @Override
-        protected WebElement getRequiredColumn(List<WebElement> tds) {
-            return tds.get(2);
-        }
-    }
-
-    public abstract class AbstractRolesInput {
-
-        @Root
-        protected WebElement root;
-
-        @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
-        private List<WebElement> result;
-
-        @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
-        private List<WebElement> selection;
-
-        public void select(String roleId, WebDriver driver) {
-            root.click();
-            WaitUtils.pause(1000);
-
-            Actions actions = new Actions(driver);
-
-            actions.sendKeys(roleId).perform();
-            WaitUtils.pause(1000);
-
-            if (result.isEmpty()) {
-                actions.sendKeys(Keys.ESCAPE).perform();
-                return;
-            }
-
-            for (WebElement result : result) {
-                if (result.getText().equalsIgnoreCase(roleId)) {
-                    result.click();
-                    return;
-                }
-            }
-        }
+        protected Function<WebElement, RolePolicyRepresentation.RoleDefinition> representation() {
+            return webElement -> {
+                List<WebElement> tds = webElement.findElements(tagName("td"));
+                RolePolicyRepresentation.RoleDefinition selectedRole = new RolePolicyRepresentation.RoleDefinition();
+                boolean clientRole = tds.size() == 4;
 
-        public Set<RolePolicyRepresentation.RoleDefinition> getSelected() {
-            List<WebElement> realmRoles = getSelectedElements();
-            Set<RolePolicyRepresentation.RoleDefinition> values = new HashSet<>();
+                selectedRole.setId(clientRole ? tds.get(1).getText() + "/" + tds.get(0).getText() : tds.get(0).getText());
+                selectedRole.setRequired(tds.get(clientRole ? 2 : 1).findElement(By.tagName("input")).isSelected());
 
-            for (WebElement realmRole : realmRoles) {
-                List<WebElement> tds = realmRole.findElements(tagName("td"));
-                if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
-                    values.add(getSelectedRoles(tds));
-                }
-            }
-
-            return values;
+                return selectedRole;
+            };
         }
 
-        protected abstract RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds);
-
-        protected abstract List<WebElement> getSelectedElements();
-
-        public void unSelect(String name, WebDriver driver) {
+        public void setRequired(RolePolicyRepresentation.RoleDefinition role) {
             Iterator<WebElement> iterator = getSelectedElements().iterator();
 
             while (iterator.hasNext()) {
                 WebElement realmRole = iterator.next();
                 List<WebElement> tds = realmRole.findElements(tagName("td"));
+                boolean clientRole = role.getId().indexOf("/") != -1;
+                WebElement roleName = tds.get(0);
 
-                if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
-                    if (tds.get(0).getText().equals(name)) {
-                        getRemoveButton(tds).findElement(By.tagName("button")).click();
-                        return;
-                    }
-                }
-            }
-        }
-
-        protected abstract WebElement getRemoveButton(List<WebElement> tds);
-
-        public void setRequired(String name, RolePolicyRepresentation.RoleDefinition role) {
-            Iterator<WebElement> iterator = getSelectedElements().iterator();
-
-            while (iterator.hasNext()) {
-                WebElement realmRole = iterator.next();
-                List<WebElement> tds = realmRole.findElements(tagName("td"));
-
-                if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
-                    if (tds.get(0).getText().equals(name)) {
-                        WebElement required = getRequiredColumn(tds).findElement(By.tagName("input"));
+                if (!roleName.getText().isEmpty()) {
+                    if (roleName.getText().equals(getRoleId(role, clientRole))) {
+                        WebElement required = tds.get(clientRole ? 2 : 1).findElement(By.tagName("input"));
 
                         if (required.isSelected() && role.isRequired()) {
                             return;
@@ -279,6 +191,34 @@ public class RolePolicyForm extends Form {
             }
         }
 
-        protected abstract WebElement getRequiredColumn(List<WebElement> tds);
+        @Override
+        protected BiFunction<WebElement, RolePolicyRepresentation.RoleDefinition, Boolean> deselect() {
+            return (webElement, roleDefinition) -> {
+                List<WebElement> tds = webElement.findElements(tagName("td"));
+                boolean clientRole = tds.size() == 4;
+
+                if (!tds.get(0).getText().isEmpty()) {
+                    if (tds.get(0).getText().equals(getRoleId(roleDefinition, clientRole))) {
+                        tds.get(clientRole ? 3 : 2).findElement(By.tagName("button")).click();
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+        }
+
+        private String getRoleId(RolePolicyRepresentation.RoleDefinition roleDefinition, boolean clientRole) {
+            return clientRole ? roleDefinition.getId().split("/")[1] : roleDefinition.getId();
+        }
+    }
+
+    public class ClientRoleSelect extends RoleMultipleSelect2 {
+        @Override
+        protected List<WebElement> getSelectedElements() {
+            return getRoot().findElements(By.xpath("(//table[@id='selected-client-roles'])/tbody/tr")).stream()
+                    .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
+                    .collect(Collectors.toList());
+        }
     }
 }
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
index 46caad0..e403d1b 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/UserPolicyForm.java
@@ -18,21 +18,17 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
 
 import static org.openqa.selenium.By.tagName;
 
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import org.jboss.arquillian.graphene.fragment.Root;
 import org.keycloak.representations.idm.authorization.Logic;
 import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.WaitUtils;
 import org.openqa.selenium.By;
-import org.openqa.selenium.Keys;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
@@ -54,7 +50,7 @@ public class UserPolicyForm extends Form {
     private WebElement deleteButton;
 
     @FindBy(id = "s2id_users")
-    private UsersInput usersInput;
+    private UserSelect usersInput;
 
     @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
     private WebElement confirmDelete;
@@ -64,34 +60,11 @@ public class UserPolicyForm extends Form {
         setInputValue(description, expected.getDescription());
         logic.selectByValue(expected.getLogic().name());
 
-        Set<String> users = expected.getUsers();
-
-        for (String user : users) {
-            usersInput.select(user, driver);
-        }
-
-        unSelect(users, usersInput.getSelected());
+        usersInput.update(expected.getUsers());
 
         save();
     }
 
-    private void unSelect(Set<String> users, Set<String> selection) {
-        for (String selected : selection) {
-            boolean isSelected = false;
-
-            for (String user : users) {
-                if (selected.equals(user)) {
-                    isSelected = true;
-                    break;
-                }
-            }
-
-            if (!isSelected) {
-                usersInput.unSelect(selected, driver);
-            }
-        }
-    }
-
     public void delete() {
         deleteButton.click();
         confirmDelete.click();
@@ -108,83 +81,34 @@ public class UserPolicyForm extends Form {
         return representation;
     }
 
-    public class UsersInput extends AbstractUserInput {
-        @Override
-        protected WebElement getRemoveButton(List<WebElement> tds) {
-            return tds.get(1);
-        }
+    public class UserSelect extends MultipleStringSelect2 {
 
         @Override
         protected List<WebElement> getSelectedElements() {
-            return root.findElements(By.xpath("(//table[@id='selected-users'])/tbody/tr"));
-        }
-    }
-
-    public abstract class AbstractUserInput {
-
-        @Root
-        protected WebElement root;
-
-        @FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
-        private List<WebElement> result;
-
-        @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
-        private List<WebElement> selection;
-
-        public void select(String roleId, WebDriver driver) {
-            root.click();
-            WaitUtils.pause(1000);
-
-            Actions actions = new Actions(driver);
-
-            actions.sendKeys(roleId).perform();
-            WaitUtils.pause(1000);
-
-            if (result.isEmpty()) {
-                actions.sendKeys(Keys.ESCAPE).perform();
-                return;
-            }
-
-            for (WebElement result : result) {
-                if (result.getText().equalsIgnoreCase(roleId)) {
-                    result.click();
-                    return;
-                }
-            }
+            return getRoot().findElements(By.xpath("(//table[@id='selected-users'])/tbody/tr")).stream()
+                    .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
+                    .collect(Collectors.toList());
         }
 
-        public Set<String> getSelected() {
-            List<WebElement> users = getSelectedElements();
-            Set<String> values = new HashSet<>();
-
-            for (WebElement user : users) {
-                List<WebElement> tds = user.findElements(tagName("td"));
-                if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
-                    values.add(tds.get(0).getText());
-                }
-            }
-
-            return values;
-        }
-
-        protected abstract List<WebElement> getSelectedElements();
-
-        public void unSelect(String name, WebDriver driver) {
-            Iterator<WebElement> iterator = getSelectedElements().iterator();
-
-            while (iterator.hasNext()) {
-                WebElement realmRole = iterator.next();
-                List<WebElement> tds = realmRole.findElements(tagName("td"));
+        @Override
+        protected BiFunction<WebElement, String, Boolean> deselect() {
+            return (webElement, name) -> {
+                List<WebElement> tds = webElement.findElements(tagName("td"));
 
-                if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
+                if (!tds.get(0).getText().isEmpty()) {
                     if (tds.get(0).getText().equals(name)) {
-                        getRemoveButton(tds).findElement(By.tagName("button")).click();
-                        return;
+                        tds.get(1).findElement(By.tagName("button")).click();
+                        return true;
                     }
                 }
-            }
+
+                return false;
+            };
         }
 
-        protected abstract WebElement getRemoveButton(List<WebElement> tds);
+        @Override
+        protected Function<WebElement, String> representation() {
+            return webElement -> webElement.findElements(tagName("td")).get(0).getText();
+        }
     }
 }
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
index 2051ac3..2299200 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
@@ -79,7 +79,7 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
         authorizationPage.navigateTo();
         AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
 
-        expected.setName("Test Aggregate Policy");
+        expected.setName("Test Update Aggregate Policy");
         expected.setDescription("description");
         expected.addPolicy("Policy A");
         expected.addPolicy("Policy B");
@@ -89,11 +89,11 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
 
         String previousName = expected.getName();
 
-        expected.setName("Changed Test Aggregate Policy");
+        expected.setName("Changed Test Update Aggregate Policy");
         expected.setDescription("Changed description");
         expected.setLogic(Logic.NEGATIVE);
-
-        expected.setPolicies(expected.getPolicies().stream().filter(policy -> !policy.equals("Policy B")).collect(Collectors.toSet()));
+        expected.getPolicies().clear();
+        expected.addPolicy("Policy A", "Policy C");
 
         authorizationPage.navigateTo();
         authorizationPage.authorizationTabs().policies().update(previousName, expected);
@@ -106,11 +106,11 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
     }
 
     @Test
-    public void testDeletePolicy() throws InterruptedException {
+    public void testDelete() throws InterruptedException {
         authorizationPage.navigateTo();
         AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
 
-        expected.setName("Test Aggregate Policy");
+        expected.setName("Test Delete Aggregate Policy");
         expected.setDescription("description");
         expected.addPolicy("Policy C");
 
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
index fffce15..0b9113c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
@@ -58,7 +58,7 @@ public class JSPolicyManagementTest extends AbstractAuthorizationSettingsTest {
     }
 
     @Test
-    public void testDeletePolicy() throws InterruptedException {
+    public void testDelete() throws InterruptedException {
         authorizationPage.navigateTo();
         JSPolicyRepresentation expected = new JSPolicyRepresentation();
 
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
index a4ab7ef..7eb6a94 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
@@ -101,7 +101,8 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
         expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
         expected.getResources().clear();
         expected.addResource("Resource B");
-        expected.setPolicies(expected.getPolicies().stream().filter(policy -> !policy.equals("Policy B")).collect(Collectors.toSet()));
+        expected.getPolicies().clear();
+        expected.addPolicy("Policy A", "Policy C");
 
         authorizationPage.navigateTo();
         authorizationPage.authorizationTabs().permissions().update(previousName, expected);
@@ -118,7 +119,7 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
         authorizationPage.navigateTo();
         ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
 
-        expected.setName("Test Resource B Permission");
+        expected.setName("Test Resource B Type Permission");
         expected.setDescription("description");
         expected.setResourceType("test-resource-type");
         expected.addPolicy("Policy A");
@@ -129,7 +130,7 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
 
         String previousName = expected.getName();
 
-        expected.setName("Changed Test Resource B Permission");
+        expected.setName("Changed Test Resource B Type Permission");
         expected.setDescription("Changed description");
         expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
 
@@ -147,7 +148,7 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
     }
 
     @Test
-    public void testDeletePolicy() throws InterruptedException {
+    public void testDelete() throws InterruptedException {
         authorizationPage.navigateTo();
         ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
 
@@ -175,7 +176,16 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
 
         assertEquals(expected.getName(), actual.getName());
         assertEquals(expected.getDescription(), actual.getDescription());
-        assertEquals(expected.getLogic(), actual.getLogic());
+        assertEquals(expected.getDecisionStrategy(), actual.getDecisionStrategy());
+        assertEquals(expected.getResourceType(), actual.getResourceType());
+        assertEquals(0, actual.getPolicies().stream().filter(actualPolicy -> !expected.getPolicies().stream()
+                .filter(expectedPolicy -> actualPolicy.equals(expectedPolicy))
+                .findFirst().isPresent())
+                .count());
+        assertEquals(0, actual.getResources().stream().filter(actualResource -> !expected.getResources().stream()
+                .filter(expectedResource -> actualResource.equals(expectedResource))
+                .findFirst().isPresent())
+                .count());
 
         return actual;
     }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
index 713b93a..44e4f70 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
@@ -55,7 +55,7 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest 
         authorizationPage.navigateTo();
         RolePolicyRepresentation expected = new RolePolicyRepresentation();
 
-        expected.setName("Test Realm Role Policy");
+        expected.setName("Test Update Realm Role Policy");
         expected.setDescription("description");
         expected.addRole("Realm Role A");
         expected.addRole("Realm Role B");
@@ -100,7 +100,7 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest 
         authorizationPage.navigateTo();
         RolePolicyRepresentation expected = new RolePolicyRepresentation();
 
-        expected.setName("Test Client Role Policy");
+        expected.setName("Test Update Client Role Policy");
         expected.setDescription("description");
 
         String clientId = newClient.getClientId();
@@ -113,7 +113,7 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest 
 
         String previousName = expected.getName();
 
-        expected.setName("Changed Test Client Role Policy");
+        expected.setName("Changed Test Update Client Role Policy");
         expected.setDescription("Changed description");
 
         expected.setRoles(expected.getRoles().stream().filter(roleDefinition -> !roleDefinition.getId().contains("Client Role B")).collect(Collectors.toSet()));
@@ -190,11 +190,11 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest 
     }
 
     @Test
-    public void testDeletePolicy() throws InterruptedException {
+    public void testDelete() throws InterruptedException {
         authorizationPage.navigateTo();
         RolePolicyRepresentation expected = new RolePolicyRepresentation();
 
-        expected.setName("Test Realm Role Policy");
+        expected.setName("Test Delete Role Policy");
         expected.setDescription("description");
         expected.addRole("Realm Role A");
         expected.addRole("Realm Role B");
@@ -224,7 +224,7 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest 
         assertNotNull(actual.getRoles());
         assertEquals(expected.getRoles().size(), actual.getRoles().size());
         assertEquals(0, actual.getRoles().stream().filter(actualDefinition -> !expected.getRoles().stream()
-                .filter(roleDefinition -> actualDefinition.getId().contains(roleDefinition.getId()) && actualDefinition.isRequired() == roleDefinition.isRequired())
+                .filter(roleDefinition -> actualDefinition.getId().contains(roleDefinition.getId().indexOf("/") != -1 ? roleDefinition.getId().split("/")[1] : roleDefinition.getId()) && actualDefinition.isRequired() == roleDefinition.isRequired())
                 .findFirst().isPresent())
                 .count());
         return actual;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
new file mode 100644
index 0000000..7852c20
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.authorization;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.AuthorizationResource;
+import org.keycloak.admin.client.resource.PoliciesResource;
+import org.keycloak.admin.client.resource.ResourcesResource;
+import org.keycloak.admin.client.resource.RolePoliciesResource;
+import org.keycloak.admin.client.resource.RolesResource;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.authorization.DecisionStrategy;
+import org.keycloak.representations.idm.authorization.ResourceRepresentation;
+import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.ScopeRepresentation;
+import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.console.page.clients.authorization.permission.ResourcePermission;
+import org.keycloak.testsuite.console.page.clients.authorization.permission.ScopePermission;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class ScopePermissionManagementTest extends AbstractAuthorizationSettingsTest {
+
+    @Before
+    public void configureTest() {
+        super.configureTest();
+        RolesResource realmRoles = testRealmResource().roles();
+        realmRoles.create(new RoleRepresentation("Role A", "", false));
+        realmRoles.create(new RoleRepresentation("Role B", "", false));
+
+        RolePolicyRepresentation policyA = new RolePolicyRepresentation();
+
+        policyA.setName("Policy A");
+        policyA.addRole("Role A");
+
+        AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
+        PoliciesResource policies = authorization.policies();
+        RolePoliciesResource roles = policies.roles();
+
+        roles.create(policyA);
+
+        RolePolicyRepresentation policyB = new RolePolicyRepresentation();
+
+        policyB.setName("Policy B");
+        policyB.addRole("Role B");
+
+        roles.create(policyB);
+
+        UserPolicyRepresentation policyC = new UserPolicyRepresentation();
+
+        policyC.setName("Policy C");
+        policyC.addUser("test");
+
+        policies.users().create(policyC);
+
+        authorization.scopes().create(new ScopeRepresentation("Scope A"));
+        authorization.scopes().create(new ScopeRepresentation("Scope B"));
+        authorization.scopes().create(new ScopeRepresentation("Scope C"));
+
+        ResourcesResource resources = authorization.resources();
+
+        resources.create(new ResourceRepresentation("Resource A", "Scope A"));
+        resources.create(new ResourceRepresentation("Resource B", "Scope B", "Scope C"));
+    }
+
+    @Test
+    public void testUpdateScopeOnly() throws InterruptedException {
+        authorizationPage.navigateTo();
+        ScopePermissionRepresentation expected = new ScopePermissionRepresentation();
+
+        expected.setName("Test Scope Only Permission");
+        expected.setDescription("description");
+        expected.addScope("Scope C", "Scope A", "Scope B");
+        expected.addPolicy("Policy C", "Policy A", "Policy B");
+
+        expected = createPermission(expected);
+
+        String previousName = expected.getName();
+
+        expected.setName(previousName + "Changed");
+        expected.setDescription("changed");
+        expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
+        expected.getScopes().clear();
+        expected.addScope("Scope B");
+        expected.getPolicies().clear();
+        expected.addPolicy("Policy C");
+
+        authorizationPage.navigateTo();
+        authorizationPage.authorizationTabs().permissions().update(previousName, expected);
+        assertAlertSuccess();
+
+        authorizationPage.navigateTo();
+        ScopePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+        assertPolicy(expected, actual);
+    }
+
+    @Test
+    public void testUpdateResourceScope() throws InterruptedException {
+        authorizationPage.navigateTo();
+        ScopePermissionRepresentation expected = new ScopePermissionRepresentation();
+
+        expected.setName("Test Resource Scope Permission");
+        expected.setDescription("description");
+        expected.addResource("Resource A");
+        expected.addScope("Scope A");
+        expected.addPolicy("Policy C", "Policy A", "Policy B");
+
+        expected = createPermission(expected);
+
+        String previousName = expected.getName();
+
+        expected.setName(previousName + "Changed");
+        expected.setDescription("changed");
+        expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
+        expected.getResources().clear();
+        expected.addResource("Resource B");
+        expected.getScopes().clear();
+        expected.addScope("Scope B", "Scope C");
+        expected.getPolicies().clear();
+        expected.addPolicy("Policy C");
+
+        authorizationPage.navigateTo();
+        authorizationPage.authorizationTabs().permissions().update(previousName, expected);
+        assertAlertSuccess();
+
+        authorizationPage.navigateTo();
+        ScopePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+        assertPolicy(expected, actual);
+    }
+
+    @Test
+    public void testDelete() throws InterruptedException {
+        authorizationPage.navigateTo();
+        ScopePermissionRepresentation expected = new ScopePermissionRepresentation();
+
+        expected.setName("Test Delete Scope Permission");
+        expected.setDescription("description");
+        expected.addScope("Scope C");
+        expected.addPolicy("Policy C");
+
+        expected = createPermission(expected);
+        authorizationPage.navigateTo();
+        authorizationPage.authorizationTabs().permissions().delete(expected.getName());
+        assertAlertSuccess();
+        authorizationPage.navigateTo();
+        assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
+    }
+
+    private ScopePermissionRepresentation createPermission(ScopePermissionRepresentation expected) {
+        ScopePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
+        assertAlertSuccess();
+        return assertPolicy(expected, policy);
+    }
+
+    private ScopePermissionRepresentation assertPolicy(ScopePermissionRepresentation expected, ScopePermission policy) {
+        ScopePermissionRepresentation actual = policy.toRepresentation();
+
+        assertEquals(expected.getName(), actual.getName());
+        assertEquals(expected.getDescription(), actual.getDescription());
+        assertEquals(expected.getDecisionStrategy(), actual.getDecisionStrategy());
+
+        assertEquals(expected.getPolicies().size(), actual.getPolicies().size());
+        assertEquals(0, actual.getPolicies().stream().filter(actualPolicy -> !expected.getPolicies().stream()
+                .filter(expectedPolicy -> actualPolicy.equals(expectedPolicy))
+                .findFirst().isPresent())
+                .count());
+
+        if (expected.getResources() != null) {
+            assertEquals(expected.getResources().size(), actual.getResources().size());
+            assertEquals(0, actual.getResources().stream().filter(actualResource -> !expected.getResources().stream()
+                    .filter(expectedResource -> actualResource.equals(expectedResource))
+                    .findFirst().isPresent())
+                    .count());
+        }
+
+        assertEquals(expected.getScopes().size(), actual.getScopes().size());
+        assertEquals(0, actual.getScopes().stream().filter(actualScope -> !expected.getScopes().stream()
+                .filter(expectedScope -> actualScope.equals(expectedScope))
+                .findFirst().isPresent())
+                .count());
+
+        return actual;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
index 9e9d2e8..6242c77 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
@@ -82,7 +82,7 @@ public class TimePolicyManagementTest extends AbstractAuthorizationSettingsTest 
     }
 
     @Test
-    public void testDeletePolicy() throws InterruptedException {
+    public void testDelete() throws InterruptedException {
         authorizationPage.navigateTo();
         TimePolicyRepresentation expected = new TimePolicyRepresentation();
 
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
index 5da3a12..cce7e24 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
@@ -29,18 +29,18 @@
                 <kc-tooltip>{{:: 'authz-permission-description.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
-                <label class="col-md-2 control-label" for="reqActions">{{:: 'authz-resource' | translate}}</label>
+                <label class="col-md-2 control-label" for="resources">{{:: 'authz-resource' | translate}}</label>
 
                 <div class="col-md-6">
-                    <input type="hidden" ui-select2="resourcesUiSelect" data-ng-change="selectResource()" id="reqActions" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-any-resource' | translate}}..." />
+                    <input type="hidden" ui-select2="resourcesUiSelect" data-ng-change="selectResource()" id="resources" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-any-resource' | translate}}..." />
                 </div>
                 <kc-tooltip>{{:: 'authz-permission-scope-resource.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix" data-ng-show="selectedResource">
-                <label class="col-md-2 control-label" for="reqActions">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label>
+                <label class="col-md-2 control-label" for="resourceScopes">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label>
 
                 <div class="col-md-6">
-                    <select ui-select2 id="reqActions2"
+                    <select ui-select2 id="resourceScopes"
                             data-ng-model="selectedScopes"
                             data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple
                             data-ng-required="selectedResource != null">
@@ -50,27 +50,27 @@
                 <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix" data-ng-show="!selectedResource">
-                <label class="col-md-2 control-label" for="reqActions">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label>
+                <label class="col-md-2 control-label" for="scopes">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label>
 
                 <div class="col-md-6">
-                    <input type="hidden" ui-select2="scopesUiSelect" id="reqActions" data-ng-model="selectedScopes" data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple data-ng-required="selectedResource == null" />
+                    <input type="hidden" ui-select2="scopesUiSelect" id="scopes" data-ng-model="selectedScopes" data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple data-ng-required="selectedResource == null" />
                 </div>
                 <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
-                <label class="col-md-2 control-label" for="reqActions">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
+                <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
 
                 <div class="col-md-6">
-                    <input type="hidden" ui-select2="policiesUiSelect" id="reqActions" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
+                    <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
                 </div>
 
                 <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
             </div>
             <div class="form-group clearfix">
-                <label class="col-md-2 control-label" for="policy.decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label>
+                <label class="col-md-2 control-label" for="decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label>
 
                 <div class="col-sm-2">
-                    <select class="form-control" id="policy.decisionStrategy"
+                    <select class="form-control" id="decisionStrategy"
                             data-ng-model="policy.decisionStrategy"
                             ng-change="selectDecisionStrategy()">
                         <option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option>