Merge pull request #4222 from vmuzikar/KEYCLOAK-5055

KEYCLOAK-4787, KEYCLOAK-5055 Stabilize UI tests
This commit is contained in:
Pavel Drozd 2017-06-27 11:42:21 +02:00 committed by GitHub
commit 947254e14f
18 changed files with 67 additions and 58 deletions

View file

@ -262,6 +262,8 @@ The UI tests are focused on the Admin Console as well as on some login scenarios
The tests also use some constants placed in [test-constants.properties](tests/base/src/test/resources/test-constants.properties). A different file can be specified by `-Dtestsuite.constants=path/to/different-test-constants.properties`
In case a custom `settings.xml` is used for Maven, you need to specify it also in `-Dkie.maven.settings.custom=path/to/settings.xml`.
#### Execution example
```
mvn -f testsuite/integration-arquillian/tests/other/console/pom.xml \

View file

@ -16,7 +16,9 @@
*/
package org.keycloak.testsuite.console.page.fragment;
import org.jboss.arquillian.graphene.fragment.Root;
import org.keycloak.testsuite.page.AbstractAlert;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -44,6 +46,9 @@ public class AdminConsoleAlert extends AbstractAlert {
public void close() {
closeButton.click();
WaitUtils.pause(500); // Sometimes, when a test is too fast,
// one of the consecutive alerts is not displayed;
// to prevent this we need to slow down a bit
}
}

View file

@ -25,6 +25,7 @@ import org.keycloak.representations.idm.authorization.ResourcePermissionRepresen
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.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -58,11 +59,9 @@ public class Permissions extends Form {
if ("resource".equals(type)) {
resourcePermission.form().populate((ResourcePermissionRepresentation) expected);
resourcePermission.form().save();
return (P) resourcePermission;
} else if ("scope".equals(type)) {
scopePermission.form().populate((ScopePermissionRepresentation) expected);
scopePermission.form().save();
return (P) scopePermission;
}
@ -73,7 +72,7 @@ public class Permissions extends Form {
for (WebElement row : permissions().rows()) {
PolicyRepresentation actual = permissions().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
String type = representation.getType();
@ -92,7 +91,7 @@ public class Permissions extends Form {
for (WebElement row : permissions().rows()) {
PolicyRepresentation actual = permissions().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
String type = actual.getType();
if ("resource".equals(type)) {
@ -109,7 +108,7 @@ public class Permissions extends Form {
for (WebElement row : permissions().rows()) {
PolicyRepresentation actual = permissions().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
String type = actual.getType();

View file

@ -18,6 +18,7 @@ package org.keycloak.testsuite.console.page.clients.authorization.permission;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
import org.keycloak.testsuite.page.Form;
@ -48,8 +49,8 @@ public class ResourcePermissionForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
@FindBy(id = "s2id_policies")
private MultipleStringSelect2 policySelect;
@ -78,7 +79,7 @@ public class ResourcePermissionForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public ResourcePermissionRepresentation toRepresentation() {

View file

@ -21,6 +21,7 @@ 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.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.console.page.fragment.SingleStringSelect2;
import org.keycloak.testsuite.page.Form;
@ -45,8 +46,8 @@ public class ScopePermissionForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
@FindBy(id = "s2id_policies")
private MultipleStringSelect2 policySelect;
@ -81,7 +82,7 @@ public class ScopePermissionForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public ScopePermissionRepresentation toRepresentation() {

View file

@ -20,6 +20,7 @@ import java.util.Set;
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.WebElement;
@ -46,8 +47,8 @@ public class AggregatePolicyForm extends Form {
@FindBy(id = "s2id_policies")
private MultipleStringSelect2 policySelect;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(AggregatePolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -83,7 +84,7 @@ public class AggregatePolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public AggregatePolicyRepresentation toRepresentation() {

View file

@ -25,6 +25,7 @@ import java.util.stream.Collectors;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.By;
@ -52,8 +53,8 @@ public class ClientPolicyForm extends Form {
@FindBy(id = "s2id_clients")
private ClientSelect clientsInput;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(ClientPolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -67,7 +68,7 @@ public class ClientPolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public ClientPolicyRepresentation toRepresentation() {

View file

@ -18,6 +18,7 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
@ -41,8 +42,8 @@ public class JSPolicyForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(JSPolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -58,7 +59,7 @@ public class JSPolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public JSPolicyRepresentation toRepresentation() {

View file

@ -30,6 +30,7 @@ import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -81,31 +82,24 @@ public class Policies extends Form {
if ("role".equals(type)) {
rolePolicy.form().populate((RolePolicyRepresentation) expected);
rolePolicy.form().save();
return (P) rolePolicy;
} else if ("user".equals(type)) {
userPolicy.form().populate((UserPolicyRepresentation) expected);
userPolicy.form().save();
return (P) userPolicy;
} else if ("aggregate".equals(type)) {
aggregatePolicy.form().populate((AggregatePolicyRepresentation) expected);
aggregatePolicy.form().save();
return (P) aggregatePolicy;
} else if ("js".equals(type)) {
jsPolicy.form().populate((JSPolicyRepresentation) expected);
jsPolicy.form().save();
return (P) jsPolicy;
} else if ("time".equals(type)) {
timePolicy.form().populate((TimePolicyRepresentation) expected);
timePolicy.form().save();
return (P) timePolicy;
} else if ("rules".equals(type)) {
rulePolicy.form().populate((RulePolicyRepresentation) expected);
rulePolicy.form().save();
return (P) rulePolicy;
} else if ("client".equals(type)) {
clientPolicy.form().populate((ClientPolicyRepresentation) expected);
clientPolicy.form().save();
return (P) clientPolicy;
} else if ("group".equals(type)) {
groupPolicy.form().populate((GroupPolicyRepresentation) expected);
@ -120,7 +114,7 @@ public class Policies extends Form {
for (WebElement row : policies().rows()) {
PolicyRepresentation actual = policies().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
String type = representation.getType();
@ -151,8 +145,7 @@ public class Policies extends Form {
for (WebElement row : policies().rows()) {
PolicyRepresentation actual = policies().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
WaitUtils.waitForPageToLoad(driver);
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
String type = actual.getType();
if ("role".equals(type)) {
return (P) rolePolicy;
@ -180,8 +173,7 @@ public class Policies extends Form {
for (WebElement row : policies().rows()) {
PolicyRepresentation actual = policies().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
WaitUtils.waitForPageToLoad(driver);
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
String type = actual.getType();

View file

@ -28,6 +28,7 @@ import java.util.stream.Collectors;
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.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
@ -60,8 +61,8 @@ public class RolePolicyForm extends Form {
@FindBy(id = "s2id_clientRoles")
private ClientRoleSelect clientRoleSelect;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(RolePolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -115,7 +116,7 @@ public class RolePolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public RolePolicyRepresentation toRepresentation() {

View file

@ -18,6 +18,7 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
@ -62,8 +63,8 @@ public class RulePolicyForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
@FindBy(id = "resolveModule")
private WebElement resolveModuleButton;
@ -92,7 +93,7 @@ public class RulePolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public RulePolicyRepresentation toRepresentation() {

View file

@ -18,6 +18,7 @@ package org.keycloak.testsuite.console.page.clients.authorization.policy;
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -77,8 +78,8 @@ public class TimePolicyForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(TimePolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -102,7 +103,7 @@ public class TimePolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public TimePolicyRepresentation toRepresentation() {

View file

@ -25,6 +25,7 @@ import java.util.stream.Collectors;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.By;
@ -52,8 +53,8 @@ public class UserPolicyForm extends Form {
@FindBy(id = "s2id_users")
private UserSelect usersInput;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(UserPolicyRepresentation expected) {
setInputValue(name, expected.getName());
@ -67,7 +68,7 @@ public class UserPolicyForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public UserPolicyRepresentation toRepresentation() {

View file

@ -23,6 +23,7 @@ import java.util.Set;
import org.jboss.arquillian.graphene.fragment.Root;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.By;
@ -54,8 +55,8 @@ public class ResourceForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
@FindBy(id = "s2id_scopes")
private ScopesInput scopesInput;
@ -94,7 +95,7 @@ public class ResourceForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
public ResourceRepresentation toRepresentation() {

View file

@ -21,6 +21,7 @@ import static org.openqa.selenium.By.tagName;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -52,7 +53,7 @@ public class Resources extends Form {
for (WebElement row : resources().rows()) {
ResourceRepresentation actual = resources().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
resource.form().populate(representation);
return;
@ -64,7 +65,7 @@ public class Resources extends Form {
for (WebElement row : resources().rows()) {
ResourceRepresentation actual = resources().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
resource.form().delete();
return;
@ -76,7 +77,7 @@ public class Resources extends Form {
for (WebElement row : resources().rows()) {
ResourceRepresentation actual = resources().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
WaitUtils.waitForPageToLoad(driver);
return resource;
}

View file

@ -17,6 +17,7 @@
package org.keycloak.testsuite.console.page.clients.authorization.scope;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -35,8 +36,8 @@ public class ScopeForm extends Form {
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
@FindBy(xpath = "//div[@class='modal-dialog']")
protected ModalDialog modalDialog;
public void populate(ScopeRepresentation expected) {
setInputValue(name, expected.getName());
@ -46,6 +47,6 @@ public class ScopeForm extends Form {
public void delete() {
deleteButton.click();
confirmDelete.click();
modalDialog.confirmDeletion();
}
}

View file

@ -21,6 +21,7 @@ import static org.openqa.selenium.By.tagName;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@ -51,7 +52,7 @@ public class Scopes extends Form {
for (WebElement row : scopes().rows()) {
ScopeRepresentation actual = scopes().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
scope.form().populate(representation);
}
}
@ -61,7 +62,7 @@ public class Scopes extends Form {
for (WebElement row : scopes().rows()) {
ScopeRepresentation actual = scopes().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
row.findElements(tagName("a")).get(0).click();
URLUtils.navigateToUri(driver, row.findElements(tagName("a")).get(0).getAttribute("href"), true);
scope.form().delete();
}
}

View file

@ -23,6 +23,7 @@ package org.keycloak.testsuite.console.clients;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
@ -92,7 +93,6 @@ public class ClientMappersOIDCTest extends AbstractClientTest {
assertEquals("oidc-hardcoded-role-mapper", found.getProtocolMapper());
Map<String, String> config = found.getConfig();
assertEquals(1, config.size());
assertEquals("offline_access", config.get("role"));
//edit
@ -164,8 +164,6 @@ public class ClientMappersOIDCTest extends AbstractClientTest {
assertEquals("oidc-usersessionmodel-note-mapper", found.getProtocolMapper());
Map<String, String> config = found.getConfig();
assertNull(config.get("id.token.claim"));
assertNull(config.get("access.token.claim"));
assertEquals("claim name", config.get("claim.name"));
assertEquals("session note", config.get("user.session.note"));
assertEquals("int", config.get("jsonType.label"));