Как правильно связать Selenide и Selenium Grid?

Всем привет!

Пытаюсь настроить выполнение Selenide-тестов в Selenium Grid. Помогите разобраться, пожалуйста.

Ссылка на проект-песочницу: GitHub - msmolyakov/maven-selenide-grid-example

Вкратце суть идеи: мне нужно выполнять тесты в Firefox 24й версии на нескольких нодах (ноды на Linux, хост-машина на Windows, если имеет значение). Браузер должен запускаться сразу в режиме fullscreen.

Открытие браузера выполняю в rules.CommonRule (расширяет TestWatcher рулу).

Вопрос №1
Правильно ли делаю, что для управления настройками браузера описываю свой драйвер FirefoxCustomDriver через реализацию WebDriverProvider?

public class FirefoxCustomDriver implements WebDriverProvider {

    @Override
    public WebDriver createDriver(DesiredCapabilities desiredCapabilities) {

        FirefoxProfile firefoxProfile = new FirefoxProfile();

        firefoxProfile.setPreference("browser.fullscreen.autohide",true);
        firefoxProfile.setPreference("browser.fullscreen.animateUp",0);

        desiredCapabilities.setCapability(PROFILE, firefoxProfile);

        return new FirefoxDriver(desiredCapabilities);
    }

}

Вопрос №2
Правильно ли понимаю, что для применения этого драйвера достаточно добавить системный параметр через System.setProperty();?

System.setProperty("selenide.browser", "webdrivers.FirefoxCustomDriver");

Вопрос №3
Почему не получается перевести браузер в полноэкранный режим командой вебдрайвера ...windows().fullscreen();?

WebDriverRunner.getWebDriver().manage().window().fullscreen();

Сейчас приходится делать так:

((FirefoxDriver)getWebDriver()).getKeyboard().pressKey(Keys.F11);

Но сейчас он разворачивается только после открытия первой страницы. Можно ли как-то настроить, чтобы браузер сразу открывался в полноэкранном режиме? Может быть через настройки профиля или DesiredCapabilities?

Вопрос №4
На хост-машине поднимаю Selenium Grid хаб командой:

java -jar selenium-server-standalone-2.53.0.jar -role hub

На Linux-нодах поднимаю Selenium Grid ноды командой:

java -jar selenium-server-standalone-2.53.0.jar -role node -hub http://172.16.101.70:4444/grid/register

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

mvn clean test site -Dremote=http://172.16.101.70:4444/

На что в большом количестве получаю такие сообщения:

ш■э 03, 2016 4:18:42 PM com.codeborne.selenide.impl.WebDriverThreadLocalContainer
 getWebDriver
INFO: No webdriver is bound to current thread: 1 - let's create new webdriver

После них браузер так и не запускается. Где я ошибся и как правильно направить тесты в Grid?

1 лайк

Для работы с гридом нужен RemoteWebDriver, а не простой FirefoxDriver.
Да и по-моему кастомный инстанс драйвера гораздо легче сетить в контекст Selenide через WebDriverRunner.setWebDriver(myWebDriver).

Не смотрел исходники fullscreen(), но раньше достаточно было вызвать maximize().

Судя по документации, при WebDriverRunner.setWebDriver(myWebDriver) придется брать на себя работу с открытием/закрытием браузера, чего не хотелось бы. Показалось удобнее взять WebDriverProvider и продолжать использовать Selenide привычным образом.

Насколько я знаю, maximize() разворачивает окно браузера по размеру экрана, но не переводит его в полноэкранный режим (как если нажать клавишу F11). На всякий случай проверил - так и есть, т.е. maximize() не подходит. И странно, что команда fullscreen() ведет себя точно так же.

Про RemoteWebDriver - спасибо, заменил. При создании экземпляра сразу передаю ему параметром URL хаба, но не помогло - получил те же самые сообщения. Для пробы убрал параметр -Dremote из вызова mvn, и когда в консоли мавена снова посыпались эти сообщения, в консоли ноды вдруг посыпались такие ошибки (раньше была тишина):

18:10:40.793 WARN - POST /selenium-server/driver/session HTTP/1.1
java.lang.NullPointerException: sessionId should not be null; has this session been started yet?
	at org.openqa.selenium.server.FrameGroupCommandQueueSet.getQueueSet(FrameGroupCommandQueueSet.java:220)
	at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleBrowserResponse(SeleniumDriverResourceHandler.java:186)
	at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:152)
	at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1526)
	at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1479)
	at org.openqa.jetty.http.HttpServer.service(HttpServer.java:920)
	at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
	at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
	at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
	at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:243)
	at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:358)
	at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:537)

Ну в вашем примере вы итак открываете браузер самостоятельно путем вызова

new FirefoxDriver(desiredCapabilities)

А закрывать браузер так же просто, как и сетить: WebDriverRunner.closeWebDriver().

Логично, URL то неверный. Нужно то вначале было почитать, как правильно конектиться к хабу.

http://172.16.101.70:4444/wd/hub

Имеешь в виду, что URL должен быть таким, который ты указал? Перед предыдущим ответом я и запушил в песочницу такой URL, посмотрев на официальный пример The Selenium Browser Automation Project | Selenium
Но результат тот же, к сожалению.
Или я неправильно понял?

Боюсь ошибиться, но Selenide же еще и отслеживает, можно ли использовать уже открытый браузер для следующего теста или надо его переоткрыть, корректно ли запустился браузер или надо попробовать открыть его еще раз и т.п.
Всё это останется на Selenide или это тоже надо будет реализовывать самостоятельно?

Ну и какой же URL в официальном примере? :slight_smile:

new URL("http://localhost:4444/wd/hub")

А теперь посмотрим на оригинальный:

-Dremote=http://172.16.101.70:4444/

Давайте поищем десять отличий. :wink:

Если вы используете кастомный драйвер, предполагается, что вы как минимум должны сетить и закрывать его, вызывая выше указанные методы. Все остальное уже происходит в контексте selenide. @asolntsev думаю сможет больше деталей предоставить. Лично я всегда использовал кастомный раннер. Потому проблем с вызовом сеттера в @Before и закрытием в @After никаких не возникало. А вообще, вот тут в javadocs описано, как нужно правильно сетить кастомный драйвер.

Давай :slight_smile: https://github.com/msmolyakov/maven-selenide-grid-example/blob/master/src/test/java/webdrivers/FirefoxCustomDriver.java#L27
О чем и говорю, что до этого уже исправил URL. На смену IP с .70 на .77 не обращай внимания - уже другая машина.

На всякий случай перепробовал:

1) указывать URL сразу и в параметре -Dremote, и в коде при создании RemoteWebDriver:

mvn clean test site -Dselenide.browser=webdrivers.FirefoxCustomDriver -Dremote=http://172.16.101.77:4444/wd/hub
return new RemoteWebDriver(new URL("http://172.16.101.77:4444/wd/hub"), desiredCapabilities);

2) указывать URL в параметре -Dremote, а в коде создавать RemoteWebDriver без параметра URL

mvn clean test site -Dselenide.browser=webdrivers.FirefoxCustomDriver -Dremote=http://172.16.101.77:4444/wd/hub
return new RemoteWebDriver(desiredCapabilities);

3) не указывать параметр -Dremote, но в коде создавать RemoteWebDriver с параметром URL

mvn clean test site -Dselenide.browser=webdrivers.FirefoxCustomDriver
return new RemoteWebDriver(new URL("http://172.16.101.77:4444/wd/hub"), desiredCapabilities);
1 лайк

По-моему, самый простой и очевидный вариант, который нужно было попробовать в первую очередь:

  1. Самому создать RemoteWebDriver перед запуском теста.
  2. Там же вызвать WebDriverRunner.setWebDriver(yourRemoteDriverInstance).
  3. В конце теста вызвать WebDriverRunner.closeWebDriver().

И никаких -Dremote и плясок с бубном.

1 лайк

Такое-то решение работает, спасибо. Ну пусть пока так и останется.
Но по-прежнему волнует момент, что то же самое не завелось через WebDriverProvider. Ожидал, что с ним как раз и избегу “плясок с бубном”, но вышло наоборот.

Ну тут надо уточнять с @asolntsev. Я лично провайдером не пользовался, потому не могу ничего сказать без детального просмотра исходников. Может он не заточен под грид, или вы что-то банально упустили.

@ArtOfLife @msmolyakov Привет!
Провайдер с гридом работает, просто не надо выставлять настройку remote.
Вместо этого все нужные свойства нужно прописать в своём провайдере:

  @Before
  public void setUp() throws Exception {
    Configuration.browser = MyGridProvider.class.getName();
  }

  private static class MyGridProvider implements WebDriverProvider {
    @Override
    public WebDriver createDriver(DesiredCapabilities capabilities) {
      FirefoxProfile firefoxProfile = new FirefoxProfile();

      firefoxProfile.setPreference("browser.fullscreen.autohide",true);
      firefoxProfile.setPreference("browser.fullscreen.animateUp",0);

      capabilities.setCapability(PROFILE, firefoxProfile);
      capabilities.setBrowserName("firefox");

      try {
        return new RemoteWebDriver(new URL("http://172.16.101.70:4444/wd/hub"), capabilities);
      }
      catch (MalformedURLException e) {
        throw new RuntimeException(e);
      }
    }
  }
4 лайка

Привет, Андрей!
Прошу прощения, что надолго пропал.

Как раз то, что изначально хотел! Работает. Спасибо за помощь. :slight_smile:

Привет!
Если разобрался, то можешь на гите до рабочего состояния обновиться?))
заранее спасибо

Привет!
Я уже подзабыл, что именно и где надо обновить?

Андрей, у автора есть проект на гите) вот я и попросил, если у него все это дело завелось то обновить проект до рабочего состояния)

Привет!
Извини, давно сюда не заходил. Для тебя еще актуален вопрос?

я думаю, этот вопрос очень будет актуальным всегда. ты можешь обновить исходники?

есть ли еще открытые проекты , на эту тему ?)

И главное не упускать capabilities.setBrowserName(“firefox”); иначе не находит нужную сессию, и выдает исключение.

maximize() не работает на linux системах в рабочем столе xvfb, там нужно задавать размер через setSize(). Но при этом опция Configuration.startMaximized = true не вызывает ошибки. Вместо maximize() в linux можно использовать опцию Configuration.browserSize = “1920x1080”;