โœ… Python web automation and testing. ๐Ÿš€ Fast, easy, reliable. ๐Ÿ’ 

Overview

SeleniumBase

Build fast, reliable, end-to-end tests.

Latest Release on GitHub Latest Release on PyPI SeleniumBase GitHub Actions SeleniumBase Azure Pipelines SeleniumBase SeleniumBase.io Docs

SeleniumBase is a Python framework for web automation, end-to-end testing, and more. Tests are run with "pytest". Browsers are controlled by WebDriver.

๐Ÿš€ Start | ๐Ÿ—‚๏ธ Features | ๐Ÿ–ฅ๏ธ CLI | ๐Ÿ‘จโ€๐Ÿซ Examples | โ™ป๏ธ Boilerplates | ๐Ÿ—พ Locales | ๐Ÿ—„๏ธ PkgManager
๐Ÿ“— API | ๐Ÿ“Š Reports | ๐Ÿ’ป Scripts | ๐Ÿ“ฑ Mobile | ๐Ÿ”ก Syntax Formats | ?? Grid Hub | โบ๏ธ Recorder
๐Ÿค– CI | ๐ŸŒ Translate | ๐Ÿ—บ๏ธ Tours | ๐Ÿ–ผ๏ธ VisualTest | ๐Ÿ“‘ Presenter | ๐Ÿ“ˆ ChartMaker | ๐Ÿ›‚ MasterQA

โœ… Get set up in minutes. Deploy anywhere.
โœ… Build Web-UI tests with a complete API.
โœ… Generate test reports and dashboards.


Example: my_first_test.py (--demo mode)

pytest my_first_test.py --demo

SeleniumBase Demo Mode

Python Setup:

๐Ÿ”ต Add Python and Git to your System PATH.

๐Ÿ”ต Create a Python virtual environment.

Install SeleniumBase:

๐Ÿ”ต You can install seleniumbase from GitHub:

git clone https://github.com/seleniumbase/SeleniumBase.git
cd SeleniumBase/
pip install .  # Normal installation
pip install -e .  # Editable install

(When using a virtual env, the Editable install is faster.)

๐Ÿ”ต You can also install seleniumbase from pypi:

pip install seleniumbase

(Add --upgrade OR -U to upgrade an installation.) (Add --force-reinstall to upgrade dependencies.) (Use pip3 if multiple versions of Python are installed.)

๐Ÿ”ต Type seleniumbase or sbase to verify that SeleniumBase was installed successfully:

   ______     __           _                 ____                
  / ____/__  / /__  ____  (_)_  ______ ___  / _  \____  ________ 
  \__ \/ _ \/ / _ \/ __ \/ / / / / __ `__ \/ /_) / __ \/ ___/ _ \
 ___/ /  __/ /  __/ / / / / /_/ / / / / / / /_) / (_/ /__  /  __/
/____/\___/_/\___/_/ /_/_/\__,_/_/ /_/ /_/_____/\__,_/____/\___/ 
-----------------------------------------------------------------

 * USAGE: "seleniumbase [COMMAND] [PARAMETERS]"
 *    OR:        "sbase [COMMAND] [PARAMETERS]"

COMMANDS:
      install         [DRIVER] [OPTIONS]
      methods         (List common Python methods)
      options         (List common pytest options)
      mkdir           [DIRECTORY] [OPTIONS]
      mkfile          [FILE.py] [OPTIONS]
      mkpres          [FILE.py] [LANG]
      print           [FILE] [OPTIONS]
      translate       [SB_FILE.py] [LANG] [ACTION]
      convert         [WEBDRIVER_UNITTEST_FILE.py]
      extract-objects [SB_FILE.py]
      inject-objects  [SB_FILE.py] [OPTIONS]
      objectify       [SB_FILE.py] [OPTIONS]
      revert-objects  [SB_FILE.py] [OPTIONS]
      encrypt         (OR: obfuscate)
      decrypt         (OR: unobfuscate)
      download server (The Selenium Grid JAR file)
      grid-hub        [start|stop] [OPTIONS]
      grid-node       [start|stop] --hub=[HOST/IP]
 * (EXAMPLE: "sbase install chromedriver latest")  *

    Type "sbase help [COMMAND]" for specific command info.
    For info on all commands, type: "seleniumbase --help".
 * (Use "pytest" for running tests) *

Download a webdriver:

โœ… SeleniumBase can download webdrivers to the seleniumbase/drivers folder with the install command:

sbase install chromedriver
  • You need a different webdriver for each browser to automate: chromedriver for Chrome, edgedriver for Edge, geckodriver for Firefox, and operadriver for Opera.
  • If you have the latest version of Chrome installed, get the latest chromedriver (otherwise it defaults to chromedriver 2.44 for compatibility reasons):
sbase install chromedriver latest
  • If you run a test without the correct webdriver installed, the driver will be downloaded automatically.

(See seleniumbase.io/seleniumbase/console_scripts/ReadMe/ for more information on SeleniumBase console scripts.)

Running tests:

๐Ÿ”ต If you've cloned SeleniumBase from GitHub, you can run sample tests from the examples/ folder:

cd examples/
pytest test_demo_site.py

(Chrome is the default browser if not specified with --browser=BROWSER. On Linux, --headless is the default behavior. You can also run in headless mode on any OS. If your Linux machine has a GUI and you want to see the web browser as tests run, add --headed or --gui.)


๐Ÿ”ต Here are more examples that you can run:

pytest my_first_test.py

pytest test_swag_labs.py

๐Ÿ”ต Run my_first_test.py in Demo Mode:

pytest my_first_test.py --demo

SeleniumBase Demo Mode

Here's the code for my_first_test.py:

from seleniumbase import BaseCase

class MyTestClass(BaseCase):

    def test_basics(self):
        url = "https://store.xkcd.com/collections/posters"
        self.open(url)
        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("About")
        self.assert_exact_text("xkcd.com", "h2")
  • By default, CSS Selectors are used for finding page elements.
  • If you're new to CSS Selectors, games like Flukeout can help you learn.
  • Here are some common SeleniumBase methods you might find in tests:
self.open(URL)  # Navigate to the web page
self.click(SELECTOR)  # Click a page element
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
self.assert_no_404_errors()  # Assert no 404 errors from files on the page
self.assert_no_js_errors()  # Assert no JavaScript errors on the page (Chrome-ONLY)
self.execute_script(JAVASCRIPT)  # Execute JavaScript code
self.go_back()  # Navigate to the previous URL
self.get_text(SELECTOR)  # Get text from a selector
self.get_attribute(SELECTOR, ATTRIBUTE)  # Get a specific attribute from a selector
self.is_element_visible(SELECTOR)  # Determine if an element is visible on the page
self.is_text_visible(TEXT)  # Determine if text is visible on the page (optional SELECTOR)
self.hover_and_click(HOVER_SELECTOR, CLICK_SELECTOR)  # Mouseover element & click another
self.select_option_by_text(DROPDOWN_SELECTOR, OPTION_TEXT)  # Select a dropdown option
self.switch_to_frame(FRAME_NAME)  # Switch webdriver control to an iframe on the page
self.switch_to_default_content()  # Switch webdriver control out of the current iframe
self.switch_to_window(WINDOW_NUMBER)  # Switch to a different window/tab
self.save_screenshot(FILE_NAME)  # Save a screenshot of the current page

๐Ÿ”ต For the complete list of SeleniumBase methods, see: Method Summary

Learn More:

โœ… Automatic WebDriver Abilities:

SeleniumBase automatically handles common WebDriver actions such as spinning up web browsers and saving screenshots during test failures. (Read more about customizing test runs.)

โœ… Simplified Code:

SeleniumBase uses simple syntax for commands. Example:

self.type("input", "dogs\n")

SeleniumBase tests can be run with both pytest and nosetests, but using pytest is recommended. (chrome is the default browser if not specified.)

pytest my_first_test.py --browser=chrome

nosetests test_suite.py --browser=firefox

โœ… Automatic Test Discovery:

All Python methods that start with test_ will automatically be run when using pytest or nosetests on a Python file, (or on folders containing Python files). You can also be more specific on what to run within a file by using the following: (Note that the syntax is different for pytest vs nosetests.)

pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]

nosetests [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]

โœ… No More Flaky Tests:

SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (up to a timeout limit). This means you no longer need random time.sleep() statements in your scripts.

NO MORE FLAKY TESTS!

โœ… Automated/Manual Hybrid Mode:

SeleniumBase includes a solution called MasterQA, which speeds up manual testing by having automation perform all the browser actions while the manual tester handles validation.

โœ… Feature-Rich:

For a full list of SeleniumBase features, Click Here.

Detailed Instructions:

Use Demo Mode to help you see what tests are asserting.

๐Ÿ”ต If the example test is moving too fast for your eyes, you can run it in Demo Mode by adding --demo on the command-line, which pauses the browser briefly between actions, highlights page elements being acted on, and lets you know what test assertions are happening in real time:

pytest my_first_test.py --demo

๐Ÿ”ต Pytest includes test discovery. If you don't specify a specific file or folder to run from, pytest will search all subdirectories automatically for tests to run based on the following matching criteria: Python filenames that start with test_ or end with _test.py. Python methods that start with test_. The Python class name can be anything since SeleniumBase's BaseCase class inherits from the unittest.TestCase class. You can see which tests are getting discovered by pytest by using:

pytest --collect-only -q

๐Ÿ”ต You can use the following calls in your scripts to help you debug issues:

import time; time.sleep(5)  # Makes the test wait and do nothing for 5 seconds.
import ipdb; ipdb.set_trace()  # Enter debugging mode. n = next, c = continue, s = step.
import pytest; pytest.set_trace()  # Enter debugging mode. n = next, c = continue, s = step.

๐Ÿ”ต To pause an active test that throws an exception or error, add --pdb:

pytest my_first_test.py --pdb

The code above will leave your browser window open in case there's a failure. (ipdb commands: 'n', 'c', 's' => next, continue, step).

๐Ÿ”ต Here are some useful command-line options that come with pytest:

-v  # Verbose mode. Prints the full name of each test run.
-q  # Quiet mode. Print fewer details in the console output when running tests.
-x  # Stop running the tests after the first failure is reached.
--html=report.html  # Creates a detailed pytest-html report after tests finish.
--collect-only | --co  # Show what tests would get run. (Without running them)
-n=NUM  # Multithread the tests using that many threads. (Speed up test runs!)
-s  # See print statements. (Should be on by default with pytest.ini present.)
--junit-xml=report.xml  # Creates a junit-xml report after tests finish.
--pdb  # If a test fails, pause run and enter debug mode. (Don't use with CI!)
-m=MARKER  # Run tests with the specified pytest marker.

๐Ÿ”ต SeleniumBase provides additional pytest command-line options for tests:

--browser=BROWSER  # (The web browser to use. Default: "chrome".)
--chrome  # (Shortcut for "--browser=chrome". On by default.)
--edge  # (Shortcut for "--browser=edge".)
--firefox  # (Shortcut for "--browser=firefox".)
--opera  # (Shortcut for "--browser=opera".)
--safari  # (Shortcut for "--browser=safari".)
--cap-file=FILE  # (The web browser's desired capabilities to use.)
--cap-string=STRING  # (The web browser's desired capabilities to use.)
--settings-file=FILE  # (Override default SeleniumBase settings.)
--env=ENV  # (Set a test environment. Use "self.env" to use this in tests.)
--data=DATA  # (Extra test data. Access with "self.data" in tests.)
--var1=DATA  # (Extra test data. Access with "self.var1" in tests.)
--var2=DATA  # (Extra test data. Access with "self.var2" in tests.)
--var3=DATA  # (Extra test data. Access with "self.var3" in tests.)
--user-data-dir=DIR  # (Set the Chrome user data directory to use.)
--server=SERVER  # (The Selenium Grid server/IP used for tests.)
--port=PORT  # (The Selenium Grid port used by the test server.)
--proxy=SERVER:PORT  # (Connect to a proxy server:port for tests.)
--proxy=USERNAME:[email protected]:PORT  # (Use authenticated proxy server.)
--agent=STRING  # (Modify the web browser's User-Agent string.)
--mobile  # (Use the mobile device emulator while running tests.)
--metrics=STRING  # (Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio".)
--extension-zip=ZIP  # (Load a Chrome Extension .zip|.crx, comma-separated.)
--extension-dir=DIR  # (Load a Chrome Extension directory, comma-separated.)
--headless  # (Run tests headlessly. Default mode on Linux OS.)
--headed  # (Run tests with a GUI on Linux OS.)
--locale=LOCALE_CODE  # (Set the Language Locale Code for the web browser.)
--start-page=URL  # (The starting URL for the web browser when tests begin.)
--archive-logs  # (Archive old log files instead of deleting them.)
--time-limit=SECONDS  # (Safely fail any test that exceeds the time limit.)
--slow  # (Slow down the automation. Faster than using Demo Mode.)
--demo  # (Slow down and visually see test actions as they occur.)
--demo-sleep=SECONDS  # (Set the wait time after Demo Mode actions.)
--highlights=NUM  # (Number of highlight animations for Demo Mode actions.)
--message-duration=SECONDS  # (The time length for Messenger alerts.)
--check-js  # (Check for JavaScript errors after page loads.)
--ad-block  # (Block some types of display ads after page loads.)
--block-images  # (Block images from loading during tests.)
--verify-delay=SECONDS  # (The delay before MasterQA verification checks.)
--disable-csp  # (Disable the Content Security Policy of websites.)
--disable-ws  # (Disable Web Security on Chromium-based browsers.)
--enable-ws  # (Enable Web Security on Chromium-based browsers.)
--enable-sync  # (Enable "Chrome Sync".)
--use-auto-ext  # (Use Chrome's automation extension.)
--remote-debug  # (Enable Chrome's Remote Debugger on http://localhost:9222)
--dashboard  # (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
--swiftshader  # (Use Chrome's "--use-gl=swiftshader" feature.)
--incognito  #  (Enable Chrome's Incognito mode.)
--guest  # (Enable Chrome's Guest mode.)
--devtools  # (Open Chrome's DevTools when the browser opens.)
--reuse-session | --rs  # (Reuse browser session between tests.)
--crumbs  # (Delete all cookies between tests reusing a session.)
--maximize-window  # (Start tests with the web browser window maximized.)
--save-screenshot  # (Save a screenshot at the end of each test.)
--visual-baseline  # (Set the visual baseline for Visual/Layout tests.)
--timeout-multiplier=MULTIPLIER  # (Multiplies the default timeout values.)

(For more details, see the full list of command-line options here.)

๐Ÿ”ต During test failures, logs and screenshots from the most recent test run will get saved to the latest_logs/ folder. Those logs will get moved to archived_logs/ if you add --archive_logs to command-line options, or have ARCHIVE_EXISTING_LOGS set to True in settings.py, otherwise log files with be cleaned up at the start of the next test run. The test_suite.py collection contains tests that fail on purpose so that you can see how logging works.

cd examples/

pytest test_suite.py --browser=chrome

pytest test_suite.py --browser=firefox

An easy way to override seleniumbase/config/settings.py is by using a custom settings file. Here's the command-line option to add to tests: (See examples/custom_settings.py) --settings_file=custom_settings.py (Settings include default timeout values, a two-factor auth key, DB credentials, S3 credentials, and other important settings used by tests.)

๐Ÿ”ต To pass additional data from the command-line to tests, add --data="ANY STRING". Inside your tests, you can use self.data to access that.

Test Directory Configuration:

๐Ÿ”ต When running tests with pytest, you'll want a copy of pytest.ini in your root folders. When running tests with nosetests, you'll want a copy of setup.cfg in your root folders. These files specify default configuration details for tests. Folders should also include a blank __init__.py file, which allows your tests to import files from that folder.

๐Ÿ”ต sbase mkdir DIR creates a folder with config files and sample tests:

sbase mkdir ui_tests

That new folder will have these files:

ui_tests/
โ”œโ”€โ”€ __init__.py
โ”œโ”€โ”€ boilerplates/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ base_test_case.py
โ”‚   โ”œโ”€โ”€ boilerplate_test.py
โ”‚   โ”œโ”€โ”€ page_objects.py
โ”‚   โ””โ”€โ”€ samples/
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ google_objects.py
โ”‚       โ””โ”€โ”€ google_test.py
โ”œโ”€โ”€ my_first_test.py
โ”œโ”€โ”€ parameterized_test.py
โ”œโ”€โ”€ pytest.ini
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ setup.cfg
โ””โ”€โ”€ test_demo_site.py

ProTipโ„ข: You can also create a boilerplate folder without any sample tests in it by adding -b or --basic to the sbase mkdir command:

sbase mkdir ui_tests --basic

That new folder will have these files:

ui_tests/
โ”œโ”€โ”€ __init__.py
โ”œโ”€โ”€ pytest.ini
โ”œโ”€โ”€ requirements.txt
โ””โ”€โ”€ setup.cfg

Of those files, the pytest.ini config file is the most important, followed by a blank __init__.py file. There's also a setup.cfg file (only needed for nosetests). Finally, the requirements.txt file can be used to help you install seleniumbase into your environments (if it's not already installed).


Log files from failed tests:

Let's try an example of a test that fails:

""" test_fail.py """
from seleniumbase import BaseCase

class MyTestClass(BaseCase):

    def test_find_army_of_robots_on_xkcd_desert_island(self):
        self.open("https://xkcd.com/731/")
        self.assert_element("div#ARMY_OF_ROBOTS", timeout=1)  # This should fail

You can run it from the examples/ folder like this:

pytest test_fail.py

๐Ÿ”ต You'll notice that a logs folder, "latest_logs", was created to hold information about the failing test, and screenshots. During test runs, past results get moved to the archived_logs folder if you have ARCHIVE_EXISTING_LOGS set to True in settings.py, or if your run tests with --archive-logs. If you choose not to archive existing logs, they will be deleted and replaced by the logs of the latest test run.


The SeleniumBase Dashboard:

๐Ÿ”ต The --dashboard option for pytest generates a SeleniumBase Dashboard located at dashboard.html, which updates automatically as tests run and produce results. Example:

pytest --dashboard --rs --headless

The SeleniumBase Dashboard

๐Ÿ”ต Additionally, you can host your own SeleniumBase Dashboard Server on a port of your choice. Here's an example of that using Python 3's http.server:

python -m http.server 1948

๐Ÿ”ต Now you can navigate to http://localhost:1948/dashboard.html in order to view the dashboard as a web app. This requires two different terminal windows: one for running the server, and another for running the tests, which should be run from the same directory. (Use CTRL-C to stop the http server.)

๐Ÿ”ต Here's a full example of what the SeleniumBase Dashboard may look like:

pytest test_suite.py --dashboard --rs --headless

The SeleniumBase Dashboard


Creating Visual Test Reports:

Pytest Reports:

๐Ÿ”ต Using --html=report.html gives you a fancy report of the name specified after your test suite completes.

pytest test_suite.py --html=report.html

Example Pytest Report

๐Ÿ”ต When combining pytest html reports with SeleniumBase Dashboard usage, the pie chart from the Dashboard will get added to the html report. Additionally, if you set the html report URL to be the same as the Dashboard URL when also using the dashboard, (example: --dashboard --html=dashboard.html), then the Dashboard will become an advanced html report when all the tests complete.

๐Ÿ”ต Here's an example of an upgraded html report:

pytest test_suite.py --dashboard --html=report.html

Dashboard Pytest HTML Report

If viewing pytest html reports in Jenkins, you may need to configure Jenkins settings for the html to render correctly. This is due to Jenkins CSP changes.

You can also use --junit-xml=report.xml to get an xml report instead. Jenkins can use this file to display better reporting for your tests.

pytest test_suite.py --junit-xml=report.xml

Nosetest Reports:

The --report option gives you a fancy report after your test suite completes.

nosetests test_suite.py --report

Example Nosetest Report

(NOTE: You can add --show-report to immediately display Nosetest reports after the test suite completes. Only use --show-report when running tests locally because it pauses the test run.)

Allure Reports:

See: https://docs.qameta.io/allure/

pytest test_suite.py --alluredir=allure_results

Using a Proxy Server:

If you wish to use a proxy server for your browser tests (Chromium or Firefox), you can add --proxy=IP_ADDRESS:PORT as an argument on the command line.

pytest proxy_test.py --proxy=IP_ADDRESS:PORT

If the proxy server that you wish to use requires authentication, you can do the following (Chromium only):

pytest proxy_test.py --proxy=USERNAME:[email protected]_ADDRESS:PORT

SeleniumBase also supports SOCKS4 and SOCKS5 proxies:

pytest proxy_test.py --proxy="socks4://IP_ADDRESS:PORT"

pytest proxy_test.py --proxy="socks5://IP_ADDRESS:PORT"

To make things easier, you can add your frequently-used proxies to PROXY_LIST in proxy_list.py, and then use --proxy=KEY_FROM_PROXY_LIST to use the IP_ADDRESS:PORT of that key.

pytest proxy_test.py --proxy=proxy1

Changing the User-Agent:

๐Ÿ”ต If you wish to change the User-Agent for your browser tests (Chromium and Firefox only), you can add --agent="USER AGENT STRING" as an argument on the command-line.

pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU"

Building Guided Tours for Websites:

๐Ÿ”ต Learn about SeleniumBase Interactive Walkthroughs (in the examples/tour_examples/ folder). It's great for prototyping a website onboarding experience.

Production Environments & Integrations:

๐Ÿ”ต Here are some things you can do to set up a production environment for your testing:

Here's an example of running tests with additional features enabled:

pytest [YOUR_TEST_FILE.py] --with-db-reporting --with-s3-logging

Detailed Method Specifications and 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 self.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.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:

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:

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 existence 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 backwards 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

๐Ÿ”ต Handling 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 next example, JavaScript creates a referral button on a page, which is then clicked:

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 deferred 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 deferred asserts come in. Here's the example:

from seleniumbase import BaseCase

class MyTestClass(BaseCase):

    def test_deferred_asserts(self):
        self.open('https://xkcd.com/993/')
        self.wait_for_element('#comic')
        self.deferred_assert_element('img[alt="Brand Identity"]')
        self.deferred_assert_element('img[alt="Rocket Ship"]')  # Will Fail
        self.deferred_assert_element('#comicmap')
        self.deferred_assert_text('Fake Item', '#middleContainer')  # Will Fail
        self.deferred_assert_text('Random', '#middleContainer')
        self.deferred_assert_element('a[name="Super Fake !!!"]')  # Will Fail
        self.process_deferred_asserts()

deferred_assert_element() and deferred_assert_text() will save any exceptions that would be raised. To flush out all the failed deferred asserts into a single exception, make sure to call self.process_deferred_asserts() at the end of your test method. If your test hits multiple pages, you can call self.process_deferred_asserts() before navigating to a new page so that the screenshot from your log files matches the URL where the deferred 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](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/common).

Wrap-Up

Congratulations on getting started with SeleniumBase!

If you see something, say something!

If you like us, give us a star!

Repo Size Join the chat!

SeleniumBase on GitHub SeleniumBase on Gitter SeleniumBase on Twitter SeleniumBase on Instagram SeleniumBase on Facebook

Comments
  • Record without ipdb

    Record without ipdb

    I would like to record user web actions using sbase mkrec recording.py --url=http://google.com . I want some help with the following

    1. when the user closes the browser, the recording is saved.
    2. I want to remove import ipdb; ipdb.set_trace() or automatically enter c in terminal and remove

    my script is as follows:

    def user_prompt_title(filename, url_str):
        url_valid = validate_url(url_str)
        if url_valid:
            if os.path.exists(filename):
                os.remove(filename)
            os.system(f"sbase mkrec {file_name} --url={string_}")
    

    desired behavior: when the above script is run by user input (irrelevant how to this question) when the user closes the browser. The recording is saved as a pytest file normally

    question 
    opened by elsheikh21 37
  • How does MySQL log in using a non-default port?

    How does MySQL log in using a non-default port?

    APP_CREDS = {

    Apps.TESTCASE_REPOSITORY: {
        TEST: (
            settings.DB_HOST,
            settings.DB_USERNAME,
            settings.DB_PASSWORD,
            settings.DB_SCHEMA)
    },
    
    opened by cw010 21
  • self.double_click('select'),will close chrome

    self.double_click('select'),will close chrome

    self.click is True. self.hover_and_double_click is none. self.double_click,chrome is close.

    windows 10 python 3.7.5 pytest 3.7.5 seleniumbase 1.37.14 chrome 68.0.3440.75

    opened by zhonghai9967 18
  • Does seleniumBase support recording electron applications?

    Does seleniumBase support recording electron applications?

    Does seleniumIDE support recording electron applications?

    I want to use seleniumIDE to record automation scripts for electron applications. If so, what should I modify in the source code to replace our electron application path๏ผŸ

    If anyone also working on the recording of automated test scripts for electron applications, please contact me:[email protected]

    question 
    opened by GuiStarF 16
  • self.type does not work with ie

    self.type does not work with ie

    The following code, works under firefox, and chrome. Under IE 11 (specifically 11.1082.18362.0), it simply fails. Reporting that the input#UserName element does not exist.

    2020-10-23 12_39_39-LK Archive - Internet Explorer

    I clearly see the element, although IE is horribly slow to inspect the element.

    Is there a better way, for me to manage this. Since IE is the "officially" supported browser for our organization, I really should perform the automated testing with it.

        def locker_login(self, username=SERVER_TO_TEST["USER"],
                            password=SERVER_TO_TEST["PASSWORD"]):
            """
            Login to the web site, user the username and password provided.
            """
            self.go_to_server()
            self.type("input#UserName", username)
            self.type("input#Password", password)
            self.click(".btn")
            self.assert_element_present("span.username", timeout=5)
    
    question incorrect usage 
    opened by bschollnick 15
  •  self.hover_and_click() does not support xpath

    self.hover_and_click() does not support xpath

    Look like self.hover_and_click() does not support xpath any way. I try to use just

    def test_sub_menu(self):
            self.get("https://www.babyshop.com")
            self.hover_and_click('//a[@data-class="babyshoes"]', '//div[@class="babyshoes mid-navigation-container"]//a')
    

    and try

    from selenium.webdriver.common.by import By
    def test_sub_menu(self):
            self.get("https://www.babyshop.com")
            self.hover_and_click('//a[@data-class="babyshoes"]', '//div[@class="babyshoes mid-navigation-container"]//a',By.XPATH,By.XPATH)
    

    but its function work only with css-selector

    opened by alex-pancho 15
  • run pytest with seleniumbase failed:

    run pytest with seleniumbase failed: "argparse.ArgumentError: argument --headless: conflicting option string: --headless"

    ######## issues ######################################################## $pytest Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.8/bin/pytest", line 8, in sys.exit(console_main()) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 185, in console_main code = main() File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 143, in main config = _prepareconfig(args, plugins) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 318, in _prepareconfig config = pluginmanager.hook.pytest_cmdline_parse( File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in call return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall gen.send(outcome) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/helpconfig.py", line 100, in pytest_cmdline_parse config: Config = outcome.get_result() File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result raise ex[1].with_traceback(ex[2]) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall res = hook_impl.function(*args) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 1003, in pytest_cmdline_parse self.parse(args) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 1283, in parse self._preparse(args, addopts=addopts) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/init.py", line 1175, in _preparse self.known_args_namespace = self._parser.parse_known_args( File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/argparsing.py", line 146, in parse_known_args return self.parse_known_and_unknown_args(args, namespace=namespace)[0] File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/argparsing.py", line 155, in parse_known_and_unknown_args optparser = self._getparser() File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/_pytest/config/argparsing.py", line 122, in _getparser arggroup.add_argument(*n, **a) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/argparse.py", line 1386, in add_argument return self._add_action(action) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/argparse.py", line 1590, in _add_action action = super(_ArgumentGroup, self)._add_action(action) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/argparse.py", line 1400, in _add_action self._check_conflict(action) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/argparse.py", line 1539, in _check_conflict conflict_handler(action, confl_optionals) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/argparse.py", line 1548, in _handle_conflict_error raise ArgumentError(action, message % conflict_string) argparse.ArgumentError: argument --headless: conflicting option string: --headless

    ######################################################################################## ######### my pip list ####################################################################### ########################################################################################

    $ pip list Package Version


    akshare 1.0.87 alembic 1.7.4 allure-pytest 2.9.45 allure-python-commons 2.9.45 amqp 5.0.6 apin 1.1.3 apispec 3.3.2 appdirs 1.4.4 Appium-Python-Client 1.2.0 appnope 0.1.2 APScheduler 3.6.3 asgiref 3.2.7 assertpy 1.1 astor 0.8.1 astroid 2.4.0 async-generator 1.10 atomicwrites 1.3.0 attrs 21.2.0 Automat 20.2.0 Babel 2.9.1 backcall 0.2.0 backoff 1.11.1 backports.entry-points-selectable 1.1.0 baostock 0.8.8 bcrypt 3.2.0 beautifulsoup4 4.10.0 behave 1.2.6 billiard 3.6.4.0 bitstring 3.1.9 bleach 4.1.0 boto 2.49.0 boto3 1.12.16 botocore 1.15.16 Brotli 1.0.9 bs4 0.0.1 celery 5.1.2 certifi 2021.10.8 cffi 1.15.0 chardet 4.0.0 charset-normalizer 2.0.7 click 8.0.3 click-didyoumean 0.3.0 click-plugins 1.1.1 click-repl 0.2.0 colorama 0.4.4 commonmark 0.9.1 compare 0.2b0 ConfigArgParse 1.2.1 configparser 5.0.0 constantly 15.1.0 contextlib2 21.6.0 coreapi 2.3.3 coreschema 0.0.4 croniter 1.0.15 crypto 1.4.1 cryptography 35.0.0 cssselect 1.1.0 cycler 0.10.0 dash 2.0.0 dash-bootstrap-components 1.0.0 dash-colorscales 0.0.4 dash-core-components 2.0.0 dash-daq 0.5.0 dash-html-components 2.0.0 dash-table 5.0.0 ddt 1.3.1 decorator 5.1.0 defusedxml 0.7.1 demjson 2.2.4 diff-match-patch 20181111 distlib 0.3.3 Django 2.0.2 django-cors-headers 2.1.0 django-crispy-forms 1.7.2 django-filter 2.2.0 django-formtools 2.1 django-import-export 1.0.0 django-rest-swagger 2.1.2 django-reversion 2.0.13 django-suit 2.0a1 djangorestframework 3.7.7 dnspython 2.1.0 docutils 0.15.2 dtable 0.0.5 edict 0.51 elist 0.4.65 email-validator 1.1.3 et-xmlfile 1.0.1 execnet 1.9.0 Faker 8.11.0 fasteners 0.16.3 filelock 3.3.2 Flask 2.0.2 Flask-AppBuilder 3.3.4 Flask-Babel 2.0.0 Flask-Caching 1.10.1 Flask-Compress 1.10.1 Flask-JWT-Extended 3.25.1 Flask-Migrate 3.1.0 flask-ngrok 0.0.25 Flask-OpenID 1.3.0 Flask-Script 2.0.6 Flask-SQLAlchemy 2.5.1 func-timeout 4.3.5 future 0.18.2 fuzzywuzzy 0.18.0 gensim 3.8.1 geographiclib 1.52 geopy 2.2.0 get 2019.4.13 gevent 1.5a3 geventhttpclient-wheels 1.3.1.dev2 glob2 0.7 greenlet 0.4.15 h11 0.12.0 html5lib 1.1 htmlmin 0.1.12 humanize 3.12.0 hyperlink 19.0.0 idna 3.3 ImageHash 4.2.1 importlib-metadata 4.8.1 importlib-resources 5.3.0 incremental 17.5.0 iniconfig 1.1.1 install 1.3.4 int-date 0.1.8 ipdb 0.13.9 ipython 7.29.0 isodate 0.6.0 isort 4.3.21 itsdangerous 2.0.1 itypes 1.1.0 jdcal 1.4.1 jedi 0.18.0 jieba 0.42.1 Jinja2 3.0.2 jmespath 0.10.0 joblib 1.1.0 jsonpath 0.82 jsonschema 3.2.0 kaleido 0.2.1 kiwisolver 1.3.1 kombu 5.1.0 lazy-object-proxy 1.4.3 locustio 0.14.5 lxml 4.4.1 lz4 3.1.3 Mako 1.1.5 Markdown 3.2.1 MarkupSafe 2.0.1 marshmallow 3.14.0 marshmallow-enum 1.5.1 marshmallow-sqlalchemy 0.26.1 matplotlib 3.4.2 matplotlib-inline 0.1.3 mccabe 0.6.1 missingno 0.4.2 more-itertools 8.11.0 MouseInfo 0.1.3 msgpack 0.6.2 multimethod 1.6 Naked 0.1.31 networkx 2.6.3 nose 1.3.7 numpy 1.21.3 openapi-codec 1.3.2 openpyxl 3.0.7 osxmetadata 0.99.33 outcome 1.1.0 packaging 21.2 pandas 1.3.4 parameterized 0.8.1 paramiko 2.7.2 parse 1.19.0 parse-type 0.5.2 parsedatetime 2.6 parsel 1.5.2 parso 0.8.2 pathlib2 2.3.6 patsy 0.5.2 pdfminer.six 20211012 pexpect 4.8.0 phik 0.12.0 pickleshare 0.7.5 Pillow 8.4.0 pip 21.3.1 pipenv 2021.5.29 platformdirs 2.4.0 plotly 5.3.1 pluggy 1.0.0 poium 1.0.2 polyline 1.4.0 post 2019.4.13 ppscore 1.2.0 prison 0.2.1 prompt-toolkit 3.0.22 Protego 0.1.16 psutil 5.7.0 ptyprocess 0.7.0 public 2019.4.13 py 1.11.0 py-applescript 1.0.2 py-mini-racer 0.6.0 pyarrow 5.0.0 pyasn1 0.4.8 pyasn1-modules 0.2.8 PyAutoGUI 0.9.53 pycparser 2.21 pydantic 1.8.2 PyDispatcher 2.0.5 PyGetWindow 0.0.9 Pygments 2.10.0 PyHamcrest 2.0.2 PyJWT 1.7.1 pylint 2.5.0 PyMsgBox 1.0.9 PyMySQL 1.0.2 PyNaCl 1.4.0 pynput 1.7.4 pyobjc 7.3 pyobjc-core 7.3 pyobjc-framework-Accounts 7.3 pyobjc-framework-AddressBook 7.3 pyobjc-framework-AdSupport 7.3 pyobjc-framework-AppleScriptKit 7.3 pyobjc-framework-AppleScriptObjC 7.3 pyobjc-framework-ApplicationServices 7.3 pyobjc-framework-Automator 7.3 pyobjc-framework-AVFoundation 7.3 pyobjc-framework-AVKit 7.3 pyobjc-framework-BusinessChat 7.3 pyobjc-framework-CalendarStore 7.3 pyobjc-framework-CFNetwork 7.3 pyobjc-framework-CloudKit 7.3 pyobjc-framework-Cocoa 7.3 pyobjc-framework-Collaboration 7.3 pyobjc-framework-ColorSync 7.3 pyobjc-framework-Contacts 7.3 pyobjc-framework-ContactsUI 7.3 pyobjc-framework-CoreAudio 7.3 pyobjc-framework-CoreAudioKit 7.3 pyobjc-framework-CoreBluetooth 7.3 pyobjc-framework-CoreData 7.3 pyobjc-framework-CoreLocation 7.3 pyobjc-framework-CoreMedia 7.3 pyobjc-framework-CoreMediaIO 7.3 pyobjc-framework-CoreMIDI 7.3 pyobjc-framework-CoreML 7.3 pyobjc-framework-CoreServices 7.3 pyobjc-framework-CoreSpotlight 7.3 pyobjc-framework-CoreText 7.3 pyobjc-framework-CoreWLAN 7.3 pyobjc-framework-CryptoTokenKit 7.3 pyobjc-framework-DictionaryServices 7.3 pyobjc-framework-DiscRecording 7.3 pyobjc-framework-DiscRecordingUI 7.3 pyobjc-framework-DiskArbitration 7.3 pyobjc-framework-DVDPlayback 7.3 pyobjc-framework-EventKit 7.3 pyobjc-framework-ExceptionHandling 7.3 pyobjc-framework-ExternalAccessory 7.3 pyobjc-framework-FinderSync 7.3 pyobjc-framework-FSEvents 7.3 pyobjc-framework-GameCenter 7.3 pyobjc-framework-GameController 7.3 pyobjc-framework-GameKit 7.3 pyobjc-framework-GameplayKit 7.3 pyobjc-framework-ImageCaptureCore 7.3 pyobjc-framework-IMServicePlugIn 7.3 pyobjc-framework-InputMethodKit 7.3 pyobjc-framework-InstallerPlugins 7.3 pyobjc-framework-InstantMessage 7.3 pyobjc-framework-Intents 7.3 pyobjc-framework-IOSurface 7.3 pyobjc-framework-iTunesLibrary 7.3 pyobjc-framework-LatentSemanticMapping 7.3 pyobjc-framework-LaunchServices 7.3 pyobjc-framework-libdispatch 7.3 pyobjc-framework-LocalAuthentication 7.3 pyobjc-framework-MapKit 7.3 pyobjc-framework-MediaAccessibility 7.3 pyobjc-framework-MediaLibrary 7.3 pyobjc-framework-MediaPlayer 7.3 pyobjc-framework-MediaToolbox 7.3 pyobjc-framework-Metal 7.3 pyobjc-framework-MetalKit 7.3 pyobjc-framework-MetalPerformanceShaders 7.3 pyobjc-framework-ModelIO 7.3 pyobjc-framework-MultipeerConnectivity 7.3 pyobjc-framework-NaturalLanguage 7.3 pyobjc-framework-NetFS 7.3 pyobjc-framework-Network 7.3 pyobjc-framework-NetworkExtension 7.3 pyobjc-framework-NotificationCenter 7.3 pyobjc-framework-OpenDirectory 7.3 pyobjc-framework-OSAKit 7.3 pyobjc-framework-Photos 7.3 pyobjc-framework-PhotosUI 7.3 pyobjc-framework-PreferencePanes 7.3 pyobjc-framework-Quartz 7.3 pyobjc-framework-SafariServices 7.3 pyobjc-framework-SceneKit 7.3 pyobjc-framework-ScreenSaver 7.3 pyobjc-framework-ScriptingBridge 7.3 pyobjc-framework-SearchKit 7.3 pyobjc-framework-Security 7.3 pyobjc-framework-SecurityFoundation 7.3 pyobjc-framework-SecurityInterface 7.3 pyobjc-framework-ServiceManagement 7.3 pyobjc-framework-Social 7.3 pyobjc-framework-SpriteKit 7.3 pyobjc-framework-StoreKit 7.3 pyobjc-framework-SyncServices 7.3 pyobjc-framework-SystemConfiguration 7.3 pyobjc-framework-UserNotifications 7.3 pyobjc-framework-VideoSubscriberAccount 7.3 pyobjc-framework-VideoToolbox 7.3 pyobjc-framework-Vision 7.3 pyobjc-framework-WebKit 7.3 pyOpenSSL 21.0.0 pyotp 2.6.0 pyparsing 2.4.6 pyperclip 1.8.2 pypinyin 0.36.0 PyQt5 5.15.6 PyQt5-Qt5 5.15.2 PyQt5-sip 12.9.0 PyQtWebEngine 5.15.5 PyQtWebEngine-Qt5 5.15.2 PyRect 0.1.4 pyrsistent 0.18.0 PyScreeze 0.1.28 pytab 1.0.4 pytesseract 0.3.8 pytest 6.2.5 pytest-bdd 4.1.0 pytest-forked 1.3.0 pytest-html 2.0.1 pytest-metadata 1.11.0 pytest-ordering 0.6 pytest-parallel 0.1.1 pytest-rerunfailures 10.2 pytest-xdist 2.4.0 python-crontab 2.2.8 python-dateutil 2.8.0 python-docx 0.8.6 python-engineio 3.11.2 python-geohash 0.8.5 python-socketio 4.4.0 python3-openid 3.2.0 pytweening 1.0.4 pytz 2017.3 PyWavelets 1.1.1 PyYAML 6.0 pyzmq 18.1.0 qtstylish 0.1.5 query-string 2019.4.13 queuelib 1.5.0 redis 2.10.6 redis-py-cluster 2.1.0 request 2019.4.13 requests 2.26.0 requests-toolbelt 0.9.1 retry 0.9.2 rich 10.13.0 rsa 4.7.2 ruamel.yaml 0.16.12 ruamel.yaml.clib 0.2.6 rubicon-objc 0.4.1 s3transfer 0.3.3 sbvirtualdisplay 1.0.0 scikit-learn 0.24.2 scipy 1.7.1 Scrapy 2.0.0 seaborn 0.11.2 seldom 2.2.4 selenium 4.0.0 seleniumbase 2.1.5 service-identity 18.1.0 setuptools 58.5.3 setuptools-scm 6.3.2 shellescape 3.8.1 simplejson 3.17.2 six 1.16.0 sklearn 0.0 smart-open 1.9.0 sniffio 1.2.0 sortedcontainers 2.4.0 soupsieve 2.3 SQLAlchemy 1.3.13 SQLAlchemy-Utils 0.37.9 sqlparse 0.3.1 squarify 0.4.3 statsmodels 0.13.0 stockstats 0.3.2 strsimpy 0.2.1 superset 0.30.1 tablib 1.1.0 tabulate 0.8.9 tangled-up-in-unicode 0.2.0 tblib 1.7.0 tenacity 8.0.1 text-unidecode 1.3 threadpoolctl 3.0.0 tlist 0.6 toml 0.10.2 tomli 1.2.2 tornado 6.1 tqdm 4.61.0 traitlets 5.1.1 trio 0.19.0 trio-websocket 0.9.2 tushare 1.2.62 Twisted 19.10.0 typing-extensions 3.10.0.2 tzlocal 2.0.0 unittest-xml-reporting 3.0.4 uritemplate 3.0.1 urllib3 1.26.7 vine 5.0.0 virtualenv 20.10.0 virtualenv-clone 0.5.7 visions 0.7.4 w3lib 1.21.0 wcwidth 0.1.9 webencodings 0.5.1 websocket-client 0.57.0 Werkzeug 2.0.2 wheel 0.37.0 wordcloud 1.8.1 wrapt 1.12.1 wsproto 1.0.0 WTForms 2.3.3 WTForms-JSON 0.3.3 xarray 0.20.0 xattr 0.9.7 xlrd 1.2.0 XlsxWriter 1.0.5 zipp 3.6.0 zope.interface 4.7.1

    pytest and operating system versions pytest-6.2.5 seleniumbase 2.1.5 MacBook Air (Retina, 13-inch, 2019) 1.6 GHz Intel Core i5 8 GB 2133 MHz LPDDR3 Intel UHD Graphics 617 1536 MB

    opened by matthewxuda 14
  • How to triple click a text field/area?

    How to triple click a text field/area?

    Hi @mdmintz ,

    Is there any way to perform triple clicks?

    I need to select text from a field and I might have multiple whitespaces inside the text, so a double click won't suffice.

    Many thanks!

    question 
    opened by createNull 14
  • How do I add a custom Chrome command-line argument?

    How do I add a custom Chrome command-line argument?

    I have a Python project using SeleniumBase 1.34.11 that's running inside a docker container, and I'm forwarding my pytest run to the X server on my Linux host. Unfortunately, Chrome v79 has a bug that makes it render a blank window to my host X server (nothing, no UI at all).

    In the Chromium project bug report, one commenter suggests starting Chrome with --use-gl=swiftshader to enable software rendering. This works for me; I can run google-chrome --use-gl=swiftshader, and I get a regular Chome window with full UI.

    I'd like to send that argument to Chrome via SeleniumBase. I've looked through the documentation and the issues in this repo, but I don't see any mention or examples of custom Chrome options. In the codebase, I see where the browser launcher's _set_chrome_options gets a ChromeOptions object and sets arguments on it, but it seems like it only understands hardcoded arguments.

    Is there a way to add a custom Chrome command-line argument?

    enhancement 
    opened by mildmojo 14
  • `--cap-file=CAP_FILE` only works with tests that run on Selenium Grid

    `--cap-file=CAP_FILE` only works with tests that run on Selenium Grid

    Currently, SeleniumBase has cap_file option, that doesn't seem to work.

    What I want to achieve is to add {'goog:loggingPrefs': {'browser': 'ALL'}}. Unfortunately, the only way I achieved that is by ugly monkey-patching around the webdriver.

    I've tried to set cap_file to file with something like below, but it didn't work. Actually nothing happened. There was no difference in capabilities with or without the file.

    My example cap_file:

    capabilities  = desired_cap = desired_capabilities = {'goog:loggingPrefs': {'browser': 'ALL'}}
    

    I've debugged the sources and it seems that the get_local_driver() method doesn't use the file at all.

    enhancement 
    opened by aklajnert 14
  • urllib3 version conflict

    urllib3 version conflict

    We are experiencing issues with urllib3 and error is pkg_resources.VersionConflict: (urllib3 1.25 (/usr/lib/python3.6/site-packages), Requirement.parse('urllib3<1.25.0,>=1.24.2'))

    In https://github.com/seleniumbase/SeleniumBase/blob/master/requirements.txt, need to change urllib3 version from 1.24.2 to 1.25.0. urllib3 has a latest release 1.25.0, please check here https://pypi.org/project/urllib3/#history

    Thanks

    opened by himasimplisafe 14
  • Undetected-Driver

    Undetected-Driver

    Hi! First of all, I would like to congratulate you on the project. I'm loving working with Selenium Base. I was facing problems with Headless from Undetected Chrome, and one of the solutions was to use 'import Driver'.

    My question is, can I use the same SB() tools together with the Driver? like css selectors, automatically wait for elements, and other amazing features. I'm new to programming, and the project is helping me a lot.

    opened by pedrots00 3
  • Maintainer on vacation from January 6 to January 12, 2023

    Maintainer on vacation from January 6 to January 12, 2023

    Hey, this is the maintainer of SeleniumBase. I'll be on vacation January 6 to January 12. Will be in Florida again, like my previous vacation a year ago (https://github.com/seleniumbase/SeleniumBase/issues/1224). Responses will be very delayed. I might be able to respond to simple questions via smartphone, but I plan on keeping the laptop lid closed during the trip, so I probably won't answer any questions until next Thursday when I'm back.

    maintainer on vacation 
    opened by mdmintz 0
  • NEWS: SeleniumBase Case Plans for test management is here! ๐Ÿ—‚๏ธ

    NEWS: SeleniumBase Case Plans for test management is here! ๐Ÿ—‚๏ธ

    SeleniumBase Case Plans ๐Ÿ—‚๏ธ

    ๐Ÿ—‚๏ธ SeleniumBase Case Plans is Test Case Management Software that uses Markdown tables for displaying test plans directly in GitHub (and other source code management systems that support Markdown format).

    ๐Ÿ—‚๏ธ The case_summary.md file is generated from individual Case Plans that exist in the case_plans/ folders of your repository. (See the example below to learn how the Case Summary file may look.)


    Example of a case_summary.md file:

    Summary of existing Case Plans

    | | | | | - | -: | - | | ๐Ÿ”ต | 8 | Case Plans with customized tables | | โญ• | 2 | Case Plans using boilerplate code | | ๐Ÿšง | 1 | Case Plan that is missing a table |


    ๐Ÿ”Ž (Click rows to expand) ๐Ÿ”

    ๐Ÿ”ต basic_test.py::MyTestClass::test_basics

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Log in to https://www.saucedemo.com with standard_user. | Login was successful. | | 2 | Click on the Backpack ADD TO CART button. | The button text changed to REMOVE. | | 3 | Click on the cart icon. | The Backpack is seen in the cart. | | 4 | Remove the Backpack from the cart. | The Backpack is no longer in the cart. | | 5 | Log out from the website. | Logout was successful. |

    ๐Ÿ”ต list_assert_test.py::MyTestClass::test_assert_list_of_elements

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://seleniumbase.io/demo_page. | | | 2 | Use self.assert_elements_present("head", "style", "script") to verify that multiple elements are present in the HTML. | The assertion is successful. | | 3 | Use self.assert_elements("h1", "h2", "h3") to verify that multiple elements are visible. | The assertion is successful. | | 4 | Use self.assert_elements(["#myDropdown", "#myButton", "#svgRect"]) to verify that multiple elements are visible. | The assertion is successful. |

    โญ• locale_code_test.py::LocaleCodeTests::test_locale_code

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Perform Action 1 | Verify Action 1 | | 2 | Perform Action 2 | Verify Action 2 |

    ๐Ÿ”ต my_first_test.py::MyTestClass::test_swag_labs

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Log in to https://www.saucedemo.com with standard_user. | Login was successful. | | 2 | Click on the Backpack ADD TO CART button. | The button text changed to REMOVE. | | 3 | Click on the cart icon. | The Backpack is seen in the cart. | | 4 | Click on the CHECKOUT button.
    Enter user details and click CONTINUE. | The Backpack is seen in the cart on the CHECKOUT: OVERVIEW page. | | 5 | Click on the FINISH button. | There is a Thank You message and a Pony Express delivery logo. | | 6 | Log out from the website. | Logout was successful. |

    โญ• proxy_test.py::ProxyTests::test_proxy

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Perform Action 1 | Verify Action 1 | | 2 | Perform Action 2 | Verify Action 2 |

    ๐Ÿ”ต shadow_root_test.py::ShadowRootTest::test_shadow_root

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://seleniumbase.io/other/shadow_dom.
    Click each tab and verify the text contained within the Shadow Root sections. | Tab 1 text: Content Panel 1
    Tab 2 text: Content Panel 2
    Tab 3 text: Content Panel 3 |

    ๐Ÿšง test_agent.py::UserAgentTests::test_user_agent

    ๐Ÿ”ต test_calculator.py::CalculatorTests::test_6_times_7_plus_12_equals_54

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://seleniumbase.io/apps/calculator.
    Perform the following calculation: 6 ร— 7 + 12 | The output is 54 after pressing = |

    ๐Ÿ”ต test_demo_site.py::DemoSiteTests::test_demo_site

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://seleniumbase.io/demo_page | | | 2 | Assert the title of the current web page.
    Assert that a given element is visible on the page.
    Assert that a text substring appears in an element's text. | The assertions were successful. | | 3 | Type text into various text fields and then verify. | The assertions were successful. | | 4 | Verify that a hover dropdown link changes page text. | The assertion was successful. | | 5 | Verify that a button click changes text on the page. | The assertion was successful. | | 6 | Verify that an SVG element is located on the page. | The assertion was successful. | | 7 | Verify that a slider control updates a progress bar. | The assertion was successful. | | 8 | Verify that a "select" option updates a meter bar. | The assertion was successful. | | 9 | Assert an element located inside an iFrame. | The assertion was successful. | | 10 | Assert text located inside an iFrame. | The assertion was successful. | | 11 | Verify that clicking a radio button selects it. | The assertion was successful. | | 12 | Verify that clicking an empty checkbox makes it selected. | The assertion was successful. | | 13 | Verify clicking on multiple elements with one call. | The assertions were successful. | | 14 | Verify that clicking an iFrame checkbox selects it. | The assertions were successful. | | 15 | Verify that Drag and Drop works. | The assertion was successful. | | 16 | Assert link text. | The assertion was successful. | | 17 | Verify clicking on link text. | The action was successful. | | 18 | Assert exact text in an element. | The assertion was successful. | | 19 | Highlight a page element. | The action was successful. | | 20 | Verify that Demo Mode works. | The assertion was successful. |

    ๐Ÿ”ต test_login.py::SwagLabsLoginTests::test_swag_labs_login

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Log in to https://www.saucedemo.com with standard_user. | Login was successful. | | 2 | Log out from the website. | Logout was successful. |

    ๐Ÿ”ต test_mfa_login.py::TestMFALogin::test_mfa_login

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://seleniumbase.io/realworld/login
    Enter credentials and Sign In. | Sign In was successful. | | 2 | Click the This Page button.
    Save a screenshot to the logs. | | | 3 | Click to Sign Out | Sign Out was successful. |


    ๐Ÿ—‚๏ธ Before you can generate a case_summary.md file that includes your existing Case Plans, first you'll need to select which existing tests you want to create boilerplate Case Plans from. For that, you can use the SeleniumBase Case Plans GUI:

    sbase caseplans
    

    ๐Ÿ—‚๏ธ Once you are running the Case Plans GUI, select the existing tests that need Case Plans, and then click: Generate boilerplate Case Plans for selected tests missing them. For each selected test that didn't already have a Case Plan file, one will be generated. Each new Case Plan file starts with default boilerplate code with a Markdown table. Eg:

    ``proxy_test.py::ProxyTests::test_proxy``
    ---
    | # | Step Description | Expected Result |
    | - | ---------------- | --------------- |
    | 1 | Perform Action 1 | Verify Action 1 |
    | 2 | Perform Action 2 | Verify Action 2 |
    
    

    ๐Ÿ—‚๏ธ When rendered as a Markdown table, the result looks like this:

    proxy_test.py::ProxyTests::test_proxy

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Perform Action 1 | Verify Action 1 | | 2 | Perform Action 2 | Verify Action 2 |

    ๐Ÿ—‚๏ธ Markdown tables are flexible, but must be constructed correctly to be displayed. For a Markdown table to render, it's important that you place pipes (|), dashes (-), and spaces in the correct locations. If you want a line break in a step, use <br />. If you want an empty step, put a space between pipes, eg: | |.

    ๐Ÿ—‚๏ธ Here's an example of a Case Plan for my_first_test.py:

    my_first_test.py::MyTestClass::test_swag_labs

    | # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Log in to https://www.saucedemo.com with standard_user. | Login was successful. | | 2 | Click on the Backpack ADD TO CART button. | The button text changed to REMOVE. | | 3 | Click on the cart icon. | The Backpack is seen in the cart. | | 4 | Click on the CHECKOUT button.
    Enter user details and click CONTINUE. | The Backpack is seen in the cart on the CHECKOUT: OVERVIEW page. | | 5 | Click on the FINISH button. | There is a Thank You message and a Pony Express delivery logo. | | 6 | Log out from the website. | Logout was successful. |

    ๐Ÿ—‚๏ธ After you've created some Case Plans, you can use the Generate Summary of existing Case Plans button in the Case Plans GUI to generate the Case Plans Summary file.

    ๐Ÿ—‚๏ธ The generated Case Plans summary file, case_summary.md, gets created in the same location where the Case Plans GUI was launched. This is NOT the same location where individual Case Plan boilerplates are generated, which is in the case_plans/ folders. The case_plans/ folders are generated where individual tests live, which means that if you have your tests in multiple folders, then you could also have multiple case_plans/ folders. A case_summary.md file may look like this when rendered:

    ๐Ÿ—‚๏ธ When calling sbase caseplans, you can provide additional arguments to limit the tests that appear in the list. The same discovery rules apply as when using pytest. Eg:

    sbase caseplans
    sbase caseplans -k agent
    sbase caseplans -m marker2
    sbase caseplans test_suite.py
    sbase caseplans offline_examples/
    

    See Case Plans in action here: case_summary.md

    NEWS SeleniumBase 4 
    opened by mdmintz 0
Releases(v4.11.2)
  • v4.11.2(Jan 4, 2023)

    Add methods for URL asserts

    • Add methods for URL asserts --> https://github.com/seleniumbase/SeleniumBase/commit/3321e5204ffe16f6a78fe5ed1473972205bb7959 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1654
    • Update translations --> https://github.com/seleniumbase/SeleniumBase/commit/98f49c19bc2e14e2e6fe59d5923ce320afe5f0e3
    • Update behave/BDD steps --> https://github.com/seleniumbase/SeleniumBase/commit/a61db3ae83dcea3afde654f245af268caf66fd82
    • Update Recorder Mode --> https://github.com/seleniumbase/SeleniumBase/commit/e6b9d82fc6cf1b99cbd710e98ba3c584d2bc3bb8

    self.assert_url(url)  # Assert that the current URL is same as the one provided.
    
    self.assert_url_contains(substring)  # Assert that the current URL contains the substring.
    
    Source code(tar.gz)
    Source code(zip)
  • v4.11.1(Jan 4, 2023)

    Refactoring and Recorder updates

    • Refactoring --> https://github.com/seleniumbase/SeleniumBase/commit/2bddc00f97a8e79ab7fc67e8f32aa41487972ef0
    • Add steps for behave/BDD mode --> https://github.com/seleniumbase/SeleniumBase/commit/e179dc3e4260b64a67edb9dfff68e0bc9330044d
    • Update Recorder Mode --> https://github.com/seleniumbase/SeleniumBase/commit/d6cb38606e23807b5b052f3250cd2cc81c764d08
    • Refresh Python dependencies --> https://github.com/seleniumbase/SeleniumBase/commit/aa806dedee707d0d9291c23223e2946bd7589b72
    • Update example tests --> https://github.com/seleniumbase/SeleniumBase/commit/04233e618a1504e14907d04568371267ef7c61d0
    Source code(tar.gz)
    Source code(zip)
  • v4.11.0(Dec 31, 2022)

    Simplifying, upgrading, and refactoring

    • Add a class method to run "pytest" if "python" was used instead --> https://github.com/seleniumbase/SeleniumBase/commit/a811e878632bc3bd79675de77f03b85da186ec6d --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1647
    • Simplify hover actions --> https://github.com/seleniumbase/SeleniumBase/commit/813ff3d5515fe9780384533e1ea9d8361cf25dda --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1649
    • Add context_click() / right_click() --> https://github.com/seleniumbase/SeleniumBase/commit/0cf99b0e6b548752ade1b29aba23a000652c5a07 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1646
    • Drop support for Python 2.7 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1651
    • Update console scripts --> https://github.com/seleniumbase/SeleniumBase/commit/c251e5a0fca96f2e6307a2f51353c4a5048df704
    • Update Recorder script generation --> https://github.com/seleniumbase/SeleniumBase/commit/eb2a33d0033cff7b269893f82dfbc70502af4861
    • Refresh Python dependencies --> https://github.com/seleniumbase/SeleniumBase/commit/5c1deaa8d1498b66ab06d82e42fc31a8142599f8
    Source code(tar.gz)
    Source code(zip)
  • v4.10.0(Dec 24, 2022)

    Update themes and add options

    • Update the default theme for Demo Mode notifications --> https://github.com/seleniumbase/SeleniumBase/commit/ac834861f1c7d682af9c9736f1396649bdae6557 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1641
    • Preload jQuery during Demo Mode on page loads --> https://github.com/seleniumbase/SeleniumBase/commit/1173c16309f4ab127ef935eb69ebd105760cf73c --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1644
    • Add "--rcs" option to reuse session for tests in same class --> https://github.com/seleniumbase/SeleniumBase/commit/95c336e0f9bcc3d0d0a5905b6454a402d290b963 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1642
    • Output the last page during test failures in verbose mode --> https://github.com/seleniumbase/SeleniumBase/commit/9338fcbf765056e392359b13a398a72eabe8262f --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1643
    • Refresh Python dependencies --> https://github.com/seleniumbase/SeleniumBase/commit/62ca490f19357a75022fa4d473c88f9b5f9ad704
    • Update several examples
    • Update a lot of documentation
    Source code(tar.gz)
    Source code(zip)
  • v4.9.11(Dec 22, 2022)

    Headless and --env settings

    • When setting headless mode, don't use options.headless --> https://github.com/seleniumbase/SeleniumBase/commit/63306d83923749e20f2dd22b3ef3332e26246d5e --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1638
    • Add --env=uat (User Acceptance Testing) --> https://github.com/seleniumbase/SeleniumBase/commit/f48da77f87ab28f905bf86a2de93171ff23482ee --> This completes changes from version 4.9.10
    Source code(tar.gz)
    Source code(zip)
  • v4.9.10(Dec 21, 2022)

    Driver Manager updates and dependencies

    • Refactor the Driver Manager --> Improvements for undetected-chromedriver users on M1/M2 Macs --> For non-M1/M2 Mac users, chromedriver is copied over as needed
    • Add a new built-in option for "--env=ENV" --> Eg. --env=uat --> https://github.com/seleniumbase/SeleniumBase/commit/0aa67c7f0ef7ee59afdc9d903130e0dbdab1d5ec
    • Update the jQuery version for scripts that use it --> (Now using 3.6.3) --> https://github.com/seleniumbase/SeleniumBase/commit/a2d5a10c651c386d554b51b2a63f7448a868e7b8
    • Refresh Python dependencies --> attrs>=22.2.0;python_version>="3.7" --> https://github.com/seleniumbase/SeleniumBase/commit/a3df451cd422e551c4700a23bd0aad6cf40f9eed
    Source code(tar.gz)
    Source code(zip)
  • v4.9.9(Dec 18, 2022)

    Refresh docs and dependencies

    • Refresh the pdbp dependency --> https://github.com/seleniumbase/SeleniumBase/commit/fdecc6ec38c68d16d2d4e0409a5d5bebfeb6721c --> More info on pdbp: https://github.com/mdmintz/pdbp
    Source code(tar.gz)
    Source code(zip)
  • v4.9.8(Dec 16, 2022)

    SB Context Manager improvements

    • This resolves https://github.com/seleniumbase/SeleniumBase/issues/1633
    • This resolves https://github.com/seleniumbase/SeleniumBase/issues/1634
    • Refresh Python dependencies: --> https://github.com/seleniumbase/SeleniumBase/commit/99e0c39492cf3da8f3230b46c068f72752ed1368
    Source code(tar.gz)
    Source code(zip)
  • v4.9.7(Dec 7, 2022)

  • v4.9.6(Dec 5, 2022)

  • v4.9.4(Dec 2, 2022)

    Improved debugging, and more

    • Update to the latest version of pdbp (Pdb+).
    • Update console scripts.
    • Handle a special case with Recorder Mode and iframes.
    • Refresh Python dependencies. --> https://github.com/seleniumbase/SeleniumBase/commit/e32d381bf84e05d36d2e621247c8e7a451e0f579
    • pytest --remote-debug is synced to chrome://inspect/#devices
    Source code(tar.gz)
    Source code(zip)
  • v4.9.3(Nov 30, 2022)

  • v4.9.2(Nov 29, 2022)

    My Own Debugger and More

    • See https://github.com/seleniumbase/SeleniumBase/issues/1623 for details.
    • I created https://github.com/mdmintz/pdbp
    • I also created https://github.com/mdmintz/tabcompleter

    SeleniumBase will automatically use the new debugger when a breakpoint is reached.


    Other changes:


    New Debugger Info

    I've been building my own debugger as an upgrade to pdb, called pdbp (Pdb+): https://github.com/mdmintz/pdbp. Originally, I tried using https://github.com/pdbpp/pdbpp, but that has bugs, and the maintainer hasn't fixed them yet. My only alternative is to build my own debugger clone if I want all my required fixes in.

    The good news is that I'm already done. The whole project and upgrade took me less than a day to complete! I'm just testing the parts to make sure everything is good before I include the new Python packages as a SeleniumBase dependency. Here's what was made:

    • https://github.com/mdmintz/tabcompleter (a replacement for https://github.com/pdbpp/fancycompleter)
    • https://github.com/mdmintz/pdbp (a replacement for https://github.com/pdbpp/pdbpp)

    Here's what the main issue was: pdbpp has a dependency on fancycompleter, which has a Windows dependency on pyreadline (https://github.com/pyreadline/pyreadline), which has this issue: https://github.com/pyreadline/pyreadline/issues/65, which leads to this error: AttributeError: module 'collections' has no attribute 'Callable'.

    Here's what I did: I created pdbp with a dependency on my own library tabcompleter, which has a dependency on the improved pyreadline3 (https://github.com/pyreadline3/pyreadline3/) instead of pyreadline. Then things started working again. As a bonus, I fixed some bugs and improved on default configuration settings.

    If testing goes well, the new debugger,pdbp / (Pdb+) will be included with SeleniumBase dependencies very soon.


    Screenshot 2022-11-28 at 1 26 59 PM Source code(tar.gz)
    Source code(zip)
  • v4.9.1(Nov 26, 2022)

    Install special debuggers optionally

    • Install special debuggers optionally. --> https://github.com/seleniumbase/SeleniumBase/commit/4e4fb11b65e84f54356a757715f6ff81bd09b112 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1619 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1620
    Source code(tar.gz)
    Source code(zip)
  • v4.9.0(Nov 25, 2022)

    New Debugger and More

    • Replace "ipdb" with an upgraded "pdb" debugger. --> https://github.com/seleniumbase/SeleniumBase/commit/a6822e93887c6140e4f5bf8ccb0b303623f40d94 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1615
    • Remove deprecated browser capabilities. --> https://github.com/seleniumbase/SeleniumBase/commit/408e037497f7463f43a78a3a355317cbb9601cd5
    • Fix issue with taking screenshots in headless mode. --> https://github.com/seleniumbase/SeleniumBase/commit/b8a0463f57debbc3351daac9cb2e01f56cf73bfa --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1616
    • Time optimizations for different modes.
    • Better handling of multithreaded tests.
    Source code(tar.gz)
    Source code(zip)
  • v4.8.6(Nov 18, 2022)

    Refactoring and removing deprecated drivers

    • Update Dockerfile to use a newer geckodriver.
    • Remove references to PhantomJS and integrations.
    • Remove Opera from Selenium Grid configurations.
    • Remove Android from DesiredCapabilities options.
    Source code(tar.gz)
    Source code(zip)
  • v4.8.5(Nov 18, 2022)

    Fix driver downloads on M1/M2 Macs

    • Fix driver downloads on M1/M2 Macs --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1612 --> https://github.com/seleniumbase/SeleniumBase/commit/f114c0ff56c8be6ea6c0b2ea9fe77ad60680bfb0
    Source code(tar.gz)
    Source code(zip)
  • v4.8.4(Nov 17, 2022)

    Optimizations

    • Optimize Recorder Mode --> https://github.com/seleniumbase/SeleniumBase/commit/628d7ec2ff1e5f702f42966236bd0334a0468ee1
    • Optimize Undetected Mode --> https://github.com/seleniumbase/SeleniumBase/commit/d99773fcd4e3b224d9f82731b3fde83a98f0e92f
    • Optimize ipdb Mode --> https://github.com/seleniumbase/SeleniumBase/commit/ad7569ba3b80650c24f25fab61c46b7ba49d8d3d
    • Refresh Python dependencies --> https://github.com/seleniumbase/SeleniumBase/commit/0d295047f778577e1ea9a4016de902f13cb864e4
    Source code(tar.gz)
    Source code(zip)
  • v4.8.3(Nov 11, 2022)

    Improve Mac M1 and M2 compatibility

    • Fix an issue with getting older drivers on M1/M2 Macs: --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1605 --> https://github.com/seleniumbase/SeleniumBase/commit/d21ff8ebad3bfc7cf2dbbcb4e731e42a2fed62e7
    • Also add translations for more methods: --> https://github.com/seleniumbase/SeleniumBase/commit/95e1818e8b9db61ce7170abb38a08407479cec4b
    • Also refresh Python dependencies: --> https://github.com/seleniumbase/SeleniumBase/commit/eab999d515f10953ea4f749ff8ab09db30f89a71
    Source code(tar.gz)
    Source code(zip)
  • v4.8.2(Nov 9, 2022)

    Mac M1 and M2 compatibility

    • Improve compatibility for M1 and M2 Macs. --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1601 --> Chrome and Edge spin up much faster on M1 and M2 Macs. --> Overall performance on Chrome and Edge is also improved.
    Source code(tar.gz)
    Source code(zip)
  • v4.8.1(Nov 7, 2022)

    Fix proxy with auth and refresh Python dependencies

    • Fix proxy with auth. --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1599
    • Refresh Python dependencies. --> Refresh Python dependencies
    • Add more retry time for failed driver downloads. --> The driver manager now waits an extra two seconds.
    • Update documentation.

    To proxy with authentication in tests, you can run pytest with:

    pytest --proxy="USER:[email protected]:PORT"
    
    Source code(tar.gz)
    Source code(zip)
  • v4.7.2(Nov 2, 2022)

    Python 3.11 updates and more

    • Fix save_teardown_screenshot() for Python 3.11 --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1593
    • Improve methods that scroll to elements.
    • Prevent extra waiting of Safari tests in Demo Mode.
    Source code(tar.gz)
    Source code(zip)
  • v4.7.1(Nov 2, 2022)

    Python 3.11 Official Support

    • Add "--no-screenshot" option to skip saving screenshots. --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1591
    • Improve Python 3.11 compatibility --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1590
    • Improve browser compatibility. --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1588
    • Improve undetectable mode compatibility. --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1586
    • Update plugins.
    • Refresh Python dependencies. --> https://github.com/seleniumbase/SeleniumBase/commit/d8b0032f47f7be31ddfc64d7c1261c893643a939
    Source code(tar.gz)
    Source code(zip)
  • v4.7.0(Oct 30, 2022)

    Wire integration, UC updates, new console methods, and more

    • Add support for the selenium-wire library --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1574
    • Prevent setting user_data_dir twice when using uc mode --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1569
    • Handle UC Mode when used with incompatible modes --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1579
    • Raise VisualException for visual diff assertion failures --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1577
    • Add more exclude options for self.assert_no_js_errors() --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1576
    • Update the SB context manager and Driver manager --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1582
    • Add sbase shortcuts for seleniumbase --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1581
    • Add new methods for console log interaction --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1575
    • Backport ExceptionGroup to earlier Python versions --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1580
    • Upgrade pytest to 7.2.0 to get all the new improvements --> This resolves https://github.com/seleniumbase/SeleniumBase/issues/1578
    Source code(tar.gz)
    Source code(zip)
  • v4.6.6(Oct 25, 2022)

    All kinds of updates

    • Refactor Undetectable Mode
    • Add option to enable WebGL and 3D APIs (--enable-3d-apis)
    • Add option to use Undetectable Mode with Recorder
    • Add wait_for_query_selector() method
    • Refresh Python dependencies
    Source code(tar.gz)
    Source code(zip)
  • v4.6.5(Oct 21, 2022)

    Update default settings for Undetected Mode

    • Update default settings for Undetected Mode (--uc): --> Use a subprocess for pure Python syntax formats --> (pytest tests still need to use --uc-sub)
    • Check if an attribute is defined before using it: --> This fixes an issue when not using pytest
    Source code(tar.gz)
    Source code(zip)
  • v4.6.4(Oct 20, 2022)

    Add arg for excluding URLs from assert_no_js_errors()

    • Add arg for excluding URLs from assert_no_js_errors()

        def assert_no_js_errors(self, exclude=[]):
            """Asserts current URL has no "SEVERE"-level JavaScript errors.
            Works ONLY on Chromium browsers (Chrome or Edge).
            Does NOT work on Firefox, IE, Safari, or some other browsers:
                * See https://github.com/SeleniumHQ/selenium/issues/1161
            Based on the following Stack Overflow solution:
                * https://stackoverflow.com/a/41150512/7058266
            @Params
            exclude -->
                A list of substrings or a single comma-separated string of
                substrings for filtering out error URLs that contain them.
                URLs that contain any excluded substring will get excluded
                from the final errors list that's used with the assertion.
            Examples:
                self.assert_no_js_errors()
                self.assert_no_js_errors(exclude=["/api.", "/analytics."])
                self.assert_no_js_errors(exclude="//api.go,/analytics.go")
            """
    
    Source code(tar.gz)
    Source code(zip)
  • v4.6.3(Oct 20, 2022)

    Flexible Driver Manager

    • Make the standalone Driver Manager more flexible. --> More options when using the Driver Manager without BaseCase. --> Added shorter method names as duplicates for some methods.
    • Refresh Python dependencies. --> https://github.com/seleniumbase/SeleniumBase/commit/e6e0971c94087e4aa53846dca61c0bfa142ef7b3

    The driver manager (via context manager)

    This pure Python format gives you a raw webdriver instance in a with block. The SeleniumBase Driver Manager will automatically make sure that your driver is compatible with your browser version. It gives you full access to customize driver options via method args or via the command-line. The driver will automatically call quit() after the code leaves the with block. Here are some examples:

    """This script can be run with pure "python". (pytest not needed)."""
    from seleniumbase import js_utils
    from seleniumbase import page_actions
    from seleniumbase import Driver
    
    # Python Context Manager
    with Driver() as driver:  # By default, browser="chrome"
        driver.get("https://google.com/ncr")
        js_utils.highlight_with_js(driver, 'img[alt="Google"]', 6, "")
    
    with Driver() as driver:  # Also accepts command-line options
        driver.get("https://seleniumbase.github.io/demo_page")
        js_utils.highlight_with_js(driver, "h2", 5, "")
        by_css = "css selector"
        driver.find_element(by_css, "#myTextInput").send_keys("Automation")
        driver.find_element(by_css, "#checkBox1").click()
        js_utils.highlight_with_js(driver, "img", 5, "")
    
    # Python Context Manager (with options given)
    with Driver(browser="chrome", incognito=True) as driver:
        driver.get("https://seleniumbase.io/apps/calculator")
        page_actions.wait_for_element(driver, "4", "id").click()
        page_actions.wait_for_element(driver, "2", "id").click()
        page_actions.wait_for_text(driver, "42", "output", "id")
        js_utils.highlight_with_js(driver, "#output", 6, "")
    

    (See examples/raw_driver.py for an example.)

    The driver manager (via direct import)

    Another way of running Selenium tests with pure python (as opposed to using pytest or nosetests) is by using this format, which bypasses BaseCase methods while still giving you a flexible driver with a manager. SeleniumBase includes helper files such as page_actions.py, which may help you get around some of the limitations of bypassing BaseCase. Here's an example:

    """This script can be run with pure "python". (pytest not needed)."""
    from seleniumbase import Driver
    from seleniumbase import js_utils
    from seleniumbase import page_actions
    
    # Example with options. (Also accepts command-line options.)
    driver = Driver(browser="chrome", headless=False)
    try:
        driver.get("https://seleniumbase.io/apps/calculator")
        page_actions.wait_for_element(driver, "4", "id").click()
        page_actions.wait_for_element(driver, "2", "id").click()
        page_actions.wait_for_text(driver, "42", "output", "id")
        js_utils.highlight_with_js(driver, "#output", 6, "")
    finally:
        driver.quit()
    
    # Example 2 using default args or command-line options
    driver = Driver()
    driver.get("https://seleniumbase.github.io/demo_page")
    js_utils.highlight_with_js(driver, "h2", 5, "")
    by_css = "css selector"
    driver.find_element(by_css, "#myTextInput").send_keys("Automation")
    driver.find_element(by_css, "#checkBox1").click()
    js_utils.highlight_with_js(driver, "img", 5, "")
    driver.quit()  # If the script fails early, the driver still quits
    

    (From examples/raw_browser_launcher.py)

    The above format can be used as a drop-in replacement for virtually every Python/selenium framework, as it uses the raw driver instance for handling commands. The Driver() method simplifies the work of managing drivers with optimal settings, and it can be configured via multiple method args. The Driver also accepts command-line options (such as python --headless) so that you don't need to modify your tests directly to use different settings. These command-line options only take effect if the associated method args remain unset (or set to None) for the specified options.

    Source code(tar.gz)
    Source code(zip)
A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

PyAutoGUI PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. pip inst

Al Sweigart 7.5k Dec 31, 2022
Code coverage measurement for Python

Coverage.py Code coverage testing for Python. Coverage.py measures code coverage, typically during test execution. It uses the code analysis tools and

Ned Batchelder 2.3k Jan 04, 2023
Automated mouse clicker script using PyAutoGUI and Typer.

clickpy Automated mouse clicker script using PyAutoGUI and Typer. This app will randomly click your mouse between 1 second and 3 minutes, to prevent y

Joe Fitzgibbons 0 Dec 01, 2021
Sixpack is a language-agnostic a/b-testing framework

Sixpack Sixpack is a framework to enable A/B testing across multiple programming languages. It does this by exposing a simple API for client libraries

1.7k Dec 24, 2022
Fail tests that take too long to run

GitHub | PyPI | Issues pytest-fail-slow is a pytest plugin for making tests fail that take too long to run. It adds a --fail-slow DURATION command-lin

John T. Wodder II 4 Nov 27, 2022
Selenium Page Object Model with Python

Page-object-model (POM) is a pattern that you can apply it to develop efficient automation framework.

Mohammad Ifran Uddin 1 Nov 29, 2021
WEB PENETRATION TESTING TOOL ๐Ÿ’ฅ

N-WEB ADVANCE WEB PENETRATION TESTING TOOL Features ๐ŸŽญ Admin Panel Finder Admin Scanner Dork Generator Advance Dork Finder Extract Links No Redirect H

56 Dec 23, 2022
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

909 Dec 15, 2022
Auto-hms-action - Automation of NU Health Management System

๐Ÿฆพ Automation of NU Health Management System ๐Ÿค– ้•ทๅดŽๅคงๅญฆ ๅฅๅบท็ฎก็†ใ‚ทใ‚นใƒ†ใƒ ใฎ่‡ชๅ‹•ๅŒ– ๐Ÿฏ Usage / ไฝฟใ„ๆ–น

k5-mot 3 Mar 04, 2022
A simple serverless create api test repository. Please Ignore.

serverless-create-api-test A simple serverless create api test repository. Please Ignore. Things to remember: Setup workflow Change Name in workflow e

Sarvesh Bhatnagar 1 Jan 18, 2022
Free cleverbot without headless browser

Cleverbot Scraper Simple free cleverbot library that doesn't require running a heavy ram wasting headless web browser to actually chat with the bot, a

Matheus Fillipe 3 Sep 25, 2022
1st Solution to QQ Browser 2021 AIAC Track 2

1st Solution to QQ Browser 2021 AIAC Track 2 This repository is the winning solution to QQ Browser 2021 AI Algorithm Competition Track 2 Automated Hyp

DAIR Lab 24 Sep 10, 2022
Yet another python home automation project. Because a smart light is more than just on or off

Automate home Yet another home automation project because a smart light is more than just on or off. Overview When talking about home automation there

Maja Massarini 62 Oct 10, 2022
A automated browsing experience.

browser-automation This app is an automated browsing technique where one has to enter the required information, it's just like searching for Animals o

Ojas Barawal 3 Aug 04, 2021
A twitter bot that simply replies with a beautiful screenshot of the tweet, powered by poet.so

Poet this! Replies with a beautiful screenshot of the tweet, powered by poet.so Installation git clone https://github.com/dhravya/poet-this.git cd po

Dhravya Shah 30 Dec 04, 2022
Doggo Browser

Doggo Browser Quick Start $ python3 -m venv ./venv/ $ source ./venv/bin/activate $ pip3 install -r requirements.txt $ ./sobaki.py References Heavily I

Alexey Kutepov 9 Dec 12, 2022
bulk upload files to libgen.lc (Selenium script)

LibgenBulkUpload bulk upload files to http://libgen.lc/librarian.php (Selenium script) Usage ./upload.py to_upload uploaded rejects So title and autho

8 Jul 07, 2022
Test scripts etc. for experimental rollup testing

rollup node experiments Test scripts etc. for experimental rollup testing. untested, work in progress python -m venv venv source venv/bin/activate #

Diederik Loerakker 14 Jan 25, 2022
Subprocesses for Humans 2.0.

Delegator.py โ€” Subprocesses for Humans 2.0 Delegator.py is a simple library for dealing with subprocesses, inspired by both envoy and pexpect (in fact

Amit Tripathi 1.6k Jan 04, 2023
automate the procedure of 403 response code bypass

403bypasser automate the procedure of 403 response code bypass Description i notice a lot of #bugbountytips describe how to bypass 403 response code s

smackerdodi2 40 Dec 16, 2022