Skip to main content

Python library that simplifies Selenium WebDriver UI test automation

Project description

Selenium UI Test Tool

Python library that simplifies Selenium WebDriver UI test automation.

๐ŸŒ Languages

๐Ÿ“‹ Table of Contents

๐Ÿš€ Installation

Install from PyPI (when published)

pip install selenium-ui-test-tool

Install from source

git clone <repository-url>
cd selenium_ui_test_tool
pip install -e .

Dependencies

  • Python >= 3.8
  • Selenium >= 4.15.0
  • python-dotenv >= 1.0.0
  • webdriver-manager >= 4.0.1

โš™๏ธ Configuration

Environment variables

Create a .env file at the root of your project with the required variables:

# Sample configuration
CHROMEDRIVER_PATH=/path/to/chromedriver  # Optional
HEADLESS=false  # true to run headless
CI=false  # true when running in CI/CD

ChromeDriver setup

The library automatically handles ChromeDriver in several ways:

  1. Environment variable: if CHROMEDRIVER_PATH is set it will be used.
  2. webdriver-manager: downloads and manages the matching version for you.
  3. Fallback: uses /opt/homebrew/bin/chromedriver (macOS Homebrew) when available.

๐Ÿ“– Usage

Basic example

from selenium_ui_test_tool import BaseTest
from selenium.webdriver.common.by import By

def test_example(driver):
    """Return True when the page title contains 'Example'."""
    title = driver.title
    return "Example" in title

# Create and run the test
test = BaseTest(
    test_function=test_example,
    success_message="โœ… Test passed!",
    failure_message="โŒ Test failed!",
    url="https://example.com",
    exit_on_failure=True
)

test.run()

Using the utilities

from selenium_ui_test_tool import (
    create_driver,
    get_url,
    wait_for_element,
    configure_actions,
    click_element,
    click_on,
    fill_input,
    fill_login_form,
    fill_login_form_with_confirm_password,
    upload_file,
    assert_text_present,
    get_env_var
)
from selenium.webdriver.common.by import By

# Create a driver
driver = create_driver(headless=False)

# Navigate to a URL
get_url(driver, "https://example.com")

# Wait for an element
element = wait_for_element(driver, By.ID, "my-element", timeout=10)

# Configure and run a scroll+click action
configure_actions(driver, By.CSS_SELECTOR, ".my-button")

# Click with custom messages
click_element(
    driver,
    By.ID,
    "submit-button",
    success_message="Button clicked successfully",
    error_message="Unable to click the button"
)

# Build an action store with click_on
ticket_actions = [
    (By.XPATH, "//span[contains(text(),'Annual')]", "Annual section selected"),
    (By.XPATH, "//span[contains(text(),'Annual Pass')]", "Annual Pass selected"),
]

for by, selector, success_message in ticket_actions:
    click_on(
        driver,
        by,
        selector,
        success_message=success_message,
        error_message=f"Unable to click {selector}"
    )

# Fill a form field
fill_input(driver, By.ID, "username", "my_user")

# Fill a full login form
fill_login_form(
    driver,
    username_env="LOGIN_USERNAME",
    password_env="LOGIN_PASSWORD",
    by=By.ID,
    selector="login-form",
    button="login-button"
)

# Upload a file based on an env var path
upload_file(
    driver,
    file_path="FILE_PATH_ENV",  # Environment variable with the absolute path
    input_selector="file-input",
    by=By.ID,
    success_message="File uploaded",
    error_message="Upload failed"
)

# Assert that text is present on the page
assert_text_present(
    driver,
    By.CSS_SELECTOR,
    ".toast-message",
    expected_text="Order completed",
    timeout=5
)

# Read an environment variable
username = get_env_var("LOGIN_USERNAME", required=True)

# Always quit the driver
driver.quit()

๐Ÿ“š API Reference

BaseTest

Main class that orchestrates complete UI tests.

BaseTest(
    test_function: Callable[[WebDriver], bool],
    success_message: str,
    failure_message: str,
    url: str,
    exit_on_failure: bool = True
)
  • test_function: callable that receives a WebDriver and returns True/False.
  • success_message: message printed when the test succeeds.
  • failure_message: message printed when the test fails.
  • url: target URL to load.
  • exit_on_failure: exit the process with code 1 when the test fails.

Methods:

  • setup() โ€“ create the driver and open the URL.
  • teardown() โ€“ close the driver.
  • run() โ€“ run the full flow (setup โ†’ trigger โ†’ teardown).

create_driver(headless: bool = False) -> WebDriver

Create and configure a Chrome WebDriver instance.

get_url(driver: WebDriver, url: str) -> None

Navigate to a given URL.

wait_for_element(driver: WebDriver, by: By, selector: str, timeout: int = 10) -> WebElement | None

Wait for an element to appear in the DOM.

configure_actions(driver: WebDriver, by: By, selector: str) -> bool

Scroll to an element and click it.

click_element(...) -> bool

Enhanced click helper that adds waits, verification, and custom messages.

click_on(...) -> bool

Thin wrapper above click_element that enforces success/error messages.

fill_input(...) -> bool

Scroll to an element, clear the field, and send keys.

fill_login_form(...) -> bool

Automatically fill username/password fields from environment variables and submit.

fill_login_form_with_confirm_password(...) -> bool

Same as fill_login_form but also fills a confirmation password field.

upload_file(...) -> bool

Upload a file through an <input type="file"> element using a path stored in the .env file.

get_env_var(name: str, required: bool = True) -> str | None

Retrieve an environment variable and raise a helpful error if it is missing.

assert_text_present(driver, by, selector, expected_text, timeout=10) -> bool

Wait for an element to appear, then assert that its text contains the expected substring. Raises AssertionError when the text does not match.

  • driver: Selenium WebDriver instance.
  • by: Locator strategy from Selenium's By.
  • selector: Locator used to find the element.
  • expected_text: Substring that must be present within the element text.
  • timeout: Seconds to wait for the element before failing (default 10).

Refer to the French documentation for the full parameter details or use the inline docstrings shipped with the package.

๐Ÿ’ก Examples

Complete login test (with fill_login_form)

from selenium_ui_test_tool import BaseTest, fill_login_form, wait_for_element
from selenium.webdriver.common.by import By

def test_login(driver):
    if not fill_login_form(
        driver,
        username_env="LOGIN_USERNAME",
        password_env="LOGIN_PASSWORD",
        by=By.ID,
        selector="login-form",
        button="login-button"
    ):
        return False

    welcome_message = wait_for_element(driver, By.CLASS_NAME, "welcome", timeout=5)
    return welcome_message is not None

test = BaseTest(
    test_function=test_login,
    success_message="โœ… Logged in successfully!",
    failure_message="โŒ Login failed",
    url="https://example.com/login",
    exit_on_failure=True
)

test.run()

Manual login test (with fill_input)

from selenium_ui_test_tool import BaseTest, fill_input, click_element, get_env_var
from selenium.webdriver.common.by import By

def test_login_manual(driver):
    if not fill_input(driver, By.ID, "username", get_env_var("LOGIN_USERNAME")):
        return False

    if not fill_input(driver, By.ID, "password", get_env_var("LOGIN_PASSWORD")):
        return False

    return click_element(
        driver,
        By.ID,
        "login-button",
        success_message="Login successful",
        error_message="Login failed"
    )

test = BaseTest(
    test_function=test_login_manual,
    success_message="โœ… Login successful!",
    failure_message="โŒ Login failed",
    url="https://example.com/login",
    exit_on_failure=True
)

test.run()

Action store with click_on

from selenium_ui_test_tool import BaseTest, click_on
from selenium.webdriver.common.by import By
import time

ACTIONS_MONTHLY = [
    (By.XPATH, "//span[contains(text(),'Monthly')]", "Monthly section opened"),
    (By.XPATH, "//span[contains(text(),'Monthly Pass')]", "Monthly Pass selected"),
]

def monthly_buying(driver):
    for by, selector, success in ACTIONS_MONTHLY:
        click_on(
            driver,
            by,
            selector,
            success_message=success,
            error_message=f"Unable to click {selector}"
        )

def buying_helper_monthly(driver):
    time.sleep(2)
    monthly_buying(driver)
    return True

test = BaseTest(
    test_function=buying_helper_monthly,
    success_message="โœ… Monthly purchase completed",
    failure_message="โŒ Purchase flow failed",
    url="https://example.com/store"
)

test.run()

Headless mode

from selenium_ui_test_tool import create_driver, get_url
import os

os.environ["HEADLESS"] = "true"

driver = create_driver(headless=True)
get_url(driver, "https://example.com")

# Run your checks...

driver.quit()

Error handling

from selenium_ui_test_tool import BaseTest, wait_for_element
from selenium.webdriver.common.by import By

def test_with_error_handling(driver):
    try:
        element = wait_for_element(driver, By.ID, "my-element", timeout=5)
        if element is None:
            print("โš ๏ธ Element not found")
            return False

        # Your assertions
        return True
    except Exception as e:
        print(f"โŒ Test error: {e}")
        return False

test = BaseTest(
    test_function=test_with_error_handling,
    success_message="โœ… Test passed",
    failure_message="โŒ Test failed",
    url="https://example.com",
    exit_on_failure=False
)

test.run()

๐Ÿ”ง CI/CD Mode

When CI=true is detected:

  • Chrome automatically runs headless.
  • Environment variables are read from GitHub Secrets (or similar).
  • No interactive pause happens at the end.

GitHub Actions sample

name: UI Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Install dependencies
        run: |
          pip install selenium-ui-test-tool
      - name: Run tests
        env:
          CI: true
          LOGIN_USERNAME: ${{ secrets.LOGIN_USERNAME }}
          LOGIN_PASSWORD: ${{ secrets.LOGIN_PASSWORD }}
        run: |
          python your_test_script.py

๐Ÿ“ Project Structure

selenium_ui_test_tool/
โ”œโ”€โ”€ selenium_ui_test_tool/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ base_test/
โ”‚   โ”œโ”€โ”€ click_element/
โ”‚   โ”œโ”€โ”€ config_actions/
โ”‚   โ”œโ”€โ”€ driver_builder/
โ”‚   โ”œโ”€โ”€ get_env_var/
โ”‚   โ”œโ”€โ”€ get_url/
โ”‚   โ””โ”€โ”€ wait_element/
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ setup.py
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ env.example

๐Ÿค Contributing

  1. Fork the project.
  2. Create your feature branch (git checkout -b feature/AmazingFeature).
  3. Commit your changes (git commit -m 'Add AmazingFeature').
  4. Push to the branch (git push origin feature/AmazingFeature).
  5. Open a Pull Request.

๐Ÿ“„ License

MIT License โ€“ see LICENSE for details.

๐Ÿ‘ค Author

Yann Dipita

๐Ÿ› Report a Bug

Please open an issue with:

  • clear description,
  • reproduction steps,
  • expected vs. actual behavior,
  • your environment (OS, Python, Selenium versions).

๐Ÿ“ง Contact

For any question: dipitay@gmail.com.


Note: This library is under active development. Minor releases may introduce breaking changes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

selenium_ui_test_tool-2.1.0.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

selenium_ui_test_tool-2.1.0-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file selenium_ui_test_tool-2.1.0.tar.gz.

File metadata

  • Download URL: selenium_ui_test_tool-2.1.0.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for selenium_ui_test_tool-2.1.0.tar.gz
Algorithm Hash digest
SHA256 9a657eae71db93c8d8d8fa1b743c7e9961c82ed4c2a0017639abcea0d3971dd8
MD5 535a88ec2b7ff17123060663aea93e56
BLAKE2b-256 860ea182c1bc60c1eb4948fb38024f57b728f1f03e52b181ade08fa67b2e00a5

See more details on using hashes here.

File details

Details for the file selenium_ui_test_tool-2.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for selenium_ui_test_tool-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1eac3e2d41454155c3c2e946896a53890b9376ce9587191ca0ee9d30b08b251b
MD5 3a6d517075b4084db1499e9603c2a1bc
BLAKE2b-256 aa556079b603d7d6c2c839c11804f8c54bb47c633af55ec75f10301c0ed07446

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page