seleniumbase 4.49.14__tar.gz → 4.50.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.
Potentially problematic release.
This version of seleniumbase might be problematic. Click here for more details.
- {seleniumbase-4.49.14/seleniumbase.egg-info → seleniumbase-4.50.0}/PKG-INFO +5 -3
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/README.md +2 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/requirements.txt +2 -2
- seleniumbase-4.50.0/seleniumbase/__version__.py +2 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/run.py +2 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_mkrec.py +10 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_recorder.py +233 -70
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/browser_launcher.py +1 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/sb_cdp.py +28 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/base_case.py +327 -119
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/pytest_plugin.py +32 -9
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/sb_manager.py +28 -9
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/selenium_plugin.py +32 -9
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/browser.py +19 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/tab.py +5 -1
- {seleniumbase-4.49.14 → seleniumbase-4.50.0/seleniumbase.egg-info}/PKG-INFO +5 -3
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase.egg-info/requires.txt +2 -2
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/setup.py +2 -2
- seleniumbase-4.49.14/seleniumbase/__version__.py +0 -2
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/.gitignore +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/LICENSE +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/MANIFEST.in +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/install.sh +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/pyproject.toml +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/pytest.ini +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/sbase/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/sbase/__main__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/sbase/steps.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/nest_asyncio.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.0}/setup.cfg +0 -0
- {seleniumbase-4.49.14 → seleniumbase-4.50.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.50.0
|
|
4
4
|
Summary: SeleniumBase is a framework for web crawling, scraping, and testing. Supports pytest. CDP Mode adds stealth. Includes many tools.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -66,7 +66,7 @@ Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
|
66
66
|
Requires-Dist: setuptools>=82.0.1; python_version >= "3.10"
|
|
67
67
|
Requires-Dist: wheel>=0.47.0
|
|
68
68
|
Requires-Dist: attrs>=26.1.0
|
|
69
|
-
Requires-Dist: certifi>=2026.
|
|
69
|
+
Requires-Dist: certifi>=2026.6.17
|
|
70
70
|
Requires-Dist: exceptiongroup>=1.3.1
|
|
71
71
|
Requires-Dist: websockets~=15.0.1; python_version < "3.10"
|
|
72
72
|
Requires-Dist: websockets>=16.0; python_version >= "3.10"
|
|
@@ -107,7 +107,7 @@ Requires-Dist: wsproto==1.2.0; python_version < "3.10"
|
|
|
107
107
|
Requires-Dist: wsproto~=1.3.2; python_version >= "3.10"
|
|
108
108
|
Requires-Dist: websocket-client~=1.9.0
|
|
109
109
|
Requires-Dist: selenium==4.32.0; python_version < "3.10"
|
|
110
|
-
Requires-Dist: selenium==4.
|
|
110
|
+
Requires-Dist: selenium==4.45.0; python_version >= "3.10"
|
|
111
111
|
Requires-Dist: cssselect==1.3.0; python_version < "3.10"
|
|
112
112
|
Requires-Dist: cssselect<2,>=1.4.0; python_version >= "3.10"
|
|
113
113
|
Requires-Dist: sortedcontainers==2.4.0
|
|
@@ -1009,6 +1009,8 @@ pytest test_coffee_cart.py --trace
|
|
|
1009
1009
|
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
|
|
1010
1010
|
--ee | --esc-end # (Lets the user end the current test via the ESC key.)
|
|
1011
1011
|
--recorder # (Enables the Recorder for turning browser actions into code.)
|
|
1012
|
+
--rec-sb-mgr # (A Recorder Mode that generates SB() context manager code.)
|
|
1013
|
+
--rec-sb-cdp # (A Recorder Mode that generates Pure CDP Mode sb_cdp code.)
|
|
1012
1014
|
--rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.)
|
|
1013
1015
|
--rec-sleep # (If the Recorder is enabled, also records self.sleep calls.)
|
|
1014
1016
|
--rec-print # (If the Recorder is enabled, prints output after tests end.)
|
|
@@ -823,6 +823,8 @@ pytest test_coffee_cart.py --trace
|
|
|
823
823
|
--verify-delay=SECONDS # (The delay before MasterQA verification checks.)
|
|
824
824
|
--ee | --esc-end # (Lets the user end the current test via the ESC key.)
|
|
825
825
|
--recorder # (Enables the Recorder for turning browser actions into code.)
|
|
826
|
+
--rec-sb-mgr # (A Recorder Mode that generates SB() context manager code.)
|
|
827
|
+
--rec-sb-cdp # (A Recorder Mode that generates Pure CDP Mode sb_cdp code.)
|
|
826
828
|
--rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.)
|
|
827
829
|
--rec-sleep # (If the Recorder is enabled, also records self.sleep calls.)
|
|
828
830
|
--rec-print # (If the Recorder is enabled, prints output after tests end.)
|
|
@@ -5,7 +5,7 @@ setuptools~=70.2;python_version<"3.10"
|
|
|
5
5
|
setuptools>=82.0.1;python_version>="3.10"
|
|
6
6
|
wheel>=0.47.0
|
|
7
7
|
attrs>=26.1.0
|
|
8
|
-
certifi>=2026.
|
|
8
|
+
certifi>=2026.6.17
|
|
9
9
|
exceptiongroup>=1.3.1
|
|
10
10
|
websockets~=15.0.1;python_version<"3.10"
|
|
11
11
|
websockets>=16.0;python_version>="3.10"
|
|
@@ -46,7 +46,7 @@ wsproto==1.2.0;python_version<"3.10"
|
|
|
46
46
|
wsproto~=1.3.2;python_version>="3.10"
|
|
47
47
|
websocket-client~=1.9.0
|
|
48
48
|
selenium==4.32.0;python_version<"3.10"
|
|
49
|
-
selenium==4.
|
|
49
|
+
selenium==4.45.0;python_version>="3.10"
|
|
50
50
|
cssselect==1.3.0;python_version<"3.10"
|
|
51
51
|
cssselect>=1.4.0,<2;python_version>="3.10"
|
|
52
52
|
sortedcontainers==2.4.0
|
|
@@ -834,6 +834,8 @@ def show_options():
|
|
|
834
834
|
op += "--help / -h (Display list of all available pytest options.)\n"
|
|
835
835
|
op += "--ftrace / --final-trace (Enter Debug Mode after tests end.)\n"
|
|
836
836
|
op += "--recorder / --rec (Save browser actions as Python scripts.)\n"
|
|
837
|
+
op += "--rec-sb-mgr (Save Recorder actions as SB() context manager.)\n"
|
|
838
|
+
op += "--rec-sb-cdp (Save Recorder actions as Pure CDP Mode sb_cdp.)\n"
|
|
837
839
|
op += "--rec-behave / --rec-gherkin (Save actions as Gherkin code.)\n"
|
|
838
840
|
op += "--rec-print (Display recorded scripts when they are created.)\n"
|
|
839
841
|
op += "--save-screenshot (Save a screenshot at the end of each test.)\n"
|
|
@@ -96,6 +96,8 @@ def main():
|
|
|
96
96
|
use_colors = True
|
|
97
97
|
force_gui = False
|
|
98
98
|
rec_behave = False
|
|
99
|
+
rec_sb_mgr = False
|
|
100
|
+
rec_sb_cdp = False
|
|
99
101
|
|
|
100
102
|
sys_executable = sys.executable
|
|
101
103
|
if " " in sys_executable:
|
|
@@ -164,6 +166,10 @@ def main():
|
|
|
164
166
|
use_uc = True
|
|
165
167
|
elif option.lower() in ("--rec-behave", "--behave", "--gherkin"):
|
|
166
168
|
rec_behave = True
|
|
169
|
+
elif option.lower() in ("--rec-sb-mgr"):
|
|
170
|
+
rec_sb_mgr = True
|
|
171
|
+
elif option.lower() in ("--rec-sb-cdp"):
|
|
172
|
+
rec_sb_cdp = True
|
|
167
173
|
elif option.lower().startswith("--url="):
|
|
168
174
|
start_page = option[len("--url="):]
|
|
169
175
|
elif option.lower() == "--url":
|
|
@@ -306,6 +312,10 @@ def main():
|
|
|
306
312
|
run_cmd += " --uc"
|
|
307
313
|
if rec_behave:
|
|
308
314
|
run_cmd += " --rec-behave"
|
|
315
|
+
if rec_sb_mgr:
|
|
316
|
+
run_cmd += " --rec-sb-mgr"
|
|
317
|
+
if rec_sb_cdp:
|
|
318
|
+
run_cmd += " --rec-sb-cdp"
|
|
309
319
|
print(run_cmd)
|
|
310
320
|
os.system(run_cmd)
|
|
311
321
|
if os.path.exists(file_path):
|
|
@@ -20,7 +20,10 @@ import os
|
|
|
20
20
|
import subprocess
|
|
21
21
|
import sys
|
|
22
22
|
import tkinter as tk
|
|
23
|
+
from tkinter import ttk
|
|
24
|
+
from contextlib import suppress
|
|
23
25
|
from seleniumbase import config as sb_config
|
|
26
|
+
from seleniumbase.core import detect_b_ver
|
|
24
27
|
from seleniumbase.fixtures import page_utils
|
|
25
28
|
from seleniumbase.fixtures import shared_utils
|
|
26
29
|
from tkinter import messagebox
|
|
@@ -76,7 +79,15 @@ def file_name_error(file_name):
|
|
|
76
79
|
return error_msg
|
|
77
80
|
|
|
78
81
|
|
|
79
|
-
def do_recording(
|
|
82
|
+
def do_recording(
|
|
83
|
+
file_name,
|
|
84
|
+
url,
|
|
85
|
+
overwrite_enabled,
|
|
86
|
+
brx,
|
|
87
|
+
ucb,
|
|
88
|
+
output_format,
|
|
89
|
+
window,
|
|
90
|
+
):
|
|
80
91
|
poll = None
|
|
81
92
|
if sb_config.rec_subprocess_used:
|
|
82
93
|
poll = sb_config.rec_subprocess_p.poll()
|
|
@@ -101,7 +112,13 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
|
|
|
101
112
|
if not page_utils.is_valid_url(url):
|
|
102
113
|
if page_utils.is_valid_url("https://" + url):
|
|
103
114
|
url = "https://" + url
|
|
104
|
-
if
|
|
115
|
+
if "edge" in brx.lower() and ucb:
|
|
116
|
+
messagebox.showwarning(
|
|
117
|
+
"Invalid selection",
|
|
118
|
+
"MS Edge cannot be combined with UC Mode "
|
|
119
|
+
"because it uses msedgedriver, not chromedriver!",
|
|
120
|
+
)
|
|
121
|
+
elif not page_utils.is_valid_url(url):
|
|
105
122
|
messagebox.showwarning(
|
|
106
123
|
"Invalid URL", "Enter a valid URL! (Eg. seleniumbase.io)"
|
|
107
124
|
)
|
|
@@ -121,13 +138,12 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
|
|
|
121
138
|
else:
|
|
122
139
|
os.remove(file_name)
|
|
123
140
|
add_on = ""
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
"--rec-behave" in command_args
|
|
127
|
-
or "--behave" in command_args
|
|
128
|
-
or "--gherkin" in command_args
|
|
129
|
-
):
|
|
141
|
+
if "Behave" in output_format:
|
|
130
142
|
add_on = " --rec-behave"
|
|
143
|
+
elif "SB()" in output_format:
|
|
144
|
+
add_on = " --rec-sb-mgr"
|
|
145
|
+
elif "sb_cdp" in output_format:
|
|
146
|
+
add_on = " --rec-sb-cdp"
|
|
131
147
|
command = (
|
|
132
148
|
"%s -m seleniumbase mkrec %s --url=%s --gui"
|
|
133
149
|
% (sys_executable, file_name, url)
|
|
@@ -142,25 +158,21 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
|
|
|
142
158
|
"%s -m seleniumbase mkrec %s --url='%s' --gui"
|
|
143
159
|
% (sys_executable, file_name, url)
|
|
144
160
|
)
|
|
145
|
-
if
|
|
161
|
+
if "edge" in brx.lower():
|
|
146
162
|
command += " --edge"
|
|
147
|
-
elif "
|
|
163
|
+
elif "opera" in brx.lower():
|
|
148
164
|
command += " --opera"
|
|
149
|
-
elif "
|
|
165
|
+
elif "brave" in brx.lower():
|
|
150
166
|
command += " --brave"
|
|
151
|
-
elif "
|
|
167
|
+
elif "comet" in brx.lower():
|
|
152
168
|
command += " --comet"
|
|
153
|
-
elif "
|
|
169
|
+
elif "atlas" in brx.lower():
|
|
154
170
|
command += " --atlas"
|
|
155
|
-
elif "
|
|
171
|
+
elif "chromium" in brx.lower():
|
|
156
172
|
command += " --use-chromium"
|
|
157
|
-
if
|
|
158
|
-
"--uc" in command_args
|
|
159
|
-
or "--cdp" in command_args
|
|
160
|
-
or "--undetected" in command_args
|
|
161
|
-
or "--undetectable" in command_args
|
|
162
|
-
):
|
|
173
|
+
if ucb:
|
|
163
174
|
command += " --uc"
|
|
175
|
+
command_args = sys.argv[2:]
|
|
164
176
|
if "--ee" in command_args:
|
|
165
177
|
command += " --ee"
|
|
166
178
|
command += add_on
|
|
@@ -175,7 +187,7 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
|
|
|
175
187
|
send_window_to_front(window)
|
|
176
188
|
|
|
177
189
|
|
|
178
|
-
def do_playback(file_name,
|
|
190
|
+
def do_playback(file_name, brx, window, demo_mode=False):
|
|
179
191
|
file_name = file_name.strip()
|
|
180
192
|
error_msg = file_name_error(file_name)
|
|
181
193
|
if error_msg:
|
|
@@ -189,11 +201,22 @@ def do_playback(file_name, use_chrome, window, demo_mode=False):
|
|
|
189
201
|
'File "%s" does not exist in the current directory!' % file_name,
|
|
190
202
|
)
|
|
191
203
|
return
|
|
192
|
-
command = "%s -m pytest %s -q -s" % (sys_executable, file_name)
|
|
204
|
+
# command = "%s -m pytest %s -q -s" % (sys_executable, file_name)
|
|
205
|
+
command = "%s %s -q -s" % (sys_executable, file_name)
|
|
193
206
|
if shared_utils.is_linux():
|
|
194
207
|
command += " --gui"
|
|
195
|
-
if
|
|
208
|
+
if "edge" in brx.lower():
|
|
196
209
|
command += " --edge"
|
|
210
|
+
elif "opera" in brx.lower():
|
|
211
|
+
command += " --opera"
|
|
212
|
+
elif "brave" in brx.lower():
|
|
213
|
+
command += " --brave"
|
|
214
|
+
elif "comet" in brx.lower():
|
|
215
|
+
command += " --comet"
|
|
216
|
+
elif "atlas" in brx.lower():
|
|
217
|
+
command += " --atlas"
|
|
218
|
+
elif "chromium" in brx.lower():
|
|
219
|
+
command += " --use-chromium"
|
|
197
220
|
if demo_mode:
|
|
198
221
|
command += " --demo"
|
|
199
222
|
command_args = sys.argv[2:]
|
|
@@ -223,100 +246,233 @@ def create_tkinter_gui():
|
|
|
223
246
|
default_file_name = "new_recording.py"
|
|
224
247
|
window = tk.Tk()
|
|
225
248
|
window.title("SeleniumBase Recorder App")
|
|
226
|
-
window.geometry("
|
|
249
|
+
window.geometry("344x564")
|
|
250
|
+
my_font = ("TkDefaultFont", 11)
|
|
227
251
|
frame = tk.Frame(window)
|
|
228
252
|
frame.pack()
|
|
229
253
|
|
|
230
|
-
tk.Label(window, text="").pack()
|
|
231
254
|
fname = tk.StringVar(value=default_file_name)
|
|
232
|
-
tk.Label(window, text="Enter filename to save recording as:")
|
|
255
|
+
label = tk.Label(window, text="Enter filename to save recording as:")
|
|
256
|
+
label.pack(pady=(20, 0.2))
|
|
233
257
|
entry = tk.Entry(window, textvariable=fname)
|
|
234
|
-
entry.
|
|
258
|
+
entry.config(width=21)
|
|
259
|
+
entry.pack(pady=(0.6, 0.2))
|
|
235
260
|
cbx = tk.IntVar()
|
|
236
261
|
chk = tk.Checkbutton(window, text="Overwrite existing files", variable=cbx)
|
|
237
262
|
chk.pack()
|
|
238
263
|
chk.select()
|
|
239
264
|
use_stealth = False
|
|
265
|
+
use_behave = False
|
|
266
|
+
use_sb_mgr = False
|
|
267
|
+
use_sb_cdp = False
|
|
268
|
+
use_atlas = False
|
|
240
269
|
command_args = sys.argv[2:]
|
|
241
270
|
if (
|
|
242
271
|
"--uc" in command_args
|
|
243
272
|
or "--cdp" in command_args
|
|
273
|
+
or "--stealth" in command_args
|
|
244
274
|
or "--undetected" in command_args
|
|
245
275
|
or "--undetectable" in command_args
|
|
246
276
|
):
|
|
247
277
|
use_stealth = True
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
278
|
+
if (
|
|
279
|
+
"--rec-behave" in command_args
|
|
280
|
+
or "--behave" in command_args
|
|
281
|
+
or "--gherkin" in command_args
|
|
282
|
+
):
|
|
283
|
+
use_behave = True
|
|
284
|
+
if "--rec-sb-mgr" in command_args:
|
|
285
|
+
use_sb_mgr = True
|
|
286
|
+
if "--rec-sb-cdp" in command_args:
|
|
287
|
+
use_sb_cdp = True
|
|
288
|
+
if "--atlas" in command_args:
|
|
289
|
+
use_atlas = True
|
|
290
|
+
|
|
291
|
+
tk.Label(window, text="\nSelect a web browser to use:").pack()
|
|
292
|
+
br_count = 2
|
|
293
|
+
br_order = {"chrome": 0, "chromium": 1}
|
|
294
|
+
options_list = ["Google Chrome"]
|
|
295
|
+
options_list.append("Chromium Browser")
|
|
296
|
+
if shared_utils.is_windows():
|
|
297
|
+
options_list.append("MS Edge (No Stealth)")
|
|
298
|
+
br_order["edge"] = br_count
|
|
299
|
+
br_count += 1
|
|
263
300
|
else:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
301
|
+
with suppress(Exception):
|
|
302
|
+
if os.path.exists(detect_b_ver.get_binary_location("edge")):
|
|
303
|
+
options_list.append("MS Edge (No Stealth)")
|
|
304
|
+
br_order["edge"] = br_count
|
|
305
|
+
br_count += 1
|
|
306
|
+
with suppress(Exception):
|
|
307
|
+
if os.path.exists(detect_b_ver.get_binary_location("opera")):
|
|
308
|
+
options_list.append("Opera Browser")
|
|
309
|
+
br_order["opera"] = br_count
|
|
310
|
+
br_count += 1
|
|
311
|
+
with suppress(Exception):
|
|
312
|
+
if os.path.exists(detect_b_ver.get_binary_location("brave")):
|
|
313
|
+
options_list.append("Brave Browser")
|
|
314
|
+
br_order["brave"] = br_count
|
|
315
|
+
br_count += 1
|
|
316
|
+
with suppress(Exception):
|
|
317
|
+
if os.path.exists(detect_b_ver.get_binary_location("comet")):
|
|
318
|
+
options_list.append("Comet Browser")
|
|
319
|
+
br_order["comet"] = br_count
|
|
320
|
+
br_count += 1
|
|
321
|
+
if use_atlas:
|
|
322
|
+
with suppress(Exception):
|
|
323
|
+
if os.path.exists(detect_b_ver.get_binary_location("atlas")):
|
|
324
|
+
options_list.append("Atlas Browser")
|
|
325
|
+
br_order["atlas"] = br_count
|
|
326
|
+
br_count += 1
|
|
327
|
+
brx = tk.StringVar(window)
|
|
328
|
+
if "--use-chromium" in command_args or "--chromium" in command_args:
|
|
329
|
+
brx.set(options_list[1])
|
|
330
|
+
elif (
|
|
331
|
+
"--edge" in command_args
|
|
332
|
+
and "edge" in br_order
|
|
333
|
+
):
|
|
334
|
+
brx.set(options_list[2])
|
|
335
|
+
use_stealth = False
|
|
336
|
+
elif "--opera" in command_args and "opera" in br_order:
|
|
337
|
+
brx.set(options_list[br_order["opera"]])
|
|
338
|
+
elif "--brave" in command_args and "brave" in br_order:
|
|
339
|
+
brx.set(options_list[br_order["brave"]])
|
|
340
|
+
elif "--comet" in command_args and "comet" in br_order:
|
|
341
|
+
brx.set(options_list[br_order["comet"]])
|
|
342
|
+
elif "--atlas" in command_args and "atlas" in br_order:
|
|
343
|
+
brx.set(options_list[br_order["atlas"]])
|
|
344
|
+
else:
|
|
345
|
+
brx.set(options_list[0])
|
|
346
|
+
question_menu = tk.OptionMenu(window, brx, *options_list)
|
|
347
|
+
question_menu.config(width=16)
|
|
348
|
+
question_menu.pack(pady=(0.6, 0.2))
|
|
349
|
+
|
|
350
|
+
ucb = tk.IntVar()
|
|
351
|
+
chkb = tk.Checkbutton(
|
|
352
|
+
window, text="Stealth Mode / UC + CDP Mode", variable=ucb
|
|
353
|
+
)
|
|
354
|
+
chkb.pack(pady=(0.4, 0.4))
|
|
355
|
+
if use_stealth:
|
|
268
356
|
chkb.select()
|
|
269
|
-
chkb.config(state=tk.DISABLED)
|
|
270
|
-
|
|
357
|
+
# chkb.config(state=tk.DISABLED)
|
|
358
|
+
|
|
359
|
+
tk.Label(window, text="\nSelect an output format to use:").pack()
|
|
360
|
+
options_list = ["pytest format / BaseCase"]
|
|
361
|
+
options_list.append("Context Manager / SB()")
|
|
362
|
+
options_list.append("Pure CDP Mode / sb_cdp")
|
|
363
|
+
if use_behave:
|
|
364
|
+
options_list.append("BehaveBDD Gherkin File")
|
|
365
|
+
frx = tk.StringVar(window)
|
|
366
|
+
if use_behave and not use_sb_mgr and not use_sb_cdp:
|
|
367
|
+
frx.set(options_list[3])
|
|
368
|
+
elif use_sb_mgr:
|
|
369
|
+
frx.set(options_list[1])
|
|
370
|
+
elif use_sb_cdp:
|
|
371
|
+
frx.set(options_list[2])
|
|
372
|
+
else:
|
|
373
|
+
frx.set(options_list[0])
|
|
374
|
+
question_menu = tk.OptionMenu(window, frx, *options_list)
|
|
375
|
+
question_menu.config(width=18)
|
|
376
|
+
question_menu.pack(pady=(0.6, 0.2))
|
|
377
|
+
|
|
271
378
|
url = tk.StringVar()
|
|
272
|
-
tk.Label(window, text="Enter
|
|
379
|
+
label = tk.Label(window, text="Enter a URL to start recording on:")
|
|
380
|
+
label.pack(pady=(20, 0.2))
|
|
273
381
|
entry = tk.Entry(window, textvariable=url)
|
|
382
|
+
entry.config(width=23)
|
|
274
383
|
entry.pack()
|
|
275
384
|
entry.focus()
|
|
276
385
|
entry.bind(
|
|
277
386
|
"<Return>",
|
|
278
387
|
(
|
|
279
388
|
lambda _: do_recording(
|
|
280
|
-
fname.get(),
|
|
389
|
+
fname.get(),
|
|
390
|
+
url.get(),
|
|
391
|
+
cbx.get(),
|
|
392
|
+
brx.get(),
|
|
393
|
+
ucb.get(),
|
|
394
|
+
frx.get(),
|
|
395
|
+
window,
|
|
281
396
|
)
|
|
282
397
|
),
|
|
283
398
|
)
|
|
284
|
-
|
|
399
|
+
# Automatically set focus on URL field when clicking back into the app
|
|
400
|
+
window.bind(
|
|
401
|
+
"<FocusIn>", lambda event: entry.focus_set()
|
|
402
|
+
if event.widget == window
|
|
403
|
+
else None
|
|
404
|
+
)
|
|
405
|
+
style = ttk.Style()
|
|
406
|
+
style.configure(
|
|
407
|
+
"Record.TButton",
|
|
408
|
+
foreground="red",
|
|
409
|
+
font=("TkDefaultFont", 12, "bold"),
|
|
410
|
+
width="8",
|
|
411
|
+
padding=(4, 3, 4, 1)
|
|
412
|
+
)
|
|
413
|
+
ttk.Button(
|
|
285
414
|
window,
|
|
286
415
|
text="Record",
|
|
287
|
-
|
|
416
|
+
style="Record.TButton",
|
|
288
417
|
command=lambda: do_recording(
|
|
289
|
-
fname.get(),
|
|
418
|
+
fname.get(),
|
|
419
|
+
url.get(),
|
|
420
|
+
cbx.get(),
|
|
421
|
+
brx.get(),
|
|
422
|
+
ucb.get(),
|
|
423
|
+
frx.get(),
|
|
424
|
+
window,
|
|
290
425
|
),
|
|
291
|
-
).pack()
|
|
292
|
-
tk.Label(window, text="")
|
|
293
|
-
|
|
294
|
-
|
|
426
|
+
).pack(pady=0.2)
|
|
427
|
+
label = tk.Label(window, text="Playback recording (Normal Mode):")
|
|
428
|
+
label.pack(pady=(18, 0))
|
|
429
|
+
|
|
430
|
+
style.configure(
|
|
431
|
+
"Playback.TButton",
|
|
432
|
+
foreground="green",
|
|
433
|
+
font=("TkDefaultFont", 11, "bold"),
|
|
434
|
+
width="8",
|
|
435
|
+
padding=(4, 3, 4, 1)
|
|
436
|
+
)
|
|
437
|
+
ttk.Button(
|
|
295
438
|
window,
|
|
296
439
|
text="Playback",
|
|
297
|
-
|
|
298
|
-
command=lambda: do_playback(fname.get(),
|
|
299
|
-
).pack()
|
|
300
|
-
tk.Label(window, text="")
|
|
301
|
-
|
|
440
|
+
style="Playback.TButton",
|
|
441
|
+
command=lambda: do_playback(fname.get(), brx.get(), window),
|
|
442
|
+
).pack(pady=0.2)
|
|
443
|
+
label = tk.Label(window, text="Playback recording (Demo Mode):")
|
|
444
|
+
label.pack(pady=(14, 0))
|
|
302
445
|
try:
|
|
303
|
-
|
|
446
|
+
style.configure(
|
|
447
|
+
"PlaybackDemo.TButton",
|
|
448
|
+
foreground="teal",
|
|
449
|
+
font=("TkDefaultFont", 11, "bold"),
|
|
450
|
+
width="16",
|
|
451
|
+
padding=(4, 3, 4, 1)
|
|
452
|
+
)
|
|
453
|
+
ttk.Button(
|
|
304
454
|
window,
|
|
305
455
|
text="Playback (Demo Mode)",
|
|
306
|
-
|
|
456
|
+
style="PlaybackDemo.TButton",
|
|
307
457
|
command=lambda: do_playback(
|
|
308
|
-
fname.get(),
|
|
458
|
+
fname.get(), brx.get(), window, demo_mode=True
|
|
309
459
|
),
|
|
310
|
-
).pack()
|
|
460
|
+
).pack(pady=0.2)
|
|
311
461
|
except Exception:
|
|
312
|
-
|
|
462
|
+
style.configure(
|
|
463
|
+
"PlaybackDemo.TButton",
|
|
464
|
+
foreground="blue",
|
|
465
|
+
font=("TkDefaultFont", 11, "bold"),
|
|
466
|
+
padding=(4, 3, 4, 1)
|
|
467
|
+
)
|
|
468
|
+
ttk.Button(
|
|
313
469
|
window,
|
|
314
470
|
text="Playback (Demo Mode)",
|
|
315
|
-
|
|
471
|
+
style="PlaybackDemo.TButton",
|
|
316
472
|
command=lambda: do_playback(
|
|
317
|
-
fname.get(),
|
|
473
|
+
fname.get(), brx.get(), window, demo_mode=True
|
|
318
474
|
),
|
|
319
|
-
).pack()
|
|
475
|
+
).pack(pady=0.2)
|
|
320
476
|
|
|
321
477
|
# Bring form window to front
|
|
322
478
|
send_window_to_front(window)
|
|
@@ -328,6 +484,13 @@ def create_tkinter_gui():
|
|
|
328
484
|
decoy.deiconify()
|
|
329
485
|
decoy.destroy()
|
|
330
486
|
# Start tkinter
|
|
487
|
+
for widget in window.winfo_children():
|
|
488
|
+
if isinstance(
|
|
489
|
+
widget, (tk.Label, tk.Entry, tk.Checkbutton, tk.OptionMenu)
|
|
490
|
+
):
|
|
491
|
+
widget.configure(font=my_font)
|
|
492
|
+
window.deiconify() # Force the OS to redraw it actively on top
|
|
493
|
+
window.focus_force() # Force keyboard focus into the entry fields
|
|
331
494
|
window.mainloop()
|
|
332
495
|
end_program()
|
|
333
496
|
|
|
@@ -761,6 +761,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
761
761
|
cdp.goto = CDPM.goto
|
|
762
762
|
cdp.reload = CDPM.reload
|
|
763
763
|
cdp.refresh = CDPM.refresh
|
|
764
|
+
cdp.goto_if_not_url = CDPM.goto_if_not_url
|
|
764
765
|
cdp.add_handler = CDPM.add_handler
|
|
765
766
|
cdp.get_event_loop = CDPM.get_event_loop
|
|
766
767
|
cdp.get_rd_host = CDPM.get_rd_host
|
|
@@ -180,6 +180,30 @@ class CDPMethods():
|
|
|
180
180
|
def refresh(self, *args, **kwargs):
|
|
181
181
|
self.reload(*args, **kwargs)
|
|
182
182
|
|
|
183
|
+
def goto_if_not_url(self, url):
|
|
184
|
+
"""Opens the url in the browser if it's not the current url (*).
|
|
185
|
+
Parameters tagged on by search engines are ignored for this method.
|
|
186
|
+
Eg. If the current url is:
|
|
187
|
+
* https://www.bing.com/search?q=SeleniumBase&source=hp
|
|
188
|
+
And the url privided by this method call is:
|
|
189
|
+
* https://www.bing.com/search?q=SeleniumBase
|
|
190
|
+
Then the urls will be considered the same,
|
|
191
|
+
and no open() action will be performed.
|
|
192
|
+
This method is primarily used by Recorder Mode script generation,
|
|
193
|
+
where both clicks and opens are recorded. So if a click() action
|
|
194
|
+
leads to an goto() action, then the script generator will attempt
|
|
195
|
+
to convert the goto() action into goto_if_not_url() so that the
|
|
196
|
+
same page isn't opened again if the user is already on the page."""
|
|
197
|
+
current_url = self.get_current_url()
|
|
198
|
+
if current_url != url:
|
|
199
|
+
if (
|
|
200
|
+
"?q=" not in current_url
|
|
201
|
+
or "&" not in current_url
|
|
202
|
+
or current_url.find("?q=") >= current_url.find("&")
|
|
203
|
+
or current_url.split("&")[0] != url
|
|
204
|
+
):
|
|
205
|
+
self.goto(url)
|
|
206
|
+
|
|
183
207
|
def get_event_loop(self):
|
|
184
208
|
return self.loop
|
|
185
209
|
|
|
@@ -2276,6 +2300,10 @@ class CDPMethods():
|
|
|
2276
2300
|
x2, y2 = self.get_gui_element_center("div.sliderTarget")
|
|
2277
2301
|
self.close_active_tab()
|
|
2278
2302
|
self.switch_to_tab(tab)
|
|
2303
|
+
if shared_utils.is_windows():
|
|
2304
|
+
time.sleep(0.48)
|
|
2305
|
+
self.loop.run_until_complete(self.page.wait(0.1))
|
|
2306
|
+
x2 = x2 + 22.5 # Overshoot drop to maximize compatibility
|
|
2279
2307
|
self.gui_drag_drop_points(x1, y1, x2, y2, timeframe=0.55)
|
|
2280
2308
|
time.sleep(0.25)
|
|
2281
2309
|
self.loop.run_until_complete(self.page.wait(0.2))
|