â Selenium Migration
â Support for migrating from raw Selenium to SeleniumBase¶
đĩ Here are some examples that can help you understand how to migrate from raw Selenium to SeleniumBase¶
The five main examples in the examples/migration/raw_selenium folder are:
Each of these examples is structured as a test that can be run with pytest
. They all inherit unittest.TestCase
either directly, or via seleniumbase.BaseCase
, which extends it. This provides automatically-called setUp()
and tearDown()
methods before and after each test.
These examples show the evolution of tests from raw Selenium to SeleniumBase. By understanding common progressions of Selenium engineers, you can avoid making the same mistakes as they did, and learn to write good tests efficiently without the long learning curve.
This is common example of how newcomers to Selenium write tests (assuming they've already learned how to break out reusuable code into setUp()
and tearDown()
methods). It uses find_element()
calls, which can lead to flaky tests because those calls fail if a page element is slow to load.
At the next stage of learning, newcomers to Selenium realize that their tests are flaky, so they start replacing existing find_element()
calls with WebDriverWait
and internal Selenium expected_conditions
methods, such as visibility_of_element_located
and element_to_be_clickable
. This can result in long/messy tests that are unmaintainable if not written carefully.
By this stage, newcomers to Selenium have evolved into legitimate test automation engineers. They have become better at writing reusable code, so they've broken down the long WebDriverWait
and expected_conditions
calls into shorter method calls, which are easier to read, but could still be improved on for better maintainability. Here, individual page actions are still written out as multiple lines of code, (or multiple method calls per line), which isn't efficient.
By now, the test automation engineer has become an expert in breaking out code into reusable methods, and the test itself has been simplified down to a single page action per line. The code is easy to read and easy to maintain. The error output is also simplified. The journey of writing a complete test automation framework for Selenium has begun.
With a complete test automation framework built, most of the hard work is already done for you. By importing BaseCase
into your test classes, your tests gain access to all SeleniumBase methods, which can simplify your code. SeleniumBase also provides a lot of additional functionality that isn't included with raw Selenium.
đĩ How is SeleniumBase different from raw Selenium?¶
đĄ SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses Selenium/WebDriver APIs and incorporates test-runners such as pytest
, pynose
, and behave
to provide organized structure, test discovery, test execution, test state (eg. passed, failed, or skipped), and command-line options for changing default settings (eg. browser selection). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.
đĄ SeleniumBase's driver manager gives you more control over automatic driver downloads. (Use --driver-version=VER
with your pytest
run command to specify the version.) By default, SeleniumBase will download a driver version that matches your major browser version if not set.
đĄ SeleniumBase automatically detects between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (but optionally you could).
đĄ SeleniumBase methods often perform multiple actions in a single method call. For example, self.type(selector, text)
does the following:
1. Waits for the element to be visible.
2. Waits for the element to be interactive.
3. Clears the text field.
4. Types in the new text.
5. Presses Enter/Submit if the text ends in "\n"
.
With raw Selenium, those actions require multiple method calls.
đĄ SeleniumBase uses default timeout values when not set:
â
self.click("button")
With raw Selenium, methods would fail instantly (by default) if an element needed more time to load:
â self.driver.find_element(by="css selector", value="button").click()
(Reliable code is better than unreliable code.)
đĄ SeleniumBase lets you change the explicit timeout values of methods:
â
self.click("button", timeout=10)
With raw Selenium, that requires more code:
â WebDriverWait(driver, 10).until(EC.element_to_be_clickable("css selector", "button")).click()
(Simple code is better than complex code.)
đĄ SeleniumBase gives you clean error output when a test fails. With raw Selenium, error messages can get very messy.
đĄ SeleniumBase gives you the option to generate a dashboard and reports for tests. It also saves screenshots from failing tests to the ./latest_logs/
folder. Raw Selenium does not have these options out-of-the-box.
đĄ SeleniumBase includes desktop GUI apps for running tests, such as SeleniumBase Commander for pytest
and SeleniumBase Behave GUI for behave
.
đĄ SeleniumBase has its own Recorder / Test Generator for creating tests from manual browser actions.
đĄ SeleniumBase comes with test case management software, ("Case Plans"), for organizing tests and step descriptions.
đĄ SeleniumBase includes tools for building data apps, ("Chart Maker"), which can generate JavaScript from Python.