Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch Remote WebDriver to add retry attempts. Add retry to Browser init. #742

Merged
merged 1 commit into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions splinter/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@

import sys

try:
from httplib import HTTPException
except ImportError:
from http.client import HTTPException

from urllib3.exceptions import MaxRetryError

from selenium.common.exceptions import WebDriverException

from splinter.driver.webdriver.firefox import WebDriver as FirefoxWebDriver
from splinter.driver.webdriver.remote import WebDriver as RemoteWebDriver
from splinter.driver.webdriver.chrome import WebDriver as ChromeWebDriver
Expand Down Expand Up @@ -43,7 +52,23 @@
pass


def Browser(driver_name="firefox", *args, **kwargs):
def get_driver(driver, retry_count=3, *args, **kwargs):
"""Try to instantiate the driver.

Common selenium errors are caught and a retry attempt occurs.
This can mitigate issues running on Remote WebDriver.

"""
for _ in range(retry_count):
try:
return driver(*args, **kwargs)
except (IOError, HTTPException, WebDriverException, MaxRetryError) as e:
pass

raise e


def Browser(driver_name="firefox", retry_count=3, *args, **kwargs):
"""
Returns a driver instance for the given name.

Expand All @@ -61,4 +86,5 @@ def Browser(driver_name="firefox", *args, **kwargs):
driver = _DRIVERS[driver_name]
except KeyError:
raise DriverNotFoundError("No driver for %s" % driver_name)
return driver(*args, **kwargs)

return get_driver(driver, *args, **kwargs)
5 changes: 5 additions & 0 deletions splinter/driver/webdriver/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
# license that can be found in the LICENSE file.

from selenium.webdriver import Remote
from selenium.webdriver.remote import remote_connection
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from splinter.driver.webdriver import (
BaseWebDriver,
WebDriverElement,
)
from splinter.driver.webdriver.cookie_manager import CookieManager
from splinter.driver.webdriver.remote_connection import patch_request

# MonkeyPatch RemoteConnection
remote_connection.RemoteConnection._request = patch_request


class WebDriver(BaseWebDriver):
Expand Down
27 changes: 27 additions & 0 deletions splinter/driver/webdriver/remote_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import socket

try:
from httplib import HTTPException
except ImportError:
from http.client import HTTPException

import urllib3
from urllib3.exceptions import MaxRetryError

from selenium.webdriver.remote import remote_connection


# Get the original _request and store for future use in the monkey patched version as 'super'
old_request = remote_connection.RemoteConnection._request


def patch_request(self, *args, **kwargs):
"""Override _request to set socket timeout to some appropriate value."""
exception = HTTPException('Unable to get response')
for _ in range(3):
try:
return old_request(self, *args, **kwargs)
except (socket.error, HTTPException, IOError, OSError, MaxRetryError) as exc:
exception = exc
self._conn = urllib3.PoolManager(timeout=self._timeout)
raise exception