Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: python-selen...@packages.debian.org Control: affects -1 + src:python-selenium
Please unblock package python-selenium [ Reason ] There was another micro update of python-selenium which includes these modifications (according to the documented upstream changes). Not all of these modification are located within the Python specific flavor of Selenium. There were added a lot more of type safe checking basically in this update and the -doc package got Sphinx related updates. Selenium 4.8.3 * Add fine grained control for arguments provided to service subprocesses by passing a `popen_kw` mapping for all services. * `Options` classes now allow `timeout` to be set partially and no longer raise an exception when all values are not provided. (#11623) * No longer sending `SIGKILL` to subprocesses in instances where `SIGTERM` was successful within 60 seconds. * Add CDP files for v111 and remove v108 * Pass default to `pop` when parsing service popen_kw * Using json output with Selenium Manager * Sphinx config update to keep invoked methods and shorter aliases in documentation (#11802) [ Impact ] User couldn't use the latest and greatest version of python-selenium in Debian bookworm. [ Tests ] All upstream tests were successfull, a small checking of some local used Selenium based snippets did also work as expected. Also the DebCI did not shown any regressions. [ Risks ] There are no real risk to me, looking at the upstream changes I don't see any potential pitfalls. python-selenium is a key package and needs an manual unblock by the RT. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] There is also a differential view visable in the source repository on GitHub. https://github.com/SeleniumHQ/selenium/compare/selenium-4.8.2-python...selenium-4.8.3-python But this is much bigger as the attached debdiff file as it also contains parts of upstream code which we do filter out to fullfill the DFSG requirements. The Debian related modifications are only this rather small part. $ git diff debian/4.8.2+dfsg-1 debian/ diff --git a/debian/changelog b/debian/changelog index e10915a..ef494f9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-selenium (4.8.3+dfsg-1) unstable; urgency=medium + + * [9118276] New upstream version 4.8.3+dfsg + * [5bb3ae9] debian/: Move d/docs to d/python-selenium-doc.links + + -- Carsten Schoenert <c.schoen...@t-online.de> Wed, 29 Mar 2023 12:14:56 +0200 + python-selenium (4.8.2+dfsg-1) unstable; urgency=medium * [8e56110] New upstream version 4.8.2+dfsg diff --git a/debian/docs b/debian/docs deleted file mode 100644 index a1320b1..0000000 --- a/debian/docs +++ /dev/null @@ -1 +0,0 @@ -README.rst diff --git a/debian/python-selenium-doc.links b/debian/python-selenium-doc.links new file mode 100644 index 0000000..567b3ed --- /dev/null +++ b/debian/python-selenium-doc.links @@ -0,0 +1,4 @@ +# We can't just copy/install the original symlink from the source, it would +# point to a non existing file after the packaging. So do the correct linking +# here. +usr/share/doc/python-selenium-doc/html/_sources/index.rst.txt usr/share/doc/python-selenium-doc/README.rst unblock python-selenium/4.8.3+dfsg-1
diff -Nru python-selenium-4.8.2+dfsg/CHANGES python-selenium-4.8.3+dfsg/CHANGES --- python-selenium-4.8.2+dfsg/CHANGES 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/CHANGES 2023-03-24 19:05:50.000000000 +0100 @@ -1,3 +1,12 @@ +Selenium 4.8.3 +* Add fine grained control for arguments provided to service subprocesses by passing a `popen_kw` mapping for all services. +* `Options` classes now allow `timeout` to be set partially and no longer raise an exception when all values are not provided. (#11623) +* No longer sending `SIGKILL` to subprocesses in instances where `SIGTERM` was successful within 60 seconds. +* Add CDP files for v111 and remove v108 +* Pass default to `pop` when parsing service popen_kw +* Using json output with Selenium Manager +* Sphinx config update to keep invoked methods and shorter aliases in documentation (#11802) + Selenium 4.8.2 * Update tox.ini for a valid "isort" version (#11667) * Undo a bug fix that caused a worse bug. (#11666) diff -Nru python-selenium-4.8.2+dfsg/conftest.py python-selenium-4.8.3+dfsg/conftest.py --- python-selenium-4.8.2+dfsg/conftest.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/conftest.py 2023-03-24 19:05:50.000000000 +0100 @@ -237,7 +237,9 @@ ) except Exception: print("Starting the Selenium server") - process = subprocess.Popen(["java", "-jar", _path, "standalone", "--port", "4444"]) + process = subprocess.Popen( + ["java", "-jar", _path, "standalone", "--port", "4444", "--selenium-manager", "true"] + ) print(f"Selenium server running as process: {process.pid}") assert wait_for_server(url, 10), f"Timed out waiting for Selenium server at {url}" print("Selenium server is ready") diff -Nru python-selenium-4.8.2+dfsg/CONTRIBUTING.md python-selenium-4.8.3+dfsg/CONTRIBUTING.md --- python-selenium-4.8.2+dfsg/CONTRIBUTING.md 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/CONTRIBUTING.md 2023-03-24 19:05:50.000000000 +0100 @@ -65,10 +65,11 @@ ### Step 1: Fork Fork the project [on Github](https://github.com/seleniumhq/selenium) -and check out your copy locally. +and check out your copy locally. Use `--depth 1` for a quick check out. +The repository is ~2GB and checking the whole history takes a while. ```shell -% git clone g...@github.com:username/selenium.git +% git clone g...@github.com:username/selenium.git --depth 1 % cd selenium % git remote add upstream git://github.com/seleniumhq/selenium.git ``` diff -Nru python-selenium-4.8.2+dfsg/debian/changelog python-selenium-4.8.3+dfsg/debian/changelog --- python-selenium-4.8.2+dfsg/debian/changelog 2023-02-20 20:12:51.000000000 +0100 +++ python-selenium-4.8.3+dfsg/debian/changelog 2023-03-29 12:14:56.000000000 +0200 @@ -1,3 +1,10 @@ +python-selenium (4.8.3+dfsg-1) unstable; urgency=medium + + * [9118276] New upstream version 4.8.3+dfsg + * [5bb3ae9] debian/: Move d/docs to d/python-selenium-doc.links + + -- Carsten Schoenert <c.schoen...@t-online.de> Wed, 29 Mar 2023 12:14:56 +0200 + python-selenium (4.8.2+dfsg-1) unstable; urgency=medium * [8e56110] New upstream version 4.8.2+dfsg diff -Nru python-selenium-4.8.2+dfsg/debian/docs python-selenium-4.8.3+dfsg/debian/docs --- python-selenium-4.8.2+dfsg/debian/docs 2023-02-20 20:12:51.000000000 +0100 +++ python-selenium-4.8.3+dfsg/debian/docs 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -README.rst diff -Nru python-selenium-4.8.2+dfsg/debian/python-selenium-doc.links python-selenium-4.8.3+dfsg/debian/python-selenium-doc.links --- python-selenium-4.8.2+dfsg/debian/python-selenium-doc.links 1970-01-01 01:00:00.000000000 +0100 +++ python-selenium-4.8.3+dfsg/debian/python-selenium-doc.links 2023-03-29 12:11:47.000000000 +0200 @@ -0,0 +1,4 @@ +# We can't just copy/install the original symlink from the source, it would +# point to a non existing file after the packaging. So do the correct linking +# here. +usr/share/doc/python-selenium-doc/html/_sources/index.rst.txt usr/share/doc/python-selenium-doc/README.rst diff -Nru python-selenium-4.8.2+dfsg/docs/source/conf.py python-selenium-4.8.3+dfsg/docs/source/conf.py --- python-selenium-4.8.2+dfsg/docs/source/conf.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/docs/source/conf.py 2023-03-24 19:05:50.000000000 +0100 @@ -271,5 +271,13 @@ # functions without docstrings. autodoc_default_flags = ['members', 'undoc-members'] +# configuration for keeping the methods that can be invoked on said classes +autodoc_default_options = { + 'members': True, + 'member-order': 'bysource', + 'undoc-members': True, + 'inherited-members': True, +} + # Include __init__ comments autoclass_content = "both" diff -Nru python-selenium-4.8.2+dfsg/docs/source/index.rst python-selenium-4.8.3+dfsg/docs/source/index.rst --- python-selenium-4.8.2+dfsg/docs/source/index.rst 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/docs/source/index.rst 2023-03-24 19:05:50.000000000 +0100 @@ -35,7 +35,7 @@ pip install -U selenium -Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.8.2.tar.gz), unarchive it, and run:: +Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.8.3.tar.gz), unarchive it, and run:: python setup.py install diff -Nru python-selenium-4.8.2+dfsg/README.rst python-selenium-4.8.3+dfsg/README.rst --- python-selenium-4.8.2+dfsg/README.rst 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/README.rst 2023-03-24 19:05:50.000000000 +0100 @@ -35,7 +35,7 @@ pip install -U selenium -Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.8.2.tar.gz), unarchive it, and run:: +Alternately, you can download the source distribution from `PyPI <https://pypi.org/project/selenium/#files>`_ (e.g. selenium-4.8.3.tar.gz), unarchive it, and run:: python setup.py install diff -Nru python-selenium-4.8.2+dfsg/requirements_lock.txt python-selenium-4.8.3+dfsg/requirements_lock.txt --- python-selenium-4.8.2+dfsg/requirements_lock.txt 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/requirements_lock.txt 2023-03-24 19:05:50.000000000 +0100 @@ -78,33 +78,30 @@ # via # -r py/requirements.txt # cryptography -cryptography==38.0.3 \ - --hash=sha256:068147f32fa662c81aebab95c74679b401b12b57494872886eb5c1139250ec5d \ - --hash=sha256:06fc3cc7b6f6cca87bd56ec80a580c88f1da5306f505876a71c8cfa7050257dd \ - --hash=sha256:25c1d1f19729fb09d42e06b4bf9895212292cb27bb50229f5aa64d039ab29146 \ - --hash=sha256:402852a0aea73833d982cabb6d0c3bb582c15483d29fb7085ef2c42bfa7e38d7 \ - --hash=sha256:4e269dcd9b102c5a3d72be3c45d8ce20377b8076a43cbed6f660a1afe365e436 \ - --hash=sha256:5419a127426084933076132d317911e3c6eb77568a1ce23c3ac1e12d111e61e0 \ - --hash=sha256:554bec92ee7d1e9d10ded2f7e92a5d70c1f74ba9524947c0ba0c850c7b011828 \ - --hash=sha256:5e89468fbd2fcd733b5899333bc54d0d06c80e04cd23d8c6f3e0542358c6060b \ - --hash=sha256:65535bc550b70bd6271984d9863a37741352b4aad6fb1b3344a54e6950249b55 \ - --hash=sha256:6ab9516b85bebe7aa83f309bacc5f44a61eeb90d0b4ec125d2d003ce41932d36 \ - --hash=sha256:6addc3b6d593cd980989261dc1cce38263c76954d758c3c94de51f1e010c9a50 \ - --hash=sha256:728f2694fa743a996d7784a6194da430f197d5c58e2f4e278612b359f455e4a2 \ - --hash=sha256:785e4056b5a8b28f05a533fab69febf5004458e20dad7e2e13a3120d8ecec75a \ - --hash=sha256:78cf5eefac2b52c10398a42765bfa981ce2372cbc0457e6bf9658f41ec3c41d8 \ - --hash=sha256:7f836217000342d448e1c9a342e9163149e45d5b5eca76a30e84503a5a96cab0 \ - --hash=sha256:8d41a46251bf0634e21fac50ffd643216ccecfaf3701a063257fe0b2be1b6548 \ - --hash=sha256:984fe150f350a3c91e84de405fe49e688aa6092b3525f407a18b9646f6612320 \ - --hash=sha256:9b24bcff7853ed18a63cfb0c2b008936a9554af24af2fb146e16d8e1aed75748 \ - --hash=sha256:b1b35d9d3a65542ed2e9d90115dfd16bbc027b3f07ee3304fc83580f26e43249 \ - --hash=sha256:b1b52c9e5f8aa2b802d48bd693190341fae201ea51c7a167d69fc48b60e8a959 \ - --hash=sha256:bbf203f1a814007ce24bd4d51362991d5cb90ba0c177a9c08825f2cc304d871f \ - --hash=sha256:be243c7e2bfcf6cc4cb350c0d5cdf15ca6383bbcb2a8ef51d3c9411a9d4386f0 \ - --hash=sha256:bfbe6ee19615b07a98b1d2287d6a6073f734735b49ee45b11324d85efc4d5cbd \ - --hash=sha256:c46837ea467ed1efea562bbeb543994c2d1f6e800785bd5a2c98bc096f5cb220 \ - --hash=sha256:dfb4f4dd568de1b6af9f4cda334adf7d72cf5bc052516e1b2608b683375dd95c \ - --hash=sha256:ed7b00096790213e09eb11c97cc6e2b757f15f3d2f85833cd2d3ec3fe37c1722 +cryptography==39.0.1 \ + --hash=sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4 \ + --hash=sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f \ + --hash=sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885 \ + --hash=sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502 \ + --hash=sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41 \ + --hash=sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965 \ + --hash=sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e \ + --hash=sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc \ + --hash=sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad \ + --hash=sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505 \ + --hash=sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388 \ + --hash=sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6 \ + --hash=sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2 \ + --hash=sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef \ + --hash=sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac \ + --hash=sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695 \ + --hash=sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6 \ + --hash=sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336 \ + --hash=sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0 \ + --hash=sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c \ + --hash=sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106 \ + --hash=sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a \ + --hash=sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8 # via # -r py/requirements.txt # pyopenssl diff -Nru python-selenium-4.8.2+dfsg/requirements.txt python-selenium-4.8.3+dfsg/requirements.txt --- python-selenium-4.8.2+dfsg/requirements.txt 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/requirements.txt 2023-03-24 19:05:50.000000000 +0100 @@ -2,7 +2,7 @@ attrs==21.4.0 certifi==2022.12.07 cffi==1.15.0 -cryptography==38.0.3 +cryptography==39.0.1 dataclasses==0.6 debugpy==1.6.0 h11==0.13.0 diff -Nru python-selenium-4.8.2+dfsg/selenium/__init__.py python-selenium-4.8.3+dfsg/selenium/__init__.py --- python-selenium-4.8.2+dfsg/selenium/__init__.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/__init__.py 2023-03-24 19:05:50.000000000 +0100 @@ -16,4 +16,4 @@ # under the License. -__version__ = "4.8.2" +__version__ = "4.8.3" diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/chrome/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/chrome/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/chrome/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/chrome/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -39,6 +39,7 @@ service_args: typing.Optional[typing.List[str]] = None, log_path: typing.Optional[str] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ) -> None: super().__init__( executable_path=executable_path, @@ -47,4 +48,5 @@ log_path=log_path, env=env, start_error_message="Please see https://chromedriver.chromium.org/home", + **kwargs, ) diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/chromium/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/chromium/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/chromium/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/chromium/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -40,6 +40,7 @@ log_path: typing.Optional[str] = None, env: typing.Optional[typing.Mapping[str, str]] = None, start_error_message: typing.Optional[str] = None, + **kwargs, ) -> None: self.service_args = service_args or [] if log_path: @@ -50,6 +51,7 @@ port=port, env=env, start_error_message=start_error_message, + **kwargs, ) def command_line_args(self) -> typing.List[str]: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/input_device.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/input_device.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/input_device.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/input_device.py 2023-03-24 19:05:50.000000000 +0100 @@ -22,11 +22,7 @@ """Describes the input device being used for the action.""" def __init__(self, name=None): - if not name: - self.name = uuid.uuid4() - else: - self.name = name - + self.name = name or uuid.uuid4() self.actions = [] def add_action(self, action): diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/key_actions.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/key_actions.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/key_actions.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/key_actions.py 2023-03-24 19:05:50.000000000 +0100 @@ -14,6 +14,8 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +from __future__ import annotations + from ..utils import keys_to_typing from .interaction import KEY from .interaction import Interaction @@ -44,7 +46,7 @@ self.key_up(letter) return self - def _key_action(self, action, letter): + def _key_action(self, action, letter) -> KeyActions: meth = getattr(self.source, action) meth(letter) return self diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/key_input.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/key_input.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/key_input.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/key_input.py 2023-03-24 19:05:50.000000000 +0100 @@ -35,7 +35,7 @@ def create_key_up(self, key) -> None: self.add_action(TypingInteraction(self, "keyUp", key)) - def create_pause(self, pause_duration=0) -> None: + def create_pause(self, pause_duration: float = 0) -> None: self.add_action(Pause(self, pause_duration)) diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/pointer_actions.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/pointer_actions.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/pointer_actions.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/pointer_actions.py 2023-03-24 19:05:50.000000000 +0100 @@ -194,7 +194,7 @@ self.pointer_up(MouseButton.LEFT) return self - def pause(self, duration=0): + def pause(self, duration: float = 0): self.source.create_pause(duration) return self diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/pointer_input.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/pointer_input.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/pointer_input.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/pointer_input.py 2023-03-24 19:05:50.000000000 +0100 @@ -35,7 +35,14 @@ self.kind = kind self.name = name - def create_pointer_move(self, duration=DEFAULT_MOVE_DURATION, x=0, y=0, origin=None, **kwargs): + def create_pointer_move( + self, + duration=DEFAULT_MOVE_DURATION, + x: float = 0, + y: float = 0, + origin: typing.Optional[WebElement] = None, + **kwargs, + ): action = {"type": "pointerMove", "duration": duration, "x": x, "y": y, **kwargs} if isinstance(origin, WebElement): action["origin"] = {"element-6066-11e4-a52e-4f735466cecf": origin.id} @@ -53,7 +60,7 @@ def create_pointer_cancel(self): self.add_action({"type": "pointerCancel"}) - def create_pause(self, pause_duration): + def create_pause(self, pause_duration: float) -> None: self.add_action({"type": "pause", "duration": int(pause_duration * 1000)}) def encode(self): diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/wheel_actions.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/wheel_actions.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/wheel_actions.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/wheel_actions.py 2023-03-24 19:05:50.000000000 +0100 @@ -24,7 +24,7 @@ source = WheelInput("wheel") super().__init__(source) - def pause(self, duration=0): + def pause(self, duration: float = 0): self.source.create_pause(duration) return self diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/wheel_input.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/wheel_input.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/actions/wheel_input.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/actions/wheel_input.py 2023-03-24 19:05:50.000000000 +0100 @@ -73,5 +73,5 @@ } ) - def create_pause(self, pause_duration: Union[int, float]) -> None: + def create_pause(self, pause_duration: float) -> None: self.add_action({"type": "pause", "duration": int(pause_duration * 1000)}) diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/options.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/options.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/options.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/options.py 2023-03-24 19:05:50.000000000 +0100 @@ -127,7 +127,7 @@ :param timeouts: values in milliseconds for implicit wait, page load and script timeout """ - if all(x in timeouts.keys() for x in ("implicit", "pageLoad", "script")): + if all(x in ("implicit", "pageLoad", "script") for x in timeouts.keys()): self.set_capability("timeouts", timeouts) else: raise ValueError("Timeout keys can only be one of the following: implicit, pageLoad, script") diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/selenium_manager.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/selenium_manager.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/selenium_manager.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/selenium_manager.py 2023-03-24 19:05:50.000000000 +0100 @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +import json import logging import subprocess import sys @@ -70,14 +71,20 @@ if browser == "ie": browser = "iexplorer" - binary, flag, browser = str(self.get_binary()), "--browser", browser - result = self.run((binary, flag, 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)) executable = result.split("\t")[-1].strip() logger.debug(f"Using driver at: {executable}") return executable @staticmethod - def run(args: Tuple[str, str, str]) -> str: + def run(args: Tuple[str, str, str, str, str]) -> str: """ Executes the Selenium Manager Binary. :Args: @@ -89,8 +96,13 @@ 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{stdout}{stderr}") + raise SeleniumManagerException(f"Selenium manager failed for: {command}.\n{result}{stderr}") else: - # selenium manager exited 0 successfully, parse the executable path from stdout. - return stdout.split("\t")[-1].strip() + # Selenium Manager exited 0 successfully, return executable path and print warnings (if any) + for item in output["logs"]: + if item["level"] == "WARN": + logger.warning(item["message"]) + return result diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/common/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/common/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/common/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/common/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -58,13 +58,15 @@ log_file: SubprocessStdAlias = DEVNULL, env: typing.Optional[typing.Mapping[typing.Any, typing.Any]] = None, start_error_message: typing.Optional[str] = None, + **kwargs, ) -> None: self.path = executable self.port = port or utils.free_port() self.log_file = open(os.devnull, "wb") if not _HAS_NATIVE_DEVNULL and log_file == DEVNULL else log_file self.start_error_message = start_error_message or "" # Default value for every python subprocess: subprocess.Popen(..., creationflags=0) - self.creation_flags = 0 + self.popen_kw = kwargs.pop("popen_kw", {}) + self.creation_flags = self.popen_kw.pop("creation_flags", 0) self.env = env or os.environ @property @@ -167,9 +169,14 @@ except AttributeError: pass self.process.terminate() - self.process.wait(60) - # Todo: only SIGKILL if necessary; the process may be cleanly exited by now. - self.process.kill() + try: + self.process.wait(60) + except subprocess.TimeoutError: + logger.error( + "Service process refused to terminate gracefully with SIGTERM, escalating to SIGKILL.", + exc_info=True, + ) + self.process.kill() except OSError: logger.error("Error terminating service process.", exc_info=True) @@ -191,15 +198,17 @@ """ cmd = [path] cmd.extend(self.command_line_args()) + close_file_descriptors = self.popen_kw.pop("close_fds", system() != "Windows") try: self.process = subprocess.Popen( cmd, env=self.env, - close_fds=system() != "Windows", + close_fds=close_file_descriptors, stdout=self.log_file, stderr=self.log_file, stdin=PIPE, creationflags=self.creation_flags, + **self.popen_kw, ) logger.debug(f"Started executable: `{self.path}` in a child process with pid: {self.process.pid}") except TypeError: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/edge/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/edge/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/edge/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/edge/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -43,6 +43,7 @@ log_path: typing.Optional[str] = None, service_args: typing.Optional[typing.List[str]] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ) -> None: self.service_args = service_args or [] @@ -61,4 +62,5 @@ log_path=log_path, env=env, start_error_message="Please download from https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/", + **kwargs, ) diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/edge/webdriver.py python-selenium-4.8.3+dfsg/selenium/webdriver/edge/webdriver.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/edge/webdriver.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/edge/webdriver.py 2023-03-24 19:05:50.000000000 +0100 @@ -30,9 +30,8 @@ class WebDriver(ChromiumDriver): """Controls the Microsoft Edge driver and allows you to drive the browser. - You will need to download the MSEdgeDriver (Chromium) executable - from https://developer.microsoft.com/en-us/microsoft- - edge/tools/webdriver/ + You will need to download the MSEdgeDriver executable from + https://developer.microsoft.com/microsoft-edge/tools/webdriver/ """ def __init__( diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/firefox/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/firefox/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/firefox/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/firefox/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -42,12 +42,19 @@ service_args: typing.Optional[typing.List[str]] = None, log_path: typing.Optional[str] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ) -> None: # Todo: This is vastly inconsistent, requires a follow up to standardise. file = log_path or "geckodriver.log" log_file = open(file, "a+", encoding="utf-8") self.service_args = service_args or [] - super().__init__(executable=executable_path, port=port, log_file=log_file, env=env) + super().__init__( + executable=executable_path, + port=port, + log_file=log_file, + env=env, + **kwargs, + ) # Set a port for CDP if "--connect-existing" not in self.service_args: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/firefox/webdriver.py python-selenium-4.8.3+dfsg/selenium/webdriver/firefox/webdriver.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/firefox/webdriver.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/firefox/webdriver.py 2023-03-24 19:05:50.000000000 +0100 @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. import base64 +import logging import os import warnings import zipfile @@ -32,6 +33,8 @@ from .service import DEFAULT_EXECUTABLE_PATH from .service import Service +logger = logging.getLogger(__name__) + # Default for log_path variable. To be deleted when deprecations for arguments are removed. DEFAULT_LOG_PATH = None DEFAULT_SERVICE_LOG_PATH = "geckodriver.log" @@ -212,8 +215,24 @@ rmtree(self.profile.path) if self.profile.tempfolder: rmtree(self.profile.tempfolder) - except Exception as e: - print(str(e)) + except Exception: + logger.exception("Unable to remove profile specific paths.") + + self._close_binary_file_handle() + + def _close_binary_file_handle(self) -> None: + """Attempts to close the underlying file handles for `FirefoxBinary` + instances if they are used and open. + + To keep inline with other cleanup raising here is swallowed and + will not cause a runtime error. + """ + try: + if isinstance(self.binary, FirefoxBinary): + if hasattr(self.binary._log_file, "close"): + self.binary._log_file.close() + except Exception: + logger.exception("Unable to close open file handle for firefox binary log file.") @property def firefox_profile(self): diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/ie/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/ie/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/ie/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/ie/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -32,6 +32,7 @@ host: typing.Optional[str] = None, log_level: typing.Optional[str] = None, log_file: typing.Optional[str] = None, + **kwargs, ) -> None: """Creates a new instance of the Service. @@ -56,6 +57,7 @@ executable_path, port=port, start_error_message="Please download from https://www.selenium.dev/downloads/ and read up at https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver", + **kwargs, ) def command_line_args(self) -> List[str]: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/__init__.py python-selenium-4.8.3+dfsg/selenium/webdriver/__init__.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/__init__.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/__init__.py 2023-03-24 19:05:50.000000000 +0100 @@ -36,7 +36,7 @@ from .wpewebkit.options import Options as WPEWebKitOptions # noqa from .wpewebkit.webdriver import WebDriver as WPEWebKit # noqa -__version__ = "4.8.2" +__version__ = "4.8.3" # We need an explicit __all__ because the above won't otherwise be exported. __all__ = [ diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/remote/errorhandler.py python-selenium-4.8.3+dfsg/selenium/webdriver/remote/errorhandler.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/remote/errorhandler.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/remote/errorhandler.py 2023-03-24 19:05:50.000000000 +0100 @@ -122,7 +122,7 @@ try: value = json.loads(value_json) - if len(value.keys()) == 1: + if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/remote/webdriver.py python-selenium-4.8.3+dfsg/selenium/webdriver/remote/webdriver.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/remote/webdriver.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/remote/webdriver.py 2023-03-24 19:05:50.000000000 +0100 @@ -685,6 +685,7 @@ """ with contextlib.suppress(NoSuchCookieException): return self.execute(Command.GET_COOKIE, {"name": name})["value"] + return None def delete_cookie(self, name) -> None: """Deletes a single cookie with the given name. diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/remote/webelement.py python-selenium-4.8.3+dfsg/selenium/webdriver/remote/webelement.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/remote/webelement.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/remote/webelement.py 2023-03-24 19:05:50.000000000 +0100 @@ -25,6 +25,7 @@ from base64 import encodebytes from hashlib import md5 as md5_hash from io import BytesIO +from typing import List from selenium.common.exceptions import JavascriptException from selenium.common.exceptions import WebDriverException @@ -424,7 +425,7 @@ return self._execute(Command.FIND_CHILD_ELEMENT, {"using": by, "value": value})["value"] - def find_elements(self, by=By.ID, value=None) -> list[WebElement]: + def find_elements(self, by=By.ID, value=None) -> List[WebElement]: """Find elements given a By strategy and locator. :Usage: diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/safari/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/safari/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/safari/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/safari/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -42,6 +42,7 @@ quiet: bool = False, service_args: typing.Optional[typing.List[str]] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ) -> None: self._check_executable(executable_path) self.service_args = service_args or [] @@ -52,6 +53,7 @@ port=port, log_file=log_file, # type: ignore env=env, + **kwargs, ) @staticmethod diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/webkitgtk/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/webkitgtk/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/webkitgtk/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/webkitgtk/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -39,10 +39,17 @@ log_path: typing.Optional[str] = None, service_args: typing.Optional[typing.List[str]] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ): self.service_args = service_args or [] log_file = open(log_path, "wb") if log_path else None - super().__init__(executable=executable_path, port=port, log_file=log_file, env=env) # type: ignore + super().__init__( + executable=executable_path, + port=port, + log_file=log_file, + env=env, + **kwargs, + ) # type: ignore def command_line_args(self) -> typing.List[str]: return ["-p", f"{self.port}"] + self.service_args diff -Nru python-selenium-4.8.2+dfsg/selenium/webdriver/wpewebkit/service.py python-selenium-4.8.3+dfsg/selenium/webdriver/wpewebkit/service.py --- python-selenium-4.8.2+dfsg/selenium/webdriver/wpewebkit/service.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/selenium/webdriver/wpewebkit/service.py 2023-03-24 19:05:50.000000000 +0100 @@ -39,10 +39,17 @@ log_path: typing.Optional[str] = None, service_args: typing.Optional[typing.List[str]] = None, env: typing.Optional[typing.Mapping[str, str]] = None, + **kwargs, ): self.service_args = service_args or [] log_file = open(log_path, "wb") if log_path else None - super().__init__(executable=executable_path, port=port, log_file=log_file, env=env) # type: ignore + super().__init__( + executable=executable_path, + port=port, + log_file=log_file, + env=env, + **kwargs, + ) # type: ignore def command_line_args(self) -> typing.List[str]: return ["-p", f"{self.port}"] + self.service_args diff -Nru python-selenium-4.8.2+dfsg/setup.py python-selenium-4.8.3+dfsg/setup.py --- python-selenium-4.8.2+dfsg/setup.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/setup.py 2023-03-24 19:05:50.000000000 +0100 @@ -27,7 +27,7 @@ setup_args = { 'cmdclass': {'install': install}, 'name': 'selenium', - 'version': "4.8.2", + 'version': "4.8.3", 'license': 'Apache 2.0', 'description': 'Python bindings for Selenium', 'long_description': open(join(abspath(dirname(__file__)), "README.rst")).read(), diff -Nru python-selenium-4.8.2+dfsg/test/selenium/webdriver/common/bidi_tests.py python-selenium-4.8.3+dfsg/test/selenium/webdriver/common/bidi_tests.py --- python-selenium-4.8.2+dfsg/test/selenium/webdriver/common/bidi_tests.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/test/selenium/webdriver/common/bidi_tests.py 2023-03-24 19:05:50.000000000 +0100 @@ -23,6 +23,8 @@ from selenium.webdriver.support.ui import WebDriverWait +@pytest.mark.xfail_firefox(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1819965") +@pytest.mark.xfail_remote(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1819965") @pytest.mark.xfail_safari async def test_check_console_messages(driver, pages): async with driver.bidi_connection() as session: @@ -35,6 +37,8 @@ assert messages["message"] == "I love cheese" +@pytest.mark.xfail_firefox(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1819965") +@pytest.mark.xfail_remote(reason="https://bugzilla.mozilla.org/show_bug.cgi?id=1819965") @pytest.mark.xfail_safari async def test_check_error_console_messages(driver, pages): async with driver.bidi_connection() as session: diff -Nru python-selenium-4.8.2+dfsg/test/selenium/webdriver/common/selenium_manager_tests.py python-selenium-4.8.3+dfsg/test/selenium/webdriver/common/selenium_manager_tests.py --- python-selenium-4.8.2+dfsg/test/selenium/webdriver/common/selenium_manager_tests.py 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/test/selenium/webdriver/common/selenium_manager_tests.py 2023-03-24 19:05:50.000000000 +0100 @@ -28,8 +28,8 @@ def test_stderr_is_propagated_to_exception_messages(): - msg = r"Selenium manager failed for:.* --browser foo\.\nERROR\tInvalid browser/driver name" + 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")) + _ = manager.run((str(binary), "--browser", "foo", "--output", "json")) diff -Nru python-selenium-4.8.2+dfsg/tox.ini python-selenium-4.8.3+dfsg/tox.ini --- python-selenium-4.8.2+dfsg/tox.ini 2023-02-18 00:17:10.000000000 +0100 +++ python-selenium-4.8.3+dfsg/tox.ini 2023-03-24 19:05:50.000000000 +0100 @@ -13,7 +13,7 @@ [testenv:mypy] skip_install = true deps = - mypy==0.991 + mypy==1.1.1 lxml==4.9.1 types-urllib3==1.26.25 types-certifi==2021.10.8.3