Skip to content

Commit fdc1a44

Browse files
committed
[py] use Selenium Manager to locate drivers on PATH
1 parent 3daa319 commit fdc1a44

File tree

15 files changed

+48
-78
lines changed

15 files changed

+48
-78
lines changed

py/selenium/webdriver/chrome/service.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
from selenium.types import SubprocessStdAlias
2020
from selenium.webdriver.chromium import service
2121

22-
DEFAULT_EXECUTABLE_PATH = "chromedriver"
23-
2422

2523
class Service(service.ChromiumService):
2624
"""A Service class that is responsible for the starting and stopping of
@@ -35,7 +33,7 @@ class Service(service.ChromiumService):
3533

3634
def __init__(
3735
self,
38-
executable_path: str = DEFAULT_EXECUTABLE_PATH,
36+
executable_path=None,
3937
port: int = 0,
4038
service_args: typing.Optional[typing.List[str]] = None,
4139
log_path: typing.Optional[str] = None,

py/selenium/webdriver/chrome/webdriver.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
from selenium.webdriver.chromium.webdriver import ChromiumDriver
1919
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
20-
from selenium.webdriver.common.driver_finder import DriverFinder
2120

2221
from .options import Options
2322
from .service import Service
@@ -40,16 +39,13 @@ def __init__(
4039
- service - Service object for handling the browser driver if you need to pass extra details
4140
- keep_alive - Whether to configure ChromeRemoteConnection to use HTTP keep-alive.
4241
"""
43-
self.service = service if service else Service()
44-
self.options = options if options else Options()
45-
self.keep_alive = keep_alive
46-
47-
self.service.path = DriverFinder.get_path(self.service, self.options)
42+
service = service if service else Service()
43+
options = options if options else Options()
4844

4945
super().__init__(
5046
DesiredCapabilities.CHROME["browserName"],
5147
"goog",
52-
self.options,
53-
self.service,
54-
self.keep_alive,
48+
options,
49+
service,
50+
keep_alive,
5551
)

py/selenium/webdriver/chromium/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ChromiumService(service.Service):
3737

3838
def __init__(
3939
self,
40-
executable_path: str,
40+
executable_path: str = None,
4141
port: int = 0,
4242
service_args: typing.Optional[typing.List[str]] = None,
4343
log_path: typing.Optional[str] = None,

py/selenium/webdriver/chromium/webdriver.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# under the License.
1717

1818
from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection
19+
from selenium.webdriver.common.driver_finder import DriverFinder
1920
from selenium.webdriver.common.options import ArgOptions
2021
from selenium.webdriver.common.service import Service
2122
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
@@ -46,7 +47,8 @@ def __init__(
4647
self.vendor_prefix = vendor_prefix
4748

4849
self.service = service
49-
self.options = options
50+
51+
self.service.path = DriverFinder.get_path(self.service, options)
5052

5153
self.service.start()
5254

@@ -57,9 +59,9 @@ def __init__(
5759
browser_name=browser_name,
5860
vendor_prefix=vendor_prefix,
5961
keep_alive=keep_alive,
60-
ignore_proxy=self.options._ignore_local_proxy,
62+
ignore_proxy=options._ignore_local_proxy,
6163
),
62-
options=self.options,
64+
options=options,
6365
)
6466
except Exception:
6567
self.quit()

py/selenium/webdriver/common/driver_finder.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717
import logging
18-
import shutil
1918
from pathlib import Path
2019

2120
from selenium.common.exceptions import NoSuchDriverException
@@ -34,13 +33,14 @@ class DriverFinder:
3433

3534
@staticmethod
3635
def get_path(service: Service, options: BaseOptions) -> str:
37-
path = shutil.which(service.path)
36+
path = service.path
3837
try:
3938
path = SeleniumManager().driver_location(options) if path is None else path
4039
except Exception as err:
41-
raise NoSuchDriverException(f"Unable to obtain {service.path} using Selenium Manager; {err}")
40+
msg = f"Unable to obtain driver for {options.capabilities['browserName']} using Selenium Manager; {err}"
41+
raise NoSuchDriverException(msg)
4242

4343
if path is None or not Path(path).is_file():
44-
raise NoSuchDriverException(f"Unable to locate or obtain {service.path}")
44+
raise NoSuchDriverException(f"Unable to locate or obtain driver for {options.capabilities['browserName']}")
4545

4646
return path

py/selenium/webdriver/common/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Service(ABC):
5050

5151
def __init__(
5252
self,
53-
executable: str,
53+
executable: str = None,
5454
port: int = 0,
5555
log_file: SubprocessStdAlias = None,
5656
log_output: SubprocessStdAlias = None,

py/selenium/webdriver/edge/service.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
from selenium.types import SubprocessStdAlias
2121
from selenium.webdriver.chromium import service
2222

23-
DEFAULT_EXECUTABLE_PATH = "msedgedriver"
24-
2523

2624
class Service(service.ChromiumService):
2725
"""A Service class that is responsible for the starting and stopping of
@@ -38,7 +36,7 @@ class Service(service.ChromiumService):
3836

3937
def __init__(
4038
self,
41-
executable_path: str = DEFAULT_EXECUTABLE_PATH,
39+
executable_path: str = None,
4240
port: int = 0,
4341
verbose: bool = False,
4442
log_path: typing.Optional[str] = None,

py/selenium/webdriver/edge/webdriver.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
from selenium.webdriver.chromium.webdriver import ChromiumDriver
1919
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
20-
from selenium.webdriver.common.driver_finder import DriverFinder
2120

2221
from .options import Options
2322
from .service import Service
@@ -40,16 +39,13 @@ def __init__(
4039
- service - Service object for handling the browser driver if you need to pass extra details
4140
- keep_alive - Whether to configure EdgeRemoteConnection to use HTTP keep-alive.
4241
"""
43-
self.service = service if service else Service()
44-
self.options = options if options else Options()
45-
self.keep_alive = keep_alive
46-
47-
self.service.path = DriverFinder.get_path(self.service, self.options)
42+
service = service if service else Service()
43+
options = options if options else Options()
4844

4945
super().__init__(
5046
DesiredCapabilities.EDGE["browserName"],
5147
"ms",
52-
self.options,
53-
self.service,
54-
self.keep_alive,
48+
options,
49+
service,
50+
keep_alive,
5551
)

py/selenium/webdriver/firefox/service.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
from selenium.webdriver.common import service
2323
from selenium.webdriver.common import utils
2424

25-
DEFAULT_EXECUTABLE_PATH = "geckodriver"
26-
2725

2826
class Service(service.Service):
2927
"""A Service class that is responsible for the starting and stopping of
@@ -39,7 +37,7 @@ class Service(service.Service):
3937

4038
def __init__(
4139
self,
42-
executable_path: str = DEFAULT_EXECUTABLE_PATH,
40+
executable_path: str = None,
4341
port: int = 0,
4442
service_args: typing.Optional[typing.List[str]] = None,
4543
log_path: typing.Optional[str] = None,

py/selenium/webdriver/firefox/webdriver.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,17 @@ def __init__(
5454
"""
5555

5656
self.service = service if service else Service()
57-
self.options = options if options else Options()
58-
self.keep_alive = keep_alive
57+
options = options if options else Options()
5958

60-
self.service.path = DriverFinder.get_path(self.service, self.options)
59+
self.service.path = DriverFinder.get_path(self.service, options)
6160
self.service.start()
6261

6362
executor = FirefoxRemoteConnection(
6463
remote_server_addr=self.service.service_url,
65-
ignore_proxy=self.options._ignore_local_proxy,
66-
keep_alive=self.keep_alive,
64+
ignore_proxy=options._ignore_local_proxy,
65+
keep_alive=keep_alive,
6766
)
68-
super().__init__(command_executor=executor, options=self.options)
67+
super().__init__(command_executor=executor, options=options)
6968

7069
self._is_remote = False
7170

py/selenium/webdriver/ie/service.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@
2121
from selenium.types import SubprocessStdAlias
2222
from selenium.webdriver.common import service
2323

24-
DEFAULT_EXECUTABLE_PATH = "IEDriverServer.exe"
25-
2624

2725
class Service(service.Service):
2826
"""Object that manages the starting and stopping of the IEDriver."""
2927

3028
def __init__(
3129
self,
32-
executable_path: str = DEFAULT_EXECUTABLE_PATH,
30+
executable_path: str = None,
3331
port: int = 0,
3432
host: typing.Optional[str] = None,
3533
service_args: typing.Optional[typing.List[str]] = None,

py/selenium/webdriver/ie/webdriver.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,21 @@ def __init__(
4343
- keep_alive - Deprecated: Whether to configure RemoteConnection to use HTTP keep-alive.
4444
"""
4545

46-
self.iedriver = service if service else Service()
47-
self.options = options if options else Options()
48-
self.keep_alive = keep_alive
46+
self.service = service if service else Service()
47+
options = options if options else Options()
4948

50-
self.iedriver.path = DriverFinder.get_path(self.iedriver, self.options)
51-
self.iedriver.start()
49+
self.service.path = DriverFinder.get_path(self.service, options)
50+
self.service.start()
5251

5352
executor = RemoteConnection(
54-
remote_server_addr=self.iedriver.service_url,
55-
keep_alive=self.keep_alive,
56-
ignore_proxy=self.options._ignore_local_proxy,
53+
remote_server_addr=self.service.service_url,
54+
keep_alive=keep_alive,
55+
ignore_proxy=options._ignore_local_proxy,
5756
)
5857

59-
super().__init__(command_executor=executor, options=self.options)
58+
super().__init__(command_executor=executor, options=options)
6059
self._is_remote = False
6160

6261
def quit(self) -> None:
6362
super().quit()
64-
self.iedriver.stop()
65-
66-
def create_options(self) -> Options:
67-
return Options()
63+
self.service.stop()

py/selenium/webdriver/safari/service.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
import os
1918
import typing
2019
import warnings
2120

2221
from selenium.webdriver.common import service
2322

24-
DEFAULT_EXECUTABLE_PATH: str = "/usr/bin/safaridriver"
25-
2623

2724
class Service(service.Service):
2825
"""A Service class that is responsible for the starting and stopping of
@@ -37,15 +34,14 @@ class Service(service.Service):
3734

3835
def __init__(
3936
self,
40-
executable_path: str = DEFAULT_EXECUTABLE_PATH,
37+
executable_path: str = None,
4138
port: int = 0,
4239
quiet: bool = None,
4340
service_args: typing.Optional[typing.List[str]] = None,
4441
env: typing.Optional[typing.Mapping[str, str]] = None,
4542
reuse_service=False,
4643
**kwargs,
4744
) -> None:
48-
self._check_executable(executable_path)
4945
self.service_args = service_args or []
5046
if quiet is not None:
5147
warnings.warn("quiet is no longer needed to supress output", DeprecationWarning, stacklevel=2)
@@ -58,15 +54,6 @@ def __init__(
5854
**kwargs,
5955
)
6056

61-
@staticmethod
62-
def _check_executable(executable_path) -> None:
63-
if not os.path.exists(executable_path):
64-
if "Safari Technology Preview" in executable_path:
65-
message = "Safari Technology Preview does not seem to be installed. You can download it at https://developer.apple.com/safari/download/."
66-
else:
67-
message = "SafariDriver was not found; are you running Safari 10 or later? You can download Safari at https://developer.apple.com/safari/download/."
68-
raise Exception(message)
69-
7057
def command_line_args(self) -> typing.List[str]:
7158
return ["-p", f"{self.port}"] + self.service_args
7259

py/selenium/webdriver/safari/webdriver.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
2323
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
2424

25+
from ..common.driver_finder import DriverFinder
2526
from .options import Options
2627
from .remote_connection import SafariRemoteConnection
2728
from .service import Service
@@ -57,20 +58,21 @@ def __init__(
5758
)
5859

5960
self.service = service if service else Service()
60-
self.options = options if options else Options()
61-
self.keep_alive = keep_alive
61+
options = options if options else Options()
62+
63+
self.service.path = DriverFinder.get_path(self.service, options)
6264

6365
self._reuse_service = reuse_service and self.service.reuse_service
6466
if not self._reuse_service:
6567
self.service.start()
6668

6769
executor = SafariRemoteConnection(
6870
remote_server_addr=self.service.service_url,
69-
keep_alive=self.keep_alive,
70-
ignore_proxy=self.options._ignore_local_proxy,
71+
keep_alive=keep_alive,
72+
ignore_proxy=options._ignore_local_proxy,
7173
)
7274

73-
super().__init__(command_executor=executor, options=self.options)
75+
super().__init__(command_executor=executor, options=options)
7476

7577
self._is_remote = False
7678

py/test/selenium/webdriver/common/selenium_manager_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,6 @@ def test_driver_finder_error(mocker):
9999

100100
service = Service()
101101
options = Options()
102-
msg = r"Unable to locate or obtain chromedriver.*errors\/driver_location"
102+
msg = r"Unable to locate or obtain driver for chrome.*errors\/driver_location"
103103
with pytest.raises(WebDriverException, match=msg):
104104
DriverFinder.get_path(service, options)

0 commit comments

Comments
 (0)