Skip to content

Commit d36d54e

Browse files
authored
Merge pull request #144 from seleniumbase/new-features
Adding new features and improving on older ones.
2 parents d3f740c + cee9f39 commit d36d54e

File tree

17 files changed

+453
-140
lines changed

17 files changed

+453
-140
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
![](https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo8s.png "SeleniumBase")
22

3+
**WebDriver automation simplified by extending Python's unittest framework.**
4+
35
[![](https://img.shields.io/pypi/v/seleniumbase.svg)](https://pypi.python.org/pypi/seleniumbase) [![Build Status](https://travis-ci.org/seleniumbase/SeleniumBase.svg?branch=master)](https://travis-ci.org/seleniumbase/SeleniumBase) [![Join the chat at https://gitter.im/seleniumbase/SeleniumBase](https://badges.gitter.im/seleniumbase/SeleniumBase.svg)](https://gitter.im/seleniumbase/SeleniumBase?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
46

5-
**The Future of Web Automation & Testing**
7+
SeleniumBase simplifies web automation & testing with WebDriver in the same way that jQuery, AnglularJS, and ReactJS simplify web development with JavaScript. All tests using SeleniumBase's BaseCase class inherit Python's unittest.TestCase class, which allows for running tests automatically with Pytest and Nosetest. This framework can use the Page Object Model for test structure, as well as all features of WebDriver and Python's unittest.
68

79
![](https://cdn2.hubspot.net/hubfs/100006/images/sb_demo.gif "SeleniumBase")
810

_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
theme: jekyll-theme-cayman
22
title: SeleniumBase
3-
description: The Future of Web Automation & Testing
3+
description: WebDriver automation simplified by extending Python's unittest framework.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'''
2+
You can use this as a boilerplate for your test framework.
3+
Define your customized library methods in a master class like this.
4+
Then have all your test classes inherit it.
5+
BaseTestCase will inherit SeleniumBase methods from BaseCase.
6+
'''
7+
8+
from seleniumbase import BaseCase
9+
10+
11+
class BaseTestCase(BaseCase):
12+
13+
def setUp(self):
14+
super(BaseTestCase, self).setUp()
15+
# Add custom setUp code for your tests AFTER the super().setUp()
16+
17+
def tearDown(self):
18+
# Add custom tearDown code for your tests BEFORE the super().tearDown()
19+
super(BaseTestCase, self).tearDown()
20+
21+
def login_to_site(self):
22+
# <<< Placeholder for actual code. Add your code here. >>>
23+
# Add frequently used methods like this in your base test case class.
24+
# This reduces the amount of duplicated code in your tests.
25+
# If the UI changes, the fix only needs to be applied in one place.
26+
pass
27+
28+
def example_method(self):
29+
# <<< Placeholder for actual code. Add your code here. >>>
30+
pass
31+
32+
33+
'''
34+
# Now you can do something like this in your test files:
35+
36+
from base_test_case import BaseTestCase
37+
38+
class MyTests(BaseTestCase):
39+
40+
def test_example(self):
41+
self.login_to_site()
42+
self.example_method()
43+
'''
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from .base_test_case import BaseTestCase
2+
from .page_objects import HomePage
3+
4+
5+
class MyTestClass(BaseTestCase):
6+
7+
def test_boilerplate(self):
8+
self.login_to_site()
9+
self.example_method()
10+
self.assert_element(HomePage.html)

examples/boilerplates/master_test_case.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

examples/boilerplates/page_objects.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77

88
class HomePage(object):
9+
html = "html"
910
ok_button = "#ok"
1011
cancel_button = "#cancel"
1112
see_items_button = "button.items"
@@ -26,13 +27,13 @@ class CheckoutPage(object):
2627
'''
2728
# Now you can do something like this in your test files:
2829
29-
from master_class import MasterTestCase
30-
from page_objects import HomePage, ShoppingPage, CheckoutPage
30+
from .base_test_case import BaseTestCase
31+
from .page_objects import HomePage, ShoppingPage, CheckoutPage
3132
32-
class MyTests(MasterTestCase):
33+
class MyTests(BaseTestCase):
3334
3435
def test_example(self):
35-
self.open(RANDOM_SHOPPING_WEBSITE)
36+
self.login_to_site()
3637
self.click(HomePage.see_items_button)
3738
self.click(ShoppingPage.buyable_item)
3839
self.click(ShoppingPage.add_to_cart)

examples/boilerplates/samples/google_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'''
44

55
from seleniumbase import BaseCase
6-
from google_objects import HomePage, ResultsPage
6+
from .google_objects import HomePage, ResultsPage
77

88

99
class GoogleTests(BaseCase):

help_docs/method_summary.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,16 @@ self.double_click(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT)
1616
self.click_chain(selectors_list, by=By.CSS_SELECTOR,
1717
timeout=settings.SMALL_TIMEOUT, spacing=0)
1818

19+
self.is_link_text_present(link_text)
20+
21+
self.get_href_from_link_text(link_text)
22+
23+
self.wait_for_href_from_link_text(link_text, timeout=settings.SMALL_TIMEOUT)
24+
1925
self.click_link_text(link_text, timeout=settings.SMALL_TIMEOUT)
2026

27+
self.click_link(link_text, timeout=settings.SMALL_TIMEOUT)
28+
2129
self.click_partial_link_text(partial_link_text, timeout=settings.SMALL_TIMEOUT)
2230

2331
self.get_text(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT)
@@ -61,6 +69,10 @@ self.is_text_visible(text, selector, by=By.CSS_SELECTOR)
6169

6270
self.find_visible_elements(selector, by=By.CSS_SELECTOR)
6371

72+
self.is_element_in_frame(selector, by=By.CSS_SELECTOR)
73+
74+
self.enter_frame_of_element(selector, by=By.CSS_SELECTOR)
75+
6476
self.execute_script(script)
6577

6678
self.set_window_size(width, height)
@@ -69,6 +81,8 @@ self.maximize_window()
6981

7082
self.activate_jquery()
7183

84+
self.bring_to_front(selector, by=By.CSS_SELECTOR)
85+
7286
self.highlight(selector, by=By.CSS_SELECTOR, loops=4, scroll=True)
7387

7488
self.scroll_to(selector, by=By.CSS_SELECTOR)
@@ -81,10 +95,24 @@ self.click_xpath(xpath)
8195

8296
self.jquery_click(selector, by=By.CSS_SELECTOR)
8397

98+
self.hide_element(selector, by=By.CSS_SELECTOR)
99+
100+
self.hide_elements(selector, by=By.CSS_SELECTOR)
101+
102+
self.show_element(selector, by=By.CSS_SELECTOR)
103+
104+
self.show_elements(selector, by=By.CSS_SELECTOR)
105+
106+
self.remove_element(selector, by=By.CSS_SELECTOR)
107+
108+
self.remove_elements(selector, by=By.CSS_SELECTOR)
109+
84110
self.jq_format(code)
85111

86112
self.get_domain_url(url)
87113

114+
self.safe_execute_script(script)
115+
88116
self.download_file(file_url, destination_folder=None)
89117

90118
self.save_file_as(file_url, new_file_name, destination_folder=None)
@@ -110,7 +138,7 @@ self.jquery_update_text_value(selector, new_value, by=By.CSS_SELECTOR,
110138
self.jquery_update_text(selector, new_value, by=By.CSS_SELECTOR,
111139
timeout=settings.SMALL_TIMEOUT)
112140

113-
self.hover_on_element(selector)
141+
self.hover_on_element(selector, by=By.CSS_SELECTOR)
114142

115143
self.hover_and_click(hover_selector, click_selector,
116144
hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR,

integrations/selenium_ide/convert_ide.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def main():
256256
if '(u"' in line:
257257
uni = "u"
258258
has_unicode = True
259-
command = '''%sself.click_link_text(%s"%s")''' % (
259+
command = '''%sself.click(%s"link=%s")''' % (
260260
whitespace, uni, link_text)
261261
seleniumbase_lines.append(command)
262262
continue
@@ -468,7 +468,7 @@ def main():
468468
# quote_type = data.group(1)
469469
link_text = data.group(2)
470470
if int(line_num) < num_lines - 2:
471-
regex_string = (r'''^\s*self.click_link_text\(["|']'''
471+
regex_string = (r'''^\s*self.click\(["|']link='''
472472
+ re.escape(link_text) + r'''["|']\)\s*$''')
473473
data2 = re.match(regex_string, lines[line_num+1])
474474
if data2:
@@ -489,7 +489,7 @@ def main():
489489
out_file = codecs.open(converted_file_name, "w+")
490490
out_file.writelines(seleniumbase_code)
491491
out_file.close()
492-
print("%s successfully created from %s\n" % (
492+
print('>>> "%s" successfully created from %s\n' % (
493493
converted_file_name, webdriver_python_file))
494494

495495

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[pytest]
2+
# Let console output be seen. Don't override the pytest plugin.
23
addopts = --capture=no --ignore conftest.py

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pip>=9.0.1
22
setuptools>=38.5.1
33
ipython==5.4.1
4-
selenium==3.8.0
4+
selenium==3.8.1
55
nose==1.3.7
66
pytest==3.4.0
77
pytest-html==1.16.1

seleniumbase/core/browser_launcher.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import warnings
12
from selenium import webdriver
23
from selenium.common.exceptions import WebDriverException
34
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
@@ -112,10 +113,13 @@ def get_remote_driver(browser_name, headless, servername, port):
112113
desired_capabilities=(
113114
webdriver.DesiredCapabilities.SAFARI))
114115
if browser_name == constants.Browser.PHANTOM_JS:
115-
return webdriver.Remote(
116-
command_executor=address,
117-
desired_capabilities=(
118-
webdriver.DesiredCapabilities.PHANTOMJS))
116+
with warnings.catch_warnings():
117+
# Ignore "PhantomJS has been deprecated" UserWarning
118+
warnings.simplefilter("ignore", category=UserWarning)
119+
return webdriver.Remote(
120+
command_executor=address,
121+
desired_capabilities=(
122+
webdriver.DesiredCapabilities.PHANTOMJS))
119123

120124

121125
def get_local_driver(browser_name, headless):
@@ -158,7 +162,10 @@ def get_local_driver(browser_name, headless):
158162
if browser_name == constants.Browser.SAFARI:
159163
return webdriver.Safari()
160164
if browser_name == constants.Browser.PHANTOM_JS:
161-
return webdriver.PhantomJS()
165+
with warnings.catch_warnings():
166+
# Ignore "PhantomJS has been deprecated" UserWarning
167+
warnings.simplefilter("ignore", category=UserWarning)
168+
return webdriver.PhantomJS()
162169
if browser_name == constants.Browser.GOOGLE_CHROME:
163170
try:
164171
chrome_options = webdriver.ChromeOptions()

0 commit comments

Comments
 (0)