DEV Community

Michael Mintz
Michael Mintz

Posted on • Edited on

Getting Started with SeleniumBase for Test Automation

You might not have heard of SeleniumBase, but you've likely heard a lot about Selenium! The common misconception is that Selenium is a complete standalone test automation framework. Not true, even according to the official website, which says: {"Selenium automates browsers. That's it!"}. That's where SeleniumBase comes in.

SeleniumBase carefully combines the powers of Selenium into Python's pytest unit testing framework, which provides customizable command line arguments and plugins for HTML reports, multi-threading, test-ordering, retrying failures, parameterization, and more. Unlike pytest-selenium (which is a very primitive merger of pytest and Selenium), SeleniumBase also does the following:

  • Contains reliable, smart-waiting code to prevent flaky tests.
  • Simplifies the process of creating UI tests for any website.
  • Includes Plugins for logging test results and screenshots.
  • Includes powerful methods such as assert_no_404_errors()
  • Includes command-line options such as --proxy=SERVER:PORT
  • Includes tools for assisted QA and website tours.
  • ... and so much more.

Here's an example of a test running in Demo Mode, which lets you see test actions as they occur:


(Above: my_first_test.py from examples/ in Demo Mode.)

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")
        self.click('input[value="Search"]')
        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_text("About")
        self.assert_exact_text("xkcd.com", "h2")
        self.click_link_text("geohashing")
        self.assert_element("#comic img")
Enter fullscreen mode Exit fullscreen mode
pytest my_first_test.py --demo
Enter fullscreen mode Exit fullscreen mode

Here's a more advanced example, which demonstrates logging in, adding items to a shopping cart, and making a purchase:


(Above: test_swag_labs.py from examples/ in Demo Mode.)

from seleniumbase import BaseCase


class SwagLabsTests(BaseCase):

    def login_to_swag_labs(self, username="standard_user"):
        """ Login to Swag Labs and verify success. """
        self.open("https://www.saucedemo.com/")
        if username not in self.get_text("#login_credentials"):
            self.fail("Invalid user for login: %s" % username)
        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")

    def test_swag_labs_basic_flow(self):
        """ This test checks functional flow of the Swag Labs store. """
        self.login_to_swag_labs(username="standard_user")

        # Verify that the "Test.allTheThings() T-Shirt" appears on the page
        item_name = "Test.allTheThings() T-Shirt"
        self.assert_text(item_name)

        # Verify that a reverse-alphabetical sort works as expected
        self.select_option_by_value("select.product_sort_container", "za")
        if item_name not in self.get_text("div.inventory_item"):
            self.fail('Sort Failed! Expecting "%s" on top!' % item_name)

        # Add the "Test.allTheThings() T-Shirt" to the cart
        self.assert_exact_text("ADD TO CART", "button.btn_inventory")
        item_price = self.get_text("div.inventory_item_price")
        self.click("button.btn_inventory")
        self.assert_exact_text("REMOVE", "button.btn_inventory")
        self.assert_exact_text("1", "span.shopping_cart_badge")

        # Verify your cart
        self.click("#shopping_cart_container path")
        self.assert_exact_text("Your Cart", "div.subheader")
        self.assert_text(item_name, "div.inventory_item_name")
        self.assert_exact_text("1", "div.cart_quantity")
        self.assert_exact_text("REMOVE", "button.cart_button")
        continue_shopping_button = "link=CONTINUE SHOPPING"
        if self.browser == "safari":
            # Safari sees this element differently
            continue_shopping_button = "link=Continue Shopping"
        self.assert_element(continue_shopping_button)

        # Checkout - Add info
        self.click("link=CHECKOUT")
        self.assert_exact_text("Checkout: Your Information", "div.subheader")
        self.assert_element("a.cart_cancel_link")
        self.type("#first-name", "SeleniumBase")
        self.type("#last-name", "Rocks")
        self.type("#postal-code", "01720")

        # Checkout - Overview
        self.click("input.btn_primary")
        self.assert_exact_text("Checkout: Overview", "div.subheader")
        self.assert_element("link=CANCEL")
        self.assert_text(item_name, "div.inventory_item_name")
        self.assert_text(item_price, "div.inventory_item_price")
        self.assert_exact_text("1", "div.summary_quantity")

        # Finish Checkout and verify item is no longer in cart
        self.click("link=FINISH")
        self.assert_exact_text("THANK YOU FOR YOUR ORDER", "h2")
        self.assert_element("img.pony_express")
        self.click("#shopping_cart_container path")
        self.assert_element_absent("div.inventory_item_name")
        self.click(continue_shopping_button)
        self.assert_element_absent("span.shopping_cart_badge")
Enter fullscreen mode Exit fullscreen mode
cd examples
pytest test_swag_labs.py --demo
Enter fullscreen mode Exit fullscreen mode

With SeleniumBase, methods such as click() and type() will automatically wait for website pages to be fully loaded before taking action on elements, which prevents flaky tests. This means you won't need to use random time.sleep() statements in tests anymore.

SeleniumBase can also create website tours by generating JavaScript out of a few lines of Python:



from seleniumbase import BaseCase


class MyTourClass(BaseCase):

    def test_google_tour(self):
        self.open('https://google.com/ncr')
        self.wait_for_element('input[title="Search"]')

        # Create a website tour using the ShepherdJS library with "dark" theme
        # Same as:  self.create_shepherd_tour(theme="dark")
        self.create_tour(theme="dark")
        self.add_tour_step("Welcome to Google!", title="SeleniumBase Tours")
        self.add_tour_step("Type in your query here.", 'input[title="Search"]')
        self.play_tour()

        self.highlight_update_text('input[title="Search"]', "Google")
        self.wait_for_element('[role="listbox"]')  # Wait for autocomplete

        # Create a website tour using the ShepherdJS library with "light" theme
        # Same as:  self.create_shepherd_tour(theme="light")
        self.create_tour(theme="light")
        self.add_tour_step("Then click to search.", '[value="Google Search"]')
        self.add_tour_step("Or press [ENTER] after entry.", '[title="Search"]')
        self.play_tour()

        self.highlight_update_text('input[title="Search"]', "GitHub\n")
        self.wait_for_element("#search")

        # Create a website tour using the Bootstrap Tour JS library
        # Same as:  self.create_bootstrap_tour()
        self.create_tour(theme="bootstrap")
        self.add_tour_step("See results here!", title="(autoplay in 5s)")
        self.add_tour_step("Here's the next tour:")
        self.play_tour(interval=5)  # Tour automatically continues after 5 sec

        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")

        # Create a website tour using the IntroJS library
        # Same as:  self.create_introjs_tour()
        self.create_tour(theme="introjs")
        self.add_tour_step("Welcome to Google Maps!")
        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()  # The default name for exports is "my_tour.js"
        self.play_tour()
Enter fullscreen mode Exit fullscreen mode
cd examples/tour_examples
pytest google_tour.py
Enter fullscreen mode Exit fullscreen mode

This is just the beginning of the #LowCode movement, which is all about using a few lines of code to do the work of many lines of code.

SeleniumBase installation is easy, and it only takes a few minutes to start running your first test. Check out the framework on GitHub, which contains lots of documentation and dozens of examples to help you get started. https://github.com/seleniumbase/SeleniumBase

Top comments (5)

Collapse
 
pjcalvo profile image
Pablo Calvo

dev.to/pjcalvo/ui-test-automation-... Would you check this post out and maybe provide some feedback?

Collapse
 
kiseta profile image
Tatyana K

Hi, is there an absolute beginner's guide to configuring the environment in which to try these examples. Obviously this needs Python to be installed on the machine. What would be next? Thanks!

Collapse
 
mintzworld profile image
Michael Mintz

Hi, the GitHub ReadMe should have all the details you need to help you get started: github.com/seleniumbase/SeleniumBa...
Once you’ve set up a virtual environment (instructions included) you can install with pip and then start running all the example tests.

Collapse
 
kiseta profile image
Tatyana K

Hi Michael, thank you for prompt reply.

Let me ask more specifically.

When instructions say 'Run pytest ... command' where do we run this from exactly? Let's take Windows, is there an IDE this is run from? Or just from the Command Prompt?

Also, let's assume there is absolutely nothing installed on the machine to use SeleniumBase, so what does a relatively technical team needs to have installed on the machines to be up and running?

  1. Python
  2. Pytest?
  3. Pip?
  4. IDE for test development, which one would you recommend? PyCharm? Any other?

Is there other prerequisites? Like doing installations under a local admin account? Folder permissions?

Apologies if this is covered in documentation later on, we're a bit stuck at the beginning, not sure where to run the commands from and if all the prerequisites are met.

Thanks!

Thread Thread
 
mintzworld profile image
Michael Mintz

Hi Tatyana, you can run that from any command prompt where Python is installed. When you install Python, it should automatically install pip for you, which is used to install Python packages in your Python virtual environment, which you can setup from the command prompt. You can use a bash shell, Mac terminal, DOS prompt, or any other shell. It should be easy once Python is installed, which may already come with the command prompt you use. From the Python virtual environment, you probably won’t need to worry about permissions, but you may need some admin access (for chromedriver, etc).