TestFlow is a Python end-to-end testing framework that combines browser automation with HTTP traffic validation in a single workflow.
Built on top of Selenium and mitmproxy, it allows you to validate not only UI behavior, but also the exact network requests and responses generated during user interactions.
This makes it possible to test full application flows the way they actually work: from click → request → response → UI result.
Most UI automation tools only validate what happens in the browser.
But modern applications are API-driven.
A test can pass visually while the backend is actually broken.
For example:
- The UI redirects to a dashboard
- But the login API returns invalid or incomplete data
- Or the wrong endpoint is called entirely
TestFlow solves this by letting you inspect and validate the network layer directly inside your tests.
This example shows a complete login validation.
It verifies:
- UI interaction (form input + click)
- API endpoint used for login
- HTTP method and payload
- Backend response
- Final UI state
from test_flow import TestFlow
test = TestFlow(
enable_logger=True,
headless=True
)
test.navigate("https://myapp.com/login")
with test.expect_request(
endpoint="https://api.myapp.com/auth/login",
method="POST",
json_body={
"email": "john@test.com",
"password": "secret123"
}
) as flow:
test.send_keys("id", "email", "john@test.com")
test.send_keys("id", "password", "secret123")
test.click("id", "login-button")
flow.assert_status(200)
flow.assert_json({
"success": True
})
test.assert_url_contains("/dashboard")
test.stop_test()Instead of splitting UI and API testing into separate layers, TestFlow merges them into one execution flow.
- UI test → checks page behavior
- API test → checks backend separately
- Manual correlation between both
with test.expect_request(
endpoint="/auth/login",
method="POST"
):
test.click("id", "login-button")
flow.assert_status(200)A single test validates:
- UI behavior
- Request correctness
- Backend response
- Integration between both layers
Simple Selenium-based API for user actions:
test.navigate(url)
test.send_keys("id", "username", "john")
test.click("id", "submit")Define expected network behavior triggered by UI actions:
with test.expect_request(
endpoint="/api/users",
method="POST",
json_body={"name": "John"}
):
test.click("id", "save-button")Validate backend responses directly:
flow.assert_status(200)
flow.assert_json({
"success": True
})Wait for specific requests before continuing execution:
test.wait_for_request(
"https://api.example.com/users",
"GET"
)Useful for:
- SPA applications
- Async API calls
- Page hydration
- Background requests
TestFlow is useful for testing:
- Login and authentication flows
- Registration forms
- Checkout and payment processes
- API-driven web applications
- Single Page Applications (SPA)
- End-to-end integration testing
- Regression testing
┌──────────────────────────────┐
│ Test Case │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ TestFlow │
│ Public API │
└───────┬───────────┬──────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Selenium │ │ HTTP Layer │
│ Automation │ │ Validation │
└──────┬──────┘ └──────┬──────┘
│ │
└───────┬───────┘
▼
┌──────────────────────────────┐
│ Embedded mitmproxy │
│ Traffic Interception │
└──────────────────────────────┘
TestFlow is built for modern web applications where frontend and backend are tightly connected.
Instead of guessing what happened behind a button click, you validate the actual HTTP traffic generated by it.
This results in:
- Fewer false positives
- Stronger integration coverage
- More realistic end-to-end tests
- Better confidence in critical user flows