diff --git a/README.md b/README.md index 5ce6f63dd05..352b192fe50 100755 --- a/README.md +++ b/README.md @@ -134,31 +134,37 @@ class CoffeeCartTest(BaseCase): ▶️ How is SeleniumBase different from raw Selenium? (click to expand)
-

💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses Selenium/WebDriver APIs, and incorporates test-runners such as pytest, pynose, and behave to provide organized structure, test discovery, test execution, test state (eg. passed, failed, or skipped), and command-line options for changing default settings (such as choosing the browser to use). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.

+

💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses Selenium/WebDriver APIs and incorporates test-runners such as pytest, pynose, and behave to provide organized structure, test discovery, test execution, test state (eg. passed, failed, or skipped), and command-line options for changing default settings (eg. browser selection). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.

-

💡 With raw Selenium, commands that use selectors need to specify the type of selector (eg. "css selector", "button#myButton"). With SeleniumBase, there's auto-detection between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (but optionally you could).

+

💡 SeleniumBase's driver manager gives you more control over automatic driver downloads. (Use --driver-version=VER with your pytest run command to specify the version.) By default, SeleniumBase will download a driver version that matches your major browser version if not set.

-

💡 SeleniumBase methods often perform multiple actions in a single method call. For example, self.type(selector,text) does the following:
1. Waits for the element to be visible.
2. Waits for the element to be interactive.
3. Clears the text field.
4. Types in the new text.
5. Presses Enter/Submit if the text ends in "\n".
With raw Selenium, those actions require multiple method calls.

+

💡 SeleniumBase automatically detects between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (but optionally you could).

+ +

💡 SeleniumBase methods often perform multiple actions in a single method call. For example, self.type(selector, text) does the following:
1. Waits for the element to be visible.
2. Waits for the element to be interactive.
3. Clears the text field.
4. Types in the new text.
5. Presses Enter/Submit if the text ends in "\n".
With raw Selenium, those actions require multiple method calls.

💡 SeleniumBase uses default timeout values when not set:
-✅self.click("button")
+✅ self.click("button")
With raw Selenium, methods would fail instantly (by default) if an element needed more time to load:
-❌self.driver.find_element(by="css selector", value="button").click()
+❌ self.driver.find_element(by="css selector", value="button").click()
(Reliable code is better than unreliable code.)

💡 SeleniumBase lets you change the explicit timeout values of methods:
-✅self.click("button",timeout=10)
+✅ self.click("button", timeout=10)
With raw Selenium, that requires more code:
-❌WebDriverWait(driver,10).until(EC.element_to_be_clickable("css selector", "button")).click()
+❌ WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()
(Simple code is better than complex code.)

💡 SeleniumBase gives you clean error output when a test fails. With raw Selenium, error messages can get very messy.

-

💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the ./latest_logs/ folder. Raw Selenium does not have these options out-of-the-box.

+

💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the ./latest_logs/ folder. Raw Selenium does not have these options out-of-the-box.

+ +

💡 SeleniumBase includes desktop GUI apps for running tests, such as SeleniumBase Commander for pytest and SeleniumBase Behave GUI for behave.

+ +

💡 SeleniumBase has its own Recorder / Test Generator for creating tests from manual browser actions.

-

💡 SeleniumBase includes desktop GUI apps for running tests, such as SeleniumBase Commander for pytest and SeleniumBase Behave GUI for behave.

+

💡 SeleniumBase comes with test case management software, ("CasePlans"), for organizing tests and step descriptions.

-

💡 SeleniumBase has its own Recorder / Test Generator that can create tests from manual browser actions. SeleniumBase also includes other useful tools and console scripts for getting things done quickly. (See the documentation for more details!)

+

💡 SeleniumBase includes tools for building data apps, ("ChartMaker"), which can generate JavaScript from Python.

@@ -688,7 +694,7 @@ pytest test_coffee_cart.py --trace --uc | --undetected # (Use undetected-chromedriver to evade bot-detection.) --uc-cdp-events # (Capture CDP events when running in "--undetected" mode.) --remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices) ---final-debug # (Enter Debug Mode after each test ends. Don't use with CI!) +--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!) --dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html) --dash-title=STRING # (Set the title shown for the generated dashboard.) --enable-3d-apis # (Enables WebGL and 3D APIs.) diff --git a/examples/hack_the_planet.py b/examples/hack_the_planet.py index 68059f0a0b9..07098cb2259 100644 --- a/examples/hack_the_planet.py +++ b/examples/hack_the_planet.py @@ -59,8 +59,10 @@ def test_all_your_base_are_belong_to_us(self): self.open("https://google.com/ncr") self.hide_elements("iframe") - self.set_text_content('a[href*="about.google"]', ayb) - self.set_text_content('a[href*="store.google"]', abtu) + if self.is_element_visible('a[href*="about.google"]'): + self.set_text_content('a[href*="about.google"]', ayb) + if self.is_element_visible('a[href*="store.google"]'): + self.set_text_content('a[href*="store.google"]', abtu) self.set_text_content('a[href*="mail.google.com"]', ayb) self.set_text_content('a[href*="google.com/img"]', abtu) self.set_attributes('[value="Google Search"]', "value", ayb) @@ -74,8 +76,10 @@ def test_all_your_base_are_belong_to_us(self): ) self.add_css_style(zoom_in) self.hide_elements("iframe") - self.highlight('a[href*="about.google"]', loops=3) - self.highlight('a[href*="store.google"]', loops=3) + if self.is_element_visible('a[href*="about.google"]'): + self.highlight('a[href*="about.google"]', loops=3) + if self.is_element_visible('a[href*="store.google"]'): + self.highlight('a[href*="store.google"]', loops=3) self.highlight('a[href*="mail.google.com"]', loops=3) self.highlight('a[href*="google.com/img"]', loops=3) self.highlight('form[role="search"]', loops=8) diff --git a/examples/migration/raw_selenium/ReadMe.md b/examples/migration/raw_selenium/ReadMe.md index ddc489ae130..57a5459fd21 100644 --- a/examples/migration/raw_selenium/ReadMe.md +++ b/examples/migration/raw_selenium/ReadMe.md @@ -41,25 +41,39 @@ With a complete test automation framework built, most of the hard work is alread ### 🔵 How is SeleniumBase different from raw Selenium?
-

💡 SeleniumBase is a Python test framework for the Selenium/WebDriver browser automation library. This framework incorporates test-runners such as pytest, nosetests, and behave to provide organized structure, test discovery, test execution, test state (eg. passed, failed, or skipped), and command-line options for changing default settings (such as choosing the browser to use). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.

-

💡 With raw Selenium, you have to manually download drivers (eg. chromedriver) before running tests. With SeleniumBase's driver manager, that's done automatically for you if the required driver isn't already on your PATH. There are also console scripts available for more control (eg. sbase get chromedriver latest to download the latest version of chromedriver to a local SeleniumBase directory).

+

💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses Selenium/WebDriver APIs and incorporates test-runners such as pytest, pynose, and behave to provide organized structure, test discovery, test execution, test state (eg. passed, failed, or skipped), and command-line options for changing default settings (eg. browser selection). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.

-

💡 With raw Selenium, commands that use selectors need to specify the type of selector (eg. "css selector", "button#myButton"). With SeleniumBase, there's auto-detection between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (but optionally you could).

+

💡 SeleniumBase's driver manager gives you more control over automatic driver downloads. (Use --driver-version=VER with your pytest run command to specify the version.) By default, SeleniumBase will download a driver version that matches your major browser version if not set.

-

💡 SeleniumBase methods often perform multiple actions in a single method call. For example, self.type(selector,text) does the following:
1. Waits for the element to be visible.
2. Waits for the element to be interactive.
3. Clears the text field.
4. Types in the new text.
5. Presses Enter/Submit if the text ends in "\n".
With raw Selenium, those actions require multiple method calls.

+

💡 SeleniumBase automatically detects between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (but optionally you could).

-

💡 SeleniumBase uses default timeout values when not set, which means that methods automatically wait for elements to appear (up to the timeout limit) before failing:
self.click("button")
With raw Selenium, methods would fail instantly (by default) if an element needed more time to load:
self.driver.find_element(by="css selector", value="button").click()
(Reliable code is better than unreliable code.)

+

💡 SeleniumBase methods often perform multiple actions in a single method call. For example, self.type(selector, text) does the following:
1. Waits for the element to be visible.
2. Waits for the element to be interactive.
3. Clears the text field.
4. Types in the new text.
5. Presses Enter/Submit if the text ends in "\n".
With raw Selenium, those actions require multiple method calls.

-

💡 SeleniumBase lets you change the explicit timeout values of methods:
self.click("button",timeout=10)
With raw Selenium, that requires more code:
WebDriverWait(driver,10).until(EC.element_to_be_clickable("css selector", "button")).click()
(Simple code is better than complex code.)

+

💡 SeleniumBase uses default timeout values when not set:
+✅ self.click("button")
+With raw Selenium, methods would fail instantly (by default) if an element needed more time to load:
+❌ self.driver.find_element(by="css selector", value="button").click()
+(Reliable code is better than unreliable code.)

+ +

💡 SeleniumBase lets you change the explicit timeout values of methods:
+✅ self.click("button", timeout=10)
+With raw Selenium, that requires more code:
+❌ WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()
+(Simple code is better than complex code.)

💡 SeleniumBase gives you clean error output when a test fails. With raw Selenium, error messages can get very messy.

-

💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the ./latest_logs/ folder. Raw Selenium does not have these options out-of-the-box.

+

💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the ./latest_logs/ folder. Raw Selenium does not have these options out-of-the-box.

+ +

💡 SeleniumBase includes desktop GUI apps for running tests, such as SeleniumBase Commander for pytest and SeleniumBase Behave GUI for behave.

+ +

💡 SeleniumBase has its own Recorder / Test Generator for creating tests from manual browser actions.

+ +

💡 SeleniumBase comes with test case management software, ("CasePlans"), for organizing tests and step descriptions.

-

💡 SeleniumBase includes desktop GUI apps for running tests, such as SeleniumBase Commander for pytest, and SeleniumBase Behave GUI.

+

💡 SeleniumBase includes tools for building data apps, ("ChartMaker"), which can generate JavaScript from Python.

-

💡 SeleniumBase has its own Recorder & Test Generator that can create tests from manual browser actions. SeleniumBase also has many other useful tools and console scripts for getting things done quickly. (See the documentation for more details!)

-------- diff --git a/help_docs/customizing_test_runs.md b/help_docs/customizing_test_runs.md index d68c4a8231f..f5b95763c11 100644 --- a/help_docs/customizing_test_runs.md +++ b/help_docs/customizing_test_runs.md @@ -174,7 +174,7 @@ pytest my_first_test.py --settings-file=custom_settings.py --uc | --undetected # (Use undetected-chromedriver to evade bot-detection.) --uc-cdp-events # (Capture CDP events when running in "--undetected" mode.) --remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices) ---final-debug # (Enter Debug Mode after each test ends. Don't use with CI!) +--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!) --dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html) --dash-title=STRING # (Set the title shown for the generated dashboard.) --enable-3d-apis # (Enables WebGL and 3D APIs.) @@ -411,6 +411,32 @@ Visit Changing the default driver version: + +🔵 By default, SeleniumBase will make sure that the major driver version matches the major browser version for Chromium tests. (Eg. If Chrome `117.X` is installed and you have chromedriver `117.X`, then nothing happens, but if you had chromedriver `116.X` instead, then SeleniumBase would download chromedriver `117.X` to match the browser version.) + +🎛️ To change this default behavior, you can use: + +```bash +pytest --driver-version=VER +``` + +The `VER` in `--driver-version=VER` can be: +* A major driver version. Eg. `117`. (milestone) +* An exact driver version. Eg. `117.0.5938.92`. +* ``"browser"`` (exact match on browser version) +* ``"keep"`` (keep using the driver you already have) +* ``"latest"`` / ``"stable"`` (latest stable version) +* ``"previous"`` / ``"latest-1"`` (latest minus one) +* ``"beta"`` (latest beta version) +* ``"dev"`` (latest dev version) +* ``"canary"`` (latest canary version) +* ``"mlatest"`` (latest version for the milestone) + +Note that different options could lead to the same result. (Eg. If you have the latest version of a browser for a milestone, then ``"browser"`` and ``"mlatest"`` should give you the same driver if the latest driver version for that milestone matches the browser version.) + +-------- +

Customizing default settings:

🎛️ An easy way to override [seleniumbase/config/settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) is by using a custom settings file. diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index 7cc7a449eba..3997c7a2e8d 100644 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -744,6 +744,7 @@ self.generate_traffic_chain(pages, loops=1) self.get_element(selector, by="css selector", timeout=None) # Duplicates: +# self.locator(selector, by="css selector", timeout=None) # self.wait_for_element_present(selector, by="css selector", timeout=None) self.wait_for_query_selector(selector, by="css selector", timeout=None) diff --git a/requirements.txt b/requirements.txt index 8c8a561db99..21156e477da 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ pip>=23.2.1 -packaging>=23.1 +packaging>=23.2 setuptools>=68.0.0;python_version<"3.8" setuptools>=68.2.2;python_version>="3.8" wheel>=0.41.2 @@ -13,7 +13,7 @@ parse-type>=0.6.2 six==1.16.0 idna==3.4 chardet==5.2.0 -charset-normalizer==3.2.0 +charset-normalizer==3.3.0 urllib3>=1.26.16,<2;python_version<"3.10" urllib3>=1.26.16,<2.1.0;python_version>="3.10" requests==2.31.0 @@ -22,8 +22,7 @@ sniffio==1.3.0 h11==0.14.0 outcome==1.2.0 trio==0.22.2 -trio-websocket==0.10.4;python_version<"3.8" -trio-websocket==0.11.1;python_version>="3.8" +trio-websocket==0.11.1 wsproto==1.2.0 selenium==4.11.2;python_version<"3.8" selenium==4.13.0;python_version>="3.8" @@ -53,12 +52,11 @@ tabcompleter==1.3.0 pdbp==1.5.0 colorama==0.4.6 exceptiongroup==1.1.3 -importlib-metadata==4.2.0;python_version<"3.8" pyotp==2.9.0 markdown-it-py==2.2.0;python_version<"3.8" markdown-it-py==3.0.0;python_version>="3.8" mdurl==0.1.2 -rich==13.5.3 +rich==13.6.0 # --- Testing Requirements --- # # ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index e3413765353..a9d6fcc26f6 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.19.0" +__version__ = "4.19.1" diff --git a/seleniumbase/console_scripts/run.py b/seleniumbase/console_scripts/run.py index 373a43bc376..9a7ec974e25 100644 --- a/seleniumbase/console_scripts/run.py +++ b/seleniumbase/console_scripts/run.py @@ -813,7 +813,7 @@ def show_options(): op += " | where / w: Show stack spot. u: Up stack. d: Down stack. |\n" op += " | longlist / ll: See code. dir(): List namespace objects. |\n" op += "--help / -h (Display list of all available pytest options.)\n" - op += "--final-debug (Enter Final Debug Mode after each test ends.)\n" + op += "--ftrace / --final-trace (Enter Debug Mode after any test.)\n" op += "--recorder / --rec (Save browser actions as Python scripts.)\n" op += "--rec-behave / --rec-gherkin (Save actions as Gherkin code.)\n" op += "--rec-print (Display recorded scripts when they are created.)\n" diff --git a/seleniumbase/core/log_helper.py b/seleniumbase/core/log_helper.py index 854e14ba2ab..c5b811e65ca 100644 --- a/seleniumbase/core/log_helper.py +++ b/seleniumbase/core/log_helper.py @@ -27,7 +27,7 @@ def log_screenshot(test_logpath, driver, screenshot=None, get=False): return try: if not screenshot: - element = driver.find_element_by_tag_name("body") + element = driver.find_element("tag name", "body") screenshot = element.screenshot_as_base64 if screenshot != screenshot_warning: with open(screenshot_path, "wb") as file: diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index adbbdd8c438..e9c4c3f31db 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -4669,6 +4669,12 @@ def __process_recorded_actions(self): srt_actions[n - 2][0] = "_skip" srt_actions[n - 1][0] = "_skip" srt_actions[n][1] = srt_actions[n - 1][1] + for n in range(len(srt_actions)): + if ( + srt_actions[n][0] == "dbclk" + and srt_actions[n][1] == "" + ): + srt_actions[n][0] = "_skip" for n in range(len(srt_actions)): if ( srt_actions[n][0] == "cho_f" @@ -8898,12 +8904,11 @@ def wait_for_element(self, selector, by="css selector", timeout=None): def get_element(self, selector, by="css selector", timeout=None): """Same as wait_for_element_present() - returns the element. The element does not need be visible (it may be hidden).""" - self.__check_scope() - if not timeout: - timeout = settings.LARGE_TIMEOUT - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - selector, by = self.__recalculate_selector(selector, by) + return self.wait_for_element_present(selector, by=by, timeout=timeout) + + def locator(self, selector, by="css selector", timeout=None): + """Same as wait_for_element_present() - returns the element. + The element does not need be visible (it may be hidden).""" return self.wait_for_element_present(selector, by=by, timeout=timeout) def wait_for_query_selector( @@ -9000,11 +9005,6 @@ def assert_elements_present(self, *args, **kwargs): def find_element(self, selector, by="css selector", timeout=None): """Same as wait_for_element_visible() - returns the element""" - self.__check_scope() - if not timeout: - timeout = settings.LARGE_TIMEOUT - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) return self.wait_for_element_visible(selector, by=by, timeout=timeout) def assert_element(self, selector, by="css selector", timeout=None): diff --git a/seleniumbase/plugins/base_plugin.py b/seleniumbase/plugins/base_plugin.py index e0ebc8ada6a..f3c77b4eb6f 100644 --- a/seleniumbase/plugins/base_plugin.py +++ b/seleniumbase/plugins/base_plugin.py @@ -17,7 +17,7 @@ class Base(Plugin): - """This plugin adds the following command-line options to nosetests: + """This plugin adds the following command-line options to pynose: --env=ENV (Set the test env. Access with "self.env" in tests.) --account=STR (Set account. Access with "self.account" in tests.) --data=STRING (Extra test data. Access with "self.data" in tests.) @@ -26,6 +26,7 @@ class Base(Plugin): --var3=STRING (Extra test data. Access with "self.var3" in tests.) --variables=DICT (Extra test data. Access with "self.variables".) --settings-file=FILE (Override default SeleniumBase settings.) + --ftrace | --final-trace (Enter Debug Mode after any test ends.) --archive-logs (Archive old log files instead of deleting them.) --archive-downloads (Archive old downloads instead of deleting.) --report (Create a fancy nosetests report after tests complete.) @@ -128,6 +129,19 @@ def options(self, parser, env): help="""The file that stores key/value pairs for overriding values in the SeleniumBase settings.py file.""", ) + parser.addoption( + "--final-debug", + "--final-trace", + "--fdebug", + "--ftrace", + action="store_true", + dest="final_debug", + default=False, + help="""Enter Debug Mode at the end of each test. + To enter Debug Mode only on failures, use "--pdb". + If using both "--final-debug" and "--pdb" together, + then Debug Mode will activate twice on failures.""", + ) parser.addoption( "--log_path", "--log-path", @@ -232,6 +246,7 @@ def beforeTest(self, test): test.test.var3 = self.options.var3 test.test.variables = variables # Already verified is a dictionary test.test.settings_file = self.options.settings_file + test.test._final_debug = self.options.final_debug test.test.log_path = self.options.log_path if self.options.archive_downloads: settings.ARCHIVE_EXISTING_DOWNLOADS = True diff --git a/seleniumbase/plugins/driver_manager.py b/seleniumbase/plugins/driver_manager.py index 3c27b2db1f0..2dce38cc7f3 100644 --- a/seleniumbase/plugins/driver_manager.py +++ b/seleniumbase/plugins/driver_manager.py @@ -328,6 +328,19 @@ def Driver( uc_subprocess = True else: uc_subprocess = False + if uc_cdp_events or uc_cdp: + undetectable = True + uc_cdp_events = True + elif ( + "--uc-cdp-events" in sys_argv + or "--uc_cdp_events" in sys_argv + or "--uc-cdp" in sys_argv + or "--uc_cdp" in sys_argv + ): + undetectable = True + uc_cdp_events = True + else: + uc_cdp_events = False if undetectable and is_mobile: is_mobile = False user_agent = None diff --git a/seleniumbase/plugins/pytest_plugin.py b/seleniumbase/plugins/pytest_plugin.py index cf50a6edbf4..b35fc4ba481 100644 --- a/seleniumbase/plugins/pytest_plugin.py +++ b/seleniumbase/plugins/pytest_plugin.py @@ -90,7 +90,7 @@ def pytest_addoption(parser): --uc | --undetected (Use undetected-chromedriver to evade bot-detection.) --uc-cdp-events (Capture CDP events when running in "--undetected" mode.) --remote-debug (Sync to Chrome Remote Debugger chrome://inspect/#devices) - --final-debug (Enter Debug Mode after each test ends. Don't use with CI!) + --ftrace | --final-trace (Debug Mode after each test. Don't use with CI!) --dashboard (Enable the SeleniumBase Dashboard. Saved at: dashboard.html) --dash-title=STRING (Set the title shown for the generated dashboard.) --enable-3d-apis (Enables WebGL and 3D APIs.) diff --git a/seleniumbase/plugins/sb_manager.py b/seleniumbase/plugins/sb_manager.py index d60527a7695..5c69257fdec 100644 --- a/seleniumbase/plugins/sb_manager.py +++ b/seleniumbase/plugins/sb_manager.py @@ -444,6 +444,19 @@ def SB( uc_subprocess = True else: uc_subprocess = False + if uc_cdp_events or uc_cdp: + undetectable = True + uc_cdp_events = True + elif ( + "--uc-cdp-events" in sys_argv + or "--uc_cdp_events" in sys_argv + or "--uc-cdp" in sys_argv + or "--uc_cdp" in sys_argv + ): + undetectable = True + uc_cdp_events = True + else: + uc_cdp_events = False if undetectable and is_mobile: is_mobile = False user_agent = None diff --git a/seleniumbase/plugins/selenium_plugin.py b/seleniumbase/plugins/selenium_plugin.py index 0b03faf8f27..e7d613c8e49 100644 --- a/seleniumbase/plugins/selenium_plugin.py +++ b/seleniumbase/plugins/selenium_plugin.py @@ -9,7 +9,7 @@ class SeleniumBrowser(Plugin): - """This plugin adds the following command-line options to nosetests: + """This plugin adds the following command-line options to pynose: --browser=BROWSER (The web browser to use. Default: "chrome".) --chrome (Shortcut for "--browser=chrome". Default.) --edge (Shortcut for "--browser=edge".) @@ -70,7 +70,6 @@ class SeleniumBrowser(Plugin): --uc | --undetected (Use undetected-chromedriver to evade bot-detection.) --uc-cdp-events (Capture CDP events when running in "--undetected" mode.) --remote-debug (Sync to Chrome Remote Debugger chrome://inspect/#devices) - --final-debug (Enter Debug Mode after each test ends. Don't use with CI!) --enable-3d-apis (Enables WebGL and 3D APIs.) --swiftshader (Use Chrome's "--use-gl=swiftshader" feature.) --incognito (Enable Chrome's Incognito mode.) @@ -757,19 +756,6 @@ def options(self, parser, env): The previous URL was at: http://localhost:9222/ Info: chromedevtools.github.io/devtools-protocol/""", ) - parser.addoption( - "--final-debug", - "--final-trace", - "--fdebug", - "--ftrace", - action="store_true", - dest="final_debug", - default=False, - help="""Enter Debug Mode at the end of each test. - To enter Debug Mode only on failures, use "--pdb". - If using both "--final-debug" and "--pdb" together, - then Debug Mode will activate twice on failures.""", - ) parser.addoption( "--enable_3d_apis", "--enable-3d-apis", @@ -1125,7 +1111,6 @@ def beforeTest(self, test): test.test.no_sandbox = self.options.no_sandbox test.test.disable_gpu = self.options.disable_gpu test.test.remote_debug = self.options.remote_debug - test.test._final_debug = self.options.final_debug test.test.enable_3d_apis = self.options.enable_3d_apis test.test.swiftshader = self.options.swiftshader test.test.incognito = self.options.incognito diff --git a/setup.py b/setup.py index 4b24cc6055a..7b948dc558f 100755 --- a/setup.py +++ b/setup.py @@ -132,7 +132,7 @@ python_requires=">=3.7", install_requires=[ 'pip>=23.2.1', - 'packaging>=23.1', + 'packaging>=23.2', 'setuptools>=68.0.0;python_version<"3.8"', 'setuptools>=68.2.2;python_version>="3.8"', 'wheel>=0.41.2', @@ -146,7 +146,7 @@ "six==1.16.0", "idna==3.4", 'chardet==5.2.0', - 'charset-normalizer==3.2.0', + 'charset-normalizer==3.3.0', 'urllib3>=1.26.16,<2;python_version<"3.10"', 'urllib3>=1.26.16,<2.1.0;python_version>="3.10"', 'requests==2.31.0', @@ -155,8 +155,7 @@ 'h11==0.14.0', 'outcome==1.2.0', 'trio==0.22.2', - 'trio-websocket==0.10.4;python_version<"3.8"', - 'trio-websocket==0.11.1;python_version>="3.8"', + 'trio-websocket==0.11.1', 'wsproto==1.2.0', 'selenium==4.11.2;python_version<"3.8"', 'selenium==4.13.0;python_version>="3.8"', @@ -186,12 +185,11 @@ "pdbp==1.5.0", 'colorama==0.4.6', 'exceptiongroup==1.1.3', - 'importlib-metadata==4.2.0;python_version<"3.8"', 'pyotp==2.9.0', 'markdown-it-py==2.2.0;python_version<"3.8"', 'markdown-it-py==3.0.0;python_version>="3.8"', 'mdurl==0.1.2', - 'rich==13.5.3', + 'rich==13.6.0', ], extras_require={ # pip install -e .[allure] @@ -232,7 +230,8 @@ 'pdfminer.six==20221105', 'cryptography==39.0.2;python_version<"3.9"', 'cryptography==41.0.4;python_version>="3.9"', - "cffi==1.15.1", + 'cffi==1.15.1;python_version<"3.8"', + 'cffi==1.16.0;python_version>="3.8"', "pycparser==2.21", ],