Merge pull request #2484 from seleniumbase/refresh-js-and-python-dependencies
Refresh JS and Python dependencies
This commit is contained in:
commit
7859ed4445
126
README.md
126
README.md
|
@ -11,9 +11,7 @@
|
|||
|
||||
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_10t.png" alt="SeleniumBase" title="SeleniumBase" width="266" /></a></p>
|
||||
|
||||
<h2 align="center" class="hero__title">All-in-one Test Automation Framework</h2>
|
||||
|
||||
<h3 align="center"><img src="https://seleniumbase.github.io/cdn/img/python_logo.png" title="SeleniumBase" width="29" /> For Python enthusiasts and enterprise developers <img src="https://seleniumbase.github.io/cdn/img/python_logo.png" title="SeleniumBase" width="29" /></h3>
|
||||
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Scraping / Testing / Reporting</b></p>
|
||||
|
||||
<p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/releases" target="_blank"><img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=22AAEE" alt="GitHub version" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://img.shields.io/gitter/room/seleniumbase/SeleniumBase.svg" alt="Gitter chat"/></a></p>
|
||||
|
||||
|
@ -57,6 +55,48 @@
|
|||
|
||||
--------
|
||||
|
||||
📚 Learn from [**over 100 examples** in the **SeleniumBase/examples/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder.
|
||||
|
||||
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>, which covers login, shopping, and checkout:</p>
|
||||
|
||||
```bash
|
||||
pytest my_first_test.py
|
||||
```
|
||||
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
|
||||
|
||||
> ``pytest`` uses ``--chrome`` by default unless set differently.
|
||||
|
||||
--------
|
||||
|
||||
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
||||
|
||||
```bash
|
||||
pytest test_coffee_cart.py --demo
|
||||
```
|
||||
|
||||
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>
|
||||
|
||||
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
||||
|
||||
--------
|
||||
|
||||
<a id="multiple_examples"></a>
|
||||
|
||||
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
||||
|
||||
```bash
|
||||
pytest test_demo_site.py
|
||||
```
|
||||
|
||||
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
|
||||
|
||||
> Easy to type, click, select, toggle, drag & drop, and more.
|
||||
|
||||
(For more examples, see the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">SeleniumBase/examples/</a> folder.)
|
||||
|
||||
--------
|
||||
|
||||
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb2.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
|
||||
|
||||
<blockquote>
|
||||
|
@ -76,64 +116,6 @@
|
|||
|
||||
--------
|
||||
|
||||
<a id="multiple_examples"></a>
|
||||
|
||||
<p align="left"><b>Example:</b> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a> from <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples" target="_blank">./examples/</a> (Uses <code translate="no">--chrome</code> by default)</p>
|
||||
|
||||
```bash
|
||||
cd examples/
|
||||
pytest test_demo_site.py
|
||||
```
|
||||
|
||||
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
|
||||
|
||||
> Easy to type, click, select, toggle, drag-and-drop, etc.
|
||||
|
||||
--------
|
||||
|
||||
<p align="left"><b>Example:</b> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a> from <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples" target="_blank">./examples/</a></p>
|
||||
|
||||
```bash
|
||||
cd examples/
|
||||
pytest test_coffee_cart.py --demo
|
||||
```
|
||||
|
||||
<p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
||||
|
||||
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>
|
||||
|
||||
> SeleniumBase automation can easily order coffee!
|
||||
|
||||
<p align="left"><b>Here's the code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py">test_coffee_cart.py</a>:</b></p>
|
||||
|
||||
```python
|
||||
from seleniumbase import BaseCase
|
||||
BaseCase.main(__name__, __file__)
|
||||
|
||||
class CoffeeCartTest(BaseCase):
|
||||
def test_coffee_cart(self):
|
||||
self.open("https://seleniumbase.io/coffee/")
|
||||
self.assert_title("Coffee Cart")
|
||||
self.assert_element('button:contains("Total: $0.00")')
|
||||
self.click('div[data-sb="Cappuccino"]')
|
||||
self.assert_exact_text("cart (1)", 'a[aria-label="Cart page"]')
|
||||
self.click('div[data-sb="Flat-White"]')
|
||||
self.assert_exact_text("cart (2)", 'a[aria-label="Cart page"]')
|
||||
self.click('div[data-sb="Cafe-Latte"]')
|
||||
self.assert_exact_text("cart (3)", 'a[aria-label="Cart page"]')
|
||||
self.click('a[aria-label="Cart page"]')
|
||||
self.assert_exact_text("Total: $53.00", "button.pay")
|
||||
self.click("button.pay")
|
||||
self.type("input#name", "Selenium Coffee")
|
||||
self.type("input#email", "test@test.test")
|
||||
self.click("button#submit-payment")
|
||||
self.assert_text("Thanks for your purchase.", "#app .success")
|
||||
```
|
||||
|
||||
(For more examples, see the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">SeleniumBase/examples/</a> folder.)
|
||||
|
||||
--------
|
||||
|
||||
<details>
|
||||
<summary> ▶️ How is <b>SeleniumBase</b> different from raw Selenium? (<b>click to expand</b>)</summary>
|
||||
<div>
|
||||
|
@ -177,7 +159,7 @@ With raw Selenium, that requires more code:<br />
|
|||
|
||||
<p>📚 <b>Learn about different ways of writing tests:</b></p>
|
||||
|
||||
<p align="left">📘📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_simple_login.py">example test</a> using <code translate="no"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/fixtures/base_case.py">BaseCase</a></code> class inheritance. Runs with <b><a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a></b> or <b><a href="https://github.com/mdmintz/pynose">pynose</a></b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">Learn more</a>). (Use <code translate="no">self.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
<p align="left">📘📝 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_simple_login.py">test_simple_login.py</a>, which uses <code translate="no"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/fixtures/base_case.py">BaseCase</a></code> class inheritance, and runs with <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a> or <a href="https://github.com/mdmintz/pynose">pynose</a>. (Use <code translate="no">self.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
|
||||
```python
|
||||
from seleniumbase import BaseCase
|
||||
|
@ -196,7 +178,7 @@ class TestSimpleLogin(BaseCase):
|
|||
self.assert_text("signed out", "#top_message")
|
||||
```
|
||||
|
||||
<p align="left">📗📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/sb_fixture_tests.py">example test</a> using the <b><code translate="no">sb</code></b> <code translate="no">pytest</code> fixture. Runs with <b><a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a></b>. (Use <code translate="no">sb.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
<p align="left">📗📝 Here's a test from <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/sb_fixture_tests.py">sb_fixture_tests.py</a>, which uses the <b><code translate="no">sb</code></b> <code translate="no">pytest</code> fixture. Runs with <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>. (Use <code translate="no">sb.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
|
||||
```python
|
||||
def test_sb_fixture_with_no_class(sb):
|
||||
|
@ -211,7 +193,7 @@ def test_sb_fixture_with_no_class(sb):
|
|||
sb.assert_text("signed out", "#top_message")
|
||||
```
|
||||
|
||||
<p align="left">📙📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_sb.py">example test</a> using the <b><code translate="no">SB</code></b> Context Manager. Runs with pure <b><code translate="no">python</code></b>. (Use <code translate="no">sb.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
<p align="left">📙📝 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_sb.py">raw_login_sb.py</a>, which uses the <b><code translate="no">SB</code></b> Context Manager. Runs with pure <code translate="no">python</code>. (Use <code translate="no">sb.driver</code> to access Selenium's raw <code translate="no">driver</code>.)</p>
|
||||
|
||||
```python
|
||||
from seleniumbase import SB
|
||||
|
@ -228,7 +210,7 @@ with SB() as sb:
|
|||
sb.assert_text("signed out", "#top_message")
|
||||
```
|
||||
|
||||
<p align="left">📔📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_context.py">example test</a> using the <b><code translate="no">DriverContext</code></b> Manager. Runs with pure <b><code translate="no">python</code></b>. (The <code translate="no">driver</code> is an improved version of Selenium's raw <code translate="no">driver</code>, with more methods.)</p>
|
||||
<p align="left">📔📝 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_context.py">raw_login_context.py</a>, which uses the <b><code translate="no">DriverContext</code></b> Manager. Runs with pure <code translate="no">python</code>. (The <code translate="no">driver</code> is an improved version of Selenium's raw <code translate="no">driver</code>, with more methods.)</p>
|
||||
|
||||
```python
|
||||
from seleniumbase import DriverContext
|
||||
|
@ -245,7 +227,7 @@ with DriverContext() as driver:
|
|||
driver.assert_text("signed out", "#top_message")
|
||||
```
|
||||
|
||||
<p align="left">📔📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_driver.py">example test</a> using the <b><code translate="no">Driver</code></b> Manager. Runs with pure <b><code translate="no">python</code></b>. (The <code>driver</code> is an improved version of Selenium's raw <code translate="no">driver</code>, with more methods.)</p>
|
||||
<p align="left">📔📝 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_login_driver.py">raw_login_driver.py</a>, which uses the <b><code translate="no">Driver</code></b> Manager. Runs with pure <code translate="no">python</code>. (The <code>driver</code> is an improved version of Selenium's raw <code translate="no">driver</code>, with more methods.)</p>
|
||||
|
||||
```python
|
||||
from seleniumbase import Driver
|
||||
|
@ -265,7 +247,7 @@ finally:
|
|||
driver.quit()
|
||||
```
|
||||
|
||||
<p align="left">📕📝 An <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/features/login_app.feature"> example test</a> using <b translate="no">behave-BDD</b> <a href="https://behave.readthedocs.io/en/stable/gherkin.html#features" target="_blank">Gherkin</a> syntax. Runs with <b><code translate="no">behave</code></b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">Learn more</a>)</p>
|
||||
<p align="left">📕📝 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/features/login_app.feature">login_app.feature</a>, which uses <a translate="no" href="https://behave.readthedocs.io/en/stable/gherkin.html#features" target="_blank">behave-BDD Gherkin</a> syntax. Runs with <code translate="no">behave</code>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">Learn about the <b>SeleniumBase behave-BDD</b> integration</a>)</p>
|
||||
|
||||
```gherkin
|
||||
Feature: SeleniumBase scenarios for the Simple App
|
||||
|
@ -410,11 +392,7 @@ cd examples/
|
|||
pytest my_first_test.py
|
||||
```
|
||||
|
||||
> (Uses ``--chrome`` by default.)
|
||||
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/swag_labs_4.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
|
||||
|
||||
> SeleniumBase easily handles login, shopping, and checkout.
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
|
||||
|
||||
<p align="left"><b>Here's the code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
||||
|
||||
|
@ -500,7 +478,7 @@ self.assert_no_js_errors() # Verify there are no JS errors.
|
|||
|
||||
<p>✅ SeleniumBase automatically handles common <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">WebDriver</a> actions such as launching web browsers before tests, saving screenshots during failures, and closing web browsers after tests.</p>
|
||||
|
||||
<p>✅ SeleniumBase lets you <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">customize test runs from the command-line</a>.</p>
|
||||
<p>✅ SeleniumBase lets you customize tests via <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">command-line options</a>.</p>
|
||||
|
||||
<p>✅ SeleniumBase uses simple syntax for commands. Example:</p>
|
||||
|
||||
|
@ -852,7 +830,7 @@ python -m http.server 1948
|
|||
🔵 Here's a full example of what the SeleniumBase Dashboard may look like:
|
||||
|
||||
```bash
|
||||
pytest test_suite.py --dashboard --rs --headless
|
||||
pytest test_suite.py test_image_saving.py --dashboard --rs --headless
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.github.io/cdn/img/dashboard_2.png" alt="The SeleniumBase Dashboard" title="The SeleniumBase Dashboard" width="480" />
|
||||
|
|
|
@ -19,7 +19,25 @@
|
|||
|
||||
--------
|
||||
|
||||
Run an [example test](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py): (Default option: ``--chrome``)
|
||||
Run an [example test](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py): (Default option: ``--chrome``)
|
||||
|
||||
```bash
|
||||
pytest my_first_test.py
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.github.io/cdn/gif/fast_swag.gif" title="SeleniumBase Demo Page" /><br />
|
||||
|
||||
--------
|
||||
|
||||
Here's one way of changing the browser to Firefox:
|
||||
|
||||
```bash
|
||||
pytest my_first_test.py --firefox
|
||||
```
|
||||
|
||||
--------
|
||||
|
||||
Another [example test](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py) for a web page that has lots of different HTML items:
|
||||
|
||||
```bash
|
||||
pytest test_demo_site.py
|
||||
|
@ -29,14 +47,6 @@ pytest test_demo_site.py
|
|||
|
||||
--------
|
||||
|
||||
Run an example test in Firefox:
|
||||
|
||||
```bash
|
||||
pytest my_first_test.py --browser=firefox
|
||||
```
|
||||
|
||||
--------
|
||||
|
||||
Run an example test in ``--demo`` mode: (highlight assertions)
|
||||
|
||||
```bash
|
||||
|
|
|
@ -45,7 +45,7 @@ python -m http.server 1948
|
|||
🔵 Here's a full example of what the SeleniumBase Dashboard may look like:
|
||||
|
||||
```bash
|
||||
pytest test_suite.py --dashboard --rs --headless
|
||||
pytest test_suite.py test_image_saving.py --dashboard --rs --headless
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.github.io/cdn/img/dashboard_2.png" alt="The SeleniumBase Dashboard" title="The SeleniumBase Dashboard" width="480" />
|
||||
|
|
|
@ -38,6 +38,7 @@ class HackTests(BaseCase):
|
|||
self.set_text_content('#shelf-1 a[href*="mac"]', "ALL")
|
||||
self.set_text_content('#shelf-1 a[href*="iphone"]', "YOUR")
|
||||
self.set_text_content('#shelf-1 a[href*="ipad"]', "BASE")
|
||||
self.remove_element('#shelf-1 [role="listitem"]:nth-child(5)')
|
||||
self.set_text_content('#shelf-1 a[href*="watch"]', "ARE")
|
||||
self.set_text_content('#shelf-1 a[href*="airpods"]', "BELONG")
|
||||
self.set_text_content('#shelf-1 a[href*="airtag"]', "TO")
|
||||
|
|
|
@ -6,33 +6,24 @@ BaseCase.main(__name__, __file__, "--uc", "-s")
|
|||
|
||||
|
||||
class UndetectedTest(BaseCase):
|
||||
def verify_success(self):
|
||||
self.assert_text("OH YEAH, you passed!", "h1", timeout=6.25)
|
||||
def test_browser_is_undetected(self):
|
||||
if not self.undetectable:
|
||||
self.get_new_driver(undetectable=True)
|
||||
self.driver.uc_open_with_reconnect(
|
||||
"https://nowsecure.nl/#relax", reconnect_time=3
|
||||
)
|
||||
self.sleep(1.2)
|
||||
if not self.is_text_visible("OH YEAH, you passed!", "h1"):
|
||||
self.get_new_driver(undetectable=True)
|
||||
self.driver.uc_open_with_reconnect(
|
||||
"https://nowsecure.nl/#relax", reconnect_time=3
|
||||
)
|
||||
self.sleep(1.2)
|
||||
if not self.is_text_visible("OH YEAH, you passed!", "h1"):
|
||||
if self.is_element_visible('iframe[src*="challenge"]'):
|
||||
with self.frame_switch('iframe[src*="challenge"]'):
|
||||
self.click("span.mark")
|
||||
self.sleep(2)
|
||||
self.assert_text("OH YEAH, you passed!", "h1", timeout=3)
|
||||
self.post_message("Selenium wasn't detected!", duration=2.8)
|
||||
self._print("\n Success! Website did not detect Selenium! ")
|
||||
|
||||
def fail_me(self):
|
||||
self.fail('Selenium was detected! Try using: "pytest --uc"')
|
||||
|
||||
def test_browser_is_undetected(self):
|
||||
if not (self.undetectable):
|
||||
self.get_new_driver(undetectable=True)
|
||||
self.driver.get("https://nowsecure.nl/#relax")
|
||||
try:
|
||||
self.verify_success()
|
||||
except Exception:
|
||||
self.clear_all_cookies()
|
||||
self.get_new_driver(undetectable=True)
|
||||
self.driver.get("https://nowsecure.nl/#relax")
|
||||
try:
|
||||
self.verify_success()
|
||||
except Exception:
|
||||
if self.is_element_visible('iframe[src*="challenge"]'):
|
||||
with self.frame_switch('iframe[src*="challenge"]'):
|
||||
self.click("span.mark")
|
||||
else:
|
||||
self.fail_me()
|
||||
try:
|
||||
self.verify_success()
|
||||
except Exception:
|
||||
self.fail_me()
|
||||
|
|
|
@ -2,12 +2,25 @@
|
|||
|
||||
## [<img src="https://seleniumbase.io/img/logo6.png" title="SeleniumBase" width="32">](https://github.com/seleniumbase/SeleniumBase/) Demo Mode 🎦
|
||||
|
||||
<p align="left"><img src="https://seleniumbase.github.io/cdn/gif/xkcd_vid.gif" width="400" alt="SeleniumBase Example" title="SeleniumBase Example" /></p>
|
||||
<p align="left"><img src="https://seleniumbase.github.io/cdn/gif/xkcd_vid.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></p>
|
||||
|
||||
<p align="left">🔵 <b translate="no">Demo Mode</b> helps you see what a test is doing.</p>
|
||||
|
||||
<p align="left">🏇💨 👀 If a test runs too fast for your eyes, use <b translate="no">Demo Mode</b> to slow it down, highlight actions, and display assertions. Example usage:</p>
|
||||
|
||||
```bash
|
||||
cd examples/
|
||||
pytest test_coffee_cart.py --demo
|
||||
```
|
||||
|
||||
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" title="SeleniumBase Coffee Cart Test" /></a></p>
|
||||
|
||||
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
||||
|
||||
--------
|
||||
|
||||
Another example:
|
||||
|
||||
```bash
|
||||
pytest my_first_test.py --demo
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!-- SeleniumBase Docs -->
|
||||
|
||||
<!-- YouTube View --><a href="https://www.youtube.com/watch?v=EablmOazy-k"><img src="http://img.youtube.com/vi/EablmOazy-k/0.jpg" title="SeleniumBase on YouTube" width="285" /></a>
|
||||
<!-- GitHub Only --><p>(<b><a href="https://www.youtube.com/watch?v=EablmOazy-k">Watch the new tutorial on YouTube</a></b>)</p>
|
||||
<!-- YouTube View --><a href="https://www.youtube.com/watch?v=EablmOazy-k"><img src="http://img.youtube.com/vi/EablmOazy-k/0.jpg" title="SeleniumBase on YouTube" width="365" /></a>
|
||||
<!-- GitHub Only --><p>(<b><a href="https://www.youtube.com/watch?v=EablmOazy-k">Watch the SeleniumBase tutorial from Selenium-Conf-2023 on YouTube</a></b>)</p>
|
||||
|
||||
<a id="feature_list"></a>
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
* Can run tests with proxy+auth via PAC URL. (``--proxy-pac-url=USER:PASS@URL.pac``)
|
||||
* Can run tests with a customized browser user agent. (``--agent=USER_AGENT_STRING``)
|
||||
* Can set a Chromium User Data Directory/Profile to load. (``--user-data-dir=DIR``)
|
||||
* Can avoid detection by sites that try to block Selenium. (``--undetected``/``--uc``)
|
||||
* Can [avoid detection](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md) by sites that try to block Selenium. (``--undetected``/``--uc``)
|
||||
* Can integrate with [selenium-wire](https://github.com/wkeeling/selenium-wire) for inspecting browser requests. (``--wire``)
|
||||
* Can load Chrome Extension ZIP files. (``--extension-zip=ZIP``)
|
||||
* Can load Chrome Extension folders. (``--extension-dir=DIR``)
|
||||
|
@ -50,11 +50,11 @@
|
|||
|
||||
--------
|
||||
|
||||
<!-- YouTube View --><a href="https://www.youtube.com/watch?v=yEQeAU_mrg0"><img src="http://img.youtube.com/vi/yEQeAU_mrg0/0.jpg" title="SeleniumBase on YouTube" width="285" /></a>
|
||||
<!-- YouTube View --><a href="https://www.youtube.com/watch?v=yEQeAU_mrg0"><img src="http://img.youtube.com/vi/yEQeAU_mrg0/0.jpg" title="SeleniumBase on YouTube" width="365" /></a>
|
||||
<!-- GitHub Only --><p>(<b><a href="https://www.youtube.com/watch?v=yEQeAU_mrg0">Have fun with test automation!</a></b>)</p>
|
||||
|
||||
(<b><a href="https://www.youtube.com/watch?v=Sjzq9kU5kOw">Watch the old tutorial on YouTube</a></b>)
|
||||
(<b><a href="https://www.youtube.com/watch?v=Sjzq9kU5kOw">Watch the original tutorial on YouTube</a></b>)
|
||||
|
||||
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_10.png" alt="SeleniumBase" title="SeleniumBase" width="200"></a></p>
|
||||
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_10.png" alt="SeleniumBase" title="SeleniumBase" width="240"></a></p>
|
||||
|
||||
[<img src="https://seleniumbase.github.io/cdn/img/super_logo_sb.png" title="SeleniumBase" width="200">](https://seleniumbase.io/)
|
||||
[<img src="https://seleniumbase.github.io/cdn/img/super_logo_sb.png" title="SeleniumBase" width="240">](https://seleniumbase.io/)
|
||||
|
|
|
@ -66,18 +66,18 @@ brew upgrade geckodriver
|
|||
|
||||
**Linux shortcuts**:
|
||||
|
||||
If you still need the web drivers, here are some scripts to help you get ``chromedriver`` and ``geckodriver`` on a Linux machine:
|
||||
If you still need drivers, these scripts download ``chromedriver`` and ``geckodriver`` to a Linux machine:
|
||||
|
||||
```bash
|
||||
wget https://chromedriver.storage.googleapis.com/72.0.3626.69/chromedriver_linux64.zip
|
||||
wget https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip
|
||||
unzip chromedriver_linux64.zip
|
||||
mv chromedriver /usr/local/bin/
|
||||
chmod +x /usr/local/bin/chromedriver
|
||||
```
|
||||
|
||||
```bash
|
||||
wget https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz
|
||||
tar xvfz geckodriver-v0.33.0-linux64.tar.gz
|
||||
wget https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-linux64.tar.gz
|
||||
tar xvfz geckodriver-v0.34.0-linux64.tar.gz
|
||||
mv geckodriver /usr/local/bin/
|
||||
chmod +x /usr/local/bin/geckodriver
|
||||
```
|
||||
|
|
|
@ -7,11 +7,11 @@ pipdeptree>=2.13.2
|
|||
python-dateutil>=2.8.2
|
||||
Markdown==3.5.2
|
||||
markdown2==2.4.12
|
||||
MarkupSafe==2.1.4
|
||||
MarkupSafe==2.1.5
|
||||
Jinja2==3.1.3
|
||||
click==8.1.7
|
||||
ghp-import==2.1.0
|
||||
watchdog==3.0.0
|
||||
watchdog==4.0.0
|
||||
cairocffi==1.6.1
|
||||
pathspec==0.12.1
|
||||
Babel==2.14.0
|
||||
|
@ -20,7 +20,7 @@ lxml==5.1.0
|
|||
pyquery==2.0.0
|
||||
readtime==3.0.0
|
||||
mkdocs==1.5.3
|
||||
mkdocs-material==9.5.6
|
||||
mkdocs-material==9.5.9
|
||||
mkdocs-exclude-search==0.6.6
|
||||
mkdocs-simple-hooks==0.1.5
|
||||
mkdocs-material-extensions==1.3.1
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
pip>=23.3.2
|
||||
pip>=24.0
|
||||
packaging>=23.2
|
||||
setuptools>=68.0.0;python_version<"3.8"
|
||||
setuptools>=69.0.3;python_version>="3.8"
|
||||
setuptools>=69.1.0;python_version>="3.8"
|
||||
wheel>=0.42.0
|
||||
attrs>=23.2.0
|
||||
certifi>=2023.11.17
|
||||
certifi>=2024.2.2
|
||||
filelock>=3.12.2;python_version<"3.8"
|
||||
filelock>=3.13.1;python_version>="3.8"
|
||||
platformdirs>=4.0.0;python_version<"3.8"
|
||||
platformdirs>=4.1.0;python_version>="3.8"
|
||||
platformdirs>=4.2.0;python_version>="3.8"
|
||||
typing-extensions>=4.9.0;python_version>="3.8"
|
||||
parse>=1.20.1
|
||||
parse-type>=0.6.2
|
||||
|
@ -18,7 +18,7 @@ idna==3.6
|
|||
chardet==5.2.0
|
||||
charset-normalizer==3.3.2
|
||||
urllib3>=1.26.18,<2;python_version<"3.10"
|
||||
urllib3>=1.26.18,<2.2.0;python_version>="3.10"
|
||||
urllib3>=1.26.18,<2.3.0;python_version>="3.10"
|
||||
requests==2.31.0
|
||||
pynose==1.4.8
|
||||
sniffio==1.3.0
|
||||
|
@ -41,7 +41,8 @@ py==1.11.0
|
|||
pytest==7.4.4;python_version<"3.8"
|
||||
pytest==8.0.0;python_version>="3.8"
|
||||
pytest-html==2.0.1
|
||||
pytest-metadata==3.0.0
|
||||
pytest-metadata==3.0.0;python_version<"3.8"
|
||||
pytest-metadata==3.1.0;python_version>="3.8"
|
||||
pytest-ordering==0.6
|
||||
pytest-rerunfailures==13.0
|
||||
pytest-xdist==3.5.0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "4.23.2"
|
||||
__version__ = "4.23.3"
|
||||
|
|
|
@ -37,6 +37,7 @@ COMMANDS:
|
|||
revert-objects [SB_FILE.py] [OPTIONS]
|
||||
encrypt / obfuscate
|
||||
decrypt / unobfuscate
|
||||
proxy (Start a basic proxy server)
|
||||
download server (Get Selenium Grid JAR file)
|
||||
grid-hub [start|stop] [OPTIONS]
|
||||
grid-node [start|stop] --hub=[HOST/IP]
|
||||
|
@ -653,6 +654,25 @@ Runs the password encryption/obfuscation tool.
|
|||
Runs the password decryption/unobfuscation tool.
|
||||
(Where you can enter an encrypted password to decrypt.)
|
||||
|
||||
<h3>proxy</h3>
|
||||
|
||||
* Usage:
|
||||
|
||||
```bash
|
||||
sbase proxy [OPTIONS]
|
||||
```
|
||||
|
||||
* Options:
|
||||
|
||||
``--hostname=HOSTNAME`` (Set ``hostname``) (Default: ``127.0.0.1``)
|
||||
``--port=PORT`` (Set ``port``) (Default: ``8899``)
|
||||
``--help`` / ``-h`` (Display list of all available ``proxy`` options.)
|
||||
|
||||
* Output:
|
||||
|
||||
Launch a basic proxy server on the current machine.
|
||||
(Uses ``127.0.0.1:8899`` as the default address.)
|
||||
|
||||
<h3>download</h3>
|
||||
|
||||
* Usage:
|
||||
|
|
|
@ -32,6 +32,8 @@ sbase objectify my_first_test.py
|
|||
sbase revert-objects my_first_test.py
|
||||
sbase encrypt
|
||||
sbase decrypt
|
||||
sbase proxy
|
||||
sbase proxy --hostname=127.0.0.1 --port=8899
|
||||
sbase download server
|
||||
sbase grid-hub start
|
||||
sbase grid-node start --hub=127.0.0.1
|
||||
|
@ -79,7 +81,7 @@ def show_basic_usage():
|
|||
show_package_location()
|
||||
show_version_info()
|
||||
print("")
|
||||
time.sleep(0.72) # Enough time to see the version
|
||||
time.sleep(0.62) # Enough time to see the version
|
||||
sc = ""
|
||||
sc += ' * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"\n'
|
||||
sc += ' * OR: "sbase [COMMAND] [PARAMETERS]"\n'
|
||||
|
@ -108,6 +110,7 @@ def show_basic_usage():
|
|||
sc += " revert-objects [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " encrypt / obfuscate\n"
|
||||
sc += " decrypt / unobfuscate\n"
|
||||
sc += " proxy (Start a basic proxy server)\n"
|
||||
sc += " download server (Get Selenium Grid JAR file)\n"
|
||||
sc += " grid-hub [start|stop] [OPTIONS]\n"
|
||||
sc += " grid-node [start|stop] --hub=[HOST/IP]\n"
|
||||
|
@ -1210,6 +1213,24 @@ def main():
|
|||
show_options()
|
||||
elif command == "behave-options" or command == "--behave-options":
|
||||
show_behave_options()
|
||||
elif command == "proxy" or command == "--proxy":
|
||||
import fasteners
|
||||
import os
|
||||
import warnings
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", category=UserWarning)
|
||||
pip_find_lock = fasteners.InterProcessLock(
|
||||
constants.PipInstall.FINDLOCK
|
||||
)
|
||||
with pip_find_lock:
|
||||
try:
|
||||
from proxy import proxy # noqa: F401
|
||||
except Exception:
|
||||
shared_utils.pip_install(
|
||||
"proxy.py", version=constants.ProxyPy.VER
|
||||
)
|
||||
os.system("proxy %s" % " ".join(sys.argv[2:]))
|
||||
elif command == "help" or command == "--help":
|
||||
if len(command_args) >= 1:
|
||||
if command_args[0] == "get":
|
||||
|
|
|
@ -11771,19 +11771,31 @@ class BaseCase(unittest.TestCase):
|
|||
raise Exception('Expecting a numeric value for "value"!')
|
||||
if not color:
|
||||
color = ""
|
||||
else:
|
||||
color = color.replace("'", "\\'")
|
||||
label = label.replace("'", "\\'")
|
||||
color = color.replace("'", "\\'")
|
||||
data_point = """
|
||||
{
|
||||
name: '%s',
|
||||
y: %s,
|
||||
color: '%s'
|
||||
},
|
||||
""" % (
|
||||
label,
|
||||
value,
|
||||
color,
|
||||
)
|
||||
if color:
|
||||
data_point = """
|
||||
{
|
||||
name: '%s',
|
||||
y: %s,
|
||||
color: '%s'
|
||||
},
|
||||
""" % (
|
||||
label,
|
||||
value,
|
||||
color,
|
||||
)
|
||||
else:
|
||||
data_point = """
|
||||
{
|
||||
name: '%s',
|
||||
y: %s,
|
||||
},
|
||||
""" % (
|
||||
label,
|
||||
value,
|
||||
)
|
||||
data_point = textwrap.dedent(data_point)
|
||||
self._chart_data[chart_name].append(data_point)
|
||||
if self._chart_first_series[chart_name]:
|
||||
|
|
|
@ -197,7 +197,7 @@ class Warnings:
|
|||
|
||||
|
||||
class JQuery:
|
||||
VER = "3.6.3"
|
||||
VER = "3.7.1"
|
||||
MIN_JS = "https://cdn.jsdelivr.net/npm/jquery@%s/dist/jquery.min.js" % VER
|
||||
|
||||
|
||||
|
@ -218,14 +218,14 @@ class Messenger:
|
|||
|
||||
|
||||
class Underscore:
|
||||
VER = "1.13.4"
|
||||
VER = "1.13.6"
|
||||
MIN_JS = (
|
||||
"https://cdn.jsdelivr.net/npm/underscore@%s/underscore.min.js" % VER
|
||||
)
|
||||
|
||||
|
||||
class Backbone:
|
||||
VER = "1.4.1"
|
||||
VER = "1.6.0"
|
||||
MIN_JS = "https://cdn.jsdelivr.net/npm/backbone@%s/backbone.min.js" % VER
|
||||
|
||||
|
||||
|
@ -263,7 +263,7 @@ class Reveal:
|
|||
|
||||
|
||||
class HighCharts:
|
||||
VER = "9.0.1" # Later versions have a bug that removes default colors
|
||||
VER = "10.3.3"
|
||||
HC_CSS = "https://code.highcharts.com/%s/css/highcharts.css" % VER
|
||||
HC_JS = "https://code.highcharts.com/%s/highcharts.js" % VER
|
||||
EXPORTING_JS = "https://code.highcharts.com/%s/modules/exporting.js" % VER
|
||||
|
@ -343,6 +343,11 @@ class Tether:
|
|||
)
|
||||
|
||||
|
||||
class ProxyPy:
|
||||
# The version installed if proxy.py is not installed
|
||||
VER = "2.4.3"
|
||||
|
||||
|
||||
class SeleniumWire:
|
||||
# The version installed if selenium-wire is not installed
|
||||
VER = "5.1.0"
|
||||
|
|
37
setup.py
37
setup.py
|
@ -92,7 +92,19 @@ setup(
|
|||
author_email="mdmintz@gmail.com",
|
||||
maintainer="Michael Mintz",
|
||||
license="MIT",
|
||||
keywords="pytest automation selenium browser testing webdriver sbase",
|
||||
keywords=[
|
||||
"pytest",
|
||||
"selenium",
|
||||
"framework",
|
||||
"automation",
|
||||
"browser",
|
||||
"testing",
|
||||
"webdriver",
|
||||
"seleniumbase",
|
||||
"sbase",
|
||||
"crawling",
|
||||
"scraping",
|
||||
],
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Console",
|
||||
|
@ -124,6 +136,8 @@ setup(
|
|||
"Topic :: Software Development :: Quality Assurance",
|
||||
"Topic :: Software Development :: Code Generators",
|
||||
"Topic :: Software Development :: Libraries",
|
||||
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Software Development :: Testing",
|
||||
"Topic :: Software Development :: Testing :: Acceptance",
|
||||
"Topic :: Software Development :: Testing :: Traffic Generation",
|
||||
|
@ -131,17 +145,17 @@ setup(
|
|||
],
|
||||
python_requires=">=3.7",
|
||||
install_requires=[
|
||||
'pip>=23.3.2',
|
||||
'pip>=24.0',
|
||||
'packaging>=23.2',
|
||||
'setuptools>=68.0.0;python_version<"3.8"',
|
||||
'setuptools>=69.0.3;python_version>="3.8"',
|
||||
'setuptools>=69.1.0;python_version>="3.8"',
|
||||
'wheel>=0.42.0',
|
||||
'attrs>=23.2.0',
|
||||
"certifi>=2023.11.17",
|
||||
"certifi>=2024.2.2",
|
||||
'filelock>=3.12.2;python_version<"3.8"',
|
||||
'filelock>=3.13.1;python_version>="3.8"',
|
||||
'platformdirs>=4.0.0;python_version<"3.8"',
|
||||
'platformdirs>=4.1.0;python_version>="3.8"',
|
||||
'platformdirs>=4.2.0;python_version>="3.8"',
|
||||
'typing-extensions>=4.9.0;python_version>="3.8"',
|
||||
'parse>=1.20.1',
|
||||
'parse-type>=0.6.2',
|
||||
|
@ -151,7 +165,7 @@ setup(
|
|||
'chardet==5.2.0',
|
||||
'charset-normalizer==3.3.2',
|
||||
'urllib3>=1.26.18,<2;python_version<"3.10"',
|
||||
'urllib3>=1.26.18,<2.2.0;python_version>="3.10"',
|
||||
'urllib3>=1.26.18,<2.3.0;python_version>="3.10"',
|
||||
'requests==2.31.0',
|
||||
"pynose==1.4.8",
|
||||
'sniffio==1.3.0',
|
||||
|
@ -174,7 +188,8 @@ setup(
|
|||
'pytest==7.4.4;python_version<"3.8"',
|
||||
'pytest==8.0.0;python_version>="3.8"',
|
||||
"pytest-html==2.0.1", # Newer ones had issues
|
||||
'pytest-metadata==3.0.0',
|
||||
'pytest-metadata==3.0.0;python_version<"3.8"',
|
||||
'pytest-metadata==3.1.0;python_version>="3.8"',
|
||||
"pytest-ordering==0.6",
|
||||
'pytest-rerunfailures==13.0',
|
||||
'pytest-xdist==3.5.0',
|
||||
|
@ -235,7 +250,7 @@ setup(
|
|||
'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.1;python_version>="3.9"',
|
||||
'cryptography==42.0.2;python_version>="3.9"',
|
||||
'cffi==1.15.1;python_version<"3.8"',
|
||||
'cffi==1.16.0;python_version>="3.8"',
|
||||
"pycparser==2.21",
|
||||
|
@ -247,6 +262,12 @@ setup(
|
|||
'Pillow==9.5.0;python_version<"3.8"',
|
||||
'Pillow==10.2.0;python_version>="3.8"',
|
||||
],
|
||||
# pip install -e .[proxy]
|
||||
# Usage: proxy
|
||||
# (That starts a proxy server on "127.0.0.1:8899".)
|
||||
"proxy": [
|
||||
"proxy.py==2.4.3",
|
||||
],
|
||||
# pip install -e .[psutil]
|
||||
"psutil": [
|
||||
"psutil==5.9.8",
|
||||
|
|
Loading…
Reference in New Issue