Python library that simplifies Selenium WebDriver UI test automation.
- π«π· Lire la documentation en franΓ§ais
- Installation
- Configuration
- Usage
- API Reference
- Examples
- CI/CD Mode
- Project Structure
- Contributing
- License
- Author
- Report a Bug
- Contact
pip install selenium-ui-test-toolgit clone <repository-url>
cd selenium_ui_test_tool
pip install -e .- Python >= 3.8
- Selenium >= 4.15.0
- python-dotenv >= 1.0.0
- webdriver-manager >= 4.0.1
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/CDThe library automatically handles ChromeDriver in several ways:
- Environment variable: if
CHROMEDRIVER_PATHis set it will be used. - webdriver-manager: downloads and manages the matching version for you.
- Fallback: uses
/opt/homebrew/bin/chromedriver(macOS Homebrew) when available.
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()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()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 aWebDriverand returnsTrue/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 code1when 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 and configure a Chrome WebDriver instance.
Navigate to a given URL.
Wait for an element to appear in the DOM.
Scroll to an element and click it.
Enhanced click helper that adds waits, verification, and custom messages.
Thin wrapper above click_element that enforces success/error messages.
Scroll to an element, clear the field, and send keys.
Automatically fill username/password fields from environment variables and submit.
Same as fill_login_form but also fills a confirmation password field.
Upload a file through an <input type="file"> element using a path stored in the .env file.
Retrieve an environment variable and raise a helpful error if it is missing.
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'sBy.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 (default10).
Refer to the French documentation for the full parameter details or use the inline docstrings shipped with the package.
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()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()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()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()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()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.
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.pyselenium_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
- Fork the project.
- Create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
MIT License β see LICENSE for details.
Yann Dipita
Please open an issue with:
- clear description,
- reproduction steps,
- expected vs. actual behavior,
- your environment (OS, Python, Selenium versions).
For any question: dipitay@gmail.com.
Note: This library is under active development. Minor releases may introduce breaking changes.