Merge pull request #780 from seleniumbase/demo-mode-updates-and-more
Demo Mode updates and more
This commit is contained in:
commit
e489ac299d
|
@ -1,5 +1,5 @@
|
|||
regex>=2020.11.13
|
||||
tqdm>=4.55.2
|
||||
tqdm>=4.56.0
|
||||
livereload==2.6.3;python_version>="3.6"
|
||||
Markdown==3.3.3
|
||||
readme-renderer==28.0
|
||||
|
|
|
@ -5,14 +5,14 @@ class MyChartMakerClass(BaseCase):
|
|||
|
||||
def test_seleniumbase_chart(self):
|
||||
self.create_presentation(theme="league", transition="slide")
|
||||
self.create_pie_chart(title="There are 4 core areas of SeleniumBase:")
|
||||
self.add_data_point("Basic API (Test methods/functions)", 1)
|
||||
self.add_data_point("Command-line Options (pytest Options)", 1)
|
||||
self.create_pie_chart(title="The 4 core areas of SeleniumBase:")
|
||||
self.add_data_point("Basic API (test methods)", 1)
|
||||
self.add_data_point("Command-line options (pytest options)", 1)
|
||||
self.add_data_point("The Console Scripts interface", 1)
|
||||
self.add_data_point("Advanced API (Tours, Charts, & Presentations)", 1)
|
||||
self.add_slide("<p>SeleniumBase core areas</p>" + self.extract_chart())
|
||||
self.add_slide(
|
||||
"<p>Basic API (Test methods/functions) Example</p>",
|
||||
"<p>Basic API (test methods). Example test:</p>",
|
||||
code=(
|
||||
'from seleniumbase import BaseCase\n\n'
|
||||
'class MyTestClass(BaseCase):\n\n'
|
||||
|
@ -27,20 +27,23 @@ class MyChartMakerClass(BaseCase):
|
|||
' self.click_link_text("comic #249")\n'
|
||||
' self.assert_element(\'img[alt*="Chess"]\')\n'))
|
||||
self.add_slide(
|
||||
"<p>Command-line Options Example</p>",
|
||||
"<p>Command-line options. Examples:</p>",
|
||||
code=(
|
||||
'$ pytest my_first_test.py\n'
|
||||
'$ pytest test_swag_labs.py --mobile\n'
|
||||
'$ pytest edge_test.py --browser=edge\n'
|
||||
'$ pytest basic_test.py --headless\n'
|
||||
'$ pytest my_first_test.py --demo\n'
|
||||
'$ pytest my_first_test.py --demo --guest\n'
|
||||
'$ pytest basic_test.py --slow\n'
|
||||
'$ pytest -v -m marker2 --headless --save-screenshot\n'
|
||||
'$ pytest test_suite.py --reuse-session --html=report.html\n'
|
||||
'$ pytest basic_test.py --incognito\n'
|
||||
'$ pytest parameterized_test.py --guest --reuse-session\n'))
|
||||
'$ pytest parameterized_test.py --reuse-session\n'
|
||||
'$ pytest test_suite.py --html=report.html --rs\n'
|
||||
'$ pytest test_suite.py --dashboard --html=report.html\n'
|
||||
'$ pytest github_test.py --demo --disable-csp\n'
|
||||
'$ pytest test_suite.py -n=2 --rs --crumbs\n'
|
||||
'$ pytest basic_test.py --incognito\n'))
|
||||
self.add_slide(
|
||||
"<p>Console scripts interface Example</p>",
|
||||
"<p>The Console Scripts interface. Examples:</p>",
|
||||
code=(
|
||||
'$ sbase install chromedriver\n'
|
||||
'$ sbase install chromedriver latest\n'
|
||||
|
@ -57,7 +60,7 @@ class MyChartMakerClass(BaseCase):
|
|||
'$ sbase grid-hub stop\n'
|
||||
'$ sbase options\n'))
|
||||
self.add_slide(
|
||||
'<p>Advanced API (creating a presentation) Example</p>',
|
||||
'<p>Advanced API. "Presenter" example:</p>',
|
||||
code=(
|
||||
'from seleniumbase import BaseCase\n\n'
|
||||
'class MyPresenterClass(BaseCase):\n\n'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<h2><img src="https://seleniumbase.io/img/sb_icon.png" title="SeleniumBase" width="30" /> Creating a SeleniumBase Test Runner with NodeJS</h2>
|
||||
<h2><img src="https://seleniumbase.io/img/sb_icon.png" title="SeleniumBase" width="30" /> Creating a Test Runner with NodeJS + Express</h2>
|
||||
|
||||
You can create a customized web app for running SeleniumBase tests by using NodeJS. (This tutorial assumes that you've already installed SeleniumBase by following the instructions from the [top-level ReadMe](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md) file.)
|
||||
You can create a customized web app for running SeleniumBase tests by using NodeJS and Express. (This tutorial assumes that you've already installed SeleniumBase by following the instructions from the [top-level ReadMe](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md) file.)
|
||||
|
||||
<img src="https://seleniumbase.io/other/node_runner.png" title="Node Runner" />
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Project information
|
||||
site_name: SeleniumBase
|
||||
site_name: SeleniumBase / Docs
|
||||
site_url: https://seleniumbase.io
|
||||
site_author: Michael Mintz
|
||||
site_description: A fast, reliable web automation framework for end-to-end testing (and RPA) with Python, pytest, and WebDriver.
|
||||
|
@ -30,7 +30,7 @@ theme:
|
|||
sticky_navigation: true
|
||||
language: en
|
||||
include_search_page: false
|
||||
search_index_only: true
|
||||
search_index_only: false
|
||||
features:
|
||||
- tabs
|
||||
- instant
|
||||
|
@ -53,7 +53,7 @@ plugins:
|
|||
on_pre_build: docs.prepare:main
|
||||
# Page tree
|
||||
nav:
|
||||
- SeleniumBase | README: README.md
|
||||
- SeleniumBase / README: README.md
|
||||
- Features List: help_docs/features_list.md
|
||||
- Running Example Tests: examples/ReadMe.md
|
||||
- Command Line Options: help_docs/customizing_test_runs.md
|
||||
|
@ -104,6 +104,7 @@ nav:
|
|||
- TinyMCE Demo Page: https://seleniumbase.io/other/tinymce
|
||||
- Virtual Device Farm: https://seleniumbase.io/devices/
|
||||
- Error Demo Page: https://seleniumbase.io/error_page/
|
||||
- Presentations:
|
||||
- Presenter Demo: https://seleniumbase.io/other/presenter.html
|
||||
- Core Presentation: https://seleniumbase.io/other/core_presentation.html
|
||||
- Chart Maker Demo: https://seleniumbase.io/other/chart_presentation.html
|
||||
|
|
|
@ -64,7 +64,7 @@ ipython==7.19.0;python_version>="3.7"
|
|||
colorama==0.4.4
|
||||
pathlib2==2.3.5;python_version<"3.5"
|
||||
importlib-metadata==2.0.0;python_version<"3.6"
|
||||
virtualenv>=20.2.2
|
||||
virtualenv>=20.3.0
|
||||
pymysql==0.10.1;python_version<"3.6"
|
||||
pymysql==1.0.2;python_version>="3.6"
|
||||
coverage==5.3.1
|
||||
|
@ -76,7 +76,7 @@ toml==0.10.2
|
|||
Pillow==6.2.2;python_version<"3.5"
|
||||
Pillow==7.2.0;python_version>="3.5" and python_version<"3.6"
|
||||
Pillow==8.1.0;python_version>="3.6"
|
||||
rich==9.7.0;python_version>="3.6" and python_version<"4.0"
|
||||
rich==9.8.0;python_version>="3.6" and python_version<"4.0"
|
||||
zipp==1.2.0;python_version<"3.6"
|
||||
zipp==3.4.0;python_version>="3.6"
|
||||
flake8==3.7.9;python_version<"3.5"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "1.51.14"
|
||||
__version__ = "1.52.0"
|
||||
|
|
|
@ -134,6 +134,8 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.SMALL_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
original_selector = selector
|
||||
original_by = by
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
if page_utils.is_link_text_selector(selector) or by == By.LINK_TEXT:
|
||||
if not self.is_link_text_visible(selector):
|
||||
|
@ -148,7 +150,7 @@ class BaseCase(unittest.TestCase):
|
|||
return
|
||||
element = page_actions.wait_for_element_visible(
|
||||
self.driver, selector, by, timeout=timeout)
|
||||
self.__demo_mode_highlight_if_active(selector, by)
|
||||
self.__demo_mode_highlight_if_active(original_selector, original_by)
|
||||
if not self.demo_mode and not self.slow_mode:
|
||||
self.__scroll_to_element(element, selector, by)
|
||||
pre_action_url = self.driver.current_url
|
||||
|
@ -226,10 +228,12 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.SMALL_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
original_selector = selector
|
||||
original_by = by
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
element = page_actions.wait_for_element_visible(
|
||||
self.driver, selector, by, timeout=timeout)
|
||||
self.__demo_mode_highlight_if_active(selector, by)
|
||||
self.__demo_mode_highlight_if_active(original_selector, original_by)
|
||||
if not self.demo_mode and not self.slow_mode:
|
||||
self.__scroll_to_element(element, selector, by)
|
||||
pre_action_url = self.driver.current_url
|
||||
|
@ -1289,13 +1293,15 @@ class BaseCase(unittest.TestCase):
|
|||
"element {%s}!" % selector)
|
||||
|
||||
def hover_on_element(self, selector, by=By.CSS_SELECTOR):
|
||||
original_selector = selector
|
||||
original_by = by
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
if page_utils.is_xpath_selector(selector):
|
||||
selector = self.convert_to_css_selector(selector, By.XPATH)
|
||||
by = By.CSS_SELECTOR
|
||||
self.wait_for_element_visible(
|
||||
selector, by=by, timeout=settings.SMALL_TIMEOUT)
|
||||
self.__demo_mode_highlight_if_active(selector, by)
|
||||
self.__demo_mode_highlight_if_active(original_selector, original_by)
|
||||
self.scroll_to(selector, by=by)
|
||||
time.sleep(0.05) # Settle down from scrolling before hovering
|
||||
if self.browser != "chrome":
|
||||
|
@ -1339,6 +1345,8 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.SMALL_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
original_selector = hover_selector
|
||||
original_by = hover_by
|
||||
hover_selector, hover_by = self.__recalculate_selector(
|
||||
hover_selector, hover_by)
|
||||
hover_selector = self.convert_to_css_selector(
|
||||
|
@ -1348,7 +1356,7 @@ class BaseCase(unittest.TestCase):
|
|||
click_selector, click_by)
|
||||
dropdown_element = self.wait_for_element_visible(
|
||||
hover_selector, by=hover_by, timeout=timeout)
|
||||
self.__demo_mode_highlight_if_active(hover_selector, hover_by)
|
||||
self.__demo_mode_highlight_if_active(original_selector, original_by)
|
||||
self.scroll_to(hover_selector, by=hover_by)
|
||||
pre_action_url = self.driver.current_url
|
||||
outdated_driver = False
|
||||
|
@ -1400,6 +1408,8 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.SMALL_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
original_selector = hover_selector
|
||||
original_by = hover_by
|
||||
hover_selector, hover_by = self.__recalculate_selector(
|
||||
hover_selector, hover_by)
|
||||
hover_selector = self.convert_to_css_selector(
|
||||
|
@ -1409,7 +1419,7 @@ class BaseCase(unittest.TestCase):
|
|||
click_selector, click_by)
|
||||
dropdown_element = self.wait_for_element_visible(
|
||||
hover_selector, by=hover_by, timeout=timeout)
|
||||
self.__demo_mode_highlight_if_active(hover_selector, hover_by)
|
||||
self.__demo_mode_highlight_if_active(original_selector, original_by)
|
||||
self.scroll_to(hover_selector, by=hover_by)
|
||||
pre_action_url = self.driver.current_url
|
||||
outdated_driver = False
|
||||
|
@ -2239,7 +2249,7 @@ class BaseCase(unittest.TestCase):
|
|||
(Default: 4. Each loop lasts for about 0.18s)
|
||||
scroll - the option to scroll to the element first (Default: True)
|
||||
"""
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
element = self.wait_for_element_visible(
|
||||
selector, by=by, timeout=settings.SMALL_TIMEOUT)
|
||||
if not loops:
|
||||
|
@ -2464,7 +2474,7 @@ class BaseCase(unittest.TestCase):
|
|||
def js_click(self, selector, by=By.CSS_SELECTOR, all_matches=False):
|
||||
""" Clicks an element using JavaScript.
|
||||
If "all_matches" is False, only the first match is clicked. """
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
if by == By.LINK_TEXT:
|
||||
message = (
|
||||
"Pure JavaScript doesn't support clicking by Link Text. "
|
||||
|
@ -2504,7 +2514,7 @@ class BaseCase(unittest.TestCase):
|
|||
|
||||
def jquery_click(self, selector, by=By.CSS_SELECTOR):
|
||||
""" Clicks an element using jQuery. Different from using pure JS. """
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
self.wait_for_element_present(
|
||||
selector, by=by, timeout=settings.SMALL_TIMEOUT)
|
||||
if self.is_element_visible(selector, by=by):
|
||||
|
@ -2517,7 +2527,7 @@ class BaseCase(unittest.TestCase):
|
|||
|
||||
def jquery_click_all(self, selector, by=By.CSS_SELECTOR):
|
||||
""" Clicks all matching elements using jQuery. """
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
self.wait_for_element_present(
|
||||
selector, by=by, timeout=settings.SMALL_TIMEOUT)
|
||||
if self.is_element_visible(selector, by=by):
|
||||
|
@ -3137,7 +3147,7 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.LARGE_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
orginal_selector = selector
|
||||
css_selector = self.convert_to_css_selector(selector, by=by)
|
||||
self.__demo_mode_highlight_if_active(orginal_selector, by)
|
||||
|
@ -3249,7 +3259,7 @@ class BaseCase(unittest.TestCase):
|
|||
timeout = settings.LARGE_TIMEOUT
|
||||
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
|
||||
timeout = self.__get_new_timeout(timeout)
|
||||
selector, by = self.__recalculate_selector(selector, by)
|
||||
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
|
||||
element = self.wait_for_element_visible(
|
||||
selector, by=by, timeout=timeout)
|
||||
self.__demo_mode_highlight_if_active(selector, by)
|
||||
|
@ -6063,8 +6073,10 @@ class BaseCase(unittest.TestCase):
|
|||
pass
|
||||
return False
|
||||
|
||||
def __recalculate_selector(self, selector, by):
|
||||
# Use auto-detection to return the correct selector with "by" updated
|
||||
def __recalculate_selector(self, selector, by, xp_ok=True):
|
||||
""" Use autodetection to return the correct selector with "by" updated.
|
||||
If "xp_ok" is False, don't call convert_css_to_xpath(), which is
|
||||
used to make the ":contains()" selector valid outside JS calls. """
|
||||
_type = type(selector) # First make sure the selector is a string
|
||||
if _type is not str:
|
||||
msg = 'Expecting a selector of type: "<class \'str\'>" (string)!'
|
||||
|
@ -6081,9 +6093,10 @@ class BaseCase(unittest.TestCase):
|
|||
name = page_utils.get_name_from_selector(selector)
|
||||
selector = '[name="%s"]' % name
|
||||
by = By.CSS_SELECTOR
|
||||
if ":contains(" in selector and by == By.CSS_SELECTOR:
|
||||
selector = self.convert_css_to_xpath(selector)
|
||||
by = By.XPATH
|
||||
if xp_ok:
|
||||
if ":contains(" in selector and by == By.CSS_SELECTOR:
|
||||
selector = self.convert_css_to_xpath(selector)
|
||||
by = By.XPATH
|
||||
return (selector, by)
|
||||
|
||||
def __looks_like_a_page_url(self, url):
|
||||
|
|
|
@ -90,7 +90,7 @@ class Messenger:
|
|||
|
||||
|
||||
class Underscore:
|
||||
VER = "1.10.2"
|
||||
VER = "1.12.0"
|
||||
MIN_JS = ("https://cdnjs.cloudflare.com/ajax/libs/"
|
||||
"underscore.js/%s/underscore-min.js" % VER)
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class ConvertibleToCssTranslator(GenericTranslator):
|
|||
|
||||
def xpath_class(self, class_selector):
|
||||
xpath = self.xpath(class_selector.selector)
|
||||
return self.xpath_attrib_equals(
|
||||
return self.xpath_attrib_includes(
|
||||
xpath, '@class', class_selector.class_name)
|
||||
|
||||
def xpath_descendant_combinator(self, left, right):
|
||||
|
|
|
@ -475,20 +475,30 @@ def activate_messenger(driver):
|
|||
add_js_link(driver, underscore_js)
|
||||
add_css_link(driver, spinner_css)
|
||||
add_js_link(driver, messenger_js)
|
||||
add_js_link(driver, msgr_theme_flat_js)
|
||||
add_js_link(driver, msgr_theme_future_js)
|
||||
from seleniumbase.core import style_sheet
|
||||
add_css_style(driver, style_sheet.messenger_style)
|
||||
|
||||
for x in range(int(settings.MINI_TIMEOUT * 10.0)):
|
||||
# Messenger needs a small amount of time to load & activate.
|
||||
try:
|
||||
driver.execute_script(msg_style)
|
||||
wait_for_ready_state_complete(driver)
|
||||
wait_for_angularjs(driver)
|
||||
return
|
||||
result = (driver.execute_script(
|
||||
""" if (typeof Messenger === 'undefined') { return "U"; } """))
|
||||
if result == "U":
|
||||
time.sleep(0.01)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
except Exception:
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.01)
|
||||
try:
|
||||
driver.execute_script(msg_style)
|
||||
add_js_link(driver, msgr_theme_flat_js)
|
||||
add_js_link(driver, msgr_theme_future_js)
|
||||
wait_for_ready_state_complete(driver)
|
||||
wait_for_angularjs(driver)
|
||||
return
|
||||
except Exception:
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
def set_messenger_theme(driver, theme="default", location="default",
|
||||
|
|
6
setup.py
6
setup.py
|
@ -49,7 +49,7 @@ if sys.argv[-1] == 'publish':
|
|||
print("\n*** Installing twine: *** (Required for PyPI uploads)\n")
|
||||
os.system("python -m pip install --upgrade 'twine>=1.15.0'")
|
||||
print("\n*** Installing tqdm: *** (Required for PyPI uploads)\n")
|
||||
os.system("python -m pip install --upgrade 'tqdm>=4.55.2'")
|
||||
os.system("python -m pip install --upgrade 'tqdm>=4.56.0'")
|
||||
print("\n*** Publishing The Release to PyPI: ***\n")
|
||||
os.system('python -m twine upload dist/*') # Requires ~/.pypirc Keys
|
||||
print("\n*** The Release was PUBLISHED SUCCESSFULLY to PyPI! :) ***\n")
|
||||
|
@ -168,7 +168,7 @@ setup(
|
|||
'colorama==0.4.4',
|
||||
'pathlib2==2.3.5;python_version<"3.5"', # Sync with "virtualenv"
|
||||
'importlib-metadata==2.0.0;python_version<"3.6"', # Sync "virtualenv"
|
||||
'virtualenv>=20.2.2', # Sync with importlib-metadata and pathlib2
|
||||
'virtualenv>=20.3.0', # Sync with importlib-metadata and pathlib2
|
||||
'pymysql==0.10.1;python_version<"3.6"',
|
||||
'pymysql==1.0.2;python_version>="3.6"',
|
||||
'coverage==5.3.1',
|
||||
|
@ -180,7 +180,7 @@ setup(
|
|||
'Pillow==6.2.2;python_version<"3.5"',
|
||||
'Pillow==7.2.0;python_version>="3.5" and python_version<"3.6"',
|
||||
'Pillow==8.1.0;python_version>="3.6"',
|
||||
'rich==9.7.0;python_version>="3.6" and python_version<"4.0"',
|
||||
'rich==9.8.0;python_version>="3.6" and python_version<"4.0"',
|
||||
'zipp==1.2.0;python_version<"3.6"',
|
||||
'zipp==3.4.0;python_version>="3.6"',
|
||||
'flake8==3.7.9;python_version<"3.5"',
|
||||
|
|
Loading…
Reference in New Issue