Skip to content

Add SeleniumBase "Presenter" #601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ archived_logs
geckodriver.log
pytestdebug.log

# Presentations
presentations_saved

# Reports
latest_report
report_archives
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,21 @@ Tests are run with "pytest". Browsers are controlled by WebDriver.
</p>

<p align="center">
<a href="#python_installation">🚀 Get Started</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🧙‍♂️ CMD Options</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🏰 Features</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">👨‍🏫 Examples</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱 Mobile Testing</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊 Reports</a>
<a href="#python_installation">🚀Get Started</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🧙‍♂️CMD Options</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🏰Features</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">👨‍🏫Examples</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊Reports</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱Mobile</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖CI</a>
<br />
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📖 API</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📖API</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">🗺️ Tours</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌎 Languages</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md">⏺️ Recorder</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂 MasterQA</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">👩‍🎨 Visual Tests</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖 GitHub-CI</a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌎Languages</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/ReadMe.md">📰Presenter</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md">⏺️Recorder</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">👩‍🎨Visual Tests</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂MasterQA</a>
</p>

<p align="center"><img src="https://cdn2.hubspot.net/hubfs/100006/images/swag_labs_gif.gif" alt="SeleniumBase" title="SeleniumBase" /></p>
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
livereload==2.6.2;python_version>="3.6"
mkdocs==1.1.2
mkdocs-material==5.3.0
mkdocs-material==5.3.3
mkdocs-simple-hooks==0.1.1
mkdocs-material-extensions==1.0
mkdocs-minify-plugin==0.3.0
149 changes: 149 additions & 0 deletions examples/presenter/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<h3 align="left"><img src="https://cdn2.hubspot.net/hubfs/100006/images/super_logo_sb23.png" alt="SeleniumBase" width="290" /></h3>

# 📰 Presenter 📰

SeleniumBase Presenter allows you to create an HTML presentation with only a few lines of Python.
The Reveal-JS library is used for running the presentations.

**Here's a sample slide:**

<img src="https://seleniumbase.io/other/presenter_screen.png" title="Screenshot"><br>

Slides can include HTML, code, images, and iframes.

Here's how to run the example presentation:
```
cd examples/presenter
pytest my_presentation.py
```


### Creating a new presentation:

```python
self.create_presentation(name=None, show_notes=True)
""" Creates a Reveal-JS presentation that you can add slides to.
@Params
name - If creating multiple presentations at the same time,
use this to specify the name of the current presentation.
show_notes - When set to True, the Notes feature becomes enabled,
which allows presenters to see notes next to slides.
"""
```

If creating multiple presentations at the same time, you can pass the ``name`` parameter to distinguish between different presentations.
Notes are enabled by default unless you specify:
``show_notes=False`` when calling.


### Adding a slide to a presentation:

```python
self.add_slide(content=None, image=None, code=None, iframe=None,
notes=None, name=None)
""" Allows the user to add slides to a presentation.
@Params
content - The HTML content to display on the presentation slide.
image - Attach an image (from a URL link) to the slide.
code - Attach code of any programming language to the slide.
Language-detection will be used to add syntax formatting.
iframe - Attach an iFrame (from a URL link) to the slide.
notes - Additional notes to include with the slide.
ONLY SEEN if show_notes is set for the presentation.
name - If creating multiple presentations at the same time,
use this to select the presentation to add slides to.
"""
```


### Running a presentation:

```python
self.begin_presentation(filename="my_presentation.html", name=None)
""" Begin a Reveal-JS Presentation in the web browser. """
```

Before the presentation is run, the full HTML is saved to the ``presentations_saved/`` folder.


All methods have the optional ``name`` argument, which is only needed if you're creating multiple presentations at once.

### Here's an example of using SeleniumBase Presenter:

```python
from seleniumbase import BaseCase


class MyPresenterClass(BaseCase):

def test_presenter(self):
self.create_presentation()
self.add_slide(
"<h2>Welcome!</h2>"
"<h4>Enjoy the Presentation!</h4>")
self.add_slide(
'<h3>SeleniumBase "Presenter"</h3>'
'<img src="https://seleniumbase.io/img/logo3a.png"></img>'
'<h4>A tool for creating presentations</h4>')
self.add_slide(
'<h3>You can add HTML to any slide:</h3><br />'
'<table style="padding:10px;border:4px solid black;font-size:60;">'
'<tr><th>Row 1</th><th>Row 2</th></tr>'
'<tr><td>Value 1</td><td>Value 2</td></tr></table><br />'
'<h4>(HTML table example)</h4>')
self.add_slide(
"<h3>You can display code:</h3>",
code=(
'from seleniumbase import BaseCase\n\n'
'class MyTestClass(BaseCase):\n\n'
' def test_basic(self):\n'
' self.open("https://store.xkcd.com/search")\n'
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'
' self.assert_text("xkcd: volume 0", "h3")\n'
' self.open("https://xkcd.com/353/")\n'
' self.assert_title("xkcd: Python")\n'
' self.assert_element(\'img[alt="Python"]\')\n'
' self.click(\'a[rel="license"]\')\n'
' self.assert_text("free to copy and reuse")\n'
' self.go_back()\n'
' self.click_link_text("About")\n'
' self.assert_exact_text("xkcd.com", "h2")\n'))
self.add_slide(
"<h3>You can highlight code:</h3>",
code=(
'from seleniumbase import BaseCase\n\n'
'<mark>class MyTestClass(BaseCase):</mark>\n\n'
' def test_basic(self):\n'
' self.open("https://store.xkcd.com/search")\n'
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'))
self.add_slide(
"<h3>You can add notes to slides:</h3>",
notes="<h2><ul><li>Note A!<li>Note B!<li>Note C!<li>Note D!</h2>")
self.add_slide(
"<h3>You can add images to slides:</h3>",
image="https://seleniumbase.io/img/sb_logo_10.png")
self.add_slide(
"<h3>You can add iframes to slides:</h3>",
iframe="https://seleniumbase.io/demo_page")
self.add_slide("<h1>The End</h1>")
self.begin_presentation()
```

#### 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:

```bash
pytest my_presentation.py
```

### Saving a presentation:

If you want to save the presentation you created as an HTML file, use:

```python
self.save_presentation(filename="my_presentation.html", name=None)
```

Presentations automatically get saved when calling:
```python
self.begin_presentation()
```
56 changes: 56 additions & 0 deletions examples/presenter/my_presentation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from seleniumbase import BaseCase


class MyPresenterClass(BaseCase):

def test_presenter(self):
self.create_presentation()
self.add_slide(
"<h2>Welcome!</h2>"
"<h4>Enjoy the Presentation!</h4>")
self.add_slide(
'<h3>SeleniumBase "Presenter"</h3>'
'<img src="https://seleniumbase.io/img/logo3a.png"></img>'
'<h4>A tool for creating presentations</h4>')
self.add_slide(
'<h3>You can add HTML to any slide:</h3><br />'
'<table style="padding:10px;border:4px solid black;font-size:60;">'
'<tr><th>Row 1</th><th>Row 2</th></tr>'
'<tr><td>Value 1</td><td>Value 2</td></tr></table><br />'
'<h4>(HTML table example)</h4>')
self.add_slide(
"<h3>You can display code:</h3>",
code=(
'from seleniumbase import BaseCase\n\n'
'class MyTestClass(BaseCase):\n\n'
' def test_basic(self):\n'
' self.open("https://store.xkcd.com/search")\n'
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'
' self.assert_text("xkcd: volume 0", "h3")\n'
' self.open("https://xkcd.com/353/")\n'
' self.assert_title("xkcd: Python")\n'
' self.assert_element(\'img[alt="Python"]\')\n'
' self.click(\'a[rel="license"]\')\n'
' self.assert_text("free to copy and reuse")\n'
' self.go_back()\n'
' self.click_link_text("About")\n'
' self.assert_exact_text("xkcd.com", "h2")\n'))
self.add_slide(
"<h3>You can highlight code:</h3>",
code=(
'from seleniumbase import BaseCase\n\n'
'<mark>class MyTestClass(BaseCase):</mark>\n\n'
' def test_basic(self):\n'
' self.open("https://store.xkcd.com/search")\n'
' self.type(\'input[name="q"]\', "xkcd book\\n")\n'))
self.add_slide(
"<h3>You can add notes to slides:</h3>",
notes="<h2><ul><li>Note A!<li>Note B!<li>Note C!<li>Note D!</h2>")
self.add_slide(
"<h3>You can add images to slides:</h3>",
image="https://seleniumbase.io/img/sb_logo_10.png")
self.add_slide(
"<h3>You can add iframes to slides:</h3>",
iframe="https://seleniumbase.io/demo_page")
self.add_slide("<h1>The End</h1>")
self.begin_presentation()
34 changes: 34 additions & 0 deletions examples/tour_examples/maps_introjs_tour.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from seleniumbase import BaseCase


class MyTourClass(BaseCase):

def test_google_maps_tour(self):
self.open("https://www.google.com/maps/@42.3598616,-71.0912631,15z")
self.wait_for_element("#searchboxinput")
self.wait_for_element("#minimap")
self.wait_for_element("#zoom")

self.create_tour(theme="introjs")
self.add_tour_step("Welcome to Google Maps!",
title="✅ SeleniumBase Tours 🌎")
self.add_tour_step("Type in a location here.", "#searchboxinput",
title="Search Box")
self.add_tour_step("Then click here to show it on the map.",
"#searchbox-searchbutton", alignment="bottom")
self.add_tour_step("Or click here to get driving directions.",
"#searchbox-directions", alignment="bottom")
self.add_tour_step("Use this button to switch to Satellite view.",
"#minimap div.widget-minimap", alignment="right")
self.add_tour_step("Click here to zoom in.", "#widget-zoom-in",
alignment="left")
self.add_tour_step("Or click here to zoom out.", "#widget-zoom-out",
alignment="left")
self.add_tour_step("Use the Menu button to see more options.",
".searchbox-hamburger-container", alignment="right")
self.add_tour_step("Or click here to see more Google apps.",
'[title="Google apps"]', alignment="left")
self.add_tour_step("Thanks for using SeleniumBase Tours!",
title="🚃 End of Guided Tour 🚃")
self.export_tour(filename="google_maps_introjs_tour.js")
self.play_tour()
10 changes: 10 additions & 0 deletions help_docs/method_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,16 @@ self.add_meta_tag(http_equiv=None, content=None)

############

self.create_presentation(name=None, show_notes=True)

self.add_slide(content=None, image=None, code=None, iframe=None, notes=None, name=None)

self.save_presentation(filename="my_presentation.html", name=None)

self.begin_presentation(filename="my_presentation.html", name=None)

############

self.create_tour(name=None, theme=None)

self.create_shepherd_tour(name=None, theme=None)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ nav:
- Console Scripts: seleniumbase/console_scripts/ReadMe.md
- JS Package Manager: help_docs/js_package_manager.md
- Site Tours: examples/tour_examples/ReadMe.md
- Presenter: examples/presenter/ReadMe.md
- Visual Testing: examples/visual_testing/ReadMe.md
- Integrations:
- Logging and Reports: examples/example_logs/ReadMe.md
Expand Down
13 changes: 6 additions & 7 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@ setuptools-scm>=4.1.2
wheel>=0.34.2
six==1.15.0
nose==1.3.7
ipdb==0.13.2
ipdb==0.13.3
idna==2.9
chardet==3.0.4
urllib3==1.25.9
requests==2.24.0
selenium==3.141.0
pluggy==0.13.1
attrs>=19.3.0
py==1.8.1;sys_platform=="win32"
py==1.8.2;sys_platform!="win32"
py==1.8.1
pytest==4.6.11;python_version<"3.5"
pytest==5.4.3;python_version>="3.5"
pytest-cov==2.10.0
pytest-forked==1.1.3
pytest-forked==1.2.0
pytest-html==1.22.1;python_version<"3.6"
pytest-html==2.0.1;python_version>="3.6"
pytest-metadata==1.8.0;python_version<"3.6"
pytest-metadata==1.9.0;python_version>="3.6"
pytest-metadata==1.10.0;python_version>="3.6"
pytest-ordering==0.6
pytest-rerunfailures==8.0;python_version<"3.6"
pytest-rerunfailures==9.0;python_version>="3.6"
Expand All @@ -43,11 +42,11 @@ coverage==5.1
pyotp==2.3.0
boto==2.49.0
cffi==1.14.0
rich==2.2.3;python_version>="3.6" and python_version<"4.0"
rich==2.2.6;python_version>="3.6" and python_version<"4.0"
flake8==3.7.9;python_version<"3.5"
flake8==3.8.3;python_version>="3.5"
pyflakes==2.1.1;python_version<"3.5"
pyflakes==2.2.0;python_version>="3.5"
certifi>=2020.4.5.2
certifi>=2020.6.20
pdfminer.six==20191110;python_version<"3.5"
pdfminer.six==20200517;python_version>="3.5"
7 changes: 7 additions & 0 deletions seleniumbase/console_scripts/sb_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,13 @@ def main():
if console_width and (code_width + extra_r_spaces < console_width):
used_width = code_width + extra_r_spaces

try:
if "🗺️" in the_code:
# Fix width of an emoji
the_code = the_code.replace("🗺️", "🗺️ ")
except Exception:
pass

magic_syntax = Syntax(
the_code, code_lang, theme="monokai",
line_numbers=line_numbers, code_width=used_width,
Expand Down
Loading