Plain English web test automation using Selenium and Playwright. No code. No maintenance.
Project description
snakeoil-web
Selector-free, self-healing web test automation.
No XPaths. No CSS selectors. No waiting. Tests that describe what users see, not how developers built it.
Install
pip install snakeoil-web
Your first test
from snakeoil_web import WebAgent
agent = WebAgent()
agent.click("Sign in")
agent.type("harish@example.com", into="Email")
agent.type("password123", into="Password")
agent.click("Sign in")
agent.verify_text("Dashboard")
That's it. No selectors. No waits. No maintenance.
Why snake-oil?
Most test automation breaks when a developer renames a CSS class or moves an element. snakeoil-web finds elements by what users actually see — visible text, labels, and position on screen — not by how the DOM is built.
# Selenium — breaks when developer renames the class
driver.find_element(By.XPATH, '//button[@data-testid="login-btn"]').click()
# snakeoil-web — works regardless of how the DOM changes
agent.click("Sign in")
When the DOM changes, your tests don't.
Two ways to write tests
Pythonic — IDE guided, autocomplete friendly:
agent = WebAgent()
agent.click("Sign in")
agent.type("harish@example.com", into="Email")
agent.verify_text("Dashboard")
English — human readable, shareable with non-developers:
agent = WebAgent()
agent.run([
'click "Sign in"',
'type "harish@example.com" into "Email"',
'verify text "Dashboard" is present',
])
Using variables
Pythonic — pass variables directly:
email = "harish@example.com"
password = "secret123"
agent.type(email, into="Email")
agent.type(password, into="Password")
agent.click("Sign in")
English — embed variables with f-strings:
email = "harish@example.com"
password = "secret123"
agent.run([
f'type "{email}" into "Email"',
f'type "{password}" into "Password"',
'click "Sign in"',
])
Mix Pythonic and English freely
Use whichever style fits each step — they work together in the same test:
from snakeoil_web import WebAgent
# Get test data from your API
user = api.create_test_user()
agent = WebAgent()
# English for readable setup steps
agent.run([
'click "Sign in"',
f'type "{user.email}" into "Email"',
f'type "{user.password}" into "Password"',
'click "Sign in"',
])
# Pythonic for assertions — IDE helps you get it right
agent.verify_text("Dashboard")
balance = agent.extract_text(next_to="Balance")
# Back to Python for logic
assert balance == user.expected_balance
# English for teardown
agent.run([
'click "Settings"',
'click "Sign out"',
])
Spatial targeting
No visible text on that icon button? Use its position instead.
agent.click("button", below="Total Price")
agent.click("icon", next_to="Search")
agent.click("button", index=2)
agent.extract_text(next_to="Balance")
agent.verify_text("$0.00", next_to="Balance")
Mix with Python
Use Python for data setup, snakeoil for the UI steps.
from snakeoil_web import WebAgent
user = api.create_test_user()
agent = WebAgent()
agent.type(user.email, into="Email")
agent.type(user.password, into="Password")
agent.click("Sign in")
agent.verify_text("Dashboard")
balance = agent.extract_text(next_to="Balance")
assert balance == user.expected_balance
Configuration
Create a snakeoil.web.config.py in your project root:
URL = "https://yourapp.com"
BROWSER = "chromium" # chromium | firefox | webkit | msedge
HEADLESS = False
TIMEOUT = 30_000 # milliseconds
MAXIMIZED = True
Supported browsers
| Browser | Support |
|---|---|
| Chrome / Chromium | ✅ |
| Firefox | ✅ |
| Safari / WebKit | ✅ |
| Edge | ✅ |
Related packages
- snakeoil-mobile — Mobile browser automation on real Android and iOS devices
- snakeoil-native — Native app automation for Android and iOS
Status
Early development. Feedback and contributions welcome.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file snakeoil_web-0.1.1.tar.gz.
File metadata
- Download URL: snakeoil_web-0.1.1.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82ca3b15783d4c582c90aed685e0aad0c90e2b994f2acea28d93942e2127abe9
|
|
| MD5 |
a25bddab8c0460c7c97b7437b99a3b9c
|
|
| BLAKE2b-256 |
ad7f6e7b1a735781a4768a4c1d23dd532b256ac9fdad4e5f9370e57c48798081
|
File details
Details for the file snakeoil_web-0.1.1-py3-none-any.whl.
File metadata
- Download URL: snakeoil_web-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9274212e2bcf9d0e8b7938dbe444308c5c51da16f5d3bf1438836c8b13f8068
|
|
| MD5 |
b061805ccdbb863f4f9a22d8ef8ddd48
|
|
| BLAKE2b-256 |
b3910770db46cb9362cadd4874a1601024ec305117682b307dc675cbc6501449
|