QA Selenium Python Writer
Purpose
Write Selenium Python E2E tests from test case specifications. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer, qa-browser-data-collector, or specs) into executable Selenium test files with WebDriver, explicit waits, Page Object Model, and headless browser support.
Trigger Phrases
- "Write Selenium tests for [feature/flow]"
- "Generate Selenium E2E tests from test cases"
- "Create Selenium Python tests with POM"
- "Add Selenium tests for [URL/page]"
- "Selenium tests with WebDriver for [browser]"
- "Selenium Python Page Object Model tests"
- "Headless Selenium tests for [feature]"
- "Selenium tests with explicit waits"
- "Heal my failing Selenium tests"
Key Features
| Feature |
Description |
| WebDriver |
Chrome, Firefox, Edge, Safari via Selenium WebDriver |
| Explicit waits |
WebDriverWait + expected_conditions; avoid implicit waits |
| Implicit waits |
Fallback only; prefer explicit waits |
| Page Object Model |
POM with @property for locators; base page + page-specific classes |
| Headless mode |
Chrome/Firefox headless for CI and faster runs |
| ActionChains |
Complex interactions: drag-drop, hover, key combos |
| Select |
Dropdown handling via Select class |
| pytest integration |
Fixtures for driver setup/teardown, conftest.py |
Workflow
- Read test cases — From specs, requirements, manual test designs, or browser-collected data
- Analyze app — Inspect pages, forms, flows; identify locators and interactions
- Generate tests with POM — Produce
test_{feature}.py with Page Objects
- Configure WebDriver — Set up driver fixtures, headless options, timeouts
- Run — User runs
pytest to execute tests
Context7 MCP
Use Context7 MCP for Selenium Python documentation when:
- WebDriver API or expected_conditions syntax is uncertain
- ActionChains, Select, or alert handling needs verification
- Browser-specific options (Chrome, Firefox headless) require up-to-date reference
Key Patterns
| Pattern |
Usage |
driver.get(url) |
Navigate to URL |
driver.find_element(By.ID, "id") |
Find by ID |
driver.find_element(By.CSS_SELECTOR, "selector") |
Find by CSS |
driver.find_element(By.XPATH, "xpath") |
Find by XPath |
driver.find_element(By.NAME, "name") |
Find by name |
driver.find_element(By.CLASS_NAME, "class") |
Find by class |
WebDriverWait(driver, timeout).until(EC.visibility_of_element_located(...)) |
Explicit wait |
POM with @property |
Encapsulate locators in page classes |
ActionChains(driver) |
Drag, hover, key combos |
Select(element) |
Dropdown select by value/text/index |
Wait Strategies
Prefer explicit waits; avoid implicit waits for reliability:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.ID, "submit-btn")))
element.click()
Common expected conditions: visibility_of_element_located, element_to_be_clickable, presence_of_element_located, text_to_be_present_in_element, url_contains.
pytest Integration
- Fixtures —
driver fixture for setup/teardown; scope function or class
- conftest.py — Shared driver factory, base URL, browser options
- File naming —
test_{feature}.py (e.g., test_login.py, test_checkout.py)
See references/config.md for pytest + Selenium setup.
File Naming
test_{feature}.py — Preferred (e.g., test_login.py, test_search.py)
- Page objects:
pages/{page_name}_page.py or page_objects/{name}.py
- Place in
tests/ per project convention
Scope
Can do (autonomous):
- Generate Selenium Python E2E tests from test case specs
- Apply Page Object Model with @property locators
- Use explicit waits (WebDriverWait + expected_conditions)
- Configure WebDriver (Chrome, Firefox, Edge, headless)
- Use ActionChains for complex interactions; Select for dropdowns
- Integrate with pytest via fixtures and conftest.py
- Use Context7 MCP for Selenium Python docs
- Delegate to qa-test-healer when tests fail (Heal Mode)
Cannot do (requires confirmation):
- Change production code structure
- Add dependencies not in requirements.txt
- Override project Selenium/pytest config without approval
- Navigate to URLs not provided
Will not do (out of scope):
- Execute tests (user runs
pytest)
- Write Playwright/Cypress tests (use qa-playwright-ts-writer, qa-cypress-writer)
- Modify CI/CD pipelines
- Bypass security or access restricted areas
References
references/patterns.md — Locators, waits, POM, ActionChains, Select, file upload, alerts, frames, windows
references/config.md — WebDriver manager, pytest integration, headless config
references/best-practices.md — Explicit waits, POM, stable locators, driver management
Quality Checklist
Troubleshooting
| Symptom |
Likely Cause |
Fix |
| Element not found |
Selector too specific, timing |
Use explicit wait; prefer ID/CSS over fragile XPath |
| StaleElementReferenceException |
DOM changed after find |
Re-find element before interaction; use explicit wait |
| Timeout |
Element not ready, slow page |
Increase WebDriverWait timeout; check for overlays/modals |
| Flaky tests |
Implicit wait, race conditions |
Replace implicit with explicit waits; ensure test isolation |
| Driver not found |
WebDriver binary missing |
Use webdriver-manager; ensure browser installed |
| Headless fails |
Browser options incorrect |
Verify Chrome/Firefox headless options for your Selenium version |
| Select fails |
Not a select element |
Use Select only on <select> elements; check element type |
1---2name: qa-selenium-py-writer3description: Generate Selenium E2E tests for Python with WebDriver, explicit/implicit waits, Page Object Model, and headless browser support.4---56# QA Selenium Python Writer78## Purpose910Write Selenium Python E2E tests from test case specifications. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer, qa-browser-data-collector, or specs) into executable Selenium test files with WebDriver, explicit waits, Page Object Model, and headless browser support.1112## Trigger Phrases1314- "Write Selenium tests for [feature/flow]"15- "Generate Selenium E2E tests from test cases"16- "Create Selenium Python tests with POM"17- "Add Selenium tests for [URL/page]"18- "Selenium tests with WebDriver for [browser]"19- "Selenium Python Page Object Model tests"20- "Headless Selenium tests for [feature]"21- "Selenium tests with explicit waits"22- "Heal my failing Selenium tests"2324## Key Features2526| Feature | Description |27| ------- | ----------- |28| **WebDriver** | Chrome, Firefox, Edge, Safari via Selenium WebDriver |29| **Explicit waits** | WebDriverWait + expected_conditions; avoid implicit waits |30| **Implicit waits** | Fallback only; prefer explicit waits |31| **Page Object Model** | POM with @property for locators; base page + page-specific classes |32| **Headless mode** | Chrome/Firefox headless for CI and faster runs |33| **ActionChains** | Complex interactions: drag-drop, hover, key combos |34| **Select** | Dropdown handling via Select class |35| **pytest integration** | Fixtures for driver setup/teardown, conftest.py |3637## Workflow38391. **Read test cases** — From specs, requirements, manual test designs, or browser-collected data402. **Analyze app** — Inspect pages, forms, flows; identify locators and interactions413. **Generate tests with POM** — Produce `test_{feature}.py` with Page Objects424. **Configure WebDriver** — Set up driver fixtures, headless options, timeouts435. **Run** — User runs `pytest` to execute tests4445## Context7 MCP4647Use **Context7 MCP** for Selenium Python documentation when:48- WebDriver API or expected_conditions syntax is uncertain49- ActionChains, Select, or alert handling needs verification50- Browser-specific options (Chrome, Firefox headless) require up-to-date reference5152## Key Patterns5354| Pattern | Usage |55| ------- | ----- |56| `driver.get(url)` | Navigate to URL |57| `driver.find_element(By.ID, "id")` | Find by ID |58| `driver.find_element(By.CSS_SELECTOR, "selector")` | Find by CSS |59| `driver.find_element(By.XPATH, "xpath")` | Find by XPath |60| `driver.find_element(By.NAME, "name")` | Find by name |61| `driver.find_element(By.CLASS_NAME, "class")` | Find by class |62| `WebDriverWait(driver, timeout).until(EC.visibility_of_element_located(...))` | Explicit wait |63| POM with `@property` | Encapsulate locators in page classes |64| `ActionChains(driver)` | Drag, hover, key combos |65| `Select(element)` | Dropdown select by value/text/index |6667## Wait Strategies6869Prefer explicit waits; avoid implicit waits for reliability:7071```python72from selenium.webdriver.support.ui import WebDriverWait73from selenium.webdriver.support import expected_conditions as EC74from selenium.webdriver.common.by import By7576wait = WebDriverWait(driver, 10)77element = wait.until(EC.visibility_of_element_located((By.ID, "submit-btn")))78element.click()79```8081Common expected conditions: `visibility_of_element_located`, `element_to_be_clickable`, `presence_of_element_located`, `text_to_be_present_in_element`, `url_contains`.8283## pytest Integration8485- **Fixtures** — `driver` fixture for setup/teardown; scope function or class86- **conftest.py** — Shared driver factory, base URL, browser options87- **File naming** — `test_{feature}.py` (e.g., `test_login.py`, `test_checkout.py`)8889See `references/config.md` for pytest + Selenium setup.9091## File Naming9293- `test_{feature}.py` — Preferred (e.g., `test_login.py`, `test_search.py`)94- Page objects: `pages/{page_name}_page.py` or `page_objects/{name}.py`95- Place in `tests/` per project convention9697## Scope9899**Can do (autonomous):**100- Generate Selenium Python E2E tests from test case specs101- Apply Page Object Model with @property locators102- Use explicit waits (WebDriverWait + expected_conditions)103- Configure WebDriver (Chrome, Firefox, Edge, headless)104- Use ActionChains for complex interactions; Select for dropdowns105- Integrate with pytest via fixtures and conftest.py106- Use Context7 MCP for Selenium Python docs107- Delegate to qa-test-healer when tests fail (Heal Mode)108109**Cannot do (requires confirmation):**110- Change production code structure111- Add dependencies not in requirements.txt112- Override project Selenium/pytest config without approval113- Navigate to URLs not provided114115**Will not do (out of scope):**116- Execute tests (user runs `pytest`)117- Write Playwright/Cypress tests (use qa-playwright-ts-writer, qa-cypress-writer)118- Modify CI/CD pipelines119- Bypass security or access restricted areas120121## References122123- `references/patterns.md` — Locators, waits, POM, ActionChains, Select, file upload, alerts, frames, windows124- `references/config.md` — WebDriver manager, pytest integration, headless config125- `references/best-practices.md` — Explicit waits, POM, stable locators, driver management126127## Quality Checklist128129- [ ] Explicit waits used; avoid implicit waits where possible130- [ ] No hardcoded sleeps; prefer WebDriverWait + expected_conditions131- [ ] POM pattern applied for page-specific logic132- [ ] Stable locators (ID, data attributes, CSS; XPath as fallback)133- [ ] Tests independent (no shared state, order-independent)134- [ ] Proper teardown (driver.quit in fixture)135- [ ] Traceability to test case IDs where applicable136- [ ] No hardcoded secrets (use env vars)137- [ ] File naming follows `test_{feature}.py` convention138139## Troubleshooting140141| Symptom | Likely Cause | Fix |142| ------- | ------------ | --- |143| Element not found | Selector too specific, timing | Use explicit wait; prefer ID/CSS over fragile XPath |144| StaleElementReferenceException | DOM changed after find | Re-find element before interaction; use explicit wait |145| Timeout | Element not ready, slow page | Increase WebDriverWait timeout; check for overlays/modals |146| Flaky tests | Implicit wait, race conditions | Replace implicit with explicit waits; ensure test isolation |147| Driver not found | WebDriver binary missing | Use webdriver-manager; ensure browser installed |148| Headless fails | Browser options incorrect | Verify Chrome/Firefox headless options for your Selenium version |149| Select fails | Not a select element | Use Select only on `<select>` elements; check element type |