seleniumbase 4.54.7__tar.gz → 4.54.9__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.54.7/seleniumbase.egg-info → seleniumbase-4.54.9}/PKG-INFO +6 -6
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/mcp_servers/server.py +34 -33
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/requirements.txt +5 -5
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/behave/behave_sb.py +13 -8
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/run.py +2 -2
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_mkchart.py +9 -8
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_mkdir.py +40 -38
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_mkfile.py +9 -8
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_mkpres.py +9 -8
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_mkrec.py +35 -42
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/base_case.py +4 -7
- {seleniumbase-4.54.7 → seleniumbase-4.54.9/seleniumbase.egg-info}/PKG-INFO +6 -6
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase.egg-info/requires.txt +5 -5
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/setup.py +5 -5
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/.gitignore +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/LICENSE +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/MANIFEST.in +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/README.md +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/install.sh +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/mcp_servers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/pyproject.toml +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/pytest.ini +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/sbase/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/sbase/__main__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/sbase/steps.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/browser_launcher.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/nest_asyncio.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/sb_cdp.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/setup.cfg +0 -0
- {seleniumbase-4.54.7 → seleniumbase-4.54.9}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.54.
|
|
3
|
+
Version: 4.54.9
|
|
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
|
|
@@ -67,11 +67,11 @@ Requires-Dist: certifi>=2026.7.22
|
|
|
67
67
|
Requires-Dist: exceptiongroup>=1.3.1
|
|
68
68
|
Requires-Dist: websockets~=16.1.1; python_version == "3.10"
|
|
69
69
|
Requires-Dist: websockets>=16.1.1; python_version >= "3.11"
|
|
70
|
-
Requires-Dist: filelock>=
|
|
70
|
+
Requires-Dist: filelock>=4.0.0
|
|
71
71
|
Requires-Dist: fasteners>=0.20
|
|
72
72
|
Requires-Dist: mycdp>=1.4.0
|
|
73
73
|
Requires-Dist: pynose>=1.5.5
|
|
74
|
-
Requires-Dist: platformdirs>=4.11.
|
|
74
|
+
Requires-Dist: platformdirs>=4.11.9
|
|
75
75
|
Requires-Dist: typing-extensions>=4.16.0
|
|
76
76
|
Requires-Dist: sbvirtualdisplay>=1.4.0
|
|
77
77
|
Requires-Dist: MarkupSafe>=3.0.3
|
|
@@ -85,8 +85,8 @@ Requires-Dist: pyyaml>=6.0.3
|
|
|
85
85
|
Requires-Dist: pygments>=2.20.1
|
|
86
86
|
Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
87
87
|
Requires-Dist: tabcompleter>=1.4.1
|
|
88
|
-
Requires-Dist: pdbp>=1.8.
|
|
89
|
-
Requires-Dist: idna>=3.
|
|
88
|
+
Requires-Dist: pdbp>=1.8.3
|
|
89
|
+
Requires-Dist: idna>=3.20
|
|
90
90
|
Requires-Dist: charset-normalizer<4,>=3.5.1
|
|
91
91
|
Requires-Dist: urllib3<3,>=2.8.0
|
|
92
92
|
Requires-Dist: requests~=2.34.2
|
|
@@ -109,7 +109,7 @@ Requires-Dist: pytest-html==4.0.2
|
|
|
109
109
|
Requires-Dist: pytest-metadata==3.1.1
|
|
110
110
|
Requires-Dist: pytest-ordering==0.6
|
|
111
111
|
Requires-Dist: pytest-rerunfailures==16.3; python_version == "3.10"
|
|
112
|
-
Requires-Dist: pytest-rerunfailures==16.
|
|
112
|
+
Requires-Dist: pytest-rerunfailures==16.7; python_version >= "3.11"
|
|
113
113
|
Requires-Dist: pytest-xdist==3.8.0
|
|
114
114
|
Requires-Dist: parameterized==0.9.0
|
|
115
115
|
Requires-Dist: behave==1.2.6
|
|
@@ -646,15 +646,16 @@ def get_attributes(
|
|
|
646
646
|
attribute: str | None = None,
|
|
647
647
|
timeout: float = 5,
|
|
648
648
|
) -> str | dict[str, Any] | None:
|
|
649
|
-
"""Get a specific HTML attribute (or all attributes) from the
|
|
650
|
-
|
|
651
|
-
|
|
649
|
+
"""Get a specific HTML attribute (or all attributes) from the selected
|
|
650
|
+
element. Examples of possible attributes include href, src, value, class,
|
|
651
|
+
id, name, type, aria-label, etc.
|
|
652
652
|
|
|
653
653
|
Args:
|
|
654
654
|
selector: CSS selector or SeleniumBase-supported XPath selector.
|
|
655
|
+
If multiple elements match, then only the first one is used.
|
|
655
656
|
|
|
656
|
-
attribute: Specific HTML attribute to retrieve. When omitted,
|
|
657
|
-
all HTML attributes of the
|
|
657
|
+
attribute: Specific HTML attribute to retrieve. When omitted, returns
|
|
658
|
+
all HTML attributes of the matching element as a dictionary.
|
|
658
659
|
|
|
659
660
|
timeout: Maximum seconds to wait for the target element. Default: 5.
|
|
660
661
|
|
|
@@ -1057,6 +1058,8 @@ def select_option(
|
|
|
1057
1058
|
) -> str:
|
|
1058
1059
|
"""Select an option from an HTML <select> dropdown.
|
|
1059
1060
|
|
|
1061
|
+
Changing a dropdown selection can trigger additional events on a page.
|
|
1062
|
+
|
|
1060
1063
|
Args:
|
|
1061
1064
|
dropdown_selector: CSS selector identifying the <select> element.
|
|
1062
1065
|
|
|
@@ -1445,8 +1448,11 @@ def manage_cookies(
|
|
|
1445
1448
|
Notes:
|
|
1446
1449
|
Loading saved cookies does not guarantee restoration of a login.
|
|
1447
1450
|
Cookies may be expired, invalidated, domain/path restricted, or
|
|
1448
|
-
dependent on other browser state.
|
|
1449
|
-
|
|
1451
|
+
dependent on other browser state.
|
|
1452
|
+
|
|
1453
|
+
When not to use:
|
|
1454
|
+
- Do not use this tool to load cookies if the cookie origin does
|
|
1455
|
+
not match the origin of the current page.
|
|
1450
1456
|
"""
|
|
1451
1457
|
sb = _get_sb()
|
|
1452
1458
|
|
|
@@ -1800,43 +1806,38 @@ def manage_tabs(
|
|
|
1800
1806
|
annotations=ToolAnnotations(
|
|
1801
1807
|
read_only_hint=False,
|
|
1802
1808
|
destructive_hint=False,
|
|
1803
|
-
idempotent_hint=False, #
|
|
1804
|
-
# rotated CAPTCHA
|
|
1809
|
+
idempotent_hint=False, # Re-attempting an already-handled or
|
|
1810
|
+
# rotated CAPTCHA is not a no-op.
|
|
1805
1811
|
open_world_hint=True, # Interacts with a 3rd-party CAPTCHA widget.
|
|
1806
1812
|
),
|
|
1807
1813
|
)
|
|
1808
1814
|
@handle_sb_errors
|
|
1809
1815
|
def solve_captcha() -> str:
|
|
1810
|
-
"""
|
|
1811
|
-
|
|
1816
|
+
"""Attempts a SeleniumBase CDP interaction (click or drag/drop) to solve
|
|
1817
|
+
detectable CAPTCHAs on the current page.
|
|
1812
1818
|
|
|
1813
|
-
Supported CAPTCHAs
|
|
1814
|
-
DataDome Slider,
|
|
1819
|
+
Supported CAPTCHAs:
|
|
1820
|
+
- CF Turnstile, reCAPTCHA, hCaptcha, DataDome Slider, FriendlyCaptcha
|
|
1815
1821
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1822
|
+
Tool workflow:
|
|
1823
|
+
1. Inspect page structure (e.g., via `get_content`) to verify that a
|
|
1824
|
+
CAPTCHA is present.
|
|
1825
|
+
2. Call `solve_captcha` if there's a CAPTCHA. (No-op if no CAPTCHA.)
|
|
1826
|
+
3. Verify success via `get_page_info`, `get_content`, or `manage_cookies`.
|
|
1819
1827
|
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
state or browser cookies.
|
|
1828
|
+
Notes:
|
|
1829
|
+
This tool does not guarantee that the CAPTCHA gets solved.
|
|
1830
|
+
A successful attempt may result in changes to page state and cookies.
|
|
1824
1831
|
|
|
1825
|
-
Tool
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1832
|
+
Tool Selection:
|
|
1833
|
+
- Use `solve_captcha` specifically for automated CAPTCHA widget
|
|
1834
|
+
interactions.
|
|
1835
|
+
- Use `click_element` for standard visible elements.
|
|
1836
|
+
- Use `hover_action` (action="hover_and_click") to reveal and
|
|
1837
|
+
click targets.
|
|
1831
1838
|
|
|
1832
1839
|
Returns:
|
|
1833
|
-
A confirmation message
|
|
1834
|
-
The message is the same for both successful and failed attempts.
|
|
1835
|
-
|
|
1836
|
-
Notes:
|
|
1837
|
-
Clicking with the Chrome DevTools Protocol (CDP) is generally
|
|
1838
|
-
stealthier than clicking with JavaScript because CDP actions
|
|
1839
|
-
can avoid triggering `isTrusted: false`.
|
|
1840
|
+
A confirmation message indicating that the attempt was initiated.
|
|
1840
1841
|
"""
|
|
1841
1842
|
sb = _get_sb()
|
|
1842
1843
|
sb.solve_captcha()
|
|
@@ -7,11 +7,11 @@ certifi>=2026.7.22
|
|
|
7
7
|
exceptiongroup>=1.3.1
|
|
8
8
|
websockets~=16.1.1;python_version=="3.10"
|
|
9
9
|
websockets>=16.1.1;python_version>="3.11"
|
|
10
|
-
filelock>=
|
|
10
|
+
filelock>=4.0.0
|
|
11
11
|
fasteners>=0.20
|
|
12
12
|
mycdp>=1.4.0
|
|
13
13
|
pynose>=1.5.5
|
|
14
|
-
platformdirs>=4.11.
|
|
14
|
+
platformdirs>=4.11.9
|
|
15
15
|
typing-extensions>=4.16.0
|
|
16
16
|
sbvirtualdisplay>=1.4.0
|
|
17
17
|
MarkupSafe>=3.0.3
|
|
@@ -25,8 +25,8 @@ pyyaml>=6.0.3
|
|
|
25
25
|
pygments>=2.20.1
|
|
26
26
|
pyreadline3>=3.5.4;platform_system=="Windows"
|
|
27
27
|
tabcompleter>=1.4.1
|
|
28
|
-
pdbp>=1.8.
|
|
29
|
-
idna>=3.
|
|
28
|
+
pdbp>=1.8.3
|
|
29
|
+
idna>=3.20
|
|
30
30
|
charset-normalizer>=3.5.1,<4
|
|
31
31
|
urllib3>=2.8.0,<3
|
|
32
32
|
requests~=2.34.2
|
|
@@ -49,7 +49,7 @@ pytest-html==4.0.2
|
|
|
49
49
|
pytest-metadata==3.1.1
|
|
50
50
|
pytest-ordering==0.6
|
|
51
51
|
pytest-rerunfailures==16.3;python_version=="3.10"
|
|
52
|
-
pytest-rerunfailures==16.
|
|
52
|
+
pytest-rerunfailures==16.7;python_version>="3.11"
|
|
53
53
|
pytest-xdist==3.8.0
|
|
54
54
|
parameterized==0.9.0
|
|
55
55
|
behave==1.2.6
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.54.
|
|
2
|
+
__version__ = "4.54.9"
|
|
@@ -334,7 +334,7 @@ def get_configured_sb(context):
|
|
|
334
334
|
continue
|
|
335
335
|
# Handle: -D locale-code=CODE / locale_code=CODE / locale=CODE
|
|
336
336
|
if low_key in ["locale-code", "locale_code", "locale"]:
|
|
337
|
-
sb.
|
|
337
|
+
sb.locale_code = userdata[key]
|
|
338
338
|
continue
|
|
339
339
|
# Handle: -D pdb / ipdb
|
|
340
340
|
if low_key in ["pdb", "ipdb"]:
|
|
@@ -881,7 +881,7 @@ def get_configured_sb(context):
|
|
|
881
881
|
sb.cap_file = cap_file
|
|
882
882
|
continue
|
|
883
883
|
# Handle: -D cap-string=STRING / cap_string=STRING
|
|
884
|
-
if low_key
|
|
884
|
+
if low_key in ["cap-string", "cap_string"]:
|
|
885
885
|
cap_string = userdata[key]
|
|
886
886
|
if cap_string == "true":
|
|
887
887
|
cap_string = sb.cap_string # revert to default
|
|
@@ -1134,14 +1134,19 @@ def _get_test_ids_():
|
|
|
1134
1134
|
def dashboard_pre_processing():
|
|
1135
1135
|
import subprocess
|
|
1136
1136
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1137
|
+
# Safely filter out --quiet and -q without shell string joining
|
|
1138
|
+
command_args = [
|
|
1139
|
+
arg for arg in sys.argv[1:] if arg not in ("--quiet", "-q")
|
|
1140
|
+
]
|
|
1141
|
+
|
|
1142
|
+
# Construct a explicit argument list without shell=True
|
|
1143
|
+
cmd = ["behave", "-d"] + command_args + ["--show-source"]
|
|
1144
|
+
|
|
1141
1145
|
proc = subprocess.Popen(
|
|
1142
|
-
|
|
1146
|
+
cmd,
|
|
1143
1147
|
stdout=subprocess.PIPE,
|
|
1144
|
-
|
|
1148
|
+
stderr=subprocess.PIPE,
|
|
1149
|
+
shell=False,
|
|
1145
1150
|
)
|
|
1146
1151
|
(output, error) = proc.communicate()
|
|
1147
1152
|
filename_count = 0
|
|
@@ -1205,7 +1205,7 @@ def main():
|
|
|
1205
1205
|
show_behave_options()
|
|
1206
1206
|
elif command == "proxy" or command == "--proxy":
|
|
1207
1207
|
import fasteners
|
|
1208
|
-
import
|
|
1208
|
+
import subprocess
|
|
1209
1209
|
import warnings
|
|
1210
1210
|
with warnings.catch_warnings():
|
|
1211
1211
|
warnings.simplefilter("ignore", category=UserWarning)
|
|
@@ -1219,7 +1219,7 @@ def main():
|
|
|
1219
1219
|
shared_utils.pip_install(
|
|
1220
1220
|
"proxy.py", version=constants.ProxyPy.VER
|
|
1221
1221
|
)
|
|
1222
|
-
|
|
1222
|
+
subprocess.run(["proxy"] + sys.argv[2:])
|
|
1223
1223
|
elif command == "help" or command == "--help" or command == "-h":
|
|
1224
1224
|
if len(command_args) >= 1:
|
|
1225
1225
|
if command_args[0] == "get":
|
|
@@ -24,6 +24,7 @@ Output:
|
|
|
24
24
|
"""
|
|
25
25
|
import colorama
|
|
26
26
|
import os
|
|
27
|
+
import subprocess
|
|
27
28
|
import sys
|
|
28
29
|
|
|
29
30
|
|
|
@@ -73,15 +74,17 @@ def main():
|
|
|
73
74
|
|
|
74
75
|
command_args = sys.argv[2:]
|
|
75
76
|
file_name = command_args[0]
|
|
77
|
+
if file_name:
|
|
78
|
+
file_name = str(file_name)
|
|
76
79
|
if file_name == "-h" or file_name == "--help":
|
|
77
80
|
invalid_run_command("help")
|
|
78
81
|
elif not file_name.endswith(".py"):
|
|
79
82
|
error_msg = 'File name must end with ".py"!'
|
|
80
|
-
elif "*" in file_name or len(
|
|
83
|
+
elif "*" in file_name or len(file_name) < 4:
|
|
81
84
|
error_msg = "Invalid file name!"
|
|
82
85
|
elif file_name.startswith("-"):
|
|
83
86
|
error_msg = 'File name cannot start with "-"!'
|
|
84
|
-
elif
|
|
87
|
+
elif any(sep in file_name for sep in ("/", "\\")):
|
|
85
88
|
error_msg = "File must be created in the current directory!"
|
|
86
89
|
elif os.path.exists(os.getcwd() + "/" + file_name):
|
|
87
90
|
error_msg = 'File "%s" already exists in this directory!' % file_name
|
|
@@ -256,12 +259,10 @@ def main():
|
|
|
256
259
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
257
260
|
file.writelines("\r\n".join(data))
|
|
258
261
|
file.close()
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
else:
|
|
264
|
-
os.system("sbase print '%s' -n" % file_name)
|
|
262
|
+
|
|
263
|
+
print_cmd = ["sbase", "print", file_name, "-n"]
|
|
264
|
+
subprocess.run(print_cmd)
|
|
265
|
+
|
|
265
266
|
success = (
|
|
266
267
|
"\n" + c1 + '* Chart Presentation: "' + file_name + '" was created! *'
|
|
267
268
|
"" + cr + "\n"
|
|
@@ -21,6 +21,7 @@ Output:
|
|
|
21
21
|
"""
|
|
22
22
|
import colorama
|
|
23
23
|
import os
|
|
24
|
+
import subprocess
|
|
24
25
|
import sys
|
|
25
26
|
|
|
26
27
|
|
|
@@ -68,15 +69,17 @@ def main():
|
|
|
68
69
|
|
|
69
70
|
command_args = sys.argv[2:]
|
|
70
71
|
dir_name = command_args[0]
|
|
72
|
+
if dir_name:
|
|
73
|
+
dir_name = str(dir_name)
|
|
71
74
|
if dir_name == "-h" or dir_name == "--help":
|
|
72
75
|
invalid_run_command("help")
|
|
73
|
-
elif len(
|
|
76
|
+
elif len(dir_name) < 2:
|
|
74
77
|
error_msg = "Directory name length must be at least 2 characters long!"
|
|
75
|
-
elif
|
|
78
|
+
elif any(sep in dir_name for sep in ("/", "\\")):
|
|
76
79
|
error_msg = 'Directory name must not include slashes ("/", "\\")!'
|
|
77
80
|
elif dir_name.startswith("-"):
|
|
78
81
|
error_msg = 'Directory name cannot start with "-"!'
|
|
79
|
-
elif os.path.exists(os.getcwd()
|
|
82
|
+
elif os.path.exists(os.path.join(os.getcwd(), dir_name)):
|
|
80
83
|
error_msg = (
|
|
81
84
|
'Directory "%s" already exists in this directory!' % dir_name
|
|
82
85
|
)
|
|
@@ -117,7 +120,7 @@ def main():
|
|
|
117
120
|
pass
|
|
118
121
|
data.append(seleniumbase_req)
|
|
119
122
|
data.append("")
|
|
120
|
-
file_path =
|
|
123
|
+
file_path = os.path.join(dir_name, "requirements.txt")
|
|
121
124
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
122
125
|
file.writelines("\r\n".join(data))
|
|
123
126
|
file.close()
|
|
@@ -155,7 +158,7 @@ def main():
|
|
|
155
158
|
data.append(" staging: custom marker")
|
|
156
159
|
data.append(" production: custom marker")
|
|
157
160
|
data.append("")
|
|
158
|
-
file_path =
|
|
161
|
+
file_path = os.path.join(dir_name, "pytest.ini")
|
|
159
162
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
160
163
|
file.writelines("\r\n".join(data))
|
|
161
164
|
file.close()
|
|
@@ -172,14 +175,14 @@ def main():
|
|
|
172
175
|
data.append("[behave]")
|
|
173
176
|
data.append("show_skipped=false")
|
|
174
177
|
data.append("show_timings=false")
|
|
175
|
-
file_path =
|
|
178
|
+
file_path = os.path.join(dir_name, "setup.cfg")
|
|
176
179
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
177
180
|
file.writelines("\r\n".join(data))
|
|
178
181
|
file.close()
|
|
179
182
|
|
|
180
183
|
data = []
|
|
181
184
|
data.append("")
|
|
182
|
-
file_path =
|
|
185
|
+
file_path = os.path.join(dir_name, "__init__.py")
|
|
183
186
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
184
187
|
file.writelines("\r\n".join(data))
|
|
185
188
|
file.close()
|
|
@@ -321,15 +324,15 @@ def main():
|
|
|
321
324
|
data.append("temp")
|
|
322
325
|
data.append("temp_*/")
|
|
323
326
|
data.append("node_modules")
|
|
324
|
-
file_path =
|
|
327
|
+
file_path = os.path.join(dir_name, ".gitignore")
|
|
325
328
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
326
329
|
file.writelines("\r\n".join(data))
|
|
327
330
|
file.close()
|
|
328
331
|
|
|
329
332
|
if gha:
|
|
330
|
-
dir_name_b = dir_name
|
|
333
|
+
dir_name_b = os.path.join(dir_name, ".github")
|
|
331
334
|
os.mkdir(dir_name_b)
|
|
332
|
-
dir_name_c = dir_name_b
|
|
335
|
+
dir_name_c = os.path.join(dir_name_b, "workflows")
|
|
333
336
|
os.mkdir(dir_name_c)
|
|
334
337
|
|
|
335
338
|
data = []
|
|
@@ -377,7 +380,7 @@ def main():
|
|
|
377
380
|
data.append(" path: ./latest_logs/")
|
|
378
381
|
data.append(" if-no-files-found: ignore")
|
|
379
382
|
data.append("")
|
|
380
|
-
file_path =
|
|
383
|
+
file_path = os.path.join(dir_name_c, "python-package.yml")
|
|
381
384
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
382
385
|
file.writelines("\r\n".join(data))
|
|
383
386
|
file.close()
|
|
@@ -393,12 +396,14 @@ def main():
|
|
|
393
396
|
data.append(" ├── pytest.ini")
|
|
394
397
|
data.append(" ├── requirements.txt")
|
|
395
398
|
data.append(" └── setup.cfg")
|
|
396
|
-
file_path =
|
|
399
|
+
file_path = os.path.join(dir_name, "outline.rst")
|
|
397
400
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
398
401
|
file.writelines("\r\n".join(data))
|
|
399
402
|
file.close()
|
|
400
|
-
|
|
403
|
+
|
|
404
|
+
subprocess.run(["sbase", "print", file_path, "-n"])
|
|
401
405
|
os.remove(file_path)
|
|
406
|
+
|
|
402
407
|
success = (
|
|
403
408
|
"\n" + c1 + '* Directory "' + dir_name + '" was created '
|
|
404
409
|
"with config files! *" + cr + "\n"
|
|
@@ -437,7 +442,7 @@ def main():
|
|
|
437
442
|
data.append(' self.js_click("a#logout_sidebar_link")')
|
|
438
443
|
data.append(' self.assert_element("div#login_button_container")')
|
|
439
444
|
data.append("")
|
|
440
|
-
file_path =
|
|
445
|
+
file_path = os.path.join(dir_name, "my_first_test.py")
|
|
441
446
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
442
447
|
file.writelines("\r\n".join(data))
|
|
443
448
|
file.close()
|
|
@@ -530,7 +535,7 @@ def main():
|
|
|
530
535
|
data.append(' self.type("input", "Have a Nice Day!")')
|
|
531
536
|
data.append(' self.assert_text("SeleniumBase", "h2")')
|
|
532
537
|
data.append("")
|
|
533
|
-
file_path =
|
|
538
|
+
file_path = os.path.join(dir_name, "test_demo_site.py")
|
|
534
539
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
535
540
|
file.writelines("\r\n".join(data))
|
|
536
541
|
file.close()
|
|
@@ -570,17 +575,17 @@ def main():
|
|
|
570
575
|
data.append(' self.assert_title_contains(title_text)')
|
|
571
576
|
data.append(' self.save_screenshot_to_logs()')
|
|
572
577
|
data.append("")
|
|
573
|
-
file_path =
|
|
578
|
+
file_path = os.path.join(dir_name, "parameterized_test.py")
|
|
574
579
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
575
580
|
file.writelines("\r\n".join(data))
|
|
576
581
|
file.close()
|
|
577
582
|
|
|
578
|
-
dir_name_2 = dir_name
|
|
583
|
+
dir_name_2 = os.path.join(dir_name, "boilerplates")
|
|
579
584
|
os.mkdir(dir_name_2)
|
|
580
585
|
|
|
581
586
|
data = []
|
|
582
587
|
data.append("")
|
|
583
|
-
file_path =
|
|
588
|
+
file_path = os.path.join(dir_name_2, "__init__.py")
|
|
584
589
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
585
590
|
file.writelines("\r\n".join(data))
|
|
586
591
|
file.close()
|
|
@@ -615,7 +620,7 @@ def main():
|
|
|
615
620
|
data.append(" # <<< Placeholder. Add your code here. >>>")
|
|
616
621
|
data.append(" pass")
|
|
617
622
|
data.append("")
|
|
618
|
-
file_path =
|
|
623
|
+
file_path = os.path.join(dir_name_2, "base_test_case.py")
|
|
619
624
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
620
625
|
file.writelines("\r\n".join(data))
|
|
621
626
|
file.close()
|
|
@@ -624,7 +629,7 @@ def main():
|
|
|
624
629
|
data.append("class Page(object):")
|
|
625
630
|
data.append(' html = "html"')
|
|
626
631
|
data.append("")
|
|
627
|
-
file_path =
|
|
632
|
+
file_path = os.path.join(dir_name_2, "page_objects.py")
|
|
628
633
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
629
634
|
file.writelines("\r\n".join(data))
|
|
630
635
|
file.close()
|
|
@@ -640,7 +645,7 @@ def main():
|
|
|
640
645
|
data.append(" self.example_method()")
|
|
641
646
|
data.append(" self.assert_element(Page.html)")
|
|
642
647
|
data.append("")
|
|
643
|
-
file_path =
|
|
648
|
+
file_path = os.path.join(dir_name_2, "boilerplate_test.py")
|
|
644
649
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
645
650
|
file.writelines("\r\n".join(data))
|
|
646
651
|
file.close()
|
|
@@ -664,7 +669,7 @@ def main():
|
|
|
664
669
|
data.append(' self.assert_text("Hello!", "p")')
|
|
665
670
|
data.append(' DataPage().add_input_text(self, "Goodbye!")')
|
|
666
671
|
data.append("")
|
|
667
|
-
file_path =
|
|
672
|
+
file_path = os.path.join(dir_name_2, "classic_obj_test.py")
|
|
668
673
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
669
674
|
file.writelines("\r\n".join(data))
|
|
670
675
|
file.close()
|
|
@@ -684,17 +689,17 @@ def main():
|
|
|
684
689
|
data.append(' sb.assert_text("Hello!", "p")')
|
|
685
690
|
data.append(' DataPage().add_input_text(sb, "Goodbye!")')
|
|
686
691
|
data.append("")
|
|
687
|
-
file_path =
|
|
692
|
+
file_path = os.path.join(dir_name_2, "sb_fixture_test.py")
|
|
688
693
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
689
694
|
file.writelines("\r\n".join(data))
|
|
690
695
|
file.close()
|
|
691
696
|
|
|
692
|
-
dir_name_3 = dir_name_2
|
|
697
|
+
dir_name_3 = os.path.join(dir_name_2, "samples")
|
|
693
698
|
os.mkdir(dir_name_3)
|
|
694
699
|
|
|
695
700
|
data = []
|
|
696
701
|
data.append("")
|
|
697
|
-
file_path =
|
|
702
|
+
file_path = os.path.join(dir_name_3, "__init__.py")
|
|
698
703
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
699
704
|
file.writelines("\r\n".join(data))
|
|
700
705
|
file.close()
|
|
@@ -713,9 +718,10 @@ def main():
|
|
|
713
718
|
data.append(" self.get_new_driver(undetectable=True)")
|
|
714
719
|
data.append(' self.goto("https://google.com/ncr")')
|
|
715
720
|
data.append(
|
|
716
|
-
"
|
|
721
|
+
" self.click_if_visible('button:contains(\"Accept all\")')"
|
|
717
722
|
)
|
|
718
723
|
data.append(' self.assert_title_contains("Google")')
|
|
724
|
+
data.append(" self.sleep(0.05)")
|
|
719
725
|
data.append(" self.save_screenshot_to_logs()")
|
|
720
726
|
data.append(' self.type(HomePage.search_box, "GitHub")')
|
|
721
727
|
data.append(" self.assert_element(HomePage.search_button)")
|
|
@@ -726,7 +732,7 @@ def main():
|
|
|
726
732
|
' self.assert_text("github.com", ResultsPage.search_results)'
|
|
727
733
|
)
|
|
728
734
|
data.append("")
|
|
729
|
-
file_path =
|
|
735
|
+
file_path = os.path.join(dir_name_3, "google_test.py")
|
|
730
736
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
731
737
|
file.writelines("\r\n".join(data))
|
|
732
738
|
file.close()
|
|
@@ -734,7 +740,7 @@ def main():
|
|
|
734
740
|
data = []
|
|
735
741
|
data.append("class HomePage(object):")
|
|
736
742
|
data.append(" dialog_box = '[role=\"dialog\"] div'")
|
|
737
|
-
data.append(" search_box = '[
|
|
743
|
+
data.append(" search_box = '[name=\"q\"]'")
|
|
738
744
|
data.append(" search_button = 'input[value=\"Google Search\"]'")
|
|
739
745
|
data.append(
|
|
740
746
|
' feeling_lucky_button = """input[value="I\'m Feeling Lucky"]"""'
|
|
@@ -744,7 +750,7 @@ def main():
|
|
|
744
750
|
data.append("class ResultsPage(object):")
|
|
745
751
|
data.append(' search_results = "div#center_col"')
|
|
746
752
|
data.append("")
|
|
747
|
-
file_path =
|
|
753
|
+
file_path = os.path.join(dir_name_3, "google_objects.py")
|
|
748
754
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
749
755
|
file.writelines("\r\n".join(data))
|
|
750
756
|
file.close()
|
|
@@ -776,7 +782,7 @@ def main():
|
|
|
776
782
|
data.append(' self.js_click("a#logout_sidebar_link")')
|
|
777
783
|
data.append(' self.assert_element("div#login_button_container")')
|
|
778
784
|
data.append("")
|
|
779
|
-
file_path =
|
|
785
|
+
file_path = os.path.join(dir_name_3, "swag_labs_test.py")
|
|
780
786
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
781
787
|
file.writelines("\r\n".join(data))
|
|
782
788
|
file.close()
|
|
@@ -803,7 +809,7 @@ def main():
|
|
|
803
809
|
data.append(' sb.js_click("a#logout_sidebar_link")')
|
|
804
810
|
data.append(' sb.assert_element("div#login_button_container")')
|
|
805
811
|
data.append("")
|
|
806
|
-
file_path =
|
|
812
|
+
file_path = os.path.join(dir_name_3, "sb_swag_test.py")
|
|
807
813
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
808
814
|
file.writelines("\r\n".join(data))
|
|
809
815
|
file.close()
|
|
@@ -834,16 +840,12 @@ def main():
|
|
|
834
840
|
data.append(" ├── google_test.py")
|
|
835
841
|
data.append(" ├── sb_swag_test.py")
|
|
836
842
|
data.append(" └── swag_labs_test.py")
|
|
837
|
-
file_path =
|
|
843
|
+
file_path = os.path.join(dir_name, "outline.rst")
|
|
838
844
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
839
845
|
file.writelines("\r\n".join(data))
|
|
840
846
|
file.close()
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
elif '"' not in file_path:
|
|
844
|
-
os.system('sbase print "%s" -n' % file_path)
|
|
845
|
-
else:
|
|
846
|
-
os.system("sbase print '%s' -n" % file_path)
|
|
847
|
+
|
|
848
|
+
subprocess.run(["sbase", "print", file_path, "-n"])
|
|
847
849
|
os.remove(file_path)
|
|
848
850
|
|
|
849
851
|
success = (
|
|
@@ -42,6 +42,7 @@ Output:
|
|
|
42
42
|
"""
|
|
43
43
|
import colorama
|
|
44
44
|
import os
|
|
45
|
+
import subprocess
|
|
45
46
|
import sys
|
|
46
47
|
|
|
47
48
|
|
|
@@ -112,15 +113,17 @@ def main():
|
|
|
112
113
|
|
|
113
114
|
command_args = sys.argv[2:]
|
|
114
115
|
file_name = command_args[0]
|
|
116
|
+
if file_name:
|
|
117
|
+
file_name = str(file_name)
|
|
115
118
|
if file_name == "-h" or file_name == "--help":
|
|
116
119
|
invalid_run_command("help")
|
|
117
120
|
elif not file_name.endswith(".py"):
|
|
118
121
|
error_msg = 'File name must end with ".py"!'
|
|
119
|
-
elif "*" in file_name or len(
|
|
122
|
+
elif "*" in file_name or len(file_name) < 4:
|
|
120
123
|
error_msg = "Invalid file name!"
|
|
121
124
|
elif file_name.startswith("-"):
|
|
122
125
|
error_msg = 'File name cannot start with "-"!'
|
|
123
|
-
elif
|
|
126
|
+
elif any(sep in file_name for sep in ("/", "\\")):
|
|
124
127
|
error_msg = "File must be created in the current directory!"
|
|
125
128
|
elif os.path.exists(os.getcwd() + "/" + file_name):
|
|
126
129
|
error_msg = 'File "%s" already exists in this directory!' % file_name
|
|
@@ -415,12 +418,10 @@ def main():
|
|
|
415
418
|
file = open(file_path, mode="w+", encoding="utf-8")
|
|
416
419
|
file.writelines("\r\n".join(data))
|
|
417
420
|
file.close()
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
else:
|
|
423
|
-
os.system("sbase print '%s' -n" % file_name)
|
|
421
|
+
|
|
422
|
+
print_cmd = ["sbase", "print", file_name, "-n"]
|
|
423
|
+
subprocess.run(print_cmd)
|
|
424
|
+
|
|
424
425
|
success = (
|
|
425
426
|
"\n" + c1 + '* Test file: "' + file_name + '" was created! *'
|
|
426
427
|
"" + cr + "\n"
|