Тесты Geb/Selenium зависают при загрузке новой страницы

Мои тесты Selenium часто зависают на CI бесконечно, всегда при попытке загрузить новую страницу в driver.get, Я использую PhantomJS 1.9.8.

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

Selenium RemoteWebDriver отправил запрос в PhantomJS/GhostDriver и ожидает ответа.

GhostDriver по-прежнему принимает запросы. Я могу видеть, на какой странице он застрял, нажав curl http://localhost:port/session/:sessionId/url и далее, если я повторно запросить ту же страницу из командной строки (curl -d '{"url": ...}' http://localhost:port/session/:sessionId/url) затем заблокированный запрос Selenium магическим образом возобновляется с того места, где он был прерван.

ОБНОВЛЕНИЕ: Сам Ghostdriver не зависает - его время ожидания по умолчанию, по существу, бесконечно. Если я укажу время загрузки страницы, например, manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS) затем, когда проблема возникает в PhantomJS, GhostDriver вернет ответ об ошибке с тайм-аутом, тест не пройден, и сборка продолжится.

Если я отлаживаю сам PhantomJS (--debug=TRUE), я вижу это как последнюю вещь в журналах на момент сбоя

2015-03-21T21:26:39 [DEBUG] WebPage - updateLoadingProgress: 86(тогда ничего, пока тайм-аут не достигнут)

Трассировка стека со стороны Java в точке зависания выглядит следующим образом:

"Forwarding get on session fd1ac2c0-ccd4-11e4-a596-a1f7b09caa5d to remote" prio=10 tid=0x0000000001f74800 nid=0x5cc3 runnable [0x00002b87c3039000]
 java.lang.Thread.State: RUNNABLE
     at java.net.SocketInputStream.socketRead0(Native Method)
     at java.net.SocketInputStream.read(SocketInputStream.java:150)
     at java.net.SocketInputStream.read(SocketInputStream.java:121)
     at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
     at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
     at horg.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281)
     at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92)
     at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
     at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
     at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
     at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
     at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219)
     at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
     at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
     at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
     at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:316)
     at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:295)
     at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:66)
     at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
     at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:276)
     at org.openqa.selenium.WebDriver$get.call(Unknown Source)
     at geb.Browser.go(Browser.groovy:371)
     at geb.Browser$go.call(Unknown Source)
     at geb.Page.to(Page.groovy:169)

Это похоже на это, но с PhantomJS вместо Firefox:

Firefox WebDriver зависает в ожидании загрузки страницы

1 ответ

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

Я проследил, чтобы он висел на driver.get() call, который для меня говорил, что что-то не проходит, или веб-драйвер просто - по какой-то причине - не возвращает команду успешной загрузки драйверу, позволяя сценарию продолжить работу.

Итак, я добавил следующее:

driver = webdriver.PhantomJS()

# set timeout information
driver.set_page_load_timeout(15)

Я проверил это за время 5 (секунд), и он просто не ждал достаточно долго, и ничего не произошло. 15 секунд отлично сработали для меня, но, возможно, это то, что вы должны проверить.

Кроме того, я также создавал цикл всякий раз, когда у веб-драйвера была возможность тайм-аута, чтобы driver.get() может попытаться повторно отправить .get() команда. Реализация try / except Сложив сценарий, я смог подойти к этому:

while finished == 0:
    try:
        driver.get(url3)
        finished = 1
    except:
        sleep(5)

Я видел ручку кроме как:

except TimeoutException as e:
    #Handle your exception here
    print(e)

но я не использовал это. Хотя было бы неплохо узнать, как отлавливать определенные исключения.

Посмотрите это решение для получения дополнительных опций для тайм-аута: Установка тайм-аута на селене webdriver.PhantomJS

Другие вопросы по тегам