From e351d5949bd8772757bb116a4bda42bb627bec68 Mon Sep 17 00:00:00 2001 From: Lukas Hanusovsky <61745358+lhanusov@users.noreply.github.com> Date: Mon, 16 Mar 2026 12:54:19 +0100 Subject: [PATCH] Test Framework - support for multiple WebDriver instances. (#46982) Signed-off-by: Lukas Hanusovsky --- .../testframework/oauth/OAuthClient.java | 12 ++- .../oauth/OAuthClientSupplier.java | 17 ++-- .../oauth/annotations/InjectOAuthClient.java | 2 + .../tests/ManagedWebDriverTest.java | 81 +++++++++++++++++++ .../ui/annotations/InjectPage.java | 8 ++ .../ui/annotations/InjectWebDriver.java | 15 +++- .../testframework/ui/page/PageSupplier.java | 6 +- .../webdriver/AbstractWebDriverSupplier.java | 8 +- .../keycloak/tests/admin/ConsentsTest.java | 9 +-- 9 files changed, 135 insertions(+), 23 deletions(-) create mode 100644 test-framework/tests/src/test/java/org/keycloak/testframework/tests/ManagedWebDriverTest.java diff --git a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java index 2ee1c90443d..e7685fb2855 100644 --- a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java +++ b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java @@ -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 { 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 { } public void close() { + if (clientResource != null) { + clientResource.remove(); + } } } diff --git a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClientSupplier.java b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClientSupplier.java index 7c6793b46b9..8014a02e9d4 100644 --- a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClientSupplier.java +++ b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClientSupplier.java @@ -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 getDependencies(RequestedInstance 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 { @Override public List getDependencies(RequestedInstance instanceContext) { - return DependenciesBuilder.create(ManagedWebDriver.class).build(); + return DependenciesBuilder.create(ManagedWebDriver.class, instanceContext.getAnnotation().webDriverRef()).build(); } @Override public AbstractPage getValue(InstanceContext 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 a, RequestedInstance b) { - return true; + return a.getAnnotation().ref().equals(b.getAnnotation().ref()); } } diff --git a/test-framework/ui/src/main/java/org/keycloak/testframework/ui/webdriver/AbstractWebDriverSupplier.java b/test-framework/ui/src/main/java/org/keycloak/testframework/ui/webdriver/AbstractWebDriverSupplier.java index e2b2e752f31..0ff6ce4cd17 100644 --- a/test-framework/ui/src/main/java/org/keycloak/testframework/ui/webdriver/AbstractWebDriverSupplier.java +++ b/test-framework/ui/src/main/java/org/keycloak/testframework/ui/webdriver/AbstractWebDriverSupplier.java @@ -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 a, RequestedInstance b) { - return true; - } - - @Override - public LifeCycle getDefaultLifecycle() { - return LifeCycle.GLOBAL; + return a.getAnnotation().ref().equals(b.getAnnotation().ref()); } @Override diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java index a208fecb3c2..1884bf23316 100644 --- a/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java @@ -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);