Method specifications with examples
Navigating to a web page (and related commands)¶
self.open("https://xkcd.com/378/") # This method opens the specified page.
self.go_back() # This method navigates the browser to the previous page.
self.go_forward() # This method navigates the browser forward in history.
self.refresh_page() # This method reloads the current page.
self.get_current_url() # This method returns the current page URL.
self.get_page_source() # This method returns the current page source.
ProTip™: You may need to use the get_page_source() method along with Python's find() command to parse through the source to find something that Selenium wouldn't be able to. (You may want to brush up on your Python programming skills for that.)
source = self.get_page_source()
head_open_tag = source.find('<head>')
head_close_tag = source.find('</head>', head_open_tag)
everything_inside_head = source[head_open_tag+len('<head>'):head_close_tag]
Clicking¶
To click an element on the page:
self.click("div#my_id")
ProTip™: In most web browsers, you can right-click on a page and select Inspect Element to see the CSS selector details that you'll need to create your own scripts.
Typing Text¶
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.update_text("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:
from selenium.webdriver.common.keys import Keys
self.find_element("textarea").send_keys(Keys.SPACE + Keys.BACK_SPACE + '\n') # The backspace should cancel out the space, leaving you with the newline
Getting the text from an element on a page¶
text = self.get_text("header h2")
Getting the attribute value from an element on a page¶
attribute = self.get_attribute("#comic img", "title")
Asserting existance of an element on a page within some number of seconds:¶
self.wait_for_element_present("div.my_class", timeout=10)
(NOTE: You can also use: self.assert_element_present(ELEMENT))
Asserting visibility of an element on a page within some number of seconds:¶
self.wait_for_element_visible("a.my_class", timeout=5)
(NOTE: The short versions of this are self.find_element(ELEMENT) and self.assert_element(ELEMENT). The find_element() version returns the element)
Since the line above returns the element, you can combine that with .click() as shown below:
self.find_element("a.my_class", timeout=5).click()
# But you're better off using the following statement, which does the same thing:
self.click("a.my_class") # DO IT THIS WAY!
ProTip™: You can use dots to signify class names (Ex: div.class_name) as a simplified version of div[class="class_name"] within a CSS selector.
You can also use *= to search for any partial value in a CSS selector as shown below:
self.click('a[name*="partial_name"]')
Asserting visibility of text inside an element on a page within some number of seconds:¶
self.assert_text("Make it so!", "div#trek div.picard div.quotes")
self.assert_text("Tea. Earl Grey. Hot.", "div#trek div.picard div.quotes", timeout=3)
(NOTE: self.find_text(TEXT, ELEMENT) and self.wait_for_text(TEXT, ELEMENT) also do this. For backwords compatibility, older method names were kept, but the default timeout may be different.)
Asserting Anything¶
self.assert_true(myvar1 == something)
self.assert_equal(var1, var2)
Useful Conditional Statements (with creative examples in action)¶
is_element_visible(selector) # is an element visible on a page
if self.is_element_visible('div#warning'):
print("Red Alert: Something bad might be happening!")
is_element_present(selector) # is an element present on a page
if self.is_element_present('div#top_secret img.tracking_cookie'):
self.contact_cookie_monster() # Not a real SeleniumBase method
else:
current_url = self.get_current_url()
self.contact_the_nsa(url=current_url, message="Dark Zone Found") # Not a real SeleniumBase method
Another example:
def is_there_a_cloaked_klingon_ship_on_this_page():
if self.is_element_present("div.ships div.klingon"):
return not self.is_element_visible("div.ships div.klingon")
return False
is_text_visible(text, selector) # is text visible on a page
def get_mirror_universe_captain_picard_superbowl_ad(superbowl_year):
selector = "div.superbowl_%s div.commercials div.transcript div.picard" % superbowl_year
if self.is_text_visible("For the Love of Marketing and Earl Grey Tea!", selector):
return "Picard HubSpot Superbowl Ad 2015"
elif self.is_text_visible("Delivery Drones... Engage", selector):
return "Picard Amazon Superbowl Ad 2015"
elif self.is_text_visible("Bing it on Screen!", selector):
return "Picard Microsoft Superbowl Ad 2015"
elif self.is_text_visible("OK Glass, Make it So!", selector):
return "Picard Google Superbowl Ad 2015"
elif self.is_text_visible("Number One, I've Never Seen Anything Like It.", selector):
return "Picard Tesla Superbowl Ad 2015"
elif self.is_text_visible("""With the first link, the chain is forged.
The first speech censored, the first thought forbidden,
the first freedom denied, chains us all irrevocably.""", selector):
return "Picard Wikimedia Superbowl Ad 2015"
elif self.is_text_visible("Let us make sure history never forgets the name ... Facebook", selector):
return "Picard Facebook Superbowl Ad 2015"
else:
raise Exception("Reports of my assimilation are greatly exaggerated.")
Switching Tabs¶
What if your test opens up a new tab/window and now you have more than one page? No problem. You need to specify which one you currently want Selenium to use. Switching between tabs/windows is easy:
self.switch_to_window(1) # This switches to the new tab (0 is the first one)
ProTip™: iFrames follow the same principle as new windows - you need to specify the iFrame if you want to take action on something in there
self.switch_to_frame('ContentManagerTextBody_ifr')
# Now you can act inside the iFrame
# .... Do something cool (here)
self.switch_to_default_content() # Exit the iFrame when you're done
Handle Pop-Up Alerts¶
What if your test makes an alert pop up in your browser? No problem. You need to switch to it and either accept it or dismiss it:
self.wait_for_and_accept_alert()
self.wait_for_and_dismiss_alert()
If you're not sure whether there's an alert before trying to accept or dismiss it, one way to handle that is to wrap your alert-handling code in a try/except block. Other methods such as .text and .send_keys() will also work with alerts.
Executing Custom jQuery Scripts:¶
jQuery is a powerful JavaScript library that allows you to perform advanced actions in a web browser. If the web page you're on already has jQuery loaded, you can start executing jQuery scripts immediately. You'd know this because the web page would contain something like the following in the HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
It's OK if you want to use jQuery on a page that doesn't have it loaded yet. To do so, run the following command first:
self.activate_jquery()
Some websites have a restrictive Content Security Policy to prevent users from loading jQuery and other external libraries onto their websites. If you need to use jQuery or another JS library on such a website, add --disable_csp on the command-line.
Here are some examples of using jQuery in your scripts:
self.execute_script('jQuery, window.scrollTo(0, 600)') # Scrolling the page
self.execute_script("jQuery('#annoying-widget').hide()") # Hiding elements on a page
self.execute_script("jQuery('#hidden-widget').show(0)") # Showing hidden elements on a page
self.execute_script("jQuery('#annoying-button a').remove()") # Removing elements on a page
self.execute_script("jQuery('%s').mouseover()" % (mouse_over_item)) # Mouse-over elements on a page
self.execute_script("jQuery('input#the_id').val('my_text')") # Fast text input on a page
self.execute_script("jQuery('div#dropdown a.link').click()") # Click elements on a page
self.execute_script("return jQuery('div#amazing')[0].text") # Returns the css "text" of the element given
self.execute_script("return jQuery('textarea')[2].value") # Returns the css "value" of the 3rd textarea element on the page
In the following example, JavaScript is used to plant code on a page that Selenium can then touch after that:
start_page = "https://xkcd.com/465/"
destination_page = "https://github.com/seleniumbase/SeleniumBase"
self.open(start_page)
referral_link = '''<a class='analytics test' href='%s'>Free-Referral Button!</a>''' % destination_page
self.execute_script('''document.body.innerHTML = \"%s\"''' % referral_link)
self.click("a.analytics") # Clicks the generated button
(Due to popular demand, this traffic generation example has been baked into SeleniumBase with the self.generate_referral(start_page, end_page) and the self.generate_traffic(start_page, end_page, loops) methods.)
Using delayed asserts:¶
Let's say you want to verify multiple different elements on a web page in a single test, but you don't want the test to fail until you verified several elements at once so that you don't have to rerun the test to find more missing elements on the same page. That's where delayed asserts come in. Here's the example:
from seleniumbase import BaseCase
class MyTestClass(BaseCase):
def test_delayed_asserts(self):
self.open('https://xkcd.com/993/')
self.wait_for_element('#comic')
self.delayed_assert_element('img[alt="Brand Identity"]')
self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail
self.delayed_assert_element('#comicmap')
self.delayed_assert_text('Fake Item', '#middleContainer') # Will Fail
self.delayed_assert_text('Random', '#middleContainer')
self.delayed_assert_element('a[name="Super Fake !!!"]') # Will Fail
self.process_delayed_asserts()
delayed_assert_element() and delayed_assert_text() will save any exceptions that would be raised.
To flush out all the failed delayed asserts into a single exception, make sure to call self.process_delayed_asserts() at the end of your test method. If your test hits multiple pages, you can call self.process_delayed_asserts() at the end of all your delayed asserts for a single page. This way, the screenshot from your log file will have the location where the delayed asserts were made.
Accessing raw WebDriver¶
If you need access to any commands that come with standard WebDriver, you can call them directly like this:
self.driver.delete_all_cookies()
capabilities = self.driver.capabilities
self.driver.find_elements_by_partial_link_text("GitHub")
(In general, you'll want to use the SeleniumBase versions of methods when available.)
Retrying failing tests automatically¶
You can use --reruns NUM to retry failing tests that many times. Use --reruns-delay SECONDS to wait that many seconds between retries. Example:
pytest --reruns 5 --reruns-delay 1
Additionally, you can use the @retry_on_exception() decorator to specifically retry failing methods. (First import: from seleniumbase import decorators) To learn more about SeleniumBase decorators, click here.