seleniumbase 4.44.1__tar.gz → 4.44.2__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.44.1/seleniumbase.egg-info → seleniumbase-4.44.2}/PKG-INFO +1 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/browser_launcher.py +3 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/sb_cdp.py +99 -27
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/base_case.py +7 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/connection.py +2 -3
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/element.py +75 -18
- {seleniumbase-4.44.1 → seleniumbase-4.44.2/seleniumbase.egg-info}/PKG-INFO +1 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/.gitignore +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/LICENSE +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/MANIFEST.in +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/README.md +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/install.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/pyproject.toml +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/pytest.ini +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/requirements.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/sbase/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/sbase/__main__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/sbase/steps.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase.egg-info/requires.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/setup.cfg +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/setup.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.2}/virtualenv_install.sh +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.44.
|
|
2
|
+
__version__ = "4.44.2"
|
|
@@ -764,6 +764,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
764
764
|
cdp.click_active_element = CDPM.click_active_element
|
|
765
765
|
cdp.click_if_visible = CDPM.click_if_visible
|
|
766
766
|
cdp.click_visible_elements = CDPM.click_visible_elements
|
|
767
|
+
cdp.click_with_offset = CDPM.click_with_offset
|
|
767
768
|
cdp.mouse_click = CDPM.mouse_click
|
|
768
769
|
cdp.get_parent = CDPM.get_parent
|
|
769
770
|
cdp.remove_element = CDPM.remove_element
|
|
@@ -793,11 +794,13 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
793
794
|
cdp.set_attributes = CDPM.set_attributes
|
|
794
795
|
cdp.is_attribute_present = CDPM.is_attribute_present
|
|
795
796
|
cdp.is_online = CDPM.is_online
|
|
797
|
+
cdp.solve_captcha = CDPM.solve_captcha
|
|
796
798
|
cdp.gui_press_key = CDPM.gui_press_key
|
|
797
799
|
cdp.gui_press_keys = CDPM.gui_press_keys
|
|
798
800
|
cdp.gui_write = CDPM.gui_write
|
|
799
801
|
cdp.gui_click_x_y = CDPM.gui_click_x_y
|
|
800
802
|
cdp.gui_click_element = CDPM.gui_click_element
|
|
803
|
+
cdp.gui_click_with_offset = CDPM.gui_click_with_offset
|
|
801
804
|
cdp.gui_click_captcha = CDPM.gui_click_captcha
|
|
802
805
|
cdp.gui_drag_drop_points = CDPM.gui_drag_drop_points
|
|
803
806
|
cdp.gui_drag_and_drop = CDPM.gui_drag_and_drop
|
|
@@ -64,6 +64,11 @@ class CDPMethods():
|
|
|
64
64
|
)
|
|
65
65
|
element.highlight_overlay = lambda: self.__highlight_overlay(element)
|
|
66
66
|
element.mouse_click = lambda: self.__mouse_click(element)
|
|
67
|
+
element.click_with_offset = (
|
|
68
|
+
lambda *args, **kwargs: self.__mouse_click_with_offset_async(
|
|
69
|
+
element, *args, **kwargs
|
|
70
|
+
)
|
|
71
|
+
)
|
|
67
72
|
element.mouse_drag = (
|
|
68
73
|
lambda destination: self.__mouse_drag(element, destination)
|
|
69
74
|
)
|
|
@@ -447,6 +452,15 @@ class CDPMethods():
|
|
|
447
452
|
self.loop.run_until_complete(self.page.wait())
|
|
448
453
|
return result
|
|
449
454
|
|
|
455
|
+
def __mouse_click_with_offset_async(self, element, *args, **kwargs):
|
|
456
|
+
result = (
|
|
457
|
+
self.loop.run_until_complete(
|
|
458
|
+
element.mouse_click_with_offset_async(*args, **kwargs)
|
|
459
|
+
)
|
|
460
|
+
)
|
|
461
|
+
self.loop.run_until_complete(self.page.wait())
|
|
462
|
+
return result
|
|
463
|
+
|
|
450
464
|
def __mouse_drag(self, element, destination):
|
|
451
465
|
return (
|
|
452
466
|
self.loop.run_until_complete(element.mouse_drag_async(destination))
|
|
@@ -689,10 +703,16 @@ class CDPMethods():
|
|
|
689
703
|
self.__slow_mode_pause_if_set()
|
|
690
704
|
element = self.find_element(selector, timeout=timeout)
|
|
691
705
|
element.scroll_into_view()
|
|
692
|
-
|
|
693
|
-
|
|
706
|
+
tag_name = element.tag_name
|
|
707
|
+
if tag_name:
|
|
708
|
+
tag_name = tag_name.lower().strip()
|
|
709
|
+
if (
|
|
710
|
+
tag_name in ["a", "button", "canvas", "div", "input", "li", "span"]
|
|
711
|
+
and "contains(" not in selector
|
|
712
|
+
):
|
|
713
|
+
element.mouse_click() # Simulated click (NOT PyAutoGUI)
|
|
694
714
|
else:
|
|
695
|
-
element.click()
|
|
715
|
+
element.click() # Standard CDP click
|
|
696
716
|
self.__slow_mode_pause_if_set()
|
|
697
717
|
self.loop.run_until_complete(self.page.wait())
|
|
698
718
|
|
|
@@ -738,7 +758,7 @@ class CDPMethods():
|
|
|
738
758
|
element.scroll_into_view()
|
|
739
759
|
element.click()
|
|
740
760
|
click_count += 1
|
|
741
|
-
time.sleep(0.
|
|
761
|
+
time.sleep(0.044)
|
|
742
762
|
self.__slow_mode_pause_if_set()
|
|
743
763
|
self.loop.run_until_complete(self.page.wait())
|
|
744
764
|
except Exception:
|
|
@@ -1757,11 +1777,32 @@ class CDPMethods():
|
|
|
1757
1777
|
self.__slow_mode_pause_if_set()
|
|
1758
1778
|
self.loop.run_until_complete(self.page.wait())
|
|
1759
1779
|
|
|
1760
|
-
def
|
|
1761
|
-
|
|
1762
|
-
|
|
1780
|
+
def gui_click_with_offset(
|
|
1781
|
+
self, selector, x, y, timeframe=0.25, center=False
|
|
1782
|
+
):
|
|
1783
|
+
"""Click an element at an {X,Y}-offset location.
|
|
1784
|
+
{0,0} is the top-left corner of the element.
|
|
1785
|
+
If center==True, {0,0} becomes the center of the element.
|
|
1786
|
+
The timeframe is the time spent moving the mouse."""
|
|
1787
|
+
if center:
|
|
1788
|
+
px, py = self.get_gui_element_center(selector)
|
|
1789
|
+
self.gui_click_x_y(px + x, py + y, timeframe=timeframe)
|
|
1790
|
+
else:
|
|
1791
|
+
element_rect = self.get_gui_element_rect(selector)
|
|
1792
|
+
px = element_rect["x"]
|
|
1793
|
+
py = element_rect["y"]
|
|
1794
|
+
self.gui_click_x_y(px + x, py + y, timeframe=timeframe)
|
|
1795
|
+
|
|
1796
|
+
def click_with_offset(self, selector, x, y, center=False):
|
|
1797
|
+
element = self.find_element(selector)
|
|
1798
|
+
element.scroll_into_view()
|
|
1799
|
+
element.click_with_offset(x=x, y=y, center=center)
|
|
1800
|
+
self.__slow_mode_pause_if_set()
|
|
1801
|
+
self.loop.run_until_complete(self.page.wait())
|
|
1802
|
+
|
|
1803
|
+
def _on_a_cf_turnstile_page(self, source=None):
|
|
1763
1804
|
if not source or len(source) < 400:
|
|
1764
|
-
time.sleep(0.
|
|
1805
|
+
time.sleep(0.2)
|
|
1765
1806
|
source = self.get_page_source()
|
|
1766
1807
|
if (
|
|
1767
1808
|
'data-callback="onCaptchaSuccess"' in source
|
|
@@ -1773,20 +1814,21 @@ class CDPMethods():
|
|
|
1773
1814
|
return True
|
|
1774
1815
|
return False
|
|
1775
1816
|
|
|
1776
|
-
def _on_a_g_recaptcha_page(self):
|
|
1777
|
-
time.sleep(0.042)
|
|
1778
|
-
source = self.get_page_source()
|
|
1817
|
+
def _on_a_g_recaptcha_page(self, source=None):
|
|
1779
1818
|
if not source or len(source) < 400:
|
|
1780
|
-
time.sleep(0.
|
|
1819
|
+
time.sleep(0.2)
|
|
1781
1820
|
source = self.get_page_source()
|
|
1782
1821
|
if (
|
|
1783
1822
|
'id="recaptcha-token"' in source
|
|
1784
1823
|
or 'title="reCAPTCHA"' in source
|
|
1785
1824
|
):
|
|
1786
1825
|
return True
|
|
1826
|
+
elif "/recaptcha/api.js" in source:
|
|
1827
|
+
time.sleep(1.6) # Still loading
|
|
1828
|
+
return True
|
|
1787
1829
|
return False
|
|
1788
1830
|
|
|
1789
|
-
def __gui_click_recaptcha(self):
|
|
1831
|
+
def __gui_click_recaptcha(self, use_cdp=False):
|
|
1790
1832
|
selector = None
|
|
1791
1833
|
if self.is_element_visible('iframe[title="reCAPTCHA"]'):
|
|
1792
1834
|
selector = 'iframe[title="reCAPTCHA"]'
|
|
@@ -1797,19 +1839,39 @@ class CDPMethods():
|
|
|
1797
1839
|
element_rect = self.get_gui_element_rect(selector, timeout=1)
|
|
1798
1840
|
e_x = element_rect["x"]
|
|
1799
1841
|
e_y = element_rect["y"]
|
|
1800
|
-
|
|
1801
|
-
|
|
1842
|
+
x_offset = 26
|
|
1843
|
+
y_offset = 35
|
|
1844
|
+
if shared_utils.is_windows():
|
|
1845
|
+
x_offset = 29
|
|
1846
|
+
x = e_x + x_offset
|
|
1847
|
+
y = e_y + y_offset
|
|
1802
1848
|
sb_config._saved_cf_x_y = (x, y)
|
|
1803
1849
|
time.sleep(0.08)
|
|
1804
|
-
|
|
1850
|
+
if use_cdp:
|
|
1851
|
+
self.sleep(0.03)
|
|
1852
|
+
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
1853
|
+
with gui_lock: # Prevent issues with multiple processes
|
|
1854
|
+
self.bring_active_window_to_front()
|
|
1855
|
+
time.sleep(0.056)
|
|
1856
|
+
self.click_with_offset(selector, x_offset, y_offset)
|
|
1857
|
+
time.sleep(0.056)
|
|
1858
|
+
else:
|
|
1859
|
+
self.gui_click_x_y(x, y)
|
|
1860
|
+
|
|
1861
|
+
def solve_captcha(self):
|
|
1862
|
+
self.__click_captcha(use_cdp=True)
|
|
1805
1863
|
|
|
1806
1864
|
def gui_click_captcha(self):
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1865
|
+
self.__click_captcha(use_cdp=False)
|
|
1866
|
+
|
|
1867
|
+
def __click_captcha(self, use_cdp=False):
|
|
1868
|
+
"""Uses PyAutoGUI unless use_cdp == True"""
|
|
1869
|
+
self.sleep(0.056)
|
|
1870
|
+
source = self.get_page_source()
|
|
1871
|
+
if self._on_a_g_recaptcha_page(source):
|
|
1872
|
+
self.__gui_click_recaptcha(use_cdp)
|
|
1811
1873
|
return
|
|
1812
|
-
|
|
1874
|
+
elif not self._on_a_cf_turnstile_page(source):
|
|
1813
1875
|
return
|
|
1814
1876
|
selector = None
|
|
1815
1877
|
if (
|
|
@@ -1970,14 +2032,24 @@ class CDPMethods():
|
|
|
1970
2032
|
element_rect = self.get_gui_element_rect(selector, timeout=1)
|
|
1971
2033
|
e_x = element_rect["x"]
|
|
1972
2034
|
e_y = element_rect["y"]
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2035
|
+
x_offset = 32
|
|
2036
|
+
y_offset = 32
|
|
2037
|
+
if shared_utils.is_windows():
|
|
2038
|
+
y_offset = 28
|
|
2039
|
+
x = e_x + x_offset
|
|
2040
|
+
y = e_y + y_offset
|
|
1978
2041
|
sb_config._saved_cf_x_y = (x, y)
|
|
1979
2042
|
time.sleep(0.08)
|
|
1980
|
-
|
|
2043
|
+
if use_cdp:
|
|
2044
|
+
self.sleep(0.03)
|
|
2045
|
+
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2046
|
+
with gui_lock: # Prevent issues with multiple processes
|
|
2047
|
+
self.bring_active_window_to_front()
|
|
2048
|
+
time.sleep(0.056)
|
|
2049
|
+
self.click_with_offset(selector, x_offset, y_offset)
|
|
2050
|
+
time.sleep(0.056)
|
|
2051
|
+
else:
|
|
2052
|
+
self.gui_click_x_y(x, y)
|
|
1981
2053
|
|
|
1982
2054
|
def __gui_drag_drop(self, x1, y1, x2, y2, timeframe=0.25, uc_lock=False):
|
|
1983
2055
|
self.__install_pyautogui_if_missing()
|
|
@@ -5008,6 +5008,9 @@ class BaseCase(unittest.TestCase):
|
|
|
5008
5008
|
self.get_new_driver(undetectable=True)
|
|
5009
5009
|
self.driver.uc_open_with_cdp_mode(url, **kwargs)
|
|
5010
5010
|
self.cdp = self.driver.cdp
|
|
5011
|
+
if hasattr(self.cdp, "solve_captcha"):
|
|
5012
|
+
self.solve_captcha = self.cdp.solve_captcha
|
|
5013
|
+
self.undetectable = True
|
|
5011
5014
|
|
|
5012
5015
|
def activate_recorder(self):
|
|
5013
5016
|
"""Activate Recorder Mode on the current tab/window.
|
|
@@ -11452,6 +11455,7 @@ class BaseCase(unittest.TestCase):
|
|
|
11452
11455
|
if cdp_swap_needed:
|
|
11453
11456
|
if not self.cdp:
|
|
11454
11457
|
self.cdp = self.driver.cdp
|
|
11458
|
+
self.undetectable = True
|
|
11455
11459
|
return True
|
|
11456
11460
|
else:
|
|
11457
11461
|
return False
|
|
@@ -13970,6 +13974,9 @@ class BaseCase(unittest.TestCase):
|
|
|
13970
13974
|
timeout=None,
|
|
13971
13975
|
center=None,
|
|
13972
13976
|
):
|
|
13977
|
+
if self.__is_cdp_swap_needed():
|
|
13978
|
+
self.cdp.click_with_offset(selector, x, y, center=center)
|
|
13979
|
+
return
|
|
13973
13980
|
self.wait_for_ready_state_complete()
|
|
13974
13981
|
if self.__needs_minimum_wait():
|
|
13975
13982
|
time.sleep(0.14)
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/connection.py
RENAMED
|
@@ -7,7 +7,6 @@ import json
|
|
|
7
7
|
import logging
|
|
8
8
|
import sys
|
|
9
9
|
import types
|
|
10
|
-
from asyncio import iscoroutine, iscoroutinefunction
|
|
11
10
|
from typing import (
|
|
12
11
|
Optional,
|
|
13
12
|
Generator,
|
|
@@ -666,8 +665,8 @@ class Listener:
|
|
|
666
665
|
for callback in callbacks:
|
|
667
666
|
try:
|
|
668
667
|
if (
|
|
669
|
-
iscoroutinefunction(callback)
|
|
670
|
-
or iscoroutine(callback)
|
|
668
|
+
inspect.iscoroutinefunction(callback)
|
|
669
|
+
or inspect.iscoroutine(callback)
|
|
671
670
|
):
|
|
672
671
|
try:
|
|
673
672
|
await callback(event, self.connection)
|
|
@@ -484,17 +484,14 @@ class Element:
|
|
|
484
484
|
buttons: typing.Optional[int] = 1,
|
|
485
485
|
modifiers: typing.Optional[int] = 0,
|
|
486
486
|
hold: bool = False,
|
|
487
|
-
_until_event: typing.Optional[type] = None,
|
|
488
487
|
):
|
|
489
488
|
"""
|
|
490
489
|
Native click (on element).
|
|
491
|
-
Note: This likely does not work at the moment. Use click() instead.
|
|
492
490
|
:param button: str (default = "left")
|
|
493
491
|
:param buttons: which button (default 1 = left)
|
|
494
492
|
:param modifiers: *(Optional)*
|
|
495
493
|
Bit field representing pressed modifier keys.
|
|
496
494
|
Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0).
|
|
497
|
-
:param _until_event: Internal. Event to wait for before returning.
|
|
498
495
|
"""
|
|
499
496
|
try:
|
|
500
497
|
center = (await self.get_position_async()).center
|
|
@@ -505,6 +502,7 @@ class Element:
|
|
|
505
502
|
return
|
|
506
503
|
logger.debug("Clicking on location: %.2f, %.2f" % center)
|
|
507
504
|
await asyncio.gather(
|
|
505
|
+
self.flash_async(0.25),
|
|
508
506
|
self._tab.send(
|
|
509
507
|
cdp.input_.dispatch_mouse_event(
|
|
510
508
|
"mousePressed",
|
|
@@ -528,10 +526,66 @@ class Element:
|
|
|
528
526
|
)
|
|
529
527
|
),
|
|
530
528
|
)
|
|
529
|
+
|
|
530
|
+
async def mouse_click_with_offset_async(
|
|
531
|
+
self,
|
|
532
|
+
x: typing.Union[float, int],
|
|
533
|
+
y: typing.Union[float, int],
|
|
534
|
+
center: bool = False,
|
|
535
|
+
button: str = "left",
|
|
536
|
+
buttons: typing.Optional[int] = 1,
|
|
537
|
+
modifiers: typing.Optional[int] = 0,
|
|
538
|
+
):
|
|
539
|
+
x_offset = int(x)
|
|
540
|
+
y_offset = int(y)
|
|
531
541
|
try:
|
|
532
|
-
await self.
|
|
533
|
-
|
|
534
|
-
|
|
542
|
+
position = (await self.get_position_async())
|
|
543
|
+
width = position.width
|
|
544
|
+
height = position.height
|
|
545
|
+
x_pos = position.left
|
|
546
|
+
y_pos = position.top
|
|
547
|
+
center_pos = (await self.get_position_async()).center
|
|
548
|
+
except AttributeError:
|
|
549
|
+
return
|
|
550
|
+
if not center_pos:
|
|
551
|
+
logger.warning("Could not calculate box model for %s", self)
|
|
552
|
+
return
|
|
553
|
+
if center:
|
|
554
|
+
x_pos = center_pos[0]
|
|
555
|
+
y_pos = center_pos[1]
|
|
556
|
+
width = 0
|
|
557
|
+
height = 0
|
|
558
|
+
logger.debug("Clicking on location: %.2f, %.2f" % center_pos)
|
|
559
|
+
else:
|
|
560
|
+
logger.debug("Clicking on location: %.2f, %.2f" % (x_pos, y_pos))
|
|
561
|
+
await asyncio.gather(
|
|
562
|
+
self.flash_async(
|
|
563
|
+
x_offset=x_offset - int(width / 2),
|
|
564
|
+
y_offset=y_offset - int(height / 2),
|
|
565
|
+
),
|
|
566
|
+
self._tab.send(
|
|
567
|
+
cdp.input_.dispatch_mouse_event(
|
|
568
|
+
"mousePressed",
|
|
569
|
+
x=x_pos + x_offset,
|
|
570
|
+
y=y_pos + y_offset,
|
|
571
|
+
modifiers=modifiers,
|
|
572
|
+
button=cdp.input_.MouseButton(button),
|
|
573
|
+
buttons=buttons,
|
|
574
|
+
click_count=1,
|
|
575
|
+
)
|
|
576
|
+
),
|
|
577
|
+
self._tab.send(
|
|
578
|
+
cdp.input_.dispatch_mouse_event(
|
|
579
|
+
"mouseReleased",
|
|
580
|
+
x=x_pos + x_offset,
|
|
581
|
+
y=y_pos + y_offset,
|
|
582
|
+
modifiers=modifiers,
|
|
583
|
+
button=cdp.input_.MouseButton(button),
|
|
584
|
+
buttons=buttons,
|
|
585
|
+
click_count=1,
|
|
586
|
+
)
|
|
587
|
+
),
|
|
588
|
+
)
|
|
535
589
|
|
|
536
590
|
async def mouse_move_async(self):
|
|
537
591
|
"""
|
|
@@ -664,7 +718,7 @@ class Element:
|
|
|
664
718
|
return
|
|
665
719
|
# await self.apply("""(el) => el.scrollIntoView(false)""")
|
|
666
720
|
|
|
667
|
-
async def clear_input_async(self
|
|
721
|
+
async def clear_input_async(self):
|
|
668
722
|
"""Clears an input field."""
|
|
669
723
|
try:
|
|
670
724
|
await self.apply('function (element) { element.value = "" } ')
|
|
@@ -952,18 +1006,21 @@ class Element:
|
|
|
952
1006
|
.replace(" ", "")
|
|
953
1007
|
.replace("\n", "")
|
|
954
1008
|
)
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1009
|
+
try:
|
|
1010
|
+
arguments = [cdp.runtime.CallArgument(
|
|
1011
|
+
object_id=self._remote_object.object_id
|
|
1012
|
+
)]
|
|
1013
|
+
await self._tab.send(
|
|
1014
|
+
cdp.runtime.call_function_on(
|
|
1015
|
+
script,
|
|
1016
|
+
object_id=self._remote_object.object_id,
|
|
1017
|
+
arguments=arguments,
|
|
1018
|
+
await_promise=True,
|
|
1019
|
+
user_gesture=True,
|
|
1020
|
+
)
|
|
965
1021
|
)
|
|
966
|
-
|
|
1022
|
+
except Exception:
|
|
1023
|
+
pass
|
|
967
1024
|
|
|
968
1025
|
async def highlight_overlay_async(self):
|
|
969
1026
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/undetected/cdp_driver/_contradict.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid_hub.py
RENAMED
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/grid_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat
RENAMED
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh
RENAMED
|
File without changes
|
|
File without changes
|
{seleniumbase-4.44.1 → seleniumbase-4.44.2}/seleniumbase/utilities/selenium_ide/convert_ide.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|