Skip to content

Commit 7e3761d

Browse files
authored
Merge pull request #2152 from seleniumbase/various-updates
Various updates
2 parents eea2441 + 8eb0653 commit 7e3761d

16 files changed

+144
-70
lines changed

README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,31 +134,37 @@ class CoffeeCartTest(BaseCase):
134134
<summary> ▶️ How is <b>SeleniumBase</b> different from raw Selenium? (<b>click to expand</b>)</summary>
135135
<div>
136136

137-
<p>💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> APIs, and incorporates test-runners such as <code translate="no">pytest</code>, <code translate="no">pynose</code>, and <code translate="no">behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>such as choosing the browser to use</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
137+
<p>💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> APIs and incorporates test-runners such as <code translate="no">pytest</code>, <code translate="no">pynose</code>, and <code translate="no">behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>eg. browser selection</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
138138

139-
<p>💡 With raw Selenium, commands that use selectors need to specify the type of selector (eg. <code translate="no">"css selector", "button#myButton"</code>). 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 (<i>but optionally you could</i>).</p>
139+
<p>💡 SeleniumBase's driver manager gives you more control over automatic driver downloads. (Use <code translate="no">--driver-version=VER</code> with your <code translate="no">pytest</code> run command to specify the version.) By default, SeleniumBase will download a driver version that matches your major browser version if not set.</p>
140140

141-
<p>💡 SeleniumBase methods often perform multiple actions in a single method call. For example, <code translate="no">self.type(selector,text)</code> does the following:<br />1. Waits for the element to be visible.<br />2. Waits for the element to be interactive.<br />3. Clears the text field.<br />4. Types in the new text.<br />5. Presses Enter/Submit if the text ends in <code translate="no">"\n"</code>.<br />With raw Selenium, those actions require multiple method calls.</p>
141+
<p>💡 SeleniumBase automatically detects between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (<i>but optionally you could</i>).</p>
142+
143+
<p>💡 SeleniumBase methods often perform multiple actions in a single method call. For example, <code translate="no">self.type(selector, text)</code> does the following:<br />1. Waits for the element to be visible.<br />2. Waits for the element to be interactive.<br />3. Clears the text field.<br />4. Types in the new text.<br />5. Presses Enter/Submit if the text ends in <code translate="no">"\n"</code>.<br />With raw Selenium, those actions require multiple method calls.</p>
142144

143145
<p>💡 SeleniumBase uses default timeout values when not set:<br />
144-
✅<code translate="no">self.click("button")</code><br />
146+
<code translate="no">self.click("button")</code><br />
145147
With raw Selenium, methods would fail instantly (<i>by default</i>) if an element needed more time to load:<br />
146-
❌<code translate="no">self.driver.find_element(by="css selector", value="button").click()</code><br />
148+
<code translate="no">self.driver.find_element(by="css selector", value="button").click()</code><br />
147149
(Reliable code is better than unreliable code.)</p>
148150

149151
<p>💡 SeleniumBase lets you change the explicit timeout values of methods:<br />
150-
✅<code translate="no">self.click("button",timeout=10)</code><br />
152+
<code translate="no">self.click("button", timeout=10)</code><br />
151153
With raw Selenium, that requires more code:<br />
152-
❌<code translate="no">WebDriverWait(driver,10).until(EC.element_to_be_clickable("css selector", "button")).click()</code><br />
154+
<code translate="no">WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()</code><br />
153155
(Simple code is better than complex code.)</p>
154156

155157
<p>💡 SeleniumBase gives you clean error output when a test fails. With raw Selenium, error messages can get very messy.</p>
156158

157-
<p>💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the <code translate="no">./latest_logs/</code> folder. Raw <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">Selenium</a> does not have these options out-of-the-box.</p>
159+
<p>💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the <code translate="no">./latest_logs/</code> folder. Raw <a href="https://www.selenium.dev/documentation/webdriver/" translate="no" target="_blank">Selenium</a> does not have these options out-of-the-box.</p>
160+
161+
<p>💡 SeleniumBase includes desktop GUI apps for running tests, such as <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/commander.md" translate="no">SeleniumBase Commander</a> for <code translate="no">pytest</code> and <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md" translate="no">SeleniumBase Behave GUI</a> for <code translate="no">behave</code>.</p>
162+
163+
<p>💡 SeleniumBase has its own <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">Recorder / Test Generator</a> for creating tests from manual browser actions.</p>
158164

159-
<p>💡 SeleniumBase includes desktop GUI apps for running tests, such as <b translate="no">SeleniumBase Commander</b> for <code translate="no">pytest</code> and <b><span translate="no">SeleniumBase Behave GUI</span> for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md"><code translate="no">behave</code></a>.</b></p>
165+
<p>💡 SeleniumBase comes with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/case_plans.md">test case management software, ("CasePlans")</a>, for organizing tests and step descriptions.</p>
160166

161-
<p>💡 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. (<i>See the documentation for more details!</i>)</p>
167+
<p>💡 SeleniumBase includes tools for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">building data apps, ("ChartMaker")</a>, which can generate JavaScript from Python.</p>
162168

163169
</div>
164170
</details>
@@ -688,7 +694,7 @@ pytest test_coffee_cart.py --trace
688694
--uc | --undetected # (Use undetected-chromedriver to evade bot-detection.)
689695
--uc-cdp-events # (Capture CDP events when running in "--undetected" mode.)
690696
--remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
691-
--final-debug # (Enter Debug Mode after each test ends. Don't use with CI!)
697+
--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!)
692698
--dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
693699
--dash-title=STRING # (Set the title shown for the generated dashboard.)
694700
--enable-3d-apis # (Enables WebGL and 3D APIs.)

examples/hack_the_planet.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ def test_all_your_base_are_belong_to_us(self):
5959

6060
self.open("https://google.com/ncr")
6161
self.hide_elements("iframe")
62-
self.set_text_content('a[href*="about.google"]', ayb)
63-
self.set_text_content('a[href*="store.google"]', abtu)
62+
if self.is_element_visible('a[href*="about.google"]'):
63+
self.set_text_content('a[href*="about.google"]', ayb)
64+
if self.is_element_visible('a[href*="store.google"]'):
65+
self.set_text_content('a[href*="store.google"]', abtu)
6466
self.set_text_content('a[href*="mail.google.com"]', ayb)
6567
self.set_text_content('a[href*="google.com/img"]', abtu)
6668
self.set_attributes('[value="Google Search"]', "value", ayb)
@@ -74,8 +76,10 @@ def test_all_your_base_are_belong_to_us(self):
7476
)
7577
self.add_css_style(zoom_in)
7678
self.hide_elements("iframe")
77-
self.highlight('a[href*="about.google"]', loops=3)
78-
self.highlight('a[href*="store.google"]', loops=3)
79+
if self.is_element_visible('a[href*="about.google"]'):
80+
self.highlight('a[href*="about.google"]', loops=3)
81+
if self.is_element_visible('a[href*="store.google"]'):
82+
self.highlight('a[href*="store.google"]', loops=3)
7983
self.highlight('a[href*="mail.google.com"]', loops=3)
8084
self.highlight('a[href*="google.com/img"]', loops=3)
8185
self.highlight('form[role="search"]', loops=8)

examples/migration/raw_selenium/ReadMe.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,39 @@ With a complete test automation framework built, most of the hard work is alread
4141
### 🔵 How is SeleniumBase different from raw Selenium?
4242

4343
<div>
44-
<p>💡 SeleniumBase is a Python test framework for the <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> browser automation library. This framework incorporates test-runners such as <code>pytest</code>, <code>nosetests</code>, and <code>behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>such as choosing the browser to use</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
4544

46-
<p>💡 With raw Selenium, you have to manually download drivers (<i>eg. chromedriver</i>) 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. <code>sbase get chromedriver latest</code> to download the latest version of chromedriver to a local SeleniumBase directory).</p>
45+
<p>💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> APIs and incorporates test-runners such as <code translate="no">pytest</code>, <code translate="no">pynose</code>, and <code translate="no">behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>eg. browser selection</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
4746

48-
<p>💡 With raw Selenium, commands that use selectors need to specify the type of selector (eg. <code>"css selector", "button#myButton"</code>). 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 (<i>but optionally you could</i>).</p>
47+
<p>💡 SeleniumBase's driver manager gives you more control over automatic driver downloads. (Use <code translate="no">--driver-version=VER</code> with your <code translate="no">pytest</code> run command to specify the version.) By default, SeleniumBase will download a driver version that matches your major browser version if not set.</p>
4948

50-
<p>💡 SeleniumBase methods often perform multiple actions in a single method call. For example, <code>self.type(selector,text)</code> does the following:<br />1. Waits for the element to be visible.<br />2. Waits for the element to be interactive.<br />3. Clears the text field.<br />4. Types in the new text.<br />5. Presses Enter/Submit if the text ends in <code>"\n"</code>.<br />With raw Selenium, those actions require multiple method calls.</p>
49+
<p>💡 SeleniumBase automatically detects between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (<i>but optionally you could</i>).</p>
5150

52-
<p>💡 SeleniumBase uses default timeout values when not set, which means that methods automatically wait for elements to appear (<i>up to the timeout limit</i>) before failing:<br />✅<code>self.click("button")</code><br />With raw Selenium, methods would fail instantly (<i>by default</i>) if an element needed more time to load:<br />❌<code>self.driver.find_element(by="css selector", value="button").click()</code><br />(Reliable code is better than unreliable code.)</p>
51+
<p>💡 SeleniumBase methods often perform multiple actions in a single method call. For example, <code translate="no">self.type(selector, text)</code> does the following:<br />1. Waits for the element to be visible.<br />2. Waits for the element to be interactive.<br />3. Clears the text field.<br />4. Types in the new text.<br />5. Presses Enter/Submit if the text ends in <code translate="no">"\n"</code>.<br />With raw Selenium, those actions require multiple method calls.</p>
5352

54-
<p>💡 SeleniumBase lets you change the explicit timeout values of methods:<br />✅<code>self.click("button",timeout=10)</code><br />With raw Selenium, that requires more code:<br />❌<code>WebDriverWait(driver,10).until(EC.element_to_be_clickable("css selector", "button")).click()</code><br />(Simple code is better than complex code.)</p>
53+
<p>💡 SeleniumBase uses default timeout values when not set:<br />
54+
✅ <code translate="no">self.click("button")</code><br />
55+
With raw Selenium, methods would fail instantly (<i>by default</i>) if an element needed more time to load:<br />
56+
❌ <code translate="no">self.driver.find_element(by="css selector", value="button").click()</code><br />
57+
(Reliable code is better than unreliable code.)</p>
58+
59+
<p>💡 SeleniumBase lets you change the explicit timeout values of methods:<br />
60+
✅ <code translate="no">self.click("button", timeout=10)</code><br />
61+
With raw Selenium, that requires more code:<br />
62+
❌ <code translate="no">WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()</code><br />
63+
(Simple code is better than complex code.)</p>
5564

5665
<p>💡 SeleniumBase gives you clean error output when a test fails. With raw Selenium, error messages can get very messy.</p>
5766

58-
<p>💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the <code>./latest_logs/</code> folder. Raw Selenium does not have these options out-of-the-box.</p>
67+
<p>💡 SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the <code translate="no">./latest_logs/</code> folder. Raw <a href="https://www.selenium.dev/documentation/webdriver/" translate="no" target="_blank">Selenium</a> does not have these options out-of-the-box.</p>
68+
69+
<p>💡 SeleniumBase includes desktop GUI apps for running tests, such as <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/commander.md" translate="no">SeleniumBase Commander</a> for <code translate="no">pytest</code> and <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md" translate="no">SeleniumBase Behave GUI</a> for <code translate="no">behave</code>.</p>
70+
71+
<p>💡 SeleniumBase has its own <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">Recorder / Test Generator</a> for creating tests from manual browser actions.</p>
72+
73+
<p>💡 SeleniumBase comes with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/case_plans.md">test case management software, ("CasePlans")</a>, for organizing tests and step descriptions.</p>
5974

60-
<p>💡 SeleniumBase includes desktop GUI apps for running tests, such as <b>SeleniumBase Commander</b> for <code>pytest</code>, and <b>SeleniumBase Behave GUI.</b></p>
75+
<p>💡 SeleniumBase includes tools for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">building data apps, ("ChartMaker")</a>, which can generate JavaScript from Python.</p>
6176

62-
<p>💡 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. (<i>See the documentation for more details!</i>)</p>
6377
</div>
6478

6579
--------

help_docs/customizing_test_runs.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pytest my_first_test.py --settings-file=custom_settings.py
174174
--uc | --undetected # (Use undetected-chromedriver to evade bot-detection.)
175175
--uc-cdp-events # (Capture CDP events when running in "--undetected" mode.)
176176
--remote-debug # (Sync to Chrome Remote Debugger chrome://inspect/#devices)
177-
--final-debug # (Enter Debug Mode after each test ends. Don't use with CI!)
177+
--ftrace | --final-trace # (Debug Mode after each test. Don't use with CI!)
178178
--dashboard # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
179179
--dash-title=STRING # (Set the title shown for the generated dashboard.)
180180
--enable-3d-apis # (Enables WebGL and 3D APIs.)
@@ -411,6 +411,32 @@ Visit <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_doc
411411

412412
--------
413413

414+
<h3><img src="https://seleniumbase.github.io/img/green_logo.png" title="SeleniumBase" width="32" /> Changing the default driver version:</h3>
415+
416+
🔵 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.)
417+
418+
🎛️ To change this default behavior, you can use:
419+
420+
```bash
421+
pytest --driver-version=VER
422+
```
423+
424+
The `VER` in `--driver-version=VER` can be:
425+
* A major driver version. Eg. `117`. (milestone)
426+
* An exact driver version. Eg. `117.0.5938.92`.
427+
* ``"browser"`` (exact match on browser version)
428+
* ``"keep"`` (keep using the driver you already have)
429+
* ``"latest"`` / ``"stable"`` (latest stable version)
430+
* ``"previous"`` / ``"latest-1"`` (latest minus one)
431+
* ``"beta"`` (latest beta version)
432+
* ``"dev"`` (latest dev version)
433+
* ``"canary"`` (latest canary version)
434+
* ``"mlatest"`` (latest version for the milestone)
435+
436+
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.)
437+
438+
--------
439+
414440
<h3><img src="https://seleniumbase.github.io/img/green_logo.png" title="SeleniumBase" width="32" /> Customizing default settings:</h3>
415441

416442
🎛️ 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.

help_docs/method_summary.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ self.generate_traffic_chain(pages, loops=1)
744744

745745
self.get_element(selector, by="css selector", timeout=None)
746746
# Duplicates:
747+
# self.locator(selector, by="css selector", timeout=None)
747748
# self.wait_for_element_present(selector, by="css selector", timeout=None)
748749

749750
self.wait_for_query_selector(selector, by="css selector", timeout=None)

0 commit comments

Comments
 (0)