mirror of
https://github.com/keycloak/keycloak.git
synced 2026-06-03 22:03:16 -04:00
Test Framework - support for multiple WebDriver instances. (#46982)
Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
parent
0466955604
commit
e351d5949b
9 changed files with 135 additions and 23 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package org.keycloak.testframework.oauth;
|
||||
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.client.registration.ClientRegistration;
|
||||
import org.keycloak.testframework.ui.page.LoginPage;
|
||||
import org.keycloak.testframework.ui.webdriver.ManagedWebDriver;
|
||||
|
|
@ -17,15 +18,21 @@ import org.openqa.selenium.support.PageFactory;
|
|||
public class OAuthClient extends AbstractOAuthClient<OAuthClient> {
|
||||
|
||||
private final ManagedWebDriver managedWebDriver;
|
||||
private final ClientResource clientResource;
|
||||
|
||||
public OAuthClient(String baseUrl, CloseableHttpClient httpClient, ManagedWebDriver managedWebDriver) {
|
||||
public OAuthClient(String baseUrl, CloseableHttpClient httpClient, ManagedWebDriver managedWebDriver, ClientResource clientResource) {
|
||||
super(baseUrl, httpClient, managedWebDriver.driver());
|
||||
this.managedWebDriver = managedWebDriver;
|
||||
this.clientResource = clientResource;
|
||||
|
||||
config = new OAuthClientConfig()
|
||||
.responseType(OAuth2Constants.CODE);
|
||||
}
|
||||
|
||||
public OAuthClient(String baseUrl, CloseableHttpClient httpClient, ManagedWebDriver managedWebDriver) {
|
||||
this(baseUrl, httpClient, managedWebDriver, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillLoginForm(String username, String password) {
|
||||
LoginPage loginPage = new LoginPage(managedWebDriver);
|
||||
|
|
@ -45,6 +52,9 @@ public class OAuthClient extends AbstractOAuthClient<OAuthClient> {
|
|||
}
|
||||
|
||||
public void close() {
|
||||
if (clientResource != null) {
|
||||
clientResource.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.keycloak.testframework.oauth;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.testframework.injection.DependenciesBuilder;
|
||||
import org.keycloak.testframework.injection.Dependency;
|
||||
|
|
@ -26,7 +27,7 @@ public class OAuthClientSupplier implements Supplier<OAuthClient, InjectOAuthCli
|
|||
public List<Dependency> getDependencies(RequestedInstance<OAuthClient, InjectOAuthClient> instanceContext) {
|
||||
return DependenciesBuilder.create(KeycloakUrls.class)
|
||||
.add(HttpClient.class)
|
||||
.add(ManagedWebDriver.class)
|
||||
.add(ManagedWebDriver.class, instanceContext.getAnnotation().webDriverRef())
|
||||
.add(TestApp.class)
|
||||
.add(ManagedRealm.class, instanceContext.getAnnotation().realmRef()).build();
|
||||
}
|
||||
|
|
@ -37,7 +38,7 @@ public class OAuthClientSupplier implements Supplier<OAuthClient, InjectOAuthCli
|
|||
|
||||
KeycloakUrls keycloakUrls = instanceContext.getDependency(KeycloakUrls.class);
|
||||
CloseableHttpClient httpClient = (CloseableHttpClient) instanceContext.getDependency(HttpClient.class);
|
||||
ManagedWebDriver webDriver = instanceContext.getDependency(ManagedWebDriver.class);
|
||||
ManagedWebDriver webDriver = instanceContext.getDependency(ManagedWebDriver.class, annotation.webDriverRef());
|
||||
TestApp testApp = instanceContext.getDependency(TestApp.class);
|
||||
|
||||
ManagedRealm realm = instanceContext.getDependency(ManagedRealm.class, annotation.realmRef());
|
||||
|
|
@ -53,12 +54,16 @@ public class OAuthClientSupplier implements Supplier<OAuthClient, InjectOAuthCli
|
|||
testAppClient.setAdminUrl(testApp.getAdminUri());
|
||||
}
|
||||
|
||||
String clientId = testAppClient.getClientId();
|
||||
String clientId = testAppClient.getClientId();;
|
||||
if (!annotation.ref().isEmpty()) {
|
||||
clientId = clientId + "-" + annotation.ref();
|
||||
testAppClient.setClientId(clientId);
|
||||
}
|
||||
String clientSecret = testAppClient.getSecret();
|
||||
|
||||
ApiUtil.getCreatedId(realm.admin().clients().create(testAppClient));
|
||||
|
||||
OAuthClient oAuthClient = new OAuthClient(keycloakUrls.getBase(), httpClient, webDriver);
|
||||
String id = ApiUtil.getCreatedId(realm.admin().clients().create(testAppClient));
|
||||
ClientResource clientResource = realm.admin().clients().get(id);
|
||||
OAuthClient oAuthClient = new OAuthClient(keycloakUrls.getBase(), httpClient, webDriver, clientResource);
|
||||
oAuthClient.config().realm(realm.getName()).client(clientId, clientSecret).redirectUri(redirectUri);
|
||||
return oAuthClient;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ public @interface InjectOAuthClient {
|
|||
|
||||
String realmRef() default "";
|
||||
|
||||
String webDriverRef() default "";
|
||||
|
||||
boolean kcAdmin() default false;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package org.keycloak.testframework.tests;
|
||||
|
||||
import org.keycloak.testframework.annotations.InjectEvents;
|
||||
import org.keycloak.testframework.annotations.InjectRealm;
|
||||
import org.keycloak.testframework.annotations.InjectUser;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.EventAssertion;
|
||||
import org.keycloak.testframework.events.Events;
|
||||
import org.keycloak.testframework.injection.LifeCycle;
|
||||
import org.keycloak.testframework.oauth.OAuthClient;
|
||||
import org.keycloak.testframework.oauth.annotations.InjectOAuthClient;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.realm.ManagedUser;
|
||||
import org.keycloak.testframework.realm.UserConfig;
|
||||
import org.keycloak.testframework.realm.UserConfigBuilder;
|
||||
import org.keycloak.testframework.ui.annotations.InjectPage;
|
||||
import org.keycloak.testframework.ui.annotations.InjectWebDriver;
|
||||
import org.keycloak.testframework.ui.page.LoginPage;
|
||||
import org.keycloak.testframework.ui.webdriver.ManagedWebDriver;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class ManagedWebDriverTest {
|
||||
|
||||
@InjectRealm
|
||||
ManagedRealm managedRealm;
|
||||
|
||||
@InjectUser(ref = "user", config = UserForManagedWebDriver.class)
|
||||
ManagedUser user;
|
||||
|
||||
@InjectWebDriver(ref = "webDriver1", lifecycle = LifeCycle.CLASS)
|
||||
ManagedWebDriver webDriver1;
|
||||
|
||||
@InjectWebDriver(ref = "webDriver2", lifecycle = LifeCycle.CLASS)
|
||||
ManagedWebDriver webDriver2;
|
||||
|
||||
@InjectOAuthClient(ref = "oauth1", webDriverRef = "webDriver1")
|
||||
OAuthClient oauth1;
|
||||
|
||||
@InjectOAuthClient(ref = "oauth2", webDriverRef = "webDriver2")
|
||||
OAuthClient oauth2;
|
||||
|
||||
@InjectEvents
|
||||
Events events;
|
||||
|
||||
@InjectPage(ref = "loginPage1", webDriverRef = "webDriver1")
|
||||
LoginPage loginPage1;
|
||||
|
||||
@InjectPage(ref = "loginPage2", webDriverRef = "webDriver2")
|
||||
LoginPage loginPage2;
|
||||
|
||||
@Test
|
||||
public void testMultipleWebDriverInstances() {
|
||||
oauth1.openLoginForm();
|
||||
|
||||
loginPage1.fillLogin(user.getUsername(), user.getPassword());
|
||||
loginPage1.submit();
|
||||
|
||||
Assertions.assertNotNull(oauth1.parseLoginResponse().getCode());
|
||||
EventAssertion.assertSuccess(events.poll()).userId(user.getId());
|
||||
|
||||
oauth2.openLoginForm();
|
||||
|
||||
loginPage2.fillLogin(user.getUsername(), user.getPassword());
|
||||
loginPage2.submit();
|
||||
|
||||
Assertions.assertNotNull(oauth2.parseLoginResponse().getCode());
|
||||
EventAssertion.assertSuccess(events.poll()).userId(user.getId());
|
||||
}
|
||||
|
||||
private static class UserForManagedWebDriver implements UserConfig {
|
||||
|
||||
@Override
|
||||
public UserConfigBuilder configure(UserConfigBuilder user) {
|
||||
return user.username("user").password("password").email("user@localhost").name("User", "Last");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,4 +12,12 @@ import java.lang.annotation.Target;
|
|||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface InjectPage {
|
||||
|
||||
/**
|
||||
* A ref must be set if a test requires multiple instances
|
||||
*/
|
||||
String ref() default "";
|
||||
|
||||
String webDriverRef() default "";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,23 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.keycloak.testframework.injection.LifeCycle;
|
||||
|
||||
/**
|
||||
* Inject a {@link org.keycloak.testframework.ui.webdriver.ManagedWebDriver} to interact directly with the web driver.
|
||||
* When possible it is recommended to use pages instead of directly accessing the web driver.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface InjectWebDriver { }
|
||||
public @interface InjectWebDriver {
|
||||
|
||||
/**
|
||||
* A ref must be set if a test requires multiple instances
|
||||
*/
|
||||
String ref() default "";
|
||||
|
||||
/**
|
||||
* Controls the lifecycle of the resource
|
||||
*/
|
||||
LifeCycle lifecycle() default LifeCycle.GLOBAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,18 +14,18 @@ public class PageSupplier implements Supplier<AbstractPage, InjectPage> {
|
|||
|
||||
@Override
|
||||
public List<Dependency> getDependencies(RequestedInstance<AbstractPage, InjectPage> instanceContext) {
|
||||
return DependenciesBuilder.create(ManagedWebDriver.class).build();
|
||||
return DependenciesBuilder.create(ManagedWebDriver.class, instanceContext.getAnnotation().webDriverRef()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractPage getValue(InstanceContext<AbstractPage, InjectPage> instanceContext) {
|
||||
ManagedWebDriver webDriver = instanceContext.getDependency(ManagedWebDriver.class);
|
||||
ManagedWebDriver webDriver = instanceContext.getDependency(ManagedWebDriver.class, instanceContext.getAnnotation().webDriverRef());
|
||||
return webDriver.page().createPage(instanceContext.getRequestedValueType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compatible(InstanceContext<AbstractPage, InjectPage> a, RequestedInstance<AbstractPage, InjectPage> b) {
|
||||
return true;
|
||||
return a.getAnnotation().ref().equals(b.getAnnotation().ref());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.keycloak.testframework.ui.webdriver;
|
|||
|
||||
|
||||
import org.keycloak.testframework.injection.InstanceContext;
|
||||
import org.keycloak.testframework.injection.LifeCycle;
|
||||
import org.keycloak.testframework.injection.RequestedInstance;
|
||||
import org.keycloak.testframework.injection.Supplier;
|
||||
import org.keycloak.testframework.ui.annotations.InjectWebDriver;
|
||||
|
|
@ -18,12 +17,7 @@ public abstract class AbstractWebDriverSupplier implements Supplier<ManagedWebDr
|
|||
|
||||
@Override
|
||||
public boolean compatible(InstanceContext<ManagedWebDriver, InjectWebDriver> a, RequestedInstance<ManagedWebDriver, InjectWebDriver> b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LifeCycle getDefaultLifecycle() {
|
||||
return LifeCycle.GLOBAL;
|
||||
return a.getAnnotation().ref().equals(b.getAnnotation().ref());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -211,9 +211,8 @@ public class ConsentsTest {
|
|||
RealmRepresentation providerRealmRep = providerRealm.admin().toRepresentation();
|
||||
providerRealmRep.setAccountTheme("keycloak");
|
||||
providerRealm.admin().update(providerRealmRep);
|
||||
providerRealm.admin().clients().create(ClientConfigBuilder.create().clientId("test-app").redirectUris("*").publicClient(true).webOrigins("*").build());
|
||||
|
||||
ClientRepresentation providerAccountRep = providerRealm.admin().clients().findByClientId("test-app").get(0);
|
||||
ClientRepresentation providerAccountRep = providerRealm.admin().clients().findByClientId("test-app-provider").get(0);
|
||||
|
||||
// add offline_scope to default account-console client scope
|
||||
ClientScopeRepresentation offlineAccessScope = providerRealm.admin().getDefaultOptionalClientScopes().stream()
|
||||
|
|
@ -261,7 +260,7 @@ public class ConsentsTest {
|
|||
@Test
|
||||
public void testConsentCancel() {
|
||||
// setup account client to require consent
|
||||
ClientResource accountClient = findClientByClientId(providerRealm.admin(), "test-app");
|
||||
ClientResource accountClient = findClientByClientId(providerRealm.admin(), "test-app-provider");
|
||||
|
||||
ClientRepresentation clientRepresentation = accountClient.toRepresentation();
|
||||
clientRepresentation.setConsentRequired(true);
|
||||
|
|
@ -308,7 +307,7 @@ public class ConsentsTest {
|
|||
userRealm.updateWithCleanup(r -> r.enabledEventTypes("REFRESH_TOKEN_ERROR"));
|
||||
String sessionId = loginEvent.getSessionId();
|
||||
|
||||
ClientRepresentation clientRepresentation = userRealm.admin().clients().findByClientId("test-app").get(0);
|
||||
ClientRepresentation clientRepresentation = userRealm.admin().clients().findByClientId("test-app-user").get(0);
|
||||
try {
|
||||
clientRepresentation.setConsentRequired(true);
|
||||
userRealm.admin().clients().get(clientRepresentation.getId()).update(clientRepresentation);
|
||||
|
|
@ -339,7 +338,7 @@ public class ConsentsTest {
|
|||
@Test
|
||||
public void testConsentWithAdditionalClientAttributes() {
|
||||
// setup account client to require consent
|
||||
ClientResource accountClient = findClientByClientId(providerRealm.admin(), "test-app");
|
||||
ClientResource accountClient = findClientByClientId(providerRealm.admin(), "test-app-provider");
|
||||
|
||||
ClientRepresentation clientRepresentation = accountClient.toRepresentation();
|
||||
clientRepresentation.setConsentRequired(true);
|
||||
|
|
|
|||
Loading…
Reference in a new issue