seleniumbase 4.43.2__tar.gz → 4.44.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {seleniumbase-4.43.2/seleniumbase.egg-info → seleniumbase-4.44.0}/PKG-INFO +7 -3
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/README.md +4 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/pyproject.toml +4 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/requirements.txt +2 -2
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/browser_launcher.py +88 -4
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/detect_b_ver.py +4 -1
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/sb_cdp.py +100 -47
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/base_case.py +53 -7
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/constants.py +24 -9
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/js_utils.py +2 -2
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/page_actions.py +1 -1
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/driver_manager.py +116 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/pytest_plugin.py +173 -2
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/sb_manager.py +120 -1
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/selenium_plugin.py +125 -0
- seleniumbase-4.44.0/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/cdp_util.py +14 -0
- seleniumbase-4.44.0/seleniumbase/utilities/__init__.py +0 -0
- seleniumbase-4.44.0/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- seleniumbase-4.44.0/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0/seleniumbase.egg-info}/PKG-INFO +7 -3
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase.egg-info/SOURCES.txt +4 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase.egg-info/requires.txt +2 -2
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/setup.py +6 -2
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/.gitignore +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/LICENSE +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/MANIFEST.in +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/install.sh +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/pytest.ini +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/sbase/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/sbase/__main__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/sbase/steps.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/drivers/cft_drivers → seleniumbase-4.44.0/seleniumbase/drivers/atlas_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/drivers/chs_drivers → seleniumbase-4.44.0/seleniumbase/drivers/brave_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/extensions → seleniumbase-4.44.0/seleniumbase/drivers/cft_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/fixtures → seleniumbase-4.44.0/seleniumbase/drivers/chs_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/js_code → seleniumbase-4.44.0/seleniumbase/drivers/comet_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/masterqa → seleniumbase-4.44.0/seleniumbase/drivers/opera_drivers}/__init__.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/plugins → seleniumbase-4.44.0/seleniumbase/extensions}/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.43.2/seleniumbase/resources → seleniumbase-4.44.0/seleniumbase/fixtures}/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/utilities → seleniumbase-4.44.0/seleniumbase/js_code}/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/utilities/selenium_grid → seleniumbase-4.44.0/seleniumbase/masterqa}/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.43.2/seleniumbase/utilities/selenium_ide → seleniumbase-4.44.0/seleniumbase/plugins}/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/setup.cfg +0 -0
- {seleniumbase-4.43.2 → seleniumbase-4.44.0}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.44.0
|
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -60,7 +60,7 @@ Requires-Python: >=3.8
|
|
|
60
60
|
Description-Content-Type: text/markdown
|
|
61
61
|
License-File: LICENSE
|
|
62
62
|
Requires-Dist: pip>=25.0.1; python_version < "3.9"
|
|
63
|
-
Requires-Dist: pip>=25.
|
|
63
|
+
Requires-Dist: pip>=25.3; python_version >= "3.9"
|
|
64
64
|
Requires-Dist: packaging>=25.0
|
|
65
65
|
Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
66
66
|
Requires-Dist: setuptools>=80.9.0; python_version >= "3.10"
|
|
@@ -113,7 +113,7 @@ Requires-Dist: websocket-client~=1.8.0; python_version < "3.9"
|
|
|
113
113
|
Requires-Dist: websocket-client~=1.9.0; python_version >= "3.9"
|
|
114
114
|
Requires-Dist: selenium==4.27.1; python_version < "3.9"
|
|
115
115
|
Requires-Dist: selenium==4.32.0; python_version >= "3.9" and python_version < "3.10"
|
|
116
|
-
Requires-Dist: selenium==4.
|
|
116
|
+
Requires-Dist: selenium==4.38.0; python_version >= "3.10"
|
|
117
117
|
Requires-Dist: cssselect==1.2.0; python_version < "3.9"
|
|
118
118
|
Requires-Dist: cssselect==1.3.0; python_version >= "3.9"
|
|
119
119
|
Requires-Dist: sortedcontainers==2.4.0
|
|
@@ -871,6 +871,10 @@ pytest test_coffee_cart.py --trace
|
|
|
871
871
|
--edge # (Shortcut for "--browser=edge".)
|
|
872
872
|
--firefox # (Shortcut for "--browser=firefox".)
|
|
873
873
|
--safari # (Shortcut for "--browser=safari".)
|
|
874
|
+
--opera # (Shortcut for "--browser=opera".)
|
|
875
|
+
--brave # (Shortcut for "--browser=brave".)
|
|
876
|
+
--comet # (Shortcut for "--browser=comet".)
|
|
877
|
+
--atlas # (Shortcut for "--browser=atlas".)
|
|
874
878
|
--settings-file=FILE # (Override default SeleniumBase settings.)
|
|
875
879
|
--env=ENV # (Set the test env. Access with "self.env" in tests.)
|
|
876
880
|
--account=STR # (Set account. Access with "self.account" in tests.)
|
|
@@ -652,6 +652,10 @@ pytest test_coffee_cart.py --trace
|
|
|
652
652
|
--edge # (Shortcut for "--browser=edge".)
|
|
653
653
|
--firefox # (Shortcut for "--browser=firefox".)
|
|
654
654
|
--safari # (Shortcut for "--browser=safari".)
|
|
655
|
+
--opera # (Shortcut for "--browser=opera".)
|
|
656
|
+
--brave # (Shortcut for "--browser=brave".)
|
|
657
|
+
--comet # (Shortcut for "--browser=comet".)
|
|
658
|
+
--atlas # (Shortcut for "--browser=atlas".)
|
|
655
659
|
--settings-file=FILE # (Override default SeleniumBase settings.)
|
|
656
660
|
--env=ENV # (Set the test env. Access with "self.env" in tests.)
|
|
657
661
|
--account=STR # (Set account. Access with "self.account" in tests.)
|
|
@@ -43,6 +43,10 @@ packages = [
|
|
|
43
43
|
"seleniumbase.drivers",
|
|
44
44
|
"seleniumbase.drivers.cft_drivers",
|
|
45
45
|
"seleniumbase.drivers.chs_drivers",
|
|
46
|
+
"seleniumbase.drivers.opera_drivers",
|
|
47
|
+
"seleniumbase.drivers.brave_drivers",
|
|
48
|
+
"seleniumbase.drivers.comet_drivers",
|
|
49
|
+
"seleniumbase.drivers.atlas_drivers",
|
|
46
50
|
"seleniumbase.extensions",
|
|
47
51
|
"seleniumbase.fixtures",
|
|
48
52
|
"seleniumbase.js_code",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
pip>=25.0.1;python_version<"3.9"
|
|
2
|
-
pip>=25.
|
|
2
|
+
pip>=25.3;python_version>="3.9"
|
|
3
3
|
packaging>=25.0
|
|
4
4
|
setuptools~=70.2;python_version<"3.10"
|
|
5
5
|
setuptools>=80.9.0;python_version>="3.10"
|
|
@@ -52,7 +52,7 @@ websocket-client~=1.8.0;python_version<"3.9"
|
|
|
52
52
|
websocket-client~=1.9.0;python_version>="3.9"
|
|
53
53
|
selenium==4.27.1;python_version<"3.9"
|
|
54
54
|
selenium==4.32.0;python_version>="3.9" and python_version<"3.10"
|
|
55
|
-
selenium==4.
|
|
55
|
+
selenium==4.38.0;python_version>="3.10"
|
|
56
56
|
cssselect==1.2.0;python_version<"3.9"
|
|
57
57
|
cssselect==1.3.0;python_version>="3.9"
|
|
58
58
|
sortedcontainers==2.4.0
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.
|
|
2
|
+
__version__ = "4.44.0"
|
|
@@ -28,6 +28,10 @@ from seleniumbase import decorators
|
|
|
28
28
|
from seleniumbase import drivers # webdriver storage folder for SeleniumBase
|
|
29
29
|
from seleniumbase.drivers import cft_drivers # chrome-for-testing
|
|
30
30
|
from seleniumbase.drivers import chs_drivers # chrome-headless-shell
|
|
31
|
+
from seleniumbase.drivers import opera_drivers # still uses chromedriver
|
|
32
|
+
from seleniumbase.drivers import brave_drivers # still uses chromedriver
|
|
33
|
+
from seleniumbase.drivers import comet_drivers # still uses chromedriver
|
|
34
|
+
from seleniumbase.drivers import atlas_drivers # still uses chromedriver
|
|
31
35
|
from seleniumbase import extensions # browser extensions storage folder
|
|
32
36
|
from seleniumbase.config import settings
|
|
33
37
|
from seleniumbase.core import detect_b_ver
|
|
@@ -44,6 +48,10 @@ urllib3.disable_warnings()
|
|
|
44
48
|
DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
|
|
45
49
|
DRIVER_DIR_CFT = os.path.dirname(os.path.realpath(cft_drivers.__file__))
|
|
46
50
|
DRIVER_DIR_CHS = os.path.dirname(os.path.realpath(chs_drivers.__file__))
|
|
51
|
+
DRIVER_DIR_OPERA = os.path.dirname(os.path.realpath(opera_drivers.__file__))
|
|
52
|
+
DRIVER_DIR_BRAVE = os.path.dirname(os.path.realpath(brave_drivers.__file__))
|
|
53
|
+
DRIVER_DIR_COMET = os.path.dirname(os.path.realpath(comet_drivers.__file__))
|
|
54
|
+
DRIVER_DIR_ATLAS = os.path.dirname(os.path.realpath(atlas_drivers.__file__))
|
|
47
55
|
# Make sure that the SeleniumBase DRIVER_DIR is at the top of the System PATH
|
|
48
56
|
# (Changes to the System PATH with os.environ only last during the test run)
|
|
49
57
|
if not os.environ["PATH"].startswith(DRIVER_DIR):
|
|
@@ -543,6 +551,19 @@ def uc_open_with_tab(driver, url):
|
|
|
543
551
|
|
|
544
552
|
def uc_open_with_reconnect(driver, url, reconnect_time=None):
|
|
545
553
|
"""Open a url, disconnect chromedriver, wait, and reconnect."""
|
|
554
|
+
if (
|
|
555
|
+
hasattr(sb_config, "_cdp_browser")
|
|
556
|
+
and sb_config._cdp_browser in ["comet", "opera", "atlas"]
|
|
557
|
+
):
|
|
558
|
+
if not __is_cdp_swap_needed(driver):
|
|
559
|
+
if not driver.current_url.startswith(
|
|
560
|
+
("about", "data", "chrome")
|
|
561
|
+
):
|
|
562
|
+
driver.get("about:blank")
|
|
563
|
+
uc_activate_cdp_mode(driver, url)
|
|
564
|
+
else:
|
|
565
|
+
driver.cdp.open(url)
|
|
566
|
+
return
|
|
546
567
|
url = shared_utils.fix_url_as_needed(url)
|
|
547
568
|
if __is_cdp_swap_needed(driver):
|
|
548
569
|
driver.cdp.get(url)
|
|
@@ -877,6 +898,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
877
898
|
cdp.assert_not_in = CDPM.assert_not_in
|
|
878
899
|
cdp.scroll_into_view = CDPM.scroll_into_view
|
|
879
900
|
cdp.scroll_to_y = CDPM.scroll_to_y
|
|
901
|
+
cdp.scroll_by_y = CDPM.scroll_by_y
|
|
880
902
|
cdp.scroll_to_top = CDPM.scroll_to_top
|
|
881
903
|
cdp.scroll_to_bottom = CDPM.scroll_to_bottom
|
|
882
904
|
cdp.scroll_up = CDPM.scroll_up
|
|
@@ -1218,8 +1240,8 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
|
|
|
1218
1240
|
driver.cdp.minimize()
|
|
1219
1241
|
driver.cdp.set_window_rect(win_x, win_y, width, height)
|
|
1220
1242
|
if IS_WINDOWS:
|
|
1221
|
-
x = x * width_ratio
|
|
1222
|
-
y = y * width_ratio
|
|
1243
|
+
x = x * (width_ratio + 0.03)
|
|
1244
|
+
y = y * (width_ratio - 0.03)
|
|
1223
1245
|
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
|
|
1224
1246
|
return
|
|
1225
1247
|
with suppress(Exception):
|
|
@@ -1260,7 +1282,7 @@ def _uc_gui_click_captcha(
|
|
|
1260
1282
|
ctype=None,
|
|
1261
1283
|
):
|
|
1262
1284
|
cdp_mode_on_at_start = __is_cdp_swap_needed(driver)
|
|
1263
|
-
if cdp_mode_on_at_start
|
|
1285
|
+
if cdp_mode_on_at_start:
|
|
1264
1286
|
return driver.cdp.gui_click_captcha()
|
|
1265
1287
|
_on_a_captcha_page = None
|
|
1266
1288
|
if ctype == "cf_t":
|
|
@@ -1952,6 +1974,15 @@ def get_valid_binary_names_for_browser(browser):
|
|
|
1952
1974
|
raise Exception("Invalid combination for OS browser binaries!")
|
|
1953
1975
|
|
|
1954
1976
|
|
|
1977
|
+
def _special_binary_exists(location, name):
|
|
1978
|
+
filename = str(location).split("/")[-1].split("\\")[-1]
|
|
1979
|
+
return (
|
|
1980
|
+
location
|
|
1981
|
+
and str(name).lower() in filename.lower()
|
|
1982
|
+
and os.path.exists(location)
|
|
1983
|
+
)
|
|
1984
|
+
|
|
1985
|
+
|
|
1955
1986
|
def _repair_chromedriver(chrome_options, headless_options, mcv=None):
|
|
1956
1987
|
if mcv:
|
|
1957
1988
|
subprocess.check_call(
|
|
@@ -2960,6 +2991,18 @@ def get_driver(
|
|
|
2960
2991
|
and sb_config.binary_location == "chs"
|
|
2961
2992
|
):
|
|
2962
2993
|
driver_dir = DRIVER_DIR_CHS
|
|
2994
|
+
if _special_binary_exists(binary_location, "opera"):
|
|
2995
|
+
driver_dir = DRIVER_DIR_OPERA
|
|
2996
|
+
sb_config._cdp_browser = "opera"
|
|
2997
|
+
if _special_binary_exists(binary_location, "brave"):
|
|
2998
|
+
driver_dir = DRIVER_DIR_BRAVE
|
|
2999
|
+
sb_config._cdp_browser = "brave"
|
|
3000
|
+
if _special_binary_exists(binary_location, "comet"):
|
|
3001
|
+
driver_dir = DRIVER_DIR_COMET
|
|
3002
|
+
sb_config._cdp_browser = "comet"
|
|
3003
|
+
if _special_binary_exists(binary_location, "atlas"):
|
|
3004
|
+
driver_dir = DRIVER_DIR_ATLAS
|
|
3005
|
+
sb_config._cdp_browser = "atlas"
|
|
2963
3006
|
if (
|
|
2964
3007
|
hasattr(sb_config, "settings")
|
|
2965
3008
|
and hasattr(sb_config.settings, "NEW_DRIVER_DIR")
|
|
@@ -2972,6 +3015,8 @@ def get_driver(
|
|
|
2972
3015
|
browser_name = browser
|
|
2973
3016
|
else:
|
|
2974
3017
|
browser_name = "chrome" # The default if not specified
|
|
3018
|
+
if browser_name in constants.ChromiumSubs.chromium_subs:
|
|
3019
|
+
browser_name = "chrome"
|
|
2975
3020
|
browser_name = browser_name.lower()
|
|
2976
3021
|
if headless2 and browser_name == constants.Browser.FIREFOX:
|
|
2977
3022
|
headless2 = False # Only for Chromium
|
|
@@ -3919,6 +3964,18 @@ def get_local_driver(
|
|
|
3919
3964
|
):
|
|
3920
3965
|
special_chrome = True
|
|
3921
3966
|
driver_dir = DRIVER_DIR_CHS
|
|
3967
|
+
if _special_binary_exists(binary_location, "opera"):
|
|
3968
|
+
special_chrome = True
|
|
3969
|
+
driver_dir = DRIVER_DIR_OPERA
|
|
3970
|
+
if _special_binary_exists(binary_location, "brave"):
|
|
3971
|
+
special_chrome = True
|
|
3972
|
+
driver_dir = DRIVER_DIR_BRAVE
|
|
3973
|
+
if _special_binary_exists(binary_location, "comet"):
|
|
3974
|
+
special_chrome = True
|
|
3975
|
+
driver_dir = DRIVER_DIR_COMET
|
|
3976
|
+
if _special_binary_exists(binary_location, "atlas"):
|
|
3977
|
+
special_chrome = True
|
|
3978
|
+
driver_dir = DRIVER_DIR_ATLAS
|
|
3922
3979
|
if (
|
|
3923
3980
|
hasattr(sb_config, "settings")
|
|
3924
3981
|
and hasattr(sb_config.settings, "NEW_DRIVER_DIR")
|
|
@@ -4756,6 +4813,27 @@ def get_local_driver(
|
|
|
4756
4813
|
)
|
|
4757
4814
|
return extend_driver(driver)
|
|
4758
4815
|
elif browser_name == constants.Browser.GOOGLE_CHROME:
|
|
4816
|
+
set_chromium = None
|
|
4817
|
+
if _special_binary_exists(binary_location, "opera"):
|
|
4818
|
+
set_chromium = "opera"
|
|
4819
|
+
local_chromedriver = DRIVER_DIR_OPERA + "/chromedriver"
|
|
4820
|
+
if IS_WINDOWS:
|
|
4821
|
+
local_chromedriver = DRIVER_DIR_OPERA + "/chromedriver.exe"
|
|
4822
|
+
if _special_binary_exists(binary_location, "brave"):
|
|
4823
|
+
set_chromium = "brave"
|
|
4824
|
+
local_chromedriver = DRIVER_DIR_BRAVE + "/chromedriver"
|
|
4825
|
+
if IS_WINDOWS:
|
|
4826
|
+
local_chromedriver = DRIVER_DIR_BRAVE + "/chromedriver.exe"
|
|
4827
|
+
if _special_binary_exists(binary_location, "comet"):
|
|
4828
|
+
set_chromium = "comet"
|
|
4829
|
+
local_chromedriver = DRIVER_DIR_COMET + "/chromedriver"
|
|
4830
|
+
if IS_WINDOWS:
|
|
4831
|
+
local_chromedriver = DRIVER_DIR_COMET + "/chromedriver.exe"
|
|
4832
|
+
if _special_binary_exists(binary_location, "atlas"):
|
|
4833
|
+
set_chromium = "atlas"
|
|
4834
|
+
local_chromedriver = DRIVER_DIR_ATLAS + "/chromedriver"
|
|
4835
|
+
if IS_WINDOWS:
|
|
4836
|
+
local_chromedriver = DRIVER_DIR_ATLAS + "/chromedriver.exe"
|
|
4759
4837
|
try:
|
|
4760
4838
|
chrome_options = _set_chrome_options(
|
|
4761
4839
|
browser_name,
|
|
@@ -4877,6 +4955,12 @@ def get_local_driver(
|
|
|
4877
4955
|
major_chrome_version = None
|
|
4878
4956
|
if major_chrome_version:
|
|
4879
4957
|
use_version = major_chrome_version
|
|
4958
|
+
if (
|
|
4959
|
+
set_chromium == "opera"
|
|
4960
|
+
and use_version.isnumeric()
|
|
4961
|
+
and int(use_version) < 130
|
|
4962
|
+
):
|
|
4963
|
+
use_version = "130" # Special case
|
|
4880
4964
|
ch_driver_version = None
|
|
4881
4965
|
path_chromedriver = chromedriver_on_path()
|
|
4882
4966
|
if os.path.exists(local_chromedriver):
|
|
@@ -4894,7 +4978,7 @@ def get_local_driver(
|
|
|
4894
4978
|
ch_driver_version = output
|
|
4895
4979
|
if driver_version == "keep":
|
|
4896
4980
|
driver_version = ch_driver_version
|
|
4897
|
-
elif path_chromedriver:
|
|
4981
|
+
elif path_chromedriver and not set_chromium:
|
|
4898
4982
|
try:
|
|
4899
4983
|
make_driver_executable_if_not(path_chromedriver)
|
|
4900
4984
|
except Exception as e:
|
|
@@ -278,11 +278,12 @@ def opera_on_windows_path(browser_type=None):
|
|
|
278
278
|
),
|
|
279
279
|
):
|
|
280
280
|
for subitem in (
|
|
281
|
+
"Programs/Opera",
|
|
281
282
|
"Opera",
|
|
282
283
|
"Opera/Application",
|
|
283
284
|
):
|
|
284
285
|
try:
|
|
285
|
-
candidates.append(os.sep.join((item, subitem, "
|
|
286
|
+
candidates.append(os.sep.join((item, subitem, "opera.exe")))
|
|
286
287
|
except TypeError:
|
|
287
288
|
pass
|
|
288
289
|
for candidate in candidates:
|
|
@@ -336,6 +337,7 @@ def comet_on_windows_path(browser_type=None):
|
|
|
336
337
|
):
|
|
337
338
|
for subitem in (
|
|
338
339
|
"Comet/Application",
|
|
340
|
+
"Programs/Comet",
|
|
339
341
|
):
|
|
340
342
|
try:
|
|
341
343
|
candidates.append(os.sep.join((item, subitem, "Comet.exe")))
|
|
@@ -364,6 +366,7 @@ def atlas_on_windows_path(browser_type=None):
|
|
|
364
366
|
):
|
|
365
367
|
for subitem in (
|
|
366
368
|
"Atlas/Application",
|
|
369
|
+
"Programs/Atlas",
|
|
367
370
|
):
|
|
368
371
|
try:
|
|
369
372
|
candidates.append(os.sep.join((item, subitem, "Atlas.exe")))
|
|
@@ -1029,12 +1029,19 @@ class CDPMethods():
|
|
|
1029
1029
|
return self.loop.run_until_complete(self.page.js_dumps(obj_name))
|
|
1030
1030
|
|
|
1031
1031
|
def maximize(self):
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
self.
|
|
1036
|
-
|
|
1037
|
-
|
|
1032
|
+
try:
|
|
1033
|
+
if self.get_window()[1].window_state.value == "maximized":
|
|
1034
|
+
return
|
|
1035
|
+
elif self.get_window()[1].window_state.value == "minimized":
|
|
1036
|
+
self.loop.run_until_complete(self.page.maximize())
|
|
1037
|
+
time.sleep(0.044)
|
|
1038
|
+
return self.loop.run_until_complete(self.page.maximize())
|
|
1039
|
+
except Exception:
|
|
1040
|
+
with suppress(Exception):
|
|
1041
|
+
width = self.evaluate("screen.availWidth;")
|
|
1042
|
+
height = self.evaluate("screen.availHeight;")
|
|
1043
|
+
self.__set_window_rect(0, 0, width, height)
|
|
1044
|
+
return
|
|
1038
1045
|
|
|
1039
1046
|
def minimize(self):
|
|
1040
1047
|
if self.get_window()[1].window_state.value != "minimized":
|
|
@@ -1333,6 +1340,17 @@ class CDPMethods():
|
|
|
1333
1340
|
x = window_rect["x"] + element_rect["x"]
|
|
1334
1341
|
y = w_bottom_y - viewport_height + element_rect["y"]
|
|
1335
1342
|
y_scroll_offset = window_rect["pageYOffset"]
|
|
1343
|
+
if (
|
|
1344
|
+
hasattr(sb_config, "_cdp_browser")
|
|
1345
|
+
and sb_config._cdp_browser == "opera"
|
|
1346
|
+
):
|
|
1347
|
+
# Handle special case where Opera side panel shifts coordinates
|
|
1348
|
+
x_offset = window_rect["outerWidth"] - window_rect["innerWidth"]
|
|
1349
|
+
if x_offset > 56:
|
|
1350
|
+
x_offset = 56
|
|
1351
|
+
elif x_offset < 22:
|
|
1352
|
+
x_offset = 0
|
|
1353
|
+
x = x + x_offset
|
|
1336
1354
|
y = y - y_scroll_offset
|
|
1337
1355
|
x = x + window_rect["scrollX"]
|
|
1338
1356
|
y = y + window_rect["scrollY"]
|
|
@@ -1674,11 +1692,6 @@ class CDPMethods():
|
|
|
1674
1692
|
import pyautogui
|
|
1675
1693
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
|
1676
1694
|
screen_width, screen_height = pyautogui.size()
|
|
1677
|
-
if (
|
|
1678
|
-
hasattr(sb_config, "_cdp_browser")
|
|
1679
|
-
and sb_config._cdp_browser == "opera"
|
|
1680
|
-
):
|
|
1681
|
-
x = x + 55
|
|
1682
1695
|
if x < 0 or y < 0 or x > screen_width or y > screen_height:
|
|
1683
1696
|
raise Exception(
|
|
1684
1697
|
"PyAutoGUI cannot click on point (%s, %s)"
|
|
@@ -1719,20 +1732,20 @@ class CDPMethods():
|
|
|
1719
1732
|
win_x = window_rect["x"]
|
|
1720
1733
|
win_y = window_rect["y"]
|
|
1721
1734
|
scr_width = pyautogui.size().width
|
|
1722
|
-
self.
|
|
1723
|
-
self.__add_light_pause()
|
|
1724
|
-
win_width = self.get_window_size()["width"]
|
|
1735
|
+
win_width = self.evaluate("screen.availWidth;")
|
|
1725
1736
|
width_ratio = round(float(scr_width) / float(win_width), 2)
|
|
1726
1737
|
width_ratio += 0.01
|
|
1727
1738
|
if width_ratio < 0.45 or width_ratio > 2.55:
|
|
1728
1739
|
width_ratio = 1.01
|
|
1729
1740
|
sb_config._saved_width_ratio = width_ratio
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1741
|
+
with suppress(Exception):
|
|
1742
|
+
self.get_window() # If this fails, skip the rest
|
|
1743
|
+
self.minimize()
|
|
1744
|
+
self.__add_light_pause()
|
|
1745
|
+
self.__set_window_rect(win_x, win_y, width, height)
|
|
1746
|
+
self.__add_light_pause()
|
|
1747
|
+
x = x * (width_ratio + 0.03)
|
|
1748
|
+
y = y * (width_ratio - 0.03)
|
|
1736
1749
|
self.bring_active_window_to_front()
|
|
1737
1750
|
self.__gui_click_x_y(x, y, timeframe=timeframe, uc_lock=False)
|
|
1738
1751
|
|
|
@@ -1760,8 +1773,43 @@ class CDPMethods():
|
|
|
1760
1773
|
return True
|
|
1761
1774
|
return False
|
|
1762
1775
|
|
|
1776
|
+
def _on_a_g_recaptcha_page(self):
|
|
1777
|
+
time.sleep(0.042)
|
|
1778
|
+
source = self.get_page_source()
|
|
1779
|
+
if not source or len(source) < 400:
|
|
1780
|
+
time.sleep(0.22)
|
|
1781
|
+
source = self.get_page_source()
|
|
1782
|
+
if (
|
|
1783
|
+
'id="recaptcha-token"' in source
|
|
1784
|
+
or 'title="reCAPTCHA"' in source
|
|
1785
|
+
):
|
|
1786
|
+
return True
|
|
1787
|
+
return False
|
|
1788
|
+
|
|
1789
|
+
def __gui_click_recaptcha(self):
|
|
1790
|
+
selector = None
|
|
1791
|
+
if self.is_element_visible('iframe[title="reCAPTCHA"]'):
|
|
1792
|
+
selector = 'iframe[title="reCAPTCHA"]'
|
|
1793
|
+
else:
|
|
1794
|
+
return
|
|
1795
|
+
with suppress(Exception):
|
|
1796
|
+
time.sleep(0.08)
|
|
1797
|
+
element_rect = self.get_gui_element_rect(selector, timeout=1)
|
|
1798
|
+
e_x = element_rect["x"]
|
|
1799
|
+
e_y = element_rect["y"]
|
|
1800
|
+
x = e_x + 29
|
|
1801
|
+
y = e_y + 35
|
|
1802
|
+
sb_config._saved_cf_x_y = (x, y)
|
|
1803
|
+
time.sleep(0.08)
|
|
1804
|
+
self.gui_click_x_y(x, y)
|
|
1805
|
+
|
|
1763
1806
|
def gui_click_captcha(self):
|
|
1764
|
-
if
|
|
1807
|
+
if self._on_a_cf_turnstile_page():
|
|
1808
|
+
pass
|
|
1809
|
+
elif self._on_a_g_recaptcha_page():
|
|
1810
|
+
self.__gui_click_recaptcha()
|
|
1811
|
+
return
|
|
1812
|
+
else:
|
|
1765
1813
|
return
|
|
1766
1814
|
selector = None
|
|
1767
1815
|
if (
|
|
@@ -1926,7 +1974,7 @@ class CDPMethods():
|
|
|
1926
1974
|
if not shared_utils.is_windows():
|
|
1927
1975
|
y = e_y + 32
|
|
1928
1976
|
else:
|
|
1929
|
-
y = e_y +
|
|
1977
|
+
y = e_y + 28
|
|
1930
1978
|
sb_config._saved_cf_x_y = (x, y)
|
|
1931
1979
|
time.sleep(0.08)
|
|
1932
1980
|
self.gui_click_x_y(x, y)
|
|
@@ -1936,12 +1984,6 @@ class CDPMethods():
|
|
|
1936
1984
|
import pyautogui
|
|
1937
1985
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
|
1938
1986
|
screen_width, screen_height = pyautogui.size()
|
|
1939
|
-
if (
|
|
1940
|
-
hasattr(sb_config, "_cdp_browser")
|
|
1941
|
-
and sb_config._cdp_browser == "opera"
|
|
1942
|
-
):
|
|
1943
|
-
x1 = x1 + 55
|
|
1944
|
-
x2 = x2 + 55
|
|
1945
1987
|
if x1 < 0 or y1 < 0 or x1 > screen_width or y1 > screen_height:
|
|
1946
1988
|
raise Exception(
|
|
1947
1989
|
"PyAutoGUI cannot drag-drop from point (%s, %s)"
|
|
@@ -1986,18 +2028,18 @@ class CDPMethods():
|
|
|
1986
2028
|
win_x = window_rect["x"]
|
|
1987
2029
|
win_y = window_rect["y"]
|
|
1988
2030
|
scr_width = pyautogui.size().width
|
|
1989
|
-
self.
|
|
1990
|
-
self.__add_light_pause()
|
|
1991
|
-
win_width = self.get_window_size()["width"]
|
|
2031
|
+
win_width = self.evaluate("screen.availWidth;")
|
|
1992
2032
|
width_ratio = round(float(scr_width) / float(win_width), 2)
|
|
1993
2033
|
width_ratio += 0.01
|
|
1994
2034
|
if width_ratio < 0.45 or width_ratio > 2.55:
|
|
1995
2035
|
width_ratio = 1.01
|
|
1996
2036
|
sb_config._saved_width_ratio = width_ratio
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2037
|
+
with suppress(Exception):
|
|
2038
|
+
self.get_window() # If this fails, skip the rest
|
|
2039
|
+
self.minimize()
|
|
2040
|
+
self.__add_light_pause()
|
|
2041
|
+
self.__set_window_rect(win_x, win_y, width, height)
|
|
2042
|
+
self.__add_light_pause()
|
|
2001
2043
|
x1 = x1 * width_ratio
|
|
2002
2044
|
y1 = y1 * (width_ratio - 0.02)
|
|
2003
2045
|
x2 = x2 * width_ratio
|
|
@@ -2033,11 +2075,6 @@ class CDPMethods():
|
|
|
2033
2075
|
import pyautogui
|
|
2034
2076
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
|
2035
2077
|
screen_width, screen_height = pyautogui.size()
|
|
2036
|
-
if (
|
|
2037
|
-
hasattr(sb_config, "_cdp_browser")
|
|
2038
|
-
and sb_config._cdp_browser == "opera"
|
|
2039
|
-
):
|
|
2040
|
-
x = x + 55
|
|
2041
2078
|
if x < 0 or y < 0 or x > screen_width or y > screen_height:
|
|
2042
2079
|
raise Exception(
|
|
2043
2080
|
"PyAutoGUI cannot hover on point (%s, %s)"
|
|
@@ -2084,15 +2121,14 @@ class CDPMethods():
|
|
|
2084
2121
|
width_ratio = sb_config._saved_width_ratio
|
|
2085
2122
|
else:
|
|
2086
2123
|
scr_width = pyautogui.size().width
|
|
2087
|
-
self.
|
|
2088
|
-
self.__add_light_pause()
|
|
2089
|
-
win_width = self.get_window_size()["width"]
|
|
2124
|
+
win_width = self.evaluate("screen.availWidth;")
|
|
2090
2125
|
width_ratio = round(float(scr_width) / float(win_width), 2)
|
|
2091
2126
|
width_ratio += 0.01
|
|
2092
2127
|
if width_ratio < 0.45 or width_ratio > 2.55:
|
|
2093
2128
|
width_ratio = 1.01
|
|
2094
2129
|
sb_config._saved_width_ratio = width_ratio
|
|
2095
|
-
|
|
2130
|
+
with suppress(Exception):
|
|
2131
|
+
self.__set_window_rect(win_x, win_y, width, height)
|
|
2096
2132
|
self.__add_light_pause()
|
|
2097
2133
|
self.bring_active_window_to_front()
|
|
2098
2134
|
elif (
|
|
@@ -2118,7 +2154,7 @@ class CDPMethods():
|
|
|
2118
2154
|
if width > 0 and height > 0:
|
|
2119
2155
|
x, y = self.get_gui_element_center(selector)
|
|
2120
2156
|
self.bring_active_window_to_front()
|
|
2121
|
-
self.__gui_hover_x_y(x, y, timeframe=timeframe)
|
|
2157
|
+
self.__gui_hover_x_y(x, y, timeframe=timeframe, uc_lock=False)
|
|
2122
2158
|
self.__slow_mode_pause_if_set()
|
|
2123
2159
|
self.loop.run_until_complete(self.page.wait())
|
|
2124
2160
|
|
|
@@ -2664,6 +2700,13 @@ class CDPMethods():
|
|
|
2664
2700
|
self.loop.run_until_complete(self.page.evaluate(js_code))
|
|
2665
2701
|
self.loop.run_until_complete(self.page.wait())
|
|
2666
2702
|
|
|
2703
|
+
def scroll_by_y(self, y):
|
|
2704
|
+
y = int(y)
|
|
2705
|
+
js_code = "window.scrollBy(0, %s);" % y
|
|
2706
|
+
with suppress(Exception):
|
|
2707
|
+
self.loop.run_until_complete(self.page.evaluate(js_code))
|
|
2708
|
+
self.loop.run_until_complete(self.page.wait())
|
|
2709
|
+
|
|
2667
2710
|
def scroll_to_top(self):
|
|
2668
2711
|
js_code = "window.scrollTo(0, 0);"
|
|
2669
2712
|
with suppress(Exception):
|
|
@@ -2677,11 +2720,21 @@ class CDPMethods():
|
|
|
2677
2720
|
self.loop.run_until_complete(self.page.wait())
|
|
2678
2721
|
|
|
2679
2722
|
def scroll_up(self, amount=25):
|
|
2680
|
-
|
|
2723
|
+
"""Scrolls up as a percentage of the page."""
|
|
2724
|
+
try:
|
|
2725
|
+
self.loop.run_until_complete(self.page.scroll_up(amount))
|
|
2726
|
+
except Exception:
|
|
2727
|
+
amount = self.get_window_size()["height"] * amount / 100
|
|
2728
|
+
self.execute_script("window.scrollBy(0, -%s);" % amount)
|
|
2681
2729
|
self.loop.run_until_complete(self.page.wait())
|
|
2682
2730
|
|
|
2683
2731
|
def scroll_down(self, amount=25):
|
|
2684
|
-
|
|
2732
|
+
"""Scrolls down as a percentage of the page."""
|
|
2733
|
+
try:
|
|
2734
|
+
self.loop.run_until_complete(self.page.scroll_down(amount))
|
|
2735
|
+
except Exception:
|
|
2736
|
+
amount = self.get_window_size()["height"] * amount / 100
|
|
2737
|
+
self.execute_script("window.scrollBy(0, %s);" % amount)
|
|
2685
2738
|
self.loop.run_until_complete(self.page.wait())
|
|
2686
2739
|
|
|
2687
2740
|
def save_page_source(self, name, folder=None):
|
|
@@ -3577,9 +3577,18 @@ class BaseCase(unittest.TestCase):
|
|
|
3577
3577
|
self.cdp.maximize()
|
|
3578
3578
|
return
|
|
3579
3579
|
self._check_browser()
|
|
3580
|
-
|
|
3580
|
+
try:
|
|
3581
|
+
self.driver.maximize_window()
|
|
3582
|
+
except Exception:
|
|
3583
|
+
with suppress(Exception):
|
|
3584
|
+
width = self.execute_script("return screen.availWidth;")
|
|
3585
|
+
height = self.execute_script("return screen.availHeight;")
|
|
3586
|
+
self.set_window_rect(0, 0, width, height)
|
|
3581
3587
|
self.__demo_mode_pause_if_active(tiny=True)
|
|
3582
3588
|
|
|
3589
|
+
def maximize(self):
|
|
3590
|
+
self.maximize_window()
|
|
3591
|
+
|
|
3583
3592
|
def minimize_window(self):
|
|
3584
3593
|
self.__check_scope()
|
|
3585
3594
|
if self.__is_cdp_swap_needed():
|
|
@@ -3589,6 +3598,9 @@ class BaseCase(unittest.TestCase):
|
|
|
3589
3598
|
self.driver.minimize_window()
|
|
3590
3599
|
self.__demo_mode_pause_if_active(tiny=True)
|
|
3591
3600
|
|
|
3601
|
+
def minimize(self):
|
|
3602
|
+
self.minimize_window()
|
|
3603
|
+
|
|
3592
3604
|
def reset_window_size(self):
|
|
3593
3605
|
self.__check_scope()
|
|
3594
3606
|
if self.__is_cdp_swap_needed():
|
|
@@ -4344,7 +4356,7 @@ class BaseCase(unittest.TestCase):
|
|
|
4344
4356
|
if self.is_chromium():
|
|
4345
4357
|
try:
|
|
4346
4358
|
if self.maximize_option:
|
|
4347
|
-
self.
|
|
4359
|
+
self.maximize_window()
|
|
4348
4360
|
self.wait_for_ready_state_complete()
|
|
4349
4361
|
else:
|
|
4350
4362
|
pass # Now handled in browser_launcher.py
|
|
@@ -4354,7 +4366,7 @@ class BaseCase(unittest.TestCase):
|
|
|
4354
4366
|
elif self.browser == "firefox":
|
|
4355
4367
|
try:
|
|
4356
4368
|
if self.maximize_option:
|
|
4357
|
-
self.
|
|
4369
|
+
self.maximize_window()
|
|
4358
4370
|
self.wait_for_ready_state_complete()
|
|
4359
4371
|
else:
|
|
4360
4372
|
with suppress(Exception):
|
|
@@ -4364,7 +4376,7 @@ class BaseCase(unittest.TestCase):
|
|
|
4364
4376
|
elif self.browser == "safari":
|
|
4365
4377
|
if self.maximize_option:
|
|
4366
4378
|
try:
|
|
4367
|
-
self.
|
|
4379
|
+
self.maximize_window()
|
|
4368
4380
|
self.wait_for_ready_state_complete()
|
|
4369
4381
|
except Exception:
|
|
4370
4382
|
pass # Keep existing browser resolution
|
|
@@ -6511,6 +6523,34 @@ class BaseCase(unittest.TestCase):
|
|
|
6511
6523
|
self.execute_script(scroll_script)
|
|
6512
6524
|
time.sleep(0.012)
|
|
6513
6525
|
|
|
6526
|
+
def scroll_by_y(self, y):
|
|
6527
|
+
"""Scrolls page by y pixels."""
|
|
6528
|
+
self.__check_scope()
|
|
6529
|
+
y = int(y)
|
|
6530
|
+
if self.__is_cdp_swap_needed():
|
|
6531
|
+
self.cdp.scroll_by_y(y)
|
|
6532
|
+
return
|
|
6533
|
+
scroll_script = "window.scrollBy(0, %s);" % y
|
|
6534
|
+
with suppress(Exception):
|
|
6535
|
+
self.execute_script(scroll_script)
|
|
6536
|
+
time.sleep(0.012)
|
|
6537
|
+
|
|
6538
|
+
def scroll_up(self, amount=25):
|
|
6539
|
+
"""Scrolls up as a percentage of the page."""
|
|
6540
|
+
if self.__is_cdp_swap_needed():
|
|
6541
|
+
self.cdp.scroll_up(amount)
|
|
6542
|
+
return
|
|
6543
|
+
amount = self.get_window_size()["height"] * amount / 100
|
|
6544
|
+
self.execute_script("window.scrollBy(0, -%s);" % amount)
|
|
6545
|
+
|
|
6546
|
+
def scroll_down(self, amount=25):
|
|
6547
|
+
"""Scrolls down as a percentage of the page."""
|
|
6548
|
+
if self.__is_cdp_swap_needed():
|
|
6549
|
+
self.cdp.scroll_down(amount)
|
|
6550
|
+
return
|
|
6551
|
+
amount = self.get_window_size()["height"] * amount / 100
|
|
6552
|
+
self.execute_script("window.scrollBy(0, %s);" % amount)
|
|
6553
|
+
|
|
6514
6554
|
def click_xpath(self, xpath):
|
|
6515
6555
|
"""Technically, self.click() automatically detects xpath selectors,
|
|
6516
6556
|
so self.click_xpath() is just a longer name for the same action."""
|
|
@@ -11408,7 +11448,13 @@ class BaseCase(unittest.TestCase):
|
|
|
11408
11448
|
|
|
11409
11449
|
def __is_cdp_swap_needed(self):
|
|
11410
11450
|
"""If the driver is disconnected, use a CDP method when available."""
|
|
11411
|
-
|
|
11451
|
+
cdp_swap_needed = shared_utils.is_cdp_swap_needed(self.driver)
|
|
11452
|
+
if cdp_swap_needed:
|
|
11453
|
+
if not self.cdp:
|
|
11454
|
+
self.cdp = self.driver.cdp
|
|
11455
|
+
return True
|
|
11456
|
+
else:
|
|
11457
|
+
return False
|
|
11412
11458
|
|
|
11413
11459
|
############
|
|
11414
11460
|
|
|
@@ -14001,7 +14047,7 @@ class BaseCase(unittest.TestCase):
|
|
|
14001
14047
|
)
|
|
14002
14048
|
raise Exception(message)
|
|
14003
14049
|
except InvalidArgumentException:
|
|
14004
|
-
if not self.
|
|
14050
|
+
if not self.is_chromium():
|
|
14005
14051
|
raise
|
|
14006
14052
|
chrome_version = self.driver.capabilities["browserVersion"]
|
|
14007
14053
|
major_chrome_version = chrome_version.split(".")[0]
|
|
@@ -14616,7 +14662,7 @@ class BaseCase(unittest.TestCase):
|
|
|
14616
14662
|
try:
|
|
14617
14663
|
shadow_root = element.shadow_root
|
|
14618
14664
|
except Exception:
|
|
14619
|
-
if self.
|
|
14665
|
+
if self.is_chromium():
|
|
14620
14666
|
chrome_dict = self.driver.capabilities["chrome"]
|
|
14621
14667
|
chrome_dr_version = chrome_dict["chromedriverVersion"]
|
|
14622
14668
|
chromedriver_version = chrome_dr_version.split(" ")[0]
|