Skip to content

Commit

Permalink
Replace wdm with selenium manager (#317)
Browse files Browse the repository at this point in the history
Co-authored-by: Carlos Kidman <[email protected]>
  • Loading branch information
ElSnoMan and Carlos Kidman authored Sep 1, 2023
1 parent 236bf9c commit 17e4f81
Show file tree
Hide file tree
Showing 8 changed files with 458 additions and 485 deletions.
780 changes: 390 additions & 390 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion pylenium.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"page_load_wait_time": 0,
"options": [],
"capabilities": {},
"version": null,
"experimental_options": null,
"extension_paths": [],
"webdriver_kwargs": {},
Expand Down
3 changes: 1 addition & 2 deletions pylenium/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class DriverConfig(BaseModel):
seleniumwire_options: Dict = {}
extension_paths: Optional[List[str]] = None
webdriver_kwargs: Optional[Dict] = None
version: Optional[str] = None
local_path: str = ""


Expand Down Expand Up @@ -50,5 +49,5 @@ class TestCase(BaseModel):
name: str
file_path: Path

class Config:
class ConfigDict:
arbitrary_types_allowed = True
11 changes: 1 addition & 10 deletions pylenium/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,7 @@ def not_contain(self, text: str) -> bool:


class Pylenium:
"""The Pylenium API.
Chrome is the default local browser
Other supported browsers:
* Firefox
* Edge Chromium
* IE
* Opera
"""
"""The Pylenium API."""

def __init__(self, config: PyleniumConfig):
self.config = config
Expand Down
1 change: 0 additions & 1 deletion pylenium/scripts/pylenium.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"page_load_wait_time": 0,
"options": [],
"capabilities": {},
"version": null,
"experimental_options": null,
"extension_paths": [],
"webdriver_kwargs": {},
Expand Down
130 changes: 59 additions & 71 deletions pylenium/webdriver_factory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
""" Factory to build WebDrivers.
""" Factory to build WebDrivers, leveraging Selenium Manager.
The Pylenium class asks for a PyleniumConfig object to build a WebDriver,
so the `build_from_config` method is the "main" method in this module.
Expand All @@ -10,12 +10,9 @@
from selenium.webdriver.edge.options import Options as EdgeOptions
from selenium.webdriver.edge.service import Service as EdgeService
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.safari.service import Service as SafariService
from selenium.webdriver.remote.webdriver import WebDriver
from seleniumwire import webdriver as wire_driver
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager, IEDriverManager
from webdriver_manager.opera import OperaDriverManager

from pylenium.config import PyleniumConfig

Expand All @@ -25,9 +22,9 @@ class Browser:

CHROME = "chrome"
EDGE = "edge"
SAFARI = "safari"
FIREFOX = "firefox"
IE = "ie"
OPERA = "opera"


def build_capabilities(browser: str, capabilities: Optional[Dict]) -> Dict:
Expand All @@ -46,14 +43,14 @@ def build_capabilities(browser: str, capabilities: Optional[Dict]) -> Dict:

if browser == Browser.CHROME:
caps.update(webdriver.DesiredCapabilities.CHROME.copy())
elif browser == Browser.EDGE:
caps.update(webdriver.DesiredCapabilities.EDGE.copy())
elif browser == Browser.SAFARI:
caps.update(webdriver.DesiredCapabilities.SAFARI.copy())
elif browser == Browser.FIREFOX:
caps.update(webdriver.DesiredCapabilities.FIREFOX.copy())
elif browser == Browser.IE:
caps.update(webdriver.DesiredCapabilities.INTERNETEXPLORER.copy())
elif browser == Browser.OPERA:
caps.update(webdriver.DesiredCapabilities.OPERA.copy())
elif browser == Browser.EDGE:
caps.update(webdriver.DesiredCapabilities.EDGE.copy())
else:
raise ValueError(f"{browser} is not supported. Cannot build capabilities.")

Expand Down Expand Up @@ -83,14 +80,14 @@ def build_options(
browser = browser.lower()
if browser == Browser.CHROME:
options = webdriver.ChromeOptions()
elif browser == Browser.EDGE:
options = EdgeOptions()
elif browser == Browser.SAFARI:
options = webdriver.SafariOptions()
elif browser == Browser.FIREFOX:
options = webdriver.FirefoxOptions()
elif browser == Browser.IE:
options = webdriver.IeOptions()
elif browser == Browser.OPERA:
options = webdriver.ChromeOptions()
elif browser == Browser.EDGE:
options = EdgeOptions()
else:
raise ValueError(f"{browser} is not supported. Cannot build options.")

Expand Down Expand Up @@ -140,7 +137,6 @@ def build_from_config(config: PyleniumConfig) -> WebDriver:
return build_remote(browser, remote_url, **_config)

# Set fields for the rest of the non-remote drivers
_config["version"] = config.driver.version
_config["local_path"] = config.driver.local_path

# Build SeleniumWire driver if enabled
Expand All @@ -154,19 +150,18 @@ def build_from_config(config: PyleniumConfig) -> WebDriver:
# Otherwise, build the driver normally
if browser == Browser.CHROME:
return build_chrome(seleniumwire_options=None, **_config)
if browser == Browser.EDGE:
return build_edge(**_config)
if browser == Browser.SAFARI:
return build_safari(**_config)
if browser == Browser.FIREFOX:
return build_firefox(seleniumwire_options=None, **_config)
if browser == Browser.IE:
return build_ie(**_config)
if browser == Browser.OPERA:
return build_opera(**_config)
if browser == Browser.EDGE:
return build_edge(**_config)
raise ValueError(f"{config.driver.browser} is not supported. Cannot build WebDriver from config.")


def build_chrome(
version: Optional[str],
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
Expand All @@ -180,7 +175,6 @@ def build_chrome(
If seleniumwire_options is not None, a SeleniumWire Chrome WebDriver is built.
Args:
version: The desired version of Chrome.
options: The list of options/arguments to include.
capabilities: The dict of capabilities to include.
experimental_options: The list of experimental options to include.
Expand All @@ -199,15 +193,15 @@ def build_chrome(

if seleniumwire_options is None: # default to regular ChromeDriver
driver = webdriver.Chrome(
service=ChromeService(local_path or ChromeDriverManager(version=version).install()),
options=browser_options,
service=ChromeService(local_path or None),
**(webdriver_kwargs or {}),
)

else:
wire_options = seleniumwire_options or {}
driver = wire_driver.Chrome(
service=ChromeService(local_path or ChromeDriverManager(version=version).install()),
service=ChromeService(local_path or None),
options=browser_options,
seleniumwire_options=wire_options,
**(webdriver_kwargs or {}),
Expand All @@ -219,7 +213,6 @@ def build_chrome(


def build_edge(
version: Optional[str],
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
Expand All @@ -230,7 +223,6 @@ def build_edge(
"""Build an Edge WebDriver.
Args:
version: The desired version of Edge.
options: The list of options/arguments to include.
capabilities: The dict of capabilities to include.
experimental_options: The list of experimental options to include.
Expand All @@ -243,16 +235,50 @@ def build_edge(
"""
caps = build_capabilities(Browser.EDGE, capabilities)
browser_options = build_options(Browser.EDGE, options, experimental_options, extension_paths)
for cap in caps:
browser_options.set_capability(cap, caps[cap])

return webdriver.Edge(
service=EdgeService(local_path or EdgeChromiumDriverManager(version=version).install()),
capabilities=caps,
service=EdgeService(local_path or None),
options=browser_options,
**(webdriver_kwargs or {}),
)


def build_safari(
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
extension_paths: Optional[List[str]],
local_path: Optional[str],
webdriver_kwargs: Optional[Dict],
) -> WebDriver:
"""Build a Safari WebDriver.
Args:
options: The list of options/arguments to include.
capabilities: The dict of capabilities to include.
experimental_options: The list of experimental options to include.
extension_paths: The list of extensions to add to the browser.
local_path: The path to the driver binary.
webdriver_kwargs: additional keyword arguments to pass.
Usage:
driver = webdriver_factory.build_safari("latest", ["headless"])
"""
browser_options = build_options(Browser.SAFARI, options, experimental_options, extension_paths)
caps = build_capabilities(Browser.SAFARI, capabilities)
for cap in caps:
browser_options.set_capability(cap, caps[cap])

return webdriver.Safari(
options=options,
service=SafariService(local_path or None),
**(webdriver_kwargs or {}),
)


def build_firefox(
version: Optional[str],
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
Expand All @@ -266,7 +292,6 @@ def build_firefox(
If seleniumwire_options is not None, a SeleniumWire Firefox WebDriver is built.
Args:
version: The desired version of Firefox.
options: The list of options/arguments to include.
capabilities: The dict of capabilities to include.
experimental_options: The list of experimental options to include.
Expand All @@ -280,27 +305,26 @@ def build_firefox(
"""
caps = build_capabilities(Browser.FIREFOX, capabilities)
browser_options = build_options(Browser.FIREFOX, options, experimental_options, extension_paths)
for cap in caps:
browser_options.set_capability(cap, caps[cap])

if seleniumwire_options is None: # default to regular FirefoxDriver
return webdriver.Firefox(
service=FirefoxService(local_path or GeckoDriverManager(version=version).install()),
capabilities=caps,
options=browser_options,
service=FirefoxService(local_path or None),
**(webdriver_kwargs or {}),
)
else:
wire_options = seleniumwire_options or {}
return wire_driver.Firefox(
service=FirefoxService(local_path or GeckoDriverManager(version=version).install()),
capabilities=caps,
options=browser_options,
service=FirefoxService(local_path or None),
seleniumwire_options=wire_options,
**(webdriver_kwargs or {}),
)


def build_ie(
version: Optional[str],
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
Expand All @@ -311,7 +335,6 @@ def build_ie(
"""Build an Internet Explorer WebDriver.
Args:
version: The desired version of IE.
options: The list of options/arguments to include.
capabilities: The dict of capabilities.
experimental_options: The list of experimental options to include.
Expand All @@ -325,48 +348,13 @@ def build_ie(
caps = build_capabilities(Browser.IE, capabilities)
browser_options = build_options(Browser.IE, options, experimental_options, extension_paths)
return webdriver.Ie(
executable_path=local_path or IEDriverManager(version=version).install(),
executable_path=local_path or None,
options=browser_options,
capabilities=caps,
**(webdriver_kwargs or {}),
)


def build_opera(
version: Optional[str],
options: Optional[List[str]],
capabilities: Optional[Dict],
experimental_options: Optional[List[Dict]],
extension_paths: Optional[List[str]],
local_path: Optional[str],
webdriver_kwargs: Optional[Dict],
) -> WebDriver:
"""Build an Opera WebDriver.
Args:
version: The desired version of Opera.
options: The list of options/arguments to include.
capabilities: The dict of capabilities to include.
experimental_options: The list of experimental options to include.
extension_paths: The list of extensions to add to the browser.
local_path: The path to the driver binary.
webdriver_kwargs: additional keyword arguments to pass.
Usage:
driver = webdriver_factory.build_opera("latest", ["headless"])
"""
browser_options = build_options(Browser.OPERA, options, experimental_options, extension_paths)
caps = build_capabilities(Browser.OPERA, capabilities)
for cap in caps:
browser_options.set_capability(cap, caps[cap])

return webdriver.Opera(
local_path or OperaDriverManager(version=version).install(),
options=options,
**(webdriver_kwargs or {}),
)


def build_remote(
browser: str,
remote_url: str,
Expand Down
16 changes: 7 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyleniumio"
version = "1.19.1"
version = "1.20.0"
description = "The best of Selenium and Cypress in a single Python Package"
authors = ["Carlos <[email protected]>"]
license = "MIT"
Expand All @@ -12,24 +12,22 @@ pylenium = "pylenium.scripts.cli:app"

[tool.poetry.dependencies]
python = ">=3.8.1"
pydantic = "^1.10.9"
requests = "^2.31.0"
pytest-xdist = "^3.3.1"
pytest-parallel = "^0.1.1"
axe-selenium-python = "^2.1.6"
Faker = "^18.11.1"
webdriver-manager = "^3.8.6"
selenium-wire = "^5.1.0"
allure-pytest = "^2.13.2"
selenium = "^4.10.0"
pytest = "^7.3.2"
typer = { version = "^0.9.0", extras = ["all"] }
selenium = "^4.11.2"
pydantic = "^2.3.0"
faker = "^19.3.1"
pytest = "^7.4.0"

[tool.poetry.dev-dependencies]
black = "^23.3.0"
poethepoet = "^0.20.0"
black = "^23.7.0"
pytest-cov = "4.1.0"
flake8 = "^6.0.0"
poethepoet = "^0.22.0"

[tool.black]
line-length = 160
Expand Down
1 change: 0 additions & 1 deletion tests/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ def test_py_config_defaults(py_config):
assert py_config.driver.wait_time == 10
assert py_config.driver.page_load_wait_time == 0
assert py_config.driver.options == []
assert py_config.driver.version is None
assert py_config.driver.capabilities == {}
assert py_config.driver.experimental_options is None
assert py_config.driver.webdriver_kwargs == {}
Expand Down

0 comments on commit 17e4f81

Please sign in to comment.