From 39d54e483d76198a48789f0750f8a1f819d32816 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 13 May 2024 00:26:48 -0400 Subject: [PATCH 1/5] Update options --- README.md | 1 + examples/raw_parameter_script.py | 1 + help_docs/customizing_test_runs.md | 1 + help_docs/recorder_mode.md | 2 + seleniumbase/console_scripts/ReadMe.md | 1 + seleniumbase/console_scripts/run.py | 2 + seleniumbase/console_scripts/sb_mkrec.py | 39 ++++++++++++++ seleniumbase/console_scripts/sb_recorder.py | 2 + seleniumbase/fixtures/base_case.py | 58 +++++++++++++++++++++ seleniumbase/plugins/pytest_plugin.py | 12 +++++ seleniumbase/plugins/selenium_plugin.py | 12 +++++ 11 files changed, 131 insertions(+) diff --git a/README.md b/README.md index 3364795f3fd..56f2a8a5abb 100755 --- a/README.md +++ b/README.md @@ -671,6 +671,7 @@ pytest test_coffee_cart.py --trace --block-images # (Block images from loading during tests.) --do-not-track # (Indicate to websites that you don't want to be tracked.) --verify-delay=SECONDS # (The delay before MasterQA verification checks.) +--ee | --esc-end # (Lets the user end the current test via the ESC key.) --recorder # (Enables the Recorder for turning browser actions into code.) --rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.) --rec-sleep # (If the Recorder is enabled, also records self.sleep calls.) diff --git a/examples/raw_parameter_script.py b/examples/raw_parameter_script.py index 89a5fcd3394..64fcec9a68c 100644 --- a/examples/raw_parameter_script.py +++ b/examples/raw_parameter_script.py @@ -76,6 +76,7 @@ sb._reuse_session = False sb._crumbs = False sb._final_debug = False + sb.esc_end = False sb.use_wire = False sb.enable_3d_apis = False sb.window_size = None diff --git a/help_docs/customizing_test_runs.md b/help_docs/customizing_test_runs.md index 6f4af19cc72..c6ca5d9c269 100644 --- a/help_docs/customizing_test_runs.md +++ b/help_docs/customizing_test_runs.md @@ -164,6 +164,7 @@ pytest my_first_test.py --settings-file=custom_settings.py --block-images # (Block images from loading during tests.) --do-not-track # (Indicate to websites that you don't want to be tracked.) --verify-delay=SECONDS # (The delay before MasterQA verification checks.) +--ee | --esc-end # (Lets the user end the current test via the ESC key.) --recorder # (Enables the Recorder for turning browser actions into code.) --rec-behave # (Same as Recorder Mode, but also generates behave-gherkin.) --rec-sleep # (If the Recorder is enabled, also records self.sleep calls.) diff --git a/help_docs/recorder_mode.md b/help_docs/recorder_mode.md index 9b88c4b143f..e859097a151 100644 --- a/help_docs/recorder_mode.md +++ b/help_docs/recorder_mode.md @@ -121,6 +121,8 @@ pytest TEST_NAME.py --trace --rec -s ⏺️ Inside recorded tests, you might find the self.open_if_not_url(URL) method, which opens the URL given if the browser is not currently on that page. SeleniumBase uses this method in recorded scripts when the Recorder detects that a browser action changed the current URL. This method prevents an unnecessary page load and shows what page the test visited after a browser action. +⏺️ By launching the Recorder App with sbase recorder --ee, you can end the recording by pressing {SHIFT+ESC} instead of the usual way of ending the recording by typing c from a breakpoint() and pressing Enter. Those buttons don't need to be pressed at the same time, but SHIFT must be pressed directly before ESC. + --------
To learn more about SeleniumBase, check out the Docs Site:
diff --git a/seleniumbase/console_scripts/ReadMe.md b/seleniumbase/console_scripts/ReadMe.md index 38438fb185c..b12476380c3 100644 --- a/seleniumbase/console_scripts/ReadMe.md +++ b/seleniumbase/console_scripts/ReadMe.md @@ -406,6 +406,7 @@ sbase codegen new_test.py --url=wikipedia.org ``--edge`` (Use Edge browser instead of Chrome.) ``--gui`` / ``--headed`` (Use headed mode on Linux.) ``--uc`` / ``--undetected`` (Use undetectable mode.) +``--ee`` (Use SHIFT + ESC to end the recording.) ``--overwrite`` (Overwrite file when it exists.) ``--behave`` (Also output Behave/Gherkin files.) diff --git a/seleniumbase/console_scripts/run.py b/seleniumbase/console_scripts/run.py index 561d23877b5..c0edf695f33 100644 --- a/seleniumbase/console_scripts/run.py +++ b/seleniumbase/console_scripts/run.py @@ -310,6 +310,7 @@ def show_mkrec_usage(): print(" --edge (Use Edge browser instead of Chrome.)") print(" --gui / --headed (Use headed mode on Linux.)") print(" --uc / --undetected (Use undetectable mode.)") + print(" --ee (Use SHIFT + ESC to end the recording.)") print(" --overwrite (Overwrite file when it exists.)") print(" --behave (Also output Behave/Gherkin files.)") print(" Output:") @@ -336,6 +337,7 @@ def show_codegen_usage(): print(" --edge (Use Edge browser instead of Chrome.)") print(" --gui / --headed (Use headed mode on Linux.)") print(" --uc / --undetected (Use undetectable mode.)") + print(" --ee (Use SHIFT + ESC to end the recording.)") print(" --overwrite (Overwrite file when it exists.)") print(" --behave (Also output Behave/Gherkin files.)") print(" Output:") diff --git a/seleniumbase/console_scripts/sb_mkrec.py b/seleniumbase/console_scripts/sb_mkrec.py index 3ee61b34eb8..6becb6c48da 100644 --- a/seleniumbase/console_scripts/sb_mkrec.py +++ b/seleniumbase/console_scripts/sb_mkrec.py @@ -93,6 +93,7 @@ def main(): invalid_cmd = None use_edge = False use_uc = False + esc_end = False start_page = None next_is_url = False use_colors = True @@ -145,6 +146,8 @@ def main(): help_me = True elif option.lower() == "--edge": use_edge = True + elif option.lower() == "--ee": + esc_end = True elif option.lower() in ("--gui", "--headed"): if "linux" in sys.platform: force_gui = True @@ -183,6 +186,42 @@ def main(): data.append(' # type "c", and press [Enter].') data.append(" import pdb; pdb.set_trace()") data.append("") + + if esc_end: + msg = ">>> Use [SHIFT + ESC] in the browser to end recording!" + d2 = [] + d2.append("from seleniumbase import BaseCase") + d2.append("") + d2.append("") + d2.append("class RecorderTest(BaseCase):") + d2.append(" def test_recording(self):") + d2.append(" if self.recorder_ext:") + d2.append(" print(") + d2.append(' "\\n\\n%s\\n"' % msg) + d2.append(" )") + d2.append(' script = self._get_rec_shift_esc_script()') + d2.append(' esc = "return document.sb_esc_end;"') + d2.append(" start_time = self.time()") + d2.append(" last_handles_num = self._get_num_handles()") + d2.append(" for i in range(1200):") + d2.append(" try:") + d2.append(" self.execute_script(script)") + d2.append(" handles_num = self._get_num_handles()") + d2.append(" if handles_num < 1:") + d2.append(" return") + d2.append(" elif handles_num != last_handles_num:") + d2.append(" self.switch_to_window(-1)") + d2.append(" last_handles_num = handles_num") + d2.append(' if self.execute_script(esc) == "yes":') + d2.append(" return") + d2.append(" elif self.time() - start_time > 600:") + d2.append(" return") + d2.append(" self.sleep(0.5)") + d2.append(" except Exception:") + d2.append(" return") + d2.append("") + data = d2 + file = codecs.open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() diff --git a/seleniumbase/console_scripts/sb_recorder.py b/seleniumbase/console_scripts/sb_recorder.py index 26cddab1dfa..056cb2b61f1 100644 --- a/seleniumbase/console_scripts/sb_recorder.py +++ b/seleniumbase/console_scripts/sb_recorder.py @@ -162,6 +162,8 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window): or "--undetectable" in command_args ): command += " --uc" + if "--ee" in command_args: + command += " --ee" command += add_on poll = None if sb_config.rec_subprocess_used: diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 1851ad9d43b..2341fa2a1c0 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -114,6 +114,7 @@ def __initialize_variables(self): ] self.version_tuple = tuple(self.version_list) self.version_info = self.version_tuple + self.time = time.time self.__page_sources = [] self.__extra_actions = [] self.__js_start_time = 0 @@ -381,6 +382,7 @@ def click( self, selector, by="css selector", timeout=None, delay=0, scroll=True ): self.__check_scope() + self.__skip_if_esc() if not timeout: timeout = settings.SMALL_TIMEOUT if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: @@ -671,6 +673,7 @@ def click( self.__demo_mode_pause_if_active(tiny=True) elif self.slow_mode: self.__slow_mode_pause_if_active() + self.__set_esc_skip() def slow_click(self, selector, by="css selector", timeout=None): """Similar to click(), but pauses for a brief moment before clicking. @@ -1586,6 +1589,7 @@ def get_partial_link_text_attribute( def click_link_text(self, link_text, timeout=None): """This method clicks link text on a page.""" self.__check_scope() + self.__skip_if_esc() if not timeout: timeout = settings.SMALL_TIMEOUT if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: @@ -4404,11 +4408,35 @@ def add_cookies(self, cookies): for cookie_dict in cookies: self.driver.add_cookie(cookie_dict) + def __set_esc_skip(self): + if hasattr(self, "esc_end") and self.esc_end: + script = ( + """document.onkeydown = function(evt) { + evt = evt || window.event; + var isEscape = false; + if ("key" in evt) { + isEscape = (evt.key === "Escape" || evt.key === "Esc"); + } else { + isEscape = (evt.keyCode === 27); + } + if (isEscape) { + document.sb_esc_end = 'yes'; + } + };""" + ) + self.execute_script(script) + + def __skip_if_esc(self): + if hasattr(self, "esc_end") and self.esc_end: + if self.execute_script("return document.sb_esc_end;") == "yes": + self.skip() + def wait_for_ready_state_complete(self, timeout=None): """Waits for the "readyState" of the page to be "complete". Returns True when the method completes.""" self.__check_scope() self._check_browser() + self.__skip_if_esc() if not timeout: timeout = settings.EXTREME_TIMEOUT if self.timeout_multiplier and timeout == settings.EXTREME_TIMEOUT: @@ -4427,6 +4455,7 @@ def wait_for_ready_state_complete(self, timeout=None): time.sleep(0.01) if self.undetectable: time.sleep(0.035) + self.__set_esc_skip() return True def wait_for_angularjs(self, timeout=None, **kwargs): @@ -5775,6 +5804,7 @@ def highlight( scroll - the option to scroll to the element first (Default: True) timeout - the time to wait for the element to appear """ self.__check_scope() + self.__skip_if_esc() if isinstance(selector, WebElement): self.__highlight_element(selector, loops=loops, scroll=scroll) return @@ -8709,6 +8739,7 @@ def wait_for_element_visible( ): """Same as self.wait_for_element()""" self.__check_scope() + self.__skip_if_esc() if not timeout: timeout = settings.LARGE_TIMEOUT if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: @@ -13478,6 +13509,7 @@ def __demo_mode_scroll_if_active(self, selector, by): self.slow_scroll_to(selector, by=by) def __demo_mode_highlight_if_active(self, selector, by): + self.__skip_if_esc() if self.demo_mode: # Includes self.slow_scroll_to(selector, by=by) by default self.__highlight(selector, by=by) @@ -14379,6 +14411,7 @@ def setUp(self, masterqa_mode=False): self.firefox_arg = sb_config.firefox_arg self.firefox_pref = sb_config.firefox_pref self.verify_delay = sb_config.verify_delay + self.esc_end = sb_config.esc_end self.recorder_mode = sb_config.recorder_mode self.recorder_ext = sb_config.recorder_mode self.rec_print = sb_config.rec_print @@ -15698,6 +15731,31 @@ def _get_driver_name_and_version(self): else: return None + def _get_num_handles(self): + return len(self.driver.window_handles) + + def _get_rec_shift_esc_script(self): + return ( + """document.onkeydown = function(evt) { + evt = evt || window.event; + var isEscape = false; + if ("key" in evt) { + isEscape = (evt.key === "Escape" || evt.key === "Esc"); + last_key = evt.key; + } else { + isEscape = (evt.keyCode === 27); + last_key = evt.keyCode; + if (last_key === 16) { + last_key = "Shift"; + } + } + if (isEscape && document.sb_last_key === "Shift") { + document.sb_esc_end = "yes"; + } + document.sb_last_key = last_key; + };""" + ) + def _addSkip(self, result, test_case, reason): """This method should NOT be called directly from tests.""" addSkip = getattr(result, 'addSkip', None) diff --git a/seleniumbase/plugins/pytest_plugin.py b/seleniumbase/plugins/pytest_plugin.py index 7aabe65e9fb..a6004c6f55b 100644 --- a/seleniumbase/plugins/pytest_plugin.py +++ b/seleniumbase/plugins/pytest_plugin.py @@ -81,6 +81,7 @@ def pytest_addoption(parser): --block-images (Block images from loading during tests.) --do-not-track (Indicate to websites that you don't want to be tracked.) --verify-delay=SECONDS (The delay before MasterQA verification checks.) + --ee / --esc-end (Lets the user end the current test via the ESC key.) --recorder (Enables the Recorder for turning browser actions into code.) --rec-behave (Same as Recorder Mode, but also generates behave-gherkin.) --rec-sleep (If the Recorder is enabled, also records self.sleep calls.) @@ -895,6 +896,16 @@ def pytest_addoption(parser): help="""Setting this overrides the default wait time before each MasterQA verification pop-up.""", ) + parser.addoption( + "--esc-end", + "--esc_end", + "--ee", + action="store_true", + dest="esc_end", + default=False, + help="""End the current test early via the ESC key. + The test will be marked as skipped.""", + ) parser.addoption( "--recorder", "--record", @@ -1549,6 +1560,7 @@ def pytest_configure(config): sb_config.block_images = config.getoption("block_images") sb_config.do_not_track = config.getoption("do_not_track") sb_config.verify_delay = config.getoption("verify_delay") + sb_config.esc_end = config.getoption("esc_end") sb_config.recorder_mode = config.getoption("recorder_mode") sb_config.recorder_ext = config.getoption("recorder_mode") # Again sb_config.rec_behave = config.getoption("rec_behave") diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index 4adc70f2a1b..c3cf01f5fc9 100644 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -60,6 +60,7 @@ class SeleniumBrowser(Plugin): --block-images (Block images from loading during tests.) --do-not-track (Indicate to websites that you don't want to be tracked.) --verify-delay=SECONDS (The delay before MasterQA verification checks.) + --ee / --esc-end (Lets the user end the current test via the ESC key.) --recorder (Enables the Recorder for turning browser actions into code.) --rec-behave (Same as Recorder Mode, but also generates behave-gherkin.) --rec-sleep (If the Recorder is enabled, also records self.sleep calls.) @@ -613,6 +614,16 @@ def options(self, parser, env): help="""Setting this overrides the default wait time before each MasterQA verification pop-up.""", ) + parser.addoption( + "--esc-end", + "--esc_end", + "--ee", + action="store_true", + dest="esc_end", + default=False, + help="""End the current test early via the ESC key. + The test will be marked as skipped.""", + ) parser.addoption( "--recorder", "--record", @@ -1126,6 +1137,7 @@ def beforeTest(self, test): test.test.block_images = self.options.block_images test.test.do_not_track = self.options.do_not_track test.test.verify_delay = self.options.verify_delay # MasterQA + test.test.esc_end = self.options.esc_end test.test.recorder_mode = self.options.recorder_mode test.test.recorder_ext = self.options.recorder_mode # Again test.test.rec_behave = self.options.rec_behave From 533c12f8a7f5b92dec31c6d8932fd80e0a3788f9 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 13 May 2024 00:29:13 -0400 Subject: [PATCH 2/5] Update UC Mode --- help_docs/method_summary.md | 2 ++ help_docs/uc_mode.md | 2 ++ seleniumbase/core/browser_launcher.py | 33 +++++++++++++++++++++++++-- seleniumbase/fixtures/base_case.py | 9 ++++++++ seleniumbase/undetected/webelement.py | 2 +- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index 2b746b4a84b..a577e33d0c9 100644 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -1046,6 +1046,8 @@ driver.uc_open_with_tab(url) # (New tab with default reconnect_time) driver.uc_open_with_reconnect(url, reconnect_time=None) # (New tab) +driver.uc_open_with_disconnect(url) # Open in new tab + disconnect() + driver.reconnect(timeout) # disconnect() + sleep(timeout) + connect() driver.disconnect() # Stops the webdriver service to prevent detection diff --git a/help_docs/uc_mode.md b/help_docs/uc_mode.md index 8c7f13b1634..1980d9fb56a 100644 --- a/help_docs/uc_mode.md +++ b/help_docs/uc_mode.md @@ -159,6 +159,8 @@ driver.uc_open_with_tab(url) driver.uc_open_with_reconnect(url, reconnect_time=None) +driver.uc_open_with_disconnect(url) + driver.reconnect(timeout) driver.disconnect() diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index c93d811a6b7..74ffcce97f4 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -443,8 +443,32 @@ def uc_open_with_reconnect(driver, url, reconnect_time=None): js_utils.call_me_later(driver, script, 3) time.sleep(0.007) driver.close() - driver.reconnect(reconnect_time) - driver.switch_to.window(driver.window_handles[-1]) + if reconnect_time == "disconnect": + driver.disconnect() + time.sleep(0.007) + else: + driver.reconnect(reconnect_time) + driver.switch_to.window(driver.window_handles[-1]) + else: + driver.default_get(url) # The original one + return None + + +def uc_open_with_disconnect(driver, url): + """Open a url and disconnect chromedriver. + Note: You can't perform Selenium actions again + until after you've called driver.connect().""" + if url.startswith("//"): + url = "https:" + url + elif ":" not in url: + url = "https://" + url + if (url.startswith("http:") or url.startswith("https:")): + script = 'window.open("%s","_blank");' % url + js_utils.call_me_later(driver, script, 3) + time.sleep(0.007) + driver.close() + driver.disconnect() + time.sleep(0.007) else: driver.default_get(url) # The original one return None @@ -3754,6 +3778,11 @@ def get_local_driver( driver, *args, **kwargs ) ) + driver.uc_open_with_disconnect = ( + lambda *args, **kwargs: uc_open_with_disconnect( + driver, *args, **kwargs + ) + ) driver.uc_click = lambda *args, **kwargs: uc_click( driver, *args, **kwargs ) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 2341fa2a1c0..eaab7864220 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -4146,6 +4146,10 @@ def get_new_driver( self.uc_open_with_tab = new_driver.uc_open_with_tab if hasattr(new_driver, "uc_open_with_reconnect"): self.uc_open_with_reconnect = new_driver.uc_open_with_reconnect + if hasattr(new_driver, "uc_open_with_disconnect"): + self.uc_open_with_disconnect = ( + new_driver.uc_open_with_disconnect + ) if hasattr(new_driver, "reconnect"): self.reconnect = new_driver.reconnect if hasattr(new_driver, "disconnect"): @@ -15886,6 +15890,11 @@ def tearDown(self): ) raise Exception(message) # *** Start tearDown() officially *** + if self.undetectable: + try: + self.driver.window_handles + except urllib3.exceptions.MaxRetryError: + self.driver.connect() self.__slow_mode_pause_if_active() has_exception = self.__has_exception() sb_config._has_exception = has_exception diff --git a/seleniumbase/undetected/webelement.py b/seleniumbase/undetected/webelement.py index 1db44f30494..ee252e56bc6 100644 --- a/seleniumbase/undetected/webelement.py +++ b/seleniumbase/undetected/webelement.py @@ -14,7 +14,7 @@ def uc_click( ): if driver and selector and by: delayed_click = False - if tag_name in ["span", "button", "div", "a"]: + if tag_name in ["span", "button", "div", "a", "b", "input"]: delayed_click = True if delayed_click and ":contains" not in selector: selector = js_utils.convert_to_css_selector(selector, by) From 5543808b126c1bf8210e4c14321d6c21f44bd18a Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 13 May 2024 00:29:44 -0400 Subject: [PATCH 3/5] Do some refactoring --- seleniumbase/fixtures/base_case.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index eaab7864220..9ae0e7f02df 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -6794,10 +6794,7 @@ def get_pdf_text( constants.PipInstall.FINDLOCK ) with pip_find_lock: - if ( - sys.version_info >= (3, 7) - and sys.version_info < (3, 9) - ): + if sys.version_info < (3, 9): # Fix bug in newer cryptography for Python 3.7 and 3.8: # "pyo3_runtime.PanicException: Python API call failed" try: From cb5fef25f3bdfa1f6d214991a706e96fa7be8c4e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 13 May 2024 00:30:42 -0400 Subject: [PATCH 4/5] Refresh Python dependencies --- mkdocs_build/requirements.txt | 10 +++++----- requirements.txt | 5 +++-- setup.py | 9 +++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index 6e3fe0f4227..97f1bf02efa 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -1,26 +1,26 @@ # mkdocs dependencies for generating the seleniumbase.io website # Minimum Python version: 3.8 (for generating docs only) -regex>=2024.4.28 +regex>=2024.5.10 pymdown-extensions>=10.8.1 -pipdeptree>=2.19.1 +pipdeptree>=2.20.0 python-dateutil>=2.8.2 Markdown==3.6 markdown2==2.4.13 MarkupSafe==2.1.5 -Jinja2==3.1.3 +Jinja2==3.1.4 click==8.1.7 ghp-import==2.1.0 watchdog==4.0.0 cairocffi==1.7.0 pathspec==0.12.1 -Babel==2.14.0 +Babel==2.15.0 paginate==0.5.6 lxml==5.2.1 pyquery==2.0.0 readtime==3.0.0 mkdocs==1.6.0 -mkdocs-material==9.5.21 +mkdocs-material==9.5.22 mkdocs-exclude-search==0.6.6 mkdocs-simple-hooks==0.1.5 mkdocs-material-extensions==1.3.1 diff --git a/requirements.txt b/requirements.txt index 3f965d49744..85f5acba230 100755 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,8 @@ behave==1.2.6 soupsieve==2.4.1;python_version<"3.8" soupsieve==2.5;python_version>="3.8" beautifulsoup4==4.12.3 -pygments==2.17.2 +pygments==2.17.2;python_version<"3.8" +pygments==2.18.0;python_version>="3.8" pyreadline3==3.4.1;platform_system=="Windows" tabcompleter==1.3.0 pdbp==1.5.0 @@ -72,7 +73,7 @@ rich==13.7.1 # ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.) coverage==7.2.7;python_version<"3.8" -coverage>=7.5.0;python_version>="3.8" +coverage>=7.5.1;python_version>="3.8" pytest-cov==4.1.0;python_version<"3.8" pytest-cov>=5.0.0;python_version>="3.8" flake8==5.0.4;python_version<"3.9" diff --git a/setup.py b/setup.py index 0749905259a..c2b4db9ec39 100755 --- a/setup.py +++ b/setup.py @@ -205,7 +205,8 @@ 'soupsieve==2.4.1;python_version<"3.8"', 'soupsieve==2.5;python_version>="3.8"', "beautifulsoup4==4.12.3", - 'pygments==2.17.2', + 'pygments==2.17.2;python_version<"3.8"', + 'pygments==2.18.0;python_version>="3.8"', 'pyreadline3==3.4.1;platform_system=="Windows"', "tabcompleter==1.3.0", "pdbp==1.5.0", @@ -229,7 +230,7 @@ # Usage: coverage run -m pytest; coverage html; coverage report "coverage": [ 'coverage==7.2.7;python_version<"3.8"', - 'coverage>=7.5.0;python_version>="3.8"', + 'coverage>=7.5.1;python_version>="3.8"', 'pytest-cov==4.1.0;python_version<"3.8"', 'pytest-cov>=5.0.0;python_version>="3.8"', ], @@ -256,7 +257,7 @@ 'pdfminer.six==20221105;python_version<"3.8"', 'pdfminer.six==20231228;python_version>="3.8"', 'cryptography==39.0.2;python_version<"3.9"', - 'cryptography==42.0.5;python_version>="3.9"', + 'cryptography==42.0.7;python_version>="3.9"', 'cffi==1.15.1;python_version<"3.8"', 'cffi==1.16.0;python_version>="3.8"', "pycparser==2.22", @@ -277,7 +278,7 @@ # Usage: proxy # (That starts a proxy server on "127.0.0.1:8899".) "proxy": [ - "proxy.py==2.4.3", + "proxy.py==2.4.4", ], # pip install -e .[psutil] "psutil": [ From b095b365cc6b7b4030984eefb9771282c4d018da Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 13 May 2024 00:31:21 -0400 Subject: [PATCH 5/5] Version 4.26.4 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 8d93f2cb5e8..9cbf6d3308a 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.26.3" +__version__ = "4.26.4"