Skip to content

Massive Release with Lots of Changes #596

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 47 commits into from
Jun 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a2b6bb7
Add the new "sbase mkfile FILE_NAME.py" command
mdmintz Jun 10, 2020
6d7d452
Update the "sbase mkdir DIR_NAME" command
mdmintz Jun 10, 2020
efdd38b
Update translations
mdmintz Jun 10, 2020
041952b
Update Messenger asserts
mdmintz Jun 10, 2020
45c48f9
Add "--rs" as a simplified command arg for "--reuse-session"
mdmintz Jun 10, 2020
f6f4463
Update the docs
mdmintz Jun 10, 2020
dbdc6b0
Update flake8 version
mdmintz Jun 10, 2020
9d08988
Version 1.40.0
mdmintz Jun 10, 2020
74d26ba
Update "rich" dependency to v2.0.1
mdmintz Jun 10, 2020
5b1889c
Update sb_mkfile
mdmintz Jun 10, 2020
9be50da
Refresh proxy list
mdmintz Jun 10, 2020
1788d16
Update sb_mkfile
mdmintz Jun 11, 2020
3b7a6a7
Set the language in the __init__
mdmintz Jun 11, 2020
63e8cc6
Set "English" as the default language
mdmintz Jun 11, 2020
8b8c269
self.type(selector, text) exists. Don't confuse it with Python type(obj)
mdmintz Jun 12, 2020
2d04bcf
Refactor master dictionary
mdmintz Jun 12, 2020
6291e1d
Simplify detection of Chinese, Japanese, and Korean characters
mdmintz Jun 12, 2020
9115581
Update "rich" Python version
mdmintz Jun 12, 2020
eac5411
Replace " # noqa" with "" when printing Python test files
mdmintz Jun 12, 2020
c36dd66
Update the SeleniumBase smart-word-wrap function
mdmintz Jun 12, 2020
cbd5047
Add translations for messages posted by Demo Mode
mdmintz Jun 12, 2020
79ca6d6
Update the docs
mdmintz Jun 12, 2020
4590442
Improve reliability of Demo Mode
mdmintz Jun 12, 2020
38fa1d0
Update the docs
mdmintz Jun 12, 2020
7737787
Remove methods that were marked as deprecated over a year ago.
mdmintz Jun 12, 2020
57ab91f
Use consistent naming: Args called "new_value" become "text"
mdmintz Jun 12, 2020
702f69b
Add self.js_type(s, t) and make arg-naming consistent
mdmintz Jun 12, 2020
4b654cb
Update method summary
mdmintz Jun 12, 2020
82490ab
Boost speed by optimizing the location of imports
mdmintz Jun 13, 2020
c84a5e9
Improve methods that type text
mdmintz Jun 13, 2020
a8c2afd
Refresh pytest-cov to version 2.10.0
mdmintz Jun 13, 2020
f6f6d4d
Update method_summary
mdmintz Jun 13, 2020
fff54f0
Update translations
mdmintz Jun 13, 2020
a7b446e
Update translations
mdmintz Jun 13, 2020
00cb83d
Add js_update_text(s, t) and js_type(s, t) to translations
mdmintz Jun 13, 2020
de8e720
Update "sbase mkdir [DIR]"
mdmintz Jun 13, 2020
73eb839
Update "sbase mkfile [FILE_NAME.py]"
mdmintz Jun 13, 2020
bc24277
Update translation examples
mdmintz Jun 13, 2020
7181b0f
Update examples
mdmintz Jun 13, 2020
9ee1fa7
Update comments
mdmintz Jun 14, 2020
5b801da
Update Messenger output for assert statements
mdmintz Jun 14, 2020
70c9501
Add self.assert_no_broken_links() to assert no 404 errors
mdmintz Jun 14, 2020
df603cf
Update the Selenium IDE export converter tool
mdmintz Jun 14, 2020
2f06000
Update "sbase mkdir DIR"
mdmintz Jun 14, 2020
9b639f0
Update the master dictionary
mdmintz Jun 14, 2020
353418a
Update examples
mdmintz Jun 14, 2020
7381e47
Update the docs
mdmintz Jun 14, 2020
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
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<meta property="og:site_name" content="SeleniumBase | Docs">
<meta property="og:title" content="SeleniumBase | Reliable Test Automation" />
<meta property="og:description" content="Simple browser automation and testing with Python." />
<meta property="og:image" content="https://seleniumbase.io/img/sb_logo_7.png" />
<meta property="og:title" content="SeleniumBase | Easy Test Automation" />
<meta property="og:description" content="Browser automation and testing with Python." />
<meta property="og:image" content="https://seleniumbase.io/img/sb_logo_10.png" />
<link rel="icon" href="https://seleniumbase.io/img/logo3a.png" />

<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/">
<img src="https://seleniumbase.io/img/sb_logo_7.png" alt="SeleniumBase" width="260" />
<img src="https://seleniumbase.io/img/sb_logo_10.png" alt="SeleniumBase" width="260" />
</a></p>
<p align="center">
<b>Everything you need to test websites.</b>
Expand Down Expand Up @@ -68,7 +68,7 @@ python setup.py install
```
If multiple versions of Python are installed, be specific (E.g. use ``python3`` instead of ``python``).

* You can also install ``seleniumbase`` from [pypi](https://pypi.python.org/pypi/seleniumbase):
* You can also install ``seleniumbase`` from [pypi](https://pypi.python.org/pypi/seleniumbase).
```bash
pip install seleniumbase
```
Expand Down Expand Up @@ -112,17 +112,17 @@ from seleniumbase import BaseCase
class MyTestClass(BaseCase):

def test_basic(self):
self.open("https://store.xkcd.com/search")
self.type('input[name="q"]', "xkcd book\n")
self.assert_text("xkcd: volume 0", "h3")
self.open("https://xkcd.com/353/")
self.assert_title("xkcd: Python")
self.assert_element('img[alt="Python"]')
self.click('a[rel="license"]')
self.assert_text("free to copy and reuse")
self.go_back()
self.click("link=About")
self.assert_text("xkcd.com", "h2")
self.open("://store.xkcd.com/collections/everything")
self.update_text("input.search-input", "xkcd book\n")
self.assert_exact_text("xkcd: volume 0", "h3")
self.click_link_text("About")
self.assert_exact_text("xkcd.com", "h2")
```

* By default, **[CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp)** are used for finding page elements.
Expand All @@ -132,7 +132,7 @@ class MyTestClass(BaseCase):
```python
self.open(URL) # Navigate to the web page
self.click(SELECTOR) # Click a page element
self.update_text(SELECTOR, TEXT) # Type text (Add "\n" to text for pressing enter/return.)
self.type(SELECTOR, TEXT) # Type text (Add "\n" to text for pressing enter/return.)
self.assert_element(SELECTOR) # Assert element is visible
self.assert_text(TEXT) # Assert text is visible (has optional SELECTOR arg)
self.assert_title(PAGE_TITLE) # Assert page title
Expand Down Expand Up @@ -163,7 +163,7 @@ SeleniumBase automatically handles common WebDriver actions such as spinning up
SeleniumBase uses simple syntax for commands, such as:

```python
self.update_text("input", "dogs\n")
self.type("input", "dogs\n")
```

The same command with regular WebDriver is very messy:
Expand Down Expand Up @@ -523,10 +523,10 @@ self.click("div#my_id")

<h4>Typing Text</h4>

self.update_text(selector, text) # updates the text from the specified element with the specified value. An exception is raised if the element is missing or if the text field is not editable. Example:
self.type(selector, text) # updates the text from the specified element with the specified value. An exception is raised if the element is missing or if the text field is not editable. Example:

```python
self.update_text("input#id_value", "2012")
self.type("input#id_value", "2012")
```
You can also use self.add_text() or the WebDriver .send_keys() command, but those won't clear the text box first if there's already text inside.
If you want to type in special keys, that's easy too. Here's an example:
Expand Down
Binary file added docs/img/sb_logo_10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions examples/basic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
class MyTestClass(BaseCase):

def test_basic(self):
self.open("https://store.xkcd.com/search")
self.type('input[name="q"]', "xkcd book\n")
self.open("https://xkcd.com/353/")
self.click('a[rel="license"]')
self.go_back()
self.click("link=About")
self.open("://store.xkcd.com/collections/everything")
self.update_text("input.search-input", "xkcd book\n")
self.click_link_text("About")
2 changes: 1 addition & 1 deletion examples/boilerplates/samples/google_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class GoogleTests(BaseCase):

def test_google_dot_com(self):
self.open('https://google.com/ncr')
self.update_text(HomePage.search_box, 'github')
self.type(HomePage.search_box, 'github')
self.assert_element(HomePage.list_box)
self.assert_element(HomePage.search_button)
self.assert_element(HomePage.feeling_lucky_button)
Expand Down
2 changes: 1 addition & 1 deletion examples/github_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_github(self):
"""AppleWebKit/537.36 (KHTML, like Gecko) """
"""Chrome/75.0.3770.100 Safari/537.36""")
self.open("https://github.com/")
self.update_text("input.header-search-input", "SeleniumBase\n")
self.type("input.header-search-input", "SeleniumBase\n")
self.slow_click('a[href="/seleniumbase/SeleniumBase"]')
self.assert_element("div.repository-content")
self.assert_text("SeleniumBase", "h1")
Expand Down
4 changes: 2 additions & 2 deletions examples/master_qa/masterqa_test_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def test_xkcd(self):
self.verify("Can you find the moon?")
self.click('a[rel="next"]')
self.verify("Do the drones look safe?")
self.open("https://store.xkcd.com/collections/everything")
self.update_text("input.search-input", "book\n")
self.open("https://store.xkcd.com/search")
self.type("input.search-input", "book\n")
self.verify("Do you see books in the search results?")
self.open("https://xkcd.com/213/")
for i in range(5):
Expand Down
88 changes: 57 additions & 31 deletions examples/my_first_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
class MyTestClass(BaseCase):

def test_basic(self):
self.open("https://store.xkcd.com/search")
self.type('input[name="q"]', "xkcd book\n")
self.assert_text("xkcd: volume 0", "h3")
self.open("https://xkcd.com/353/")
self.assert_title("xkcd: Python")
self.assert_element('img[alt="Python"]')
self.click('a[rel="license"]')
self.assert_text("free to copy and reuse")
self.go_back()
self.click("link=About")
self.assert_text("xkcd.com", "h2")
self.open("://store.xkcd.com/collections/everything")
self.update_text("input.search-input", "xkcd book\n")
self.assert_exact_text("xkcd: volume 0", "h3")
self.click_link_text("About")
self.assert_exact_text("xkcd.com", "h2")

####

Expand All @@ -23,14 +23,17 @@ def test_basic(self):
# **** NOTES / USEFUL INFO ****
#
# 1. By default, CSS Selectors are used to identify elements.
# Other options include: "LINK_TEXT", "PARTIAL_LINK_TEXT", "NAME",
# CSS Guide: "https://www.w3schools.com/cssref/css_selectors.asp".
# Other selectors include: "LINK_TEXT", "PARTIAL_LINK_TEXT", "NAME",
# "CLASS_NAME", and "ID", but most of those can be expressed as CSS.
#
# Here's an example of changing the "by":
# [
# from selenium.webdriver.common.by import By
# ...
# self.click('Next', by=By.PARTIAL_LINK_TEXT)
# ]
#
# XPath is used by default if the arg starts with "/", "./", or "(":
# [
# self.click('/html/body/div[3]/div[4]/p[2]/a')
Expand All @@ -39,27 +42,46 @@ def test_basic(self):
# If you're completely new to CSS selectors, right-click on a
# web page and select "Inspect" to see the CSS in the html.
#
# 2. Most methods have the optional `timeout` argument. Ex:
# 2. Most methods have the optional "timeout" argument.
# Here's an example of changing the "timeout":
# [
# self.assert_element('img[alt="Python"]', timeout=15)
# ]
# The `timeout` argument tells the method how many seconds to wait
# for an element to appear before raising an exception. This is
# The "timeout" argument tells the method how many seconds to wait
# for an element to appear before failing the test. This is
# useful if a web page needs additional time to load an element.
# If you don't specify a `timeout`, a default timeout is used.
# If you don't specify a "timeout", a default timeout is used.
# Default timeouts are configured in seleniumbase/config/settings.py
#
# 3. SeleniumBase methods are very versatile. For example,
# self.update_text(SELECTOR, TEXT) does the following:
# * Waits for the element to be visible
# * Waits for the element to be interactive
# * Clears the text field
# * Types in the new text
# * Hits Enter/Submit (if the text ends in "\n")
# 3. SeleniumBase methods often perform multiple actions. For example,
# self.type(SELECTOR, TEXT) will do the following:
# * Wait for the element to be visible
# * Wait for the element to be interactive
# * Clear the text field
# * Type in the new text
# * Press Enter/Submit if the text ends in "\n"
#
# self.update_text(S, T) can also be written as self.input(S, T)
# 4. Duplicate method names may exist for the same method:
# (This makes it easier to switch over from other test frameworks.)
# Example:
# self.open() = self.visit() = self.open_url() = self.goto()
# self.type() = self.update_text() = self.input()
# self.send_keys() = self.add_text()
# self.get_element() = self.wait_for_element_present()
# self.find_element() = self.wait_for_element_visible()
# = self.wait_for_element()
# self.assert_element() = self.assert_element_visible()
# self.assert_text() = self.assert_text_visible()
# self.find_text() = self.wait_for_text_visible()
# = self.wait_for_text()
# self.click_link_text(text) = self.click(link=text)
# = self.click_link(text)
# * self.get(url) is SPECIAL: *
# If {url} is a valid URL, self.get() works just like self.open()
# Otherwise {url} becomes a selector for calling self.get_element()
#
# 4. There's usually more than one way to do the same thing. Ex:
# 5. There's usually more than one way to do the same thing.
# Example 1:
# [
# self.assert_text("xkcd: volume 0", "h3")
# ]
Expand All @@ -68,33 +90,37 @@ def test_basic(self):
# text = self.get_text("h3")
# self.assert_true("xkcd: volume 0" in text)
# ]
# Or:
# Is also the same as:
# [
# text = self.find_element("h3").text
# element = self.find_element("h3")
# text = element.text
# self.assert_true("xkcd: volume 0" in text)
# ]
#
# And the following line:
# Example 2:
# [
# self.assert_exact_text("xkcd.com", "h2")
# ]
# Is the same as:
# [
# text = self.get_text("h2").strip()
# self.assert_true("xkcd.com".strip() == text)
# ]
#
# Example 3:
# [
# title = self.get_attribute("#comic img", "title")
# ]
# Can also be written as:
# Is the same as:
# [
# element = self.find_element("#comic img")
# title = element.get_attribute("title")
# ]
#
# 5. self.assert_exact_text(TEXT) ignores leading and trailing
# 6. self.assert_exact_text(TEXT) ignores leading and trailing
# whitespace in the TEXT assertion.
# So, self.assert_exact_text("Some Text") will find [" Some Text "].
#
# 6. For backwards-compatibilty, some SeleniumBase methods that do the
# same thing have multiple names, kept on from previous versions.
# Ex: self.wait_for_element() is the same as self.find_element().
# Both search for and return the element, and raise an exception if
# the element does not appear on the page within the timeout limit.
# And self.assert_element() does this too (without returning it).
#
# 7. If a URL starts with "://", then "https://" is automatically used.
# Example: [self.open("://URL")] becomes [self.open("https://URL")]
# This helps by reducing the line length by 5 characters.
Expand Down
15 changes: 7 additions & 8 deletions examples/offline_examples/test_demo_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ def test_demo_page(self):
# Assert that the text appears within a given element
self.assert_text("Demo Page", "h1")

# Update the text of various text fields on the page
self.update_text("#myTextInput", "This is Automated")
self.update_text("textarea.area1", "Testing Time!\n")
self.update_text('[name="preText2"]', "Typing Text!")
# Type/update text in text fields on the page
self.type("#myTextInput", "This is Automated")
self.type("textarea.area1", "Testing Time!\n")
self.type('[name="preText2"]', "Typing Text!")

# Verify that a hover dropdown link changes page text
self.assert_text("Automation Practice", "h3")
Expand Down Expand Up @@ -92,9 +92,8 @@ def test_demo_page(self):
# Assert link text - Use click_link_text() to click
self.assert_link_text("seleniumbase.com")
self.assert_link_text("SeleniumBase on GitHub")

# Assert the title of the current web page
self.assert_link_text("seleniumbase.com")
self.assert_link_text("SeleniumBase on GitHub")
self.assert_link_text("seleniumbase.io")
self.assert_link_text("SeleniumBase Demo Page")

# Assert exact text
self.assert_exact_text("Demo Page", "h1")
2 changes: 1 addition & 1 deletion examples/parameterized_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ class GoogleTestClass(BaseCase):
])
def test_parameterized_google_search(self, search_term, expected_text):
self.open('https://google.com/ncr')
self.update_text('input[title="Search"]', search_term + '\n')
self.type('input[title="Search"]', search_term + '\n')
self.assert_element('#result-stats')
self.assert_text(expected_text, '#search')
10 changes: 5 additions & 5 deletions examples/swag_labs_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def login(self, username="standard_user"):
self.open("https://www.saucedemo.com/")
if username not in self.get_text("#login_credentials"):
self.fail("Invalid user for login: %s" % username)
self.update_text("#user-name", username)
self.update_text("#password", "secret_sauce")
self.type("#user-name", username)
self.type("#password", "secret_sauce")
self.click('input[type="submit"]')
self.assert_element("#inventory_container")
self.assert_text("Products", "div.product_label")
Expand Down Expand Up @@ -58,9 +58,9 @@ def test_swag_labs_basic_functional_flow(self, username):
self.click("link=CHECKOUT")
self.assert_exact_text("Checkout: Your Information", "div.subheader")
self.assert_element("a.cart_cancel_link")
self.update_text("#first-name", "SeleniumBase")
self.update_text("#last-name", "Rocks")
self.update_text("#postal-code", "01720")
self.type("#first-name", "SeleniumBase")
self.type("#last-name", "Rocks")
self.type("#postal-code", "01720")

# Checkout - Overview
self.click("input.btn_primary")
Expand Down
2 changes: 1 addition & 1 deletion examples/test_apple_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def test_apple_developer_site_webdriver_instructions(self):
self.message_duration = 2.0
self.open("https://developer.apple.com/search/")
title = "Testing with WebDriver in Safari"
self.update_text('[placeholder*="developer.apple.com"]', title + "\n")
self.type('[placeholder*="developer.apple.com"]', title + "\n")
self.click("link=%s" % title)
self.assert_element('[href="/documentation"]')
self.assert_text(title, "h1")
Expand Down
14 changes: 10 additions & 4 deletions examples/test_demo_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ def test_demo_site(self):
# Assert that the text appears within a given element
self.assert_text("Demo Page", "h1")

# Update the text of various text fields on the page
self.update_text("#myTextInput", "This is Automated")
self.update_text("textarea.area1", "Testing Time!\n")
self.update_text('[name="preText2"]', "Typing Text!")
# Type/update text in text fields on the page
self.type("#myTextInput", "This is Automated")
self.type("textarea.area1", "Testing Time!\n")
self.type('[name="preText2"]', "Typing Text!")

# Verify that a hover dropdown link changes page text
self.assert_text("Automation Practice", "h3")
Expand Down Expand Up @@ -93,3 +93,9 @@ def test_demo_site(self):

# Assert exact text
self.assert_exact_text("Demo Page", "h1")

# Assert no broken links
self.assert_no_404_errors()

# Assert no JavaScript errors
self.assert_no_js_errors()
4 changes: 2 additions & 2 deletions examples/test_event_firing.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ def test_event_firing_webdriver(self):
print("\n* EventFiringWebDriver example *")
self.open("https://xkcd.com/1862/")
self.click("link=About")
self.open("https://store.xkcd.com/collections/everything")
self.update_text("input.search-input", "xkcd book\n")
self.open("https://store.xkcd.com/search")
self.type('input[name="q"]', "xkcd book\n")
self.open("https://xkcd.com/1822/")
2 changes: 1 addition & 1 deletion examples/test_hack_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_hack_search(self):
self.assert_element('input[title="Search"]')
self.set_attribute('[action="/search"]', "action", "//bing.com/search")
self.set_attributes('[value="Google Search"]', "value", "Bing Search")
self.update_text('input[title="Search"]', "SeleniumBase GitHub")
self.type('input[title="Search"]', "SeleniumBase GitHub")
self.click('[value="Bing Search"]')
self.assert_element("h1.b_logo")
self.click('[href*="github.com/seleniumbase/SeleniumBase"]')
Expand Down
Loading