Skip to content

Commit

Permalink
[py] Selenium Manager get Browser Version from Options classes
Browse files Browse the repository at this point in the history
  • Loading branch information
diemol committed Apr 15, 2023
1 parent c8f3f7f commit bd24090
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 17 deletions.
3 changes: 3 additions & 0 deletions common/common-web.iml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="ModuleRunConfigurationManager">
<shared />
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/src/web">
Expand Down
6 changes: 5 additions & 1 deletion py/python.iml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
<configuration sdkName="" />
</facet>
</component>
<component name="ModuleRunConfigurationManager">
<shared />
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/selenium" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 2.7" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.9 (py)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="sonarModuleSettings">
Expand Down
2 changes: 1 addition & 1 deletion py/selenium/webdriver/common/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def browser_version(self) -> str:
"""
:returns: the version of the browser if set, otherwise None.
"""
return self._caps["browserVersion"]
return self._caps.get("browserVersion")

@browser_version.setter
def browser_version(self, version: str) -> None:
Expand Down
25 changes: 12 additions & 13 deletions py/selenium/webdriver/common/selenium_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import subprocess
import sys
from pathlib import Path
from typing import Tuple
from typing import List

from selenium.common.exceptions import SeleniumManagerException
from selenium.webdriver.common.options import BaseOptions
Expand Down Expand Up @@ -87,37 +87,36 @@ def driver_location(self, options: BaseOptions) -> str:

browser = allowed_browsers[browser]

binary, browser_flag, browser, output_flag, output = (
str(self.get_binary()),
"--browser",
browser,
"--output",
"json",
)
result = self.run((binary, browser_flag, browser, output_flag, output))
args = [str(self.get_binary()), "--browser", browser, "--output", "json"]

if options.browser_version:
args.append("--browser-version")
args.append(str(options.browser_version))

result = self.run(args)
executable = result.split("\t")[-1].strip()
logger.debug(f"Using driver at: {executable}")
return executable

@staticmethod
def run(args: Tuple[str, str, str, str, str]) -> str:
def run(args: List[str]) -> str:
"""
Executes the Selenium Manager Binary.
:Args:
- args: the components of the command being executed.
:Returns: The log string containing the driver location.
"""
command = " ".join(args)
logger.debug(f"Executing: {command}")
logger.info(f"Executing: {command}")
completed_proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
stderr = completed_proc.stderr.decode("utf-8").rstrip("\n")
output = json.loads(stdout)
result = output["result"]["message"]
if completed_proc.returncode:
raise SeleniumManagerException(f"Selenium manager failed for: {command}.\n{result}{stderr}")
raise SeleniumManagerException(f"Selenium Manager failed for: {command}.\n{result}{stderr}")
else:
# Selenium Manager exited 0 successfully, return executable path and print warnings (if any)
# Selenium Manager exited successfully, return executable path and print warnings
for item in output["logs"]:
if item["level"] == "WARN":
logger.warning(item["message"])
Expand Down
25 changes: 23 additions & 2 deletions py/test/selenium/webdriver/common/selenium_manager_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# specific language governing permissions and limitations
# under the License.

from unittest.mock import Mock

import pytest

from selenium.common.exceptions import SeleniumManagerException
Expand All @@ -30,9 +32,28 @@ def test_non_supported_browser_raises_sme():
_ = SeleniumManager().driver_location(options)


def test_browser_version_is_used_for_sm(mocker):
import subprocess

mock_run = mocker.patch("subprocess.run")
mocked_result = Mock()
mocked_result.configure_mock(
**{"stdout.decode.return_value": '{"result": {"message": "driver"}, "logs": []}', "returncode": 0}
)
mock_run.return_value = mocked_result
options = Options()
options.capabilities["browserName"] = "chrome"
options.browser_version = 110

_ = SeleniumManager().driver_location(options)
args, kwargs = subprocess.run.call_args
assert "--browser-version" in args[0]
assert "110" in args[0]


def test_stderr_is_propagated_to_exception_messages():
msg = r"Selenium manager failed for:.* --browser foo --output json\.\nInvalid browser name: foo\n"
msg = r"Selenium Manager failed for:.* --browser foo --output json\.\nInvalid browser name: foo\n"
with pytest.raises(SeleniumManagerException, match=msg):
manager = SeleniumManager()
binary = manager.get_binary()
_ = manager.run((str(binary), "--browser", "foo", "--output", "json"))
_ = manager.run([str(binary), "--browser", "foo", "--output", "json"])

0 comments on commit bd24090

Please sign in to comment.