Общие настройки веб-драйвера Selenium-Jupiter не применяются

Я хочу использовать Selenium-Jupiter в моем проекте Spring Boot Project, но мое требование - переключить реализацию WebDriver во время выполнения - в зависимости от среды выполнения - с использованием одного общего базового класса для всех тестов.

Я уже проверил этот пост и этот, но я не мог заставить его работать.

Трассировки стека:

  2020-09-17 23:17:47.196  INFO 14092 --- [    Test worker] d[....path....].SignupPageTest  : Started SignupPageTest in 26.133 seconds (JVM running for 29.179)
    2020-09-17 23:17:47.498  WARN 14092 --- [    Test worker] i.g.bonigarcia.seljup.SeleniumExtension  : Driver handler for context id [engine:junit-jupiter]/[class:de,[....path....].SignupPageTest]/[method:verifyLogInPage(org.openqa.selenium.WebDriver)] not found

    Failed to resolve parameter [org.openqa.selenium.WebDriver genDriver] in method [public void de.[....path....].SignupPageTest.verifyLogInPage(org.openqa.selenium.WebDriver) throws java.lang.Exception]: org/glassfish/hk2/api/MultiException
    org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [org.openqa.selenium.WebDriver genDriver] in method [public void de.[....path....].SignupPageTest.verifyLogInPage(org.openqa.selenium.WebDriver) throws java.lang.Exception]: org/glassfish/hk2/api/MultiException
        at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:239)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:183)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:144)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:96)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
        at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
        at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
        at com.sun.proxy.$Proxy5.stop(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.base/java.lang.Thread.run(Thread.java:832)
    Caused by: java.lang.NoClassDefFoundError: org/glassfish/hk2/api/MultiException
        at io.github.bonigarcia.seljup.DockerService.<init>(DockerService.java:79)
        at io.github.bonigarcia.seljup.SeleniumExtension.initHandlerForDocker(SeleniumExtension.java:381)
        at io.github.bonigarcia.seljup.SeleniumExtension.getDriverHandler(SeleniumExtension.java:242)
        at io.github.bonigarcia.seljup.SeleniumExtension.resolveParameter(SeleniumExtension.java:220)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:216)
        ... 73 more
    Caused by: java.lang.ClassNotFoundException: org.glassfish.hk2.api.MultiException
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 78 more
    
    de.[....path....].SignupPageTest > verifyLogInPage(WebDriver) FAILED
        org.junit.jupiter.api.extension.ParameterResolutionException at ExecutableInvoker.java:239
            Caused by: java.lang.NoClassDefFoundError at DockerService.java:79
                Caused by: java.lang.ClassNotFoundException at BuiltinClassLoader.java:602

Просто заранее с хром-драйвером все работает нормально, но не с обычным веб-драйвером.

Я использую Java14 и создал дополнительный исходный набор для тестов на селен под названием "endToEndTest"
Вот все, что связано с gradle.build:

sourceCompatibility = 14

sourceSets {
    endToEndTest {
        java.srcDir('src/end-to-end-test/java')
        resources.srcDir file('src/end-to-end-tests/resources')
        compileClasspath += sourceSets.main.output + configurations.testRuntime
        runtimeClasspath += output + compileClasspath
    }
}

configurations {
    endToEndTestImplementation.extendsFrom testImplementation
    endToEndTestRuntimeOnly.extendsFrom testRuntimeOnly
}

task endToEndTest(type: Test) {
    testClassesDirs = sourceSets.endToEndTest.output.classesDirs
    classpath = sourceSets.endToEndTest.runtimeClasspath
    useJUnitPlatform ()
}

endToEndTestImplementation('io.github.bonigarcia:selenium-jupiter:3.3.5')

У меня есть базовый класс, от которого должен расширяться любой другой тестовый класс. Он заботится о запуске веб-среды и т. Д.

Базовый класс

@ExtendWith({SpringExtension.class})
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SeleniumBaseTestEnvironment {

  @RegisterExtension
  static SeleniumExtension seleniumJupiter = new SeleniumExtension();

  @LocalServerPort
  protected int serverPort;

  @BeforeAll
  public static void beforeAll() {
    //both seems to have no impact
    seleniumJupiter.getConfig().setDefaultBrowser("chrome");
    seleniumJupiter.addBrowsers(BrowserBuilder.chrome().build());
  }

  protected String getUrl(String address) {
    return "http://localhost:" + serverPort + address;
  }
}

Testclass Он отлично работает, если я заменю WebDriver на ChromeDriver. Но мне нужен универсальный драйвер.

public class SignupPageTest extends SeleniumBaseTestEnvironment {

  @Test
  public void verifyLogInPage(WebDriver genDriver) throws Exception {
    genDriver.get(getUrl("/"));
    List<WebElement> cardTitleList = genDriver.findElements(By.className("card-title"));
    List<WebElement> navbar = genDriver.findElements(By.className("navbar-toggler collapsed"));
    assertEquals(cardTitleList.get(0).getText(), "Login");
    assertTrue(navbar.isEmpty());

  }
}

Похоже, мои настройки браузера по умолчанию не применяются. Другие настройки, такие как для снимков экрана, работают нормально.

1 ответ

Решение

Согласно моим исследованиям, добавление браузеров в Selenium Extension работает только для функции тестовых шаблонов в Selenium Jupiter.

Таким образом, при использовании тестовых шаблонов следующий код должен работать:

    @ExtendWith({SpringExtension.class})
    @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class SeleniumBaseTestEnvironment {
    
      @RegisterExtension
      static SeleniumExtension seleniumJupiter = new SeleniumExtension();
    
      @LocalServerPort
      protected int serverPort;
    
      @BeforeAll
      public static void beforeAll() {
        String browsersList = System.getProperty("prop.browsers.list");
            List<String> browsers = Arrays.asList(browsersList.split(","));
        
        if (browsers.contains("chrome")) {
        seleniumJupiter.addBrowsers(BrowserBuilder.chrome().build()); 
        }
        if (browsers.contains("firefox")) {
            seleniumJupiter.addBrowsers(BrowserBuilder.firefox().build());
        }
        //----// All browsers you need
    
      }
    
      protected String getUrl(String address) {
        return "http://localhost:" + serverPort + address;
      }


public class SignupPageTest extends SeleniumBaseTestEnvironment {

    @TestTemplate
    public void verifyLogInPage(WebDriver genDriver) throws Exception {
        genDriver.get(getUrl("/"));
        List<WebElement> cardTitleList = genDriver.findElements(By.className("card-title"));
        List<WebElement> navbar = genDriver.findElements(By.className("navbar-toggler collapsed"));
        assertEquals(cardTitleList.get(0).getText(), "Login");
        assertTrue(navbar.isEmpty());

    }
}

Пожалуйста, обратите внимание:

  1. В моем примере я использую вариант виртуальной машины -Dprop.browsers.list=chrome,firefox чтобы включить в тест несколько браузеров.
  2. Аннотации @TestTemplate следует размещать для каждого метода всех подклассов SeleniumBaseTestEnvironment (вы можете создать свою собственную аннотацию уровня класса, чтобы обойти это).
  3. Чтобы переключить Webdriver реализации, вы можете настроить конфигурацию Spring для каждой среды, которая предоставит соответствующий список драйверов.
Другие вопросы по тегам