mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-16 20:15:46 -06:00
Fix Chrome and Firefox in new test framework on GitHub Actions (#44804)
Closes #44776 Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -914,7 +914,7 @@ jobs:
|
||||
|
||||
- name: Run new Forms IT
|
||||
run: |
|
||||
./mvnw package -f tests/pom.xml -Dkc.test.browser=${{ matrix.browser }} -Dtest=FormsTestSuite
|
||||
./mvnw package -f tests/pom.xml -Dkc.test.browser=${{ matrix.browser }}-headless -Dtest=FormsTestSuite
|
||||
|
||||
- uses: ./.github/actions/upload-flaky-tests
|
||||
name: Upload flaky tests
|
||||
|
||||
@@ -174,6 +174,16 @@ Valid values:
|
||||
| firefox | Firefox WebDriver |
|
||||
| firefox-headless | Firefox WebDriver without UI |
|
||||
|
||||
Resolving the web driver is done either automatically by Selenium, or the binary can be specified directly either
|
||||
through using `CHROMEWEBDRIVER` and `GECKOWEBDRIVER` environment variables (these environment variables are already
|
||||
configured on GitHub Actions), or it can be configured using standard test framework configuration options.
|
||||
|
||||
Configuration:
|
||||
|
||||
| Value | Description |
|
||||
|-----------------------------------------------------|--------------------|
|
||||
| `kc.test.browser.driver` / `KC_TEST_BROWSER_DRIVER` | Path to the driver |
|
||||
|
||||
### Supplier configuration
|
||||
|
||||
#### Set the supplier
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
<description>UI extension for Keycloak Test Framework</description>
|
||||
|
||||
<properties>
|
||||
<selenium.version>4.25.0</selenium.version>
|
||||
<selenium.html.unit.version>4.25.0</selenium.html.unit.version>
|
||||
<selenium.version>4.39.0</selenium.version>
|
||||
<selenium.html.unit.version>4.39.0</selenium.html.unit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.testframework.injection.InstanceContext;
|
||||
import org.keycloak.testframework.injection.LifeCycle;
|
||||
@@ -9,10 +7,7 @@ import org.keycloak.testframework.injection.RequestedInstance;
|
||||
import org.keycloak.testframework.injection.Supplier;
|
||||
import org.keycloak.testframework.ui.annotations.InjectWebDriver;
|
||||
|
||||
import org.openqa.selenium.MutableCapabilities;
|
||||
import org.openqa.selenium.PageLoadStrategy;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.remote.CapabilityType;
|
||||
|
||||
public abstract class AbstractWebDriverSupplier implements Supplier<ManagedWebDriver, InjectWebDriver> {
|
||||
|
||||
@@ -38,9 +33,4 @@ public abstract class AbstractWebDriverSupplier implements Supplier<ManagedWebDr
|
||||
|
||||
public abstract WebDriver getWebDriver();
|
||||
|
||||
public void setCommonCapabilities(MutableCapabilities capabilities) {
|
||||
capabilities.setCapability(CapabilityType.PAGE_LOAD_STRATEGY, PageLoadStrategy.NORMAL.toString());
|
||||
capabilities.setCapability("timeouts", Map.of("implicit", Duration.ofSeconds(5).toMillis()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
|
||||
public class ChromeHeadlessWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@@ -13,15 +11,6 @@ public class ChromeHeadlessWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@Override
|
||||
public WebDriver getWebDriver() {
|
||||
ChromeOptions options = new ChromeOptions();
|
||||
setCommonCapabilities(options);
|
||||
options.addArguments(
|
||||
"--headless",
|
||||
"--disable-gpu",
|
||||
"--window-size=1920,1200",
|
||||
"--ignore-certificate-errors",
|
||||
"--disable-dev-shm-usage"
|
||||
);
|
||||
return new ChromeDriver(options);
|
||||
return DriverUtils.createChromeDriver(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
|
||||
public class ChromeWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@@ -13,8 +11,6 @@ public class ChromeWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@Override
|
||||
public WebDriver getWebDriver() {
|
||||
ChromeOptions options = new ChromeOptions();
|
||||
setCommonCapabilities(options);
|
||||
return new ChromeDriver(options);
|
||||
return DriverUtils.createChromeDriver(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
|
||||
import org.openqa.selenium.MutableCapabilities;
|
||||
import org.openqa.selenium.PageLoadStrategy;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
|
||||
import org.openqa.selenium.remote.CapabilityType;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
||||
class DriverOptions {
|
||||
|
||||
static ChromeOptions createChromeOptions(boolean headless) {
|
||||
ChromeOptions options = new ChromeOptions();
|
||||
setCommonCapabilities(options);
|
||||
|
||||
if (headless) {
|
||||
options.addArguments(
|
||||
"--headless=new",
|
||||
"--disable-gpu",
|
||||
"--window-size=1920,1200",
|
||||
"--ignore-certificate-errors",
|
||||
"--disable-dev-shm-usage",
|
||||
"--remote-allow-origins=*",
|
||||
"--no-sandbox"
|
||||
);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
static FirefoxOptions createFirefoxOptions(boolean headless) {
|
||||
FirefoxOptions options = new FirefoxOptions();
|
||||
setCommonCapabilities(options);
|
||||
|
||||
if (headless) {
|
||||
options.addArguments("-headless");
|
||||
}
|
||||
|
||||
options.addPreference("extensions.update.enabled", "false");
|
||||
options.addPreference("app.update.enabled", "false");
|
||||
options.addPreference("app.update.auto", "false");
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
static DesiredCapabilities createHtmlUnitOptions() {
|
||||
DesiredCapabilities capabilities = new DesiredCapabilities();
|
||||
setCommonCapabilities(capabilities);
|
||||
|
||||
capabilities.setBrowserName("htmlunit");
|
||||
capabilities.setCapability(HtmlUnitDriver.DOWNLOAD_IMAGES_CAPABILITY, false);
|
||||
capabilities.setCapability(HtmlUnitDriver.JAVASCRIPT_ENABLED, true);
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
private static void setCommonCapabilities(MutableCapabilities capabilities) {
|
||||
capabilities.setCapability(CapabilityType.PAGE_LOAD_STRATEGY, PageLoadStrategy.NORMAL.toString());
|
||||
capabilities.setCapability("timeouts", Map.of("implicit", Duration.ofSeconds(5).toMillis()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.keycloak.testframework.config.Config;
|
||||
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriverService;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxDriverService;
|
||||
import org.openqa.selenium.firefox.GeckoDriverService;
|
||||
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
|
||||
|
||||
class DriverUtils {
|
||||
|
||||
static ChromeDriver createChromeDriver(boolean headless) {
|
||||
ChromeDriverService.Builder builder = new ChromeDriverService.Builder();
|
||||
|
||||
File driver = resolveDriver("CHROMEWEBDRIVER", "chromedriver");
|
||||
if (driver != null) {
|
||||
builder.usingDriverExecutable(driver);
|
||||
}
|
||||
|
||||
ChromeDriverService driverService = builder.build();
|
||||
return new ChromeDriver(driverService, DriverOptions.createChromeOptions(headless));
|
||||
}
|
||||
|
||||
static FirefoxDriver createFirefoxDriver(boolean headless) {
|
||||
GeckoDriverService.Builder builder = new GeckoDriverService.Builder();
|
||||
|
||||
File driver = resolveDriver("GECKOWEBDRIVER", "geckodriver");
|
||||
if (driver != null) {
|
||||
builder.usingDriverExecutable(driver);
|
||||
}
|
||||
|
||||
FirefoxDriverService driverService = builder.build();
|
||||
return new FirefoxDriver(driverService, DriverOptions.createFirefoxOptions(headless));
|
||||
}
|
||||
|
||||
static HtmlUnitDriver createHtmlUnitDriver() {
|
||||
HtmlUnitDriver driver = new HtmlUnitDriver(DriverOptions.createHtmlUnitOptions());
|
||||
driver.getWebClient().getOptions().setCssEnabled(false);
|
||||
return driver;
|
||||
}
|
||||
|
||||
private static File resolveDriver(String envName, String driverName) {
|
||||
File driver = Config.getValueTypeConfig(ManagedWebDriver.class, "driver", null, File.class);
|
||||
if (driver != null) {
|
||||
return driver;
|
||||
}
|
||||
|
||||
// Environment variable can point to directory where the driver is located, or the driver directly
|
||||
String driverPathFromEnv = System.getenv(envName);
|
||||
if (driverPathFromEnv != null) {
|
||||
driver = new File(driverPathFromEnv);
|
||||
if (driver.isFile()) {
|
||||
return driver;
|
||||
} else {
|
||||
return new File(driver, driverName + (isWindows() ? ".exe" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").toLowerCase().contains("win");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||
|
||||
public class FirefoxHeadlessWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@@ -13,9 +11,6 @@ public class FirefoxHeadlessWebDriverSupplier extends AbstractWebDriverSupplier
|
||||
|
||||
@Override
|
||||
public WebDriver getWebDriver() {
|
||||
FirefoxOptions options = new FirefoxOptions();
|
||||
setCommonCapabilities(options);
|
||||
options.addArguments("-headless");
|
||||
return new FirefoxDriver(options);
|
||||
return DriverUtils.createFirefoxDriver(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||
|
||||
public class FirefoxWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@@ -13,8 +11,6 @@ public class FirefoxWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@Override
|
||||
public WebDriver getWebDriver() {
|
||||
FirefoxOptions options = new FirefoxOptions();
|
||||
setCommonCapabilities(options);
|
||||
return new FirefoxDriver(options);
|
||||
return DriverUtils.createFirefoxDriver(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.keycloak.testframework.ui.webdriver;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
||||
public class HtmlUnitWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@@ -13,15 +11,6 @@ public class HtmlUnitWebDriverSupplier extends AbstractWebDriverSupplier {
|
||||
|
||||
@Override
|
||||
public WebDriver getWebDriver() {
|
||||
DesiredCapabilities capabilities = new DesiredCapabilities();
|
||||
setCommonCapabilities(capabilities);
|
||||
|
||||
capabilities.setBrowserName("htmlunit");
|
||||
capabilities.setCapability(HtmlUnitDriver.DOWNLOAD_IMAGES_CAPABILITY, false);
|
||||
capabilities.setCapability(HtmlUnitDriver.JAVASCRIPT_ENABLED, true);
|
||||
|
||||
HtmlUnitDriver driver = new HtmlUnitDriver(capabilities);
|
||||
driver.getWebClient().getOptions().setCssEnabled(false);
|
||||
return driver;
|
||||
return DriverUtils.createHtmlUnitDriver();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.function.Function;
|
||||
import org.keycloak.testframework.ui.page.AbstractPage;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.openqa.selenium.StaleElementReferenceException;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
@@ -21,7 +22,7 @@ public class WaitUtils {
|
||||
public WaitUtils waitForPage(AbstractPage page) {
|
||||
String expectedPageId = page.getExpectedPageId();
|
||||
try {
|
||||
createDefaultWait().until(d -> expectedPageId.equals(managed.page().getCurrentPageId()));
|
||||
createDefaultWait().ignoring(StaleElementReferenceException.class).until(d -> expectedPageId.equals(managed.page().getCurrentPageId()));
|
||||
} catch (TimeoutException e) {
|
||||
Assertions.fail("Expected page '" + expectedPageId + "' to be loaded, but currently on page '" + managed.page().getCurrentPageId() + "' after timeout");
|
||||
}
|
||||
@@ -47,7 +48,7 @@ public class WaitUtils {
|
||||
}
|
||||
|
||||
private WebDriverWait createDefaultWait() {
|
||||
return new WebDriverWait(managed.driver(), Duration.ofSeconds(5), Duration.ofMillis(50));
|
||||
return new WebDriverWait(managed.driver(), Duration.ofSeconds(10), Duration.ofMillis(50));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.keycloak.tests.suites;
|
||||
|
||||
import org.keycloak.tests.admin.AdminHeadersTest;
|
||||
import org.keycloak.tests.i18n.LoginPageTest;
|
||||
|
||||
import org.junit.platform.suite.api.SelectClasses;
|
||||
import org.junit.platform.suite.api.Suite;
|
||||
|
||||
@Suite
|
||||
// TODO: Select relevant test classes or packages once they have been migrated
|
||||
@SelectClasses({AdminHeadersTest.class})
|
||||
@SelectClasses({
|
||||
LoginPageTest.class
|
||||
})
|
||||
public class FormsTestSuite {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user