Skip to content

Commit fcebb6e

Browse files
authored
Merge pull request #601 from seleniumbase/seleniumbase-presenter
Add Seleniumbase "Presenter"
2 parents 16436b7 + ccde2ef commit fcebb6e

File tree

13 files changed

+456
-27
lines changed

13 files changed

+456
-27
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ archived_logs
7474
geckodriver.log
7575
pytestdebug.log
7676

77+
# Presentations
78+
presentations_saved
79+
7780
# Reports
7881
latest_report
7982
report_archives

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,21 @@ Tests are run with "pytest". Browsers are controlled by WebDriver.
2727
</p>
2828

2929
<p align="center">
30-
<a href="#python_installation">🚀 Get Started</a> |
31-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🧙‍♂️ CMD Options</a> |
32-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🏰 Features</a> |
33-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">👨‍🏫 Examples</a> |
34-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱 Mobile Testing</a> |
35-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊 Reports</a>
30+
<a href="#python_installation">🚀Get Started</a> |
31+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🧙‍♂️CMD Options</a> |
32+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🏰Features</a> |
33+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">👨‍🏫Examples</a> |
34+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊Reports</a> |
35+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱Mobile</a> |
36+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖CI</a>
3637
<br />
37-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📖 API</a> |
38+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📖API</a> |
3839
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">🗺️ Tours</a> |
39-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌎 Languages</a> |
40-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md">⏺️ Recorder</a> |
41-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂 MasterQA</a> |
42-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">👩‍🎨 Visual Tests</a> |
43-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖 GitHub-CI</a>
40+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌎Languages</a> |
41+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/ReadMe.md">📰Presenter</a> |
42+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md">⏺️Recorder</a> |
43+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">👩‍🎨Visual Tests</a> |
44+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂MasterQA</a>
4445
</p>
4546

4647
<p align="center"><img src="https://cdn2.hubspot.net/hubfs/100006/images/swag_labs_gif.gif" alt="SeleniumBase" title="SeleniumBase" /></p>

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
livereload==2.6.2;python_version>="3.6"
22
mkdocs==1.1.2
3-
mkdocs-material==5.3.0
3+
mkdocs-material==5.3.3
44
mkdocs-simple-hooks==0.1.1
55
mkdocs-material-extensions==1.0
66
mkdocs-minify-plugin==0.3.0

examples/presenter/ReadMe.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<h3 align="left"><img src="https://cdn2.hubspot.net/hubfs/100006/images/super_logo_sb23.png" alt="SeleniumBase" width="290" /></h3>
2+
3+
# 📰 Presenter 📰
4+
5+
SeleniumBase Presenter allows you to create an HTML presentation with only a few lines of Python.
6+
The Reveal-JS library is used for running the presentations.
7+
8+
**Here's a sample slide:**
9+
10+
<img src="https://seleniumbase.io/other/presenter_screen.png" title="Screenshot"><br>
11+
12+
Slides can include HTML, code, images, and iframes.
13+
14+
Here's how to run the example presentation:
15+
```
16+
cd examples/presenter
17+
pytest my_presentation.py
18+
```
19+
20+
21+
### Creating a new presentation:
22+
23+
```python
24+
self.create_presentation(name=None, show_notes=True)
25+
""" Creates a Reveal-JS presentation that you can add slides to.
26+
@Params
27+
name - If creating multiple presentations at the same time,
28+
use this to specify the name of the current presentation.
29+
show_notes - When set to True, the Notes feature becomes enabled,
30+
which allows presenters to see notes next to slides.
31+
"""
32+
```
33+
34+
If creating multiple presentations at the same time, you can pass the ``name`` parameter to distinguish between different presentations.
35+
Notes are enabled by default unless you specify:
36+
``show_notes=False`` when calling.
37+
38+
39+
### Adding a slide to a presentation:
40+
41+
```python
42+
self.add_slide(content=None, image=None, code=None, iframe=None,
43+
notes=None, name=None)
44+
""" Allows the user to add slides to a presentation.
45+
@Params
46+
content - The HTML content to display on the presentation slide.
47+
image - Attach an image (from a URL link) to the slide.
48+
code - Attach code of any programming language to the slide.
49+
Language-detection will be used to add syntax formatting.
50+
iframe - Attach an iFrame (from a URL link) to the slide.
51+
notes - Additional notes to include with the slide.
52+
ONLY SEEN if show_notes is set for the presentation.
53+
name - If creating multiple presentations at the same time,
54+
use this to select the presentation to add slides to.
55+
"""
56+
```
57+
58+
59+
### Running a presentation:
60+
61+
```python
62+
self.begin_presentation(filename="my_presentation.html", name=None)
63+
""" Begin a Reveal-JS Presentation in the web browser. """
64+
```
65+
66+
Before the presentation is run, the full HTML is saved to the ``presentations_saved/`` folder.
67+
68+
69+
All methods have the optional ``name`` argument, which is only needed if you're creating multiple presentations at once.
70+
71+
### Here's an example of using SeleniumBase Presenter:
72+
73+
```python
74+
from seleniumbase import BaseCase
75+
76+
77+
class MyPresenterClass(BaseCase):
78+
79+
def test_presenter(self):
80+
self.create_presentation()
81+
self.add_slide(
82+
"<h2>Welcome!</h2>"
83+
"<h4>Enjoy the Presentation!</h4>")
84+
self.add_slide(
85+
'<h3>SeleniumBase "Presenter"</h3>'
86+
'<img src="https://seleniumbase.io/img/logo3a.png"></img>'
87+
'<h4>A tool for creating presentations</h4>')
88+
self.add_slide(
89+
'<h3>You can add HTML to any slide:</h3><br />'
90+
'<table style="padding:10px;border:4px solid black;font-size:60;">'
91+
'<tr><th>Row 1</th><th>Row 2</th></tr>'
92+
'<tr><td>Value 1</td><td>Value 2</td></tr></table><br />'
93+
'<h4>(HTML table example)</h4>')
94+
self.add_slide(
95+
"<h3>You can display code:</h3>",
96+
code=(
97+
'from seleniumbase import BaseCase\n\n'
98+
'class MyTestClass(BaseCase):\n\n'
99+
' def test_basic(self):\n'
100+
' self.open("https://store.xkcd.com/search")\n'
101+
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'
102+
' self.assert_text("xkcd: volume 0", "h3")\n'
103+
' self.open("https://xkcd.com/353/")\n'
104+
' self.assert_title("xkcd: Python")\n'
105+
' self.assert_element(\'img[alt="Python"]\')\n'
106+
' self.click(\'a[rel="license"]\')\n'
107+
' self.assert_text("free to copy and reuse")\n'
108+
' self.go_back()\n'
109+
' self.click_link_text("About")\n'
110+
' self.assert_exact_text("xkcd.com", "h2")\n'))
111+
self.add_slide(
112+
"<h3>You can highlight code:</h3>",
113+
code=(
114+
'from seleniumbase import BaseCase\n\n'
115+
'<mark>class MyTestClass(BaseCase):</mark>\n\n'
116+
' def test_basic(self):\n'
117+
' self.open("https://store.xkcd.com/search")\n'
118+
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'))
119+
self.add_slide(
120+
"<h3>You can add notes to slides:</h3>",
121+
notes="<h2><ul><li>Note A!<li>Note B!<li>Note C!<li>Note D!</h2>")
122+
self.add_slide(
123+
"<h3>You can add images to slides:</h3>",
124+
image="https://seleniumbase.io/img/sb_logo_10.png")
125+
self.add_slide(
126+
"<h3>You can add iframes to slides:</h3>",
127+
iframe="https://seleniumbase.io/demo_page")
128+
self.add_slide("<h1>The End</h1>")
129+
self.begin_presentation()
130+
```
131+
132+
#### This example is from [my_presentation.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/my_presentation.py), which you can run from the ``examples/presenter`` folder with the following command:
133+
134+
```bash
135+
pytest my_presentation.py
136+
```
137+
138+
### Saving a presentation:
139+
140+
If you want to save the presentation you created as an HTML file, use:
141+
142+
```python
143+
self.save_presentation(filename="my_presentation.html", name=None)
144+
```
145+
146+
Presentations automatically get saved when calling:
147+
```python
148+
self.begin_presentation()
149+
```

examples/presenter/my_presentation.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from seleniumbase import BaseCase
2+
3+
4+
class MyPresenterClass(BaseCase):
5+
6+
def test_presenter(self):
7+
self.create_presentation()
8+
self.add_slide(
9+
"<h2>Welcome!</h2>"
10+
"<h4>Enjoy the Presentation!</h4>")
11+
self.add_slide(
12+
'<h3>SeleniumBase "Presenter"</h3>'
13+
'<img src="https://seleniumbase.io/img/logo3a.png"></img>'
14+
'<h4>A tool for creating presentations</h4>')
15+
self.add_slide(
16+
'<h3>You can add HTML to any slide:</h3><br />'
17+
'<table style="padding:10px;border:4px solid black;font-size:60;">'
18+
'<tr><th>Row 1</th><th>Row 2</th></tr>'
19+
'<tr><td>Value 1</td><td>Value 2</td></tr></table><br />'
20+
'<h4>(HTML table example)</h4>')
21+
self.add_slide(
22+
"<h3>You can display code:</h3>",
23+
code=(
24+
'from seleniumbase import BaseCase\n\n'
25+
'class MyTestClass(BaseCase):\n\n'
26+
' def test_basic(self):\n'
27+
' self.open("https://store.xkcd.com/search")\n'
28+
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'
29+
' self.assert_text("xkcd: volume 0", "h3")\n'
30+
' self.open("https://xkcd.com/353/")\n'
31+
' self.assert_title("xkcd: Python")\n'
32+
' self.assert_element(\'img[alt="Python"]\')\n'
33+
' self.click(\'a[rel="license"]\')\n'
34+
' self.assert_text("free to copy and reuse")\n'
35+
' self.go_back()\n'
36+
' self.click_link_text("About")\n'
37+
' self.assert_exact_text("xkcd.com", "h2")\n'))
38+
self.add_slide(
39+
"<h3>You can highlight code:</h3>",
40+
code=(
41+
'from seleniumbase import BaseCase\n\n'
42+
'<mark>class MyTestClass(BaseCase):</mark>\n\n'
43+
' def test_basic(self):\n'
44+
' self.open("https://store.xkcd.com/search")\n'
45+
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'))
46+
self.add_slide(
47+
"<h3>You can add notes to slides:</h3>",
48+
notes="<h2><ul><li>Note A!<li>Note B!<li>Note C!<li>Note D!</h2>")
49+
self.add_slide(
50+
"<h3>You can add images to slides:</h3>",
51+
image="https://seleniumbase.io/img/sb_logo_10.png")
52+
self.add_slide(
53+
"<h3>You can add iframes to slides:</h3>",
54+
iframe="https://seleniumbase.io/demo_page")
55+
self.add_slide("<h1>The End</h1>")
56+
self.begin_presentation()
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from seleniumbase import BaseCase
2+
3+
4+
class MyTourClass(BaseCase):
5+
6+
def test_google_maps_tour(self):
7+
self.open("https://www.google.com/maps/@42.3598616,-71.0912631,15z")
8+
self.wait_for_element("#searchboxinput")
9+
self.wait_for_element("#minimap")
10+
self.wait_for_element("#zoom")
11+
12+
self.create_tour(theme="introjs")
13+
self.add_tour_step("Welcome to Google Maps!",
14+
title="✅ SeleniumBase Tours 🌎")
15+
self.add_tour_step("Type in a location here.", "#searchboxinput",
16+
title="Search Box")
17+
self.add_tour_step("Then click here to show it on the map.",
18+
"#searchbox-searchbutton", alignment="bottom")
19+
self.add_tour_step("Or click here to get driving directions.",
20+
"#searchbox-directions", alignment="bottom")
21+
self.add_tour_step("Use this button to switch to Satellite view.",
22+
"#minimap div.widget-minimap", alignment="right")
23+
self.add_tour_step("Click here to zoom in.", "#widget-zoom-in",
24+
alignment="left")
25+
self.add_tour_step("Or click here to zoom out.", "#widget-zoom-out",
26+
alignment="left")
27+
self.add_tour_step("Use the Menu button to see more options.",
28+
".searchbox-hamburger-container", alignment="right")
29+
self.add_tour_step("Or click here to see more Google apps.",
30+
'[title="Google apps"]', alignment="left")
31+
self.add_tour_step("Thanks for using SeleniumBase Tours!",
32+
title="🚃 End of Guided Tour 🚃")
33+
self.export_tour(filename="google_maps_introjs_tour.js")
34+
self.play_tour()

help_docs/method_summary.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,16 @@ self.add_meta_tag(http_equiv=None, content=None)
356356

357357
############
358358

359+
self.create_presentation(name=None, show_notes=True)
360+
361+
self.add_slide(content=None, image=None, code=None, iframe=None, notes=None, name=None)
362+
363+
self.save_presentation(filename="my_presentation.html", name=None)
364+
365+
self.begin_presentation(filename="my_presentation.html", name=None)
366+
367+
############
368+
359369
self.create_tour(name=None, theme=None)
360370

361371
self.create_shepherd_tour(name=None, theme=None)

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ nav:
7373
- Console Scripts: seleniumbase/console_scripts/ReadMe.md
7474
- JS Package Manager: help_docs/js_package_manager.md
7575
- Site Tours: examples/tour_examples/ReadMe.md
76+
- Presenter: examples/presenter/ReadMe.md
7677
- Visual Testing: examples/visual_testing/ReadMe.md
7778
- Integrations:
7879
- Logging and Reports: examples/example_logs/ReadMe.md

requirements.txt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,23 @@ setuptools-scm>=4.1.2
66
wheel>=0.34.2
77
six==1.15.0
88
nose==1.3.7
9-
ipdb==0.13.2
9+
ipdb==0.13.3
1010
idna==2.9
1111
chardet==3.0.4
1212
urllib3==1.25.9
1313
requests==2.24.0
1414
selenium==3.141.0
1515
pluggy==0.13.1
1616
attrs>=19.3.0
17-
py==1.8.1;sys_platform=="win32"
18-
py==1.8.2;sys_platform!="win32"
17+
py==1.8.1
1918
pytest==4.6.11;python_version<"3.5"
2019
pytest==5.4.3;python_version>="3.5"
2120
pytest-cov==2.10.0
22-
pytest-forked==1.1.3
21+
pytest-forked==1.2.0
2322
pytest-html==1.22.1;python_version<"3.6"
2423
pytest-html==2.0.1;python_version>="3.6"
2524
pytest-metadata==1.8.0;python_version<"3.6"
26-
pytest-metadata==1.9.0;python_version>="3.6"
25+
pytest-metadata==1.10.0;python_version>="3.6"
2726
pytest-ordering==0.6
2827
pytest-rerunfailures==8.0;python_version<"3.6"
2928
pytest-rerunfailures==9.0;python_version>="3.6"
@@ -43,11 +42,11 @@ coverage==5.1
4342
pyotp==2.3.0
4443
boto==2.49.0
4544
cffi==1.14.0
46-
rich==2.2.3;python_version>="3.6" and python_version<"4.0"
45+
rich==2.2.6;python_version>="3.6" and python_version<"4.0"
4746
flake8==3.7.9;python_version<"3.5"
4847
flake8==3.8.3;python_version>="3.5"
4948
pyflakes==2.1.1;python_version<"3.5"
5049
pyflakes==2.2.0;python_version>="3.5"
51-
certifi>=2020.4.5.2
50+
certifi>=2020.6.20
5251
pdfminer.six==20191110;python_version<"3.5"
5352
pdfminer.six==20200517;python_version>="3.5"

seleniumbase/console_scripts/sb_print.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,13 @@ def main():
342342
if console_width and (code_width + extra_r_spaces < console_width):
343343
used_width = code_width + extra_r_spaces
344344

345+
try:
346+
if "🗺️" in the_code:
347+
# Fix width of an emoji
348+
the_code = the_code.replace("🗺️", "🗺️ ")
349+
except Exception:
350+
pass
351+
345352
magic_syntax = Syntax(
346353
the_code, code_lang, theme="monokai",
347354
line_numbers=line_numbers, code_width=used_width,

0 commit comments

Comments
 (0)