Skip to content

Commit a1355a6

Browse files
noamkushsandre35noamk-hl
authored
Support latest selenium (#317)
* chore: remove py dependency * docker: fix context path * Release v4.0.2 * Support latest selenium. --------- Co-authored-by: Alexandre Muller <[email protected]> Co-authored-by: Noam Kushinsky <[email protected]>
1 parent d16cda7 commit a1355a6

20 files changed

+205
-191
lines changed

.github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ jobs:
4040
strategy:
4141
fail-fast: false
4242
matrix:
43-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
43+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
4444
include:
4545
- os: ubuntu-latest
4646
python-version: pypy3.9
4747
tox-env: py3.9
4848

4949
- os: ubuntu-latest
50-
python-version: 3.11
50+
python-version: 3.12
5151
tox-env: devel
5252

5353
steps:

docker/docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ services:
6767
webserver:
6868
container_name: webserver
6969
build:
70-
context: docker
70+
context: .
7171
environment:
7272
- PYTHONDONTWRITEBYTECODE=1
7373
networks:

docs/news.rst

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
Release Notes
22
=============
33

4+
4.0.2 (2023-09-13)
5+
------------------
6+
7+
* Support selenium 4.10-4.15
8+
9+
* Thanks to `@noamkush <https://github.com/noamkush>`_ for the PR.
10+
11+
* Remove py dependency
12+
13+
* Thanks to `@treiher <https://github.com/treiher>`_ for reporting the issue.
14+
15+
* Thanks to `@sandre35 <https://github.com/sandre35>`_ for the PR.
16+
417
4.0.1 (2023-05-28)
518
------------------
619

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ classifiers = [
4646
dependencies = [
4747
"pytest>=6.0.0",
4848
"pytest-base-url>=2.0.0",
49-
"pytest-html>=2.0.0",
49+
"pytest-html>=4.0.0",
5050
"pytest-variables>=2.0.0",
5151
"requests>=2.26.0",
52-
"selenium>=4.0.0",
52+
"selenium>=4.10.0",
5353
"tenacity>=6.0.0",
5454
]
5555
dynamic = [

src/pytest_selenium/drivers/browserstack.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

55
import pytest
6+
from selenium.webdriver.common.options import ArgOptions
67

78
from pytest_selenium.drivers.cloud import Provider
89
from pytest_selenium.exceptions import MissingCloudSettingError
@@ -93,23 +94,22 @@ def pytest_selenium_runtest_makereport(item, report, summary, extra):
9394
summary.append("WARNING: Failed to update job status: {0}".format(e))
9495

9596

96-
def driver_kwargs(request, test, capabilities, **kwargs):
97+
def driver_kwargs(test, capabilities, **kwargs):
9798
provider = BrowserStack()
9899
assert provider.job_access
99-
if (
100-
"bstack:options" in capabilities
101-
and type(capabilities["bstack:options"]) is dict
102-
):
103-
capabilities["bstack:options"].setdefault("sessionName", test)
104-
capabilities["bstack:options"].setdefault("userName", provider.username)
105-
capabilities["bstack:options"].setdefault("accessKey", provider.key)
100+
options = ArgOptions()
101+
bstack_options = capabilities.pop("bstack:options", None)
102+
if isinstance(bstack_options, dict):
103+
bstack_options.setdefault("sessionName", test)
104+
bstack_options.setdefault("userName", provider.username)
105+
bstack_options.setdefault("accessKey", provider.key)
106+
options.set_capability("bstack:options", bstack_options)
106107
else:
107-
capabilities.setdefault("name", test)
108-
capabilities.setdefault("browserstack.user", provider.username)
109-
capabilities.setdefault("browserstack.key", provider.key)
110-
kwargs = {
108+
options.set_capability("name", test)
109+
options.set_capability("browserstack.user", provider.username)
110+
options.set_capability("browserstack.key", provider.key)
111+
return {
111112
"command_executor": provider.executor,
112-
"desired_capabilities": capabilities,
113113
"keep_alive": True,
114+
"options": options,
114115
}
115-
return kwargs

src/pytest_selenium/drivers/chrome.py

+10-14
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,20 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
import pytest
55
from selenium.webdriver.chrome.options import Options
6+
from selenium.webdriver.chrome.service import Service
67

78

8-
def driver_kwargs(
9-
capabilities, driver_args, driver_log, driver_path, chrome_options, **kwargs
10-
):
11-
kwargs = {
12-
"desired_capabilities": capabilities,
13-
"service_log_path": driver_log,
14-
"options": chrome_options,
15-
}
16-
17-
if driver_args is not None:
18-
kwargs["service_args"] = driver_args
19-
if driver_path is not None:
20-
kwargs["executable_path"] = driver_path
21-
return kwargs
9+
def driver_kwargs(chrome_options, chrome_service, **kwargs):
10+
return {"options": chrome_options, "service": chrome_service}
2211

2312

2413
@pytest.fixture
2514
def chrome_options():
2615
return Options()
16+
17+
18+
@pytest.fixture
19+
def chrome_service(driver_path, driver_args, driver_log):
20+
return Service(
21+
executable_path=driver_path, service_args=driver_args, log_output=driver_log
22+
)

src/pytest_selenium/drivers/crossbrowsertesting.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

5-
from py.xml import html
5+
import html
66
import pytest
77

88
from pytest_selenium.drivers.cloud import Provider
@@ -113,13 +113,9 @@ def driver_kwargs(request, test, capabilities, **kwargs):
113113

114114

115115
def _video_html(video):
116-
html.__tagspec__.update(dict([(x, 1) for x in ("video", "source")]))
117-
video_attrs = {
118-
"controls": "",
119-
"poster": video.get("image"),
120-
"play-pause-on-click": "",
121-
"style": "border:1px solid #e6e6e6; float:right; height:240px; "
122-
"margin-left:5px; overflow:hidden; width:320px",
123-
}
124-
source_attrs = {"src": video.get("video"), "type": "video/mp4"}
125-
return str(html.video(html.source(**source_attrs), **video_attrs))
116+
return (
117+
f'<video controls="" play-pause-on-click="" poster="{html.escape(video.get("image"))}"'
118+
'style="border:1px solid #e6e6e6; float:right; height:240px; margin-left:5px; overflow:hidden; width:320px">'
119+
f'<source src="{html.escape(video.get("video"))}" type="video/mp4"></source>'
120+
"</video>"
121+
)

src/pytest_selenium/drivers/edge.py

+10-13
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,20 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
import pytest
55
from selenium.webdriver.edge.options import Options
6+
from selenium.webdriver.edge.service import Service
67

78

8-
def driver_kwargs(capabilities, driver_log, driver_path, edge_options, **kwargs):
9-
10-
kwargs = {
11-
"service_log_path": driver_log,
12-
"options": edge_options,
13-
}
14-
15-
if capabilities:
16-
kwargs["capabilities"] = capabilities
17-
if driver_path is not None:
18-
kwargs["executable_path"] = driver_path
19-
20-
return kwargs
9+
def driver_kwargs(edge_options, edge_service, **kwargs):
10+
return {"options": edge_options, "service": edge_service}
2111

2212

2313
@pytest.fixture
2414
def edge_options():
2515
return Options()
16+
17+
18+
@pytest.fixture
19+
def edge_service(driver_path, driver_args, driver_log):
20+
return Service(
21+
executable_path=driver_path, service_args=driver_args, log_output=driver_log
22+
)

src/pytest_selenium/drivers/firefox.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77

88
from selenium.webdriver.firefox.options import Options
9+
from selenium.webdriver.firefox.service import Service
910

1011
LOGGER = logging.getLogger(__name__)
1112

@@ -26,17 +27,8 @@ def pytest_configure(config):
2627
)
2728

2829

29-
def driver_kwargs(capabilities, driver_log, driver_path, firefox_options, **kwargs):
30-
kwargs = {"service_log_path": driver_log}
31-
32-
if capabilities:
33-
kwargs["capabilities"] = capabilities
34-
if driver_path is not None:
35-
kwargs["executable_path"] = driver_path
36-
37-
kwargs["options"] = firefox_options
38-
39-
return kwargs
30+
def driver_kwargs(firefox_options, firefox_service, **kwargs):
31+
return {"options": firefox_options, "service": firefox_service}
4032

4133

4234
@pytest.fixture
@@ -52,6 +44,13 @@ def firefox_options(request):
5244
return options
5345

5446

47+
@pytest.fixture
48+
def firefox_service(driver_path, driver_args, driver_log):
49+
return Service(
50+
executable_path=driver_path, service_args=driver_args, log_output=driver_log
51+
)
52+
53+
5554
def get_arguments_from_markers(node):
5655
arguments = []
5756
for m in node.iter_markers("firefox_arguments"):
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
# This Source Code Form is subject to the terms of the Mozilla Public
22
# License, v. 2.0. If a copy of the MPL was not distributed with this
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
import pytest
5+
from selenium.webdriver.ie.options import Options
6+
from selenium.webdriver.ie.service import Service
47

58

6-
def driver_kwargs(capabilities, driver_log, driver_path, **kwargs):
9+
def driver_kwargs(ie_options, ie_service, **kwargs):
10+
return {"options": ie_options, "service": ie_service}
711

8-
kwargs = {"service_log_path": driver_log}
912

10-
if capabilities:
11-
kwargs["capabilities"] = capabilities
12-
if driver_path is not None:
13-
kwargs["executable_path"] = driver_path
14-
return kwargs
13+
@pytest.fixture
14+
def ie_options():
15+
return Options()
16+
17+
18+
@pytest.fixture
19+
def ie_service(driver_path, driver_args, driver_log):
20+
return Service(
21+
executable_path=driver_path, service_args=driver_args, log_output=driver_log
22+
)

src/pytest_selenium/drivers/remote.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,28 @@
44

55
import os
66

7+
import pytest
8+
79
HOST = os.environ.get("SELENIUM_HOST", "localhost")
810
PORT = os.environ.get("SELENIUM_PORT", 4444)
911

1012

11-
def driver_kwargs(capabilities, host, port, **kwargs):
13+
def driver_kwargs(remote_options, host, port, **kwargs):
1214
host = host if host.startswith("http") else f"http://{host}"
1315
executor = f"{host}:{port}/wd/hub"
1416

15-
kwargs = {
17+
return {
1618
"command_executor": executor,
17-
"desired_capabilities": capabilities,
19+
"options": remote_options,
1820
}
19-
return kwargs
21+
22+
23+
@pytest.fixture
24+
def remote_options(chrome_options, firefox_options, edge_options, capabilities):
25+
browser = capabilities.get("browserName", "").upper()
26+
if browser == "CHROME":
27+
return chrome_options
28+
elif browser == "FIREFOX":
29+
return firefox_options
30+
elif browser == "EDGE":
31+
return edge_options

src/pytest_selenium/drivers/safari.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
# This Source Code Form is subject to the terms of the Mozilla Public
22
# License, v. 2.0. If a copy of the MPL was not distributed with this
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
import pytest
5+
from selenium.webdriver.safari.options import Options
6+
from selenium.webdriver.safari.service import Service
47

58

6-
def driver_kwargs(capabilities, driver_path, **kwargs):
7-
kwargs = {"desired_capabilities": capabilities}
8-
if driver_path is not None:
9-
kwargs["executable_path"] = driver_path
10-
return kwargs
9+
def driver_kwargs(safari_options, safari_service, **kwargs):
10+
return {
11+
"options": safari_options,
12+
"service": safari_service,
13+
}
14+
15+
16+
@pytest.fixture
17+
def safari_options():
18+
return Options()
19+
20+
21+
@pytest.fixture
22+
def safari_service(driver_path, driver_args, driver_log):
23+
return Service(
24+
executable_path=driver_path, service_args=driver_args, log_output=driver_log
25+
)

0 commit comments

Comments
 (0)