Skip to content

Commit 79a3d3d

Browse files
authored
Merge pull request #217 from seleniumbase/exporting-tours
Add the ability to export a website tour as a .js file
2 parents 1a3dcd5 + 58a8a6b commit 79a3d3d

File tree

15 files changed

+278
-54
lines changed

15 files changed

+278
-54
lines changed

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pytest my_first_test.py --demo_mode
4949
```
5050

5151
<img src="https://cdn2.hubspot.net/hubfs/100006/sb_demo_mode.gif" title="SeleniumBase" height="270"><br>
52-
(Above: Actual demo of [my_first_test.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py) running on [xkcd.com](http://xkcd.com/353/))
52+
(Above: Actual demo of [my_first_test.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py) running on [xkcd.com](https://xkcd.com/353/))
5353

5454
There are many more examples to try out from the [SeleniumBase/examples](https://github.com/seleniumbase/SeleniumBase/blob/master/examples) directory, which you can run easily if you clone SeleniumBase.
5555

@@ -181,18 +181,18 @@ from seleniumbase import BaseCase
181181
class MyTestClass(BaseCase):
182182

183183
def test_basic(self):
184-
self.open('http://xkcd.com/353/')
184+
self.open('https://xkcd.com/353/')
185185
self.assert_element('img[alt="Python"]')
186186
self.click('a[rel="license"]')
187187
self.assert_text('free to copy', 'div center')
188-
self.open("http://xkcd.com/1481/")
188+
self.open("https://xkcd.com/1481/")
189189
title = self.get_attribute("#comic img", "title")
190190
self.assertTrue("86,400 seconds per day" in title)
191191
self.click('link=Blag')
192192
self.assert_text('The blag of the webcomic', 'h2')
193193
self.update_text('input#s', 'Robots!\n')
194194
self.assert_text('Hooray robots!', '#content')
195-
self.open('http://xkcd.com/1319/')
195+
self.open('https://xkcd.com/1319/')
196196
self.assert_text('Automation', 'div#ctitle')
197197
```
198198
(<i>By default, [CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp) are used for finding page elements.</i>)
@@ -393,7 +393,7 @@ from seleniumbase import BaseCase
393393
class MyTestClass(BaseCase):
394394

395395
def test_find_army_of_robots_on_xkcd_desert_island(self):
396-
self.open("http://xkcd.com/731/")
396+
self.open("https://xkcd.com/731/")
397397
self.assert_element("div#ARMY_OF_ROBOTS", timeout=1) # This should fail
398398
```
399399

@@ -661,7 +661,7 @@ from seleniumbase import BaseCase
661661
class MyTestClass(BaseCase):
662662

663663
def test_delayed_asserts(self):
664-
self.open('http://xkcd.com/993/')
664+
self.open('https://xkcd.com/993/')
665665
self.wait_for_element('#comic')
666666
self.delayed_assert_element('img[alt="Brand Identity"]')
667667
self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail
@@ -685,6 +685,15 @@ self.driver.find_elements_by_partial_link_text("GitHub")
685685
```
686686
(In general, you'll want to use the SeleniumBase versions of methods when available.)
687687

688+
#### Retry Failing Tests Automatically
689+
690+
You can use ``--reruns #`` to retry failing tests that many times. Use ``--reruns-delay #`` to wait that many seconds between retries. Example:
691+
```
692+
pytest --reruns 5 --reruns-delay 1
693+
```
694+
695+
Additionally, you can use the ``@retry_on_exception()`` decorator to specifically retry failing methods. (First import: ``from seleniumbase import decorators``) To learn more about SeleniumBase decorators, [click here](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/common).
696+
688697
#### Checking Email:
689698
Let's say you have a test that sends an email, and now you want to check that the email was received:
690699

examples/basic_script.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
class MyTestClass(BaseCase):
99

1010
def test_basic(self):
11-
self.open('http://xkcd.com/353/')
11+
self.open('https://xkcd.com/353/')
1212
self.click('a[rel="license"]')
13-
self.open('http://xkcd.com/1481/')
13+
self.open('https://xkcd.com/1481/')
1414
self.click("link=Blag")
1515
self.update_text('input#s', 'Robots!\n')
16-
self.open('http://xkcd.com/1319/')
16+
self.open('https://xkcd.com/1319/')

examples/delayed_assert_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class MyTestClass(BaseCase):
55

66
def test_delayed_asserts(self):
7-
self.open('http://xkcd.com/993/')
7+
self.open('https://xkcd.com/993/')
88
self.wait_for_element('#comic')
99
self.delayed_assert_element('img[alt="Brand Identity"]')
1010
self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail

examples/my_first_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
class MyTestClass(BaseCase):
55

66
def test_basic(self):
7-
self.open('http://xkcd.com/353/') # Navigate to the web page
7+
self.open('https://xkcd.com/353/') # Navigate to the web page
88
self.assert_element('img[alt="Python"]') # Assert element on page
99
self.click('a[rel="license"]') # Click element on page
1010
self.assert_text('free to copy', 'div center') # Assert text on page
11-
self.open("http://xkcd.com/1481/")
11+
self.open("https://xkcd.com/1481/")
1212
title = self.get_attribute("#comic img", "title") # Get an attribute
1313
self.assertTrue("86,400 seconds per day" in title)
1414
self.click('link=Blag') # Click on link
1515
self.assert_text('The blag of the webcomic', 'h2')
1616
self.update_text('input#s', 'Robots!\n') # Type text
1717
self.assert_text('Hooray robots!', '#content')
18-
self.open('http://xkcd.com/1319/')
18+
self.open('https://xkcd.com/1319/')
1919
self.assert_text('Automation', 'div#ctitle')
2020

2121
####

examples/my_test_suite.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class MyTestSuite(BaseCase):
77

88
def test_1(self):
9-
self.open("http://xkcd.com/1663/")
9+
self.open("https://xkcd.com/1663/")
1010
self.find_text("Garden", "div#ctitle", timeout=3)
1111
for p in range(4):
1212
self.click('a[rel="next"]')
@@ -15,17 +15,17 @@ def test_1(self):
1515
def test_2(self):
1616
# This test should FAIL
1717
print("\n(This test fails on purpose)")
18-
self.open("http://xkcd.com/1675/")
18+
self.open("https://xkcd.com/1675/")
1919
raise Exception("FAKE EXCEPTION: This test fails on purpose.")
2020

2121
def test_3(self):
22-
self.open("http://xkcd.com/1406/")
22+
self.open("https://xkcd.com/1406/")
2323
self.find_text("Universal Converter Box", "div#ctitle", timeout=3)
24-
self.open("http://xkcd.com/608/")
24+
self.open("https://xkcd.com/608/")
2525
self.find_text("Form", "div#ctitle", timeout=3)
2626

2727
def test_4(self):
2828
# This test should FAIL
2929
print("\n(This test fails on purpose)")
30-
self.open("http://xkcd.com/1670/")
30+
self.open("https://xkcd.com/1670/")
3131
self.find_element("FakeElement.DoesNotExist", timeout=0.5)

examples/test_fail.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
class MyTestClass(BaseCase):
88

99
def test_find_army_of_robots_on_xkcd_desert_island(self):
10-
self.open("http://xkcd.com/731/")
10+
self.open("https://xkcd.com/731/")
1111
print("\n(This test fails on purpose)")
1212
self.assert_element("div#ARMY_OF_ROBOTS", timeout=1)

examples/tour_examples/ReadMe.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,15 @@ class MyTourClass(BaseCase):
9797
```bash
9898
pytest google_tour.py
9999
```
100+
101+
### Exporting a Tour:
102+
103+
If you want to save the tour you created as a Javascript file, use:
104+
105+
``self.export_tour()``
106+
107+
OR
108+
109+
``self.export_tour(name=None, filename="my_tour.js")``
110+
111+
(``name`` is optional, needed only if you were creating multiple tours at once. ``filename`` is the name of the file to save the Javascript to.) Once you've exported your tour, you can use it outside of SeleniumBase. You can even copy the tour's Javascript code to the Console of your web browser to play the tour from there (you need to be on the correct web page for it to work).

examples/tour_examples/xkcd_tour.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from seleniumbase import BaseCase
2+
3+
4+
class MyTestClass(BaseCase):
5+
6+
def test_basic(self):
7+
self.open('https://xkcd.com/1117/')
8+
self.assert_element('img[alt="My Sky"]')
9+
self.create_shepherd_tour()
10+
self.add_tour_step("Welcome to XKCD!")
11+
self.add_tour_step("This is the XKCD logo.", "#masthead img")
12+
self.add_tour_step("Here's the daily webcomic.", "#comic img")
13+
self.add_tour_step("This is the title.", "#ctitle", alignment="top")
14+
self.add_tour_step("Click here for the next comic.", 'a[rel="next"]')
15+
self.add_tour_step("Or here for the previous comic.", 'a[rel="prev"]')
16+
self.add_tour_step("Learn about the author here.", 'a[rel="author"]')
17+
self.add_tour_step("Click for the license here.", 'a[rel="license"]')
18+
self.add_tour_step("This selects a random comic.", 'a[href*="random"]')
19+
self.add_tour_step("Thanks for taking this tour!")
20+
# self.export_tour() # Use this to export the tour as a .js file
21+
self.play_tour()
22+

help_docs/method_summary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ self.add_tour_step(message, selector=None, name=None,
110110

111111
self.play_tour(name=None)
112112

113+
self.export_tour(name=None, filename="my_tour.js")
114+
113115
self.activate_messenger()
114116

115117
self.post_message(message, style="info", duration=None)

seleniumbase/common/ReadMe.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
Example demonstrating a rate-limited printing functionality:
1212
```python
1313
import unittest
14-
from seleniumbase.common import decorators
14+
from seleniumbase import decorators
1515

1616

1717
class MyTestClass(unittest.TestCase):

0 commit comments

Comments
 (0)