Skip to content

Commit d15ce8b

Browse files
authored
Merge pull request #1653 from seleniumbase/refactoring-and-recorder-updates
Refactoring and Recorder updates
2 parents c2fd5c6 + ca261fe commit d15ce8b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+246
-213
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2014-2022 Michael Mintz
3+
Copyright (c) 2014-2023 Michael Mintz
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<meta property="og:image" content="https://seleniumbase.github.io/cdn/img/mac_sb_logo_5b.png" />
88
<link rel="icon" href="https://seleniumbase.github.io/img/logo7.png" />
99

10-
<h3 align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/mac_sb_logo_b.png" alt="SeleniumBase" title="SeleniumBase" width="408" /></a></h3>
10+
<h3 align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/sb_logo_10t.png" alt="SeleniumBase" title="SeleniumBase" width="350" /></a></h3>
1111

12-
<h2 align="center">SeleniumBase: Enterprise Python Web Testing</h2>
12+
<h2 align="center">Python Web UI Testing Framework</h2>
1313

1414
<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://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="SeleniumBase" /></a></p>
1515

@@ -24,7 +24,7 @@
2424
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📘 APIs</a> |
2525
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md"> 🔡 Formats</a> |
2626
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊 Dashboard</a> |
27-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">⏺️ Recorder</a> |
27+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">🔴 Recorder</a> |
2828
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾 Locales</a> |
2929
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md">🌐 Grid</a>
3030
<br />
@@ -53,23 +53,42 @@
5353

5454
--------
5555

56-
5756
<a id="multiple_examples"></a>
58-
<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">SeleniumBase/examples/</a></p>
57+
<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>
5958

6059
```bash
6160
cd examples/
6261
pytest test_coffee_cart.py --demo
6362
```
6463

65-
<p>(<code>--demo</code> slows the test with highlighting for better visibility.)</p>
64+
<p>(<code>--demo</code> mode slows down tests and highlights actions)</p>
6665

6766
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
6867

68+
* Here's a preview of that test:
69+
70+
```python
71+
from seleniumbase import BaseCase
72+
73+
class CoffeeCartTest(BaseCase):
74+
def test_coffee_cart(self):
75+
self.open("https://seleniumbase.io/coffee/")
76+
self.click('div[data-sb="Cappuccino"]')
77+
self.click('div[data-sb="Flat-White"]')
78+
self.click('div[data-sb="Cafe-Latte"]')
79+
self.click('a[aria-label="Cart page"]')
80+
self.assert_exact_text("Total: $53.00", "button.pay")
81+
self.click("button.pay")
82+
self.type("input#name", "Selenium Coffee")
83+
self.type("input#email", "[email protected]")
84+
self.click("button#submit-payment")
85+
self.assert_text("Thanks for your purchase.", "#app")
86+
```
87+
6988
--------
7089

7190
<details>
72-
<summary> ▶️ How is SeleniumBase different from raw Selenium? (<b>click to expand</b>)</summary>
91+
<summary> ▶️ How is <b>SeleniumBase</b> different from raw Selenium? (<b>click to expand</b>)</summary>
7392
<div>
7493

7594
<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>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>

examples/boilerplates/samples/file_parsing/parse_files.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
"""
2-
Demonstration of parsing data from files.
3-
In this example, login information is pulled for tests.
4-
"""
5-
1+
"""Example of parsing data from files."""
62
from seleniumbase import BaseCase
73

84

95
class ParseTestCase(BaseCase):
106
def setUp(self):
11-
super(ParseTestCase, self).setUp()
7+
super().setUp()
128

139
def get_login_credentials(self, user_type):
1410
# Example of parsing data from a file (Method 1)

examples/coffee_cart_tests.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,18 @@ def test_coffee_promo_with_preview(self):
2424
self.click('div[data-test="Americano"]')
2525
self.click('div[data-test="Cafe_Latte"]')
2626
self.assert_exact_text("cart (3)", 'a[aria-label="Cart page"]')
27-
self.assert_text("Get an extra cup of Mocha for $4.", "div.promo")
28-
self.click("div.promo button.yes")
29-
self.assert_exact_text("cart (4)", 'a[aria-label="Cart page"]')
27+
promo = False
28+
total_string = "Total: $33.00"
29+
if self.is_element_visible("div.promo"):
30+
self.assert_text("Get an extra cup of Mocha for $4.", "div.promo")
31+
self.click("div.promo button.yes")
32+
self.assert_exact_text("cart (4)", 'a[aria-label="Cart page"]')
33+
promo = True
34+
total_string = "Total: $37.00"
3035
self.hover('button[data-test="checkout"]')
31-
self.assert_text("(Discounted) Mocha", "ul.cart-preview")
32-
self.assert_exact_text("Total: $37.00", 'button[data-test="checkout"]')
36+
if promo:
37+
self.assert_text("(Discounted) Mocha", "ul.cart-preview")
38+
self.assert_exact_text(total_string, 'button[data-test="checkout"]')
3339
self.click('button[data-test="checkout"]')
3440
self.type("input#name", "Selenium Coffee")
3541
self.type("input#email", "[email protected]")
Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
1-
examples.test_fail.MyTestClass.test_find_army_of_robots_on_xkcd_desert_island
2-
----------------------------------------------------
1+
test_fail.py::FailingTests::test_find_army_of_robots_on_xkcd_desert_island
2+
--------------------------------------------------------------------
33
Last Page: https://xkcd.com/731/
4-
Browser: firefox
5-
Timestamp: 1599068455 (Unix Timestamp)
6-
Date: Wednesday, September 2, 2020
7-
Time: 1:40:55 PM (EDT, UTC-05:00)
8-
----------------------------------------------------
9-
Traceback: File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
10-
testMethod()
11-
File "/Users/michael/github/SeleniumBase/examples/test_fail.py", line 17, in test_find_army_of_robots_on_xkcd_desert_island
4+
Duration: 1.63s
5+
Browser: Chrome 108.0.5359.124
6+
Driver: chromedriver 108.0.5359.71
7+
Timestamp: 1672785363 (Unix Timestamp)
8+
Date: Tuesday, January 3, 2023
9+
Time: 5:36:03 PM (EDT, UTC-05:00)
10+
--------------------------------------------------------------------
11+
Traceback: File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/unittest/case.py", line 57, in testPartExecutor
12+
yield
13+
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/unittest/case.py", line 623, in run
14+
self._callTestMethod(testMethod)
15+
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/unittest/case.py", line 579, in _callTestMethod
16+
if method() is not None:
17+
^^^^^^^^
18+
File "/Users/michael/github/SeleniumBase/examples/test_fail.py", line 16, in test_find_army_of_robots_on_xkcd_desert_island
1219
self.assert_element("div#ARMY_OF_ROBOTS", timeout=1)
13-
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/base_case.py", line 4931, in assert_element
20+
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/base_case.py", line 8279, in assert_element
1421
self.wait_for_element_visible(selector, by=by, timeout=timeout)
15-
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/base_case.py", line 3290, in wait_for_element_visible
16-
self.driver, selector, by, timeout)
17-
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/page_actions.py", line 299, in wait_for_element_visible
22+
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/base_case.py", line 7718, in wait_for_element_visible
23+
return page_actions.wait_for_element_visible(
24+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/page_actions.py", line 428, in wait_for_element_visible
1826
timeout_exception(NoSuchElementException, message)
19-
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/page_actions.py", line 117, in timeout_exception
20-
raise exc(message)
27+
File "/Users/michael/github/SeleniumBase/seleniumbase/fixtures/page_actions.py", line 191, in timeout_exception
28+
raise exc(msg)
29+
2130
Exception: Message:
2231
Element {div#ARMY_OF_ROBOTS} was not present after 1 second!

examples/my_first_test.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"""A complete end-to-end test for an e-commerce website."""
22
from seleniumbase import BaseCase
33

4+
if __name__ == "__main__": # If "python" called
5+
from pytest import main
6+
from sys import argv
7+
main([*argv, "-s"]) # Run pytest, same args
8+
49

510
class MyTestClass(BaseCase):
611
def test_swag_labs(self):
@@ -28,12 +33,6 @@ def test_swag_labs(self):
2833
self.assert_element("div#login_button_container")
2934

3035

31-
if __name__ == "__main__": # If "python", run pytest
32-
from pytest import main
33-
from sys import argv
34-
main([*argv, "-s"]) # Run pytest using same args
35-
36-
3736
#######################################################################
3837
#
3938
# **** NOTES / USEFUL INFO ****

examples/swag_labs_user_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,4 @@ def tearDown(self):
9191
self.js_click_if_present("a#logout_sidebar_link")
9292
except Exception:
9393
pass
94-
super(SwagLabsTests, self).tearDown()
94+
super().tearDown()

examples/test_coffee_cart.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"""Use SeleniumBase to test the Coffee Cart App."""
22
from seleniumbase import BaseCase
33

4+
if __name__ == "__main__": # If "python" called
5+
from pytest import main
6+
from sys import argv
7+
main([*argv, "-s"]) # Run pytest, same args
8+
49

510
class CoffeeCartTest(BaseCase):
611
def test_coffee_cart(self):
@@ -9,15 +14,9 @@ def test_coffee_cart(self):
914
self.click('div[data-sb="Flat-White"]')
1015
self.click('div[data-sb="Cafe-Latte"]')
1116
self.click('a[aria-label="Cart page"]')
12-
self.assert_exact_text("Total: $53.00", 'button.pay')
13-
self.click('button.pay')
17+
self.assert_exact_text("Total: $53.00", "button.pay")
18+
self.click("button.pay")
1419
self.type("input#name", "Selenium Coffee")
1520
self.type("input#email", "[email protected]")
1621
self.click("button#submit-payment")
1722
self.assert_text("Thanks for your purchase.", "#app .success")
18-
19-
20-
if __name__ == "__main__": # If "python", run pytest
21-
from pytest import main
22-
from sys import argv
23-
main([*argv, "-s"]) # Run pytest using same args

examples/test_mfa_login.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
from seleniumbase import BaseCase
22

3+
if __name__ == "__main__": # If "python" called
4+
from pytest import main
5+
from sys import argv
6+
main([*argv, "-s"]) # Run pytest, same args
7+
38

49
class TestMFALogin(BaseCase):
510
def test_mfa_login(self):
@@ -14,9 +19,3 @@ def test_mfa_login(self):
1419
self.click_link("Sign out") # Link must be "a" tag. Not "button".
1520
self.assert_element('a:contains("Sign in")')
1621
self.assert_exact_text("You have been signed out!", "#top_message")
17-
18-
19-
if __name__ == "__main__": # If "python", run pytest
20-
from pytest import main
21-
from sys import argv
22-
main([*argv, "-s"]) # Run pytest using same args

examples/test_override_sb_fixture.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ def get_new_driver(self, *args, **kwargs):
2020
return webdriver.Chrome(options=options)
2121

2222
def setUp(self):
23-
super(BaseClass, self).setUp()
23+
super().setUp()
2424

2525
def base_method(self):
2626
pass
2727

2828
def tearDown(self):
2929
self.save_teardown_screenshot()
30-
super(BaseClass, self).tearDown()
30+
super().tearDown()
3131

3232
sb = BaseClass("base_method")
3333
sb.setUpClass()

0 commit comments

Comments
 (0)