This recipe is the smallest end-to-end Selenium test that walks the QA Shop guest cart flow in Python.
It opens a product detail page, clicks the add-to-cart button, and waits for the header cart badge to update — using explicit waits and stable data-testid selectors rather than sleeps or brittle CSS classes.
It is the canonical first Python-on-Selenium test to write against any e-commerce site, and on QA Shop it is a copy-paste away thanks to the testid contract on every interactive element.
§ 01 · PREREQUISITES
Prerequisites
You need a Python 3.10+ environment with selenium installed and a Chrome browser available locally. Selenium 4.6+ ships with Selenium Manager, which auto-downloads the matching chromedriver, so no separate driver setup is needed.
Install with pip install selenium (or uv pip install selenium). Confirm the version with python -c "import selenium; print(selenium.__version__)" — this recipe is verified against 4.43.
Set to http://localhost:3002 for a local checkout, or https://automationtestingplatform.com for the hosted demo. The script reads it at import time with a sensible default.
The recipe assumes the server is already up. The script does not start it for you.
§ 02 · THE SCRIPT
The script
Save this file as tests/recipes/selenium/test_add_to_cart.py and run it with pytest tests/recipes/selenium/test_add_to_cart.py (or invoke directly with python tests/recipes/selenium/test_add_to_cart.py after wrapping the call).
# title="test_add_to_cart.py"
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
BASE_URL = os.environ.get("RECIPE_BASE_URL", "http://localhost:3002")
def test_add_to_cart():
driver = webdriver.Chrome()
try:
driver.get(f"{BASE_URL}/products/wooden-train-set-100-piece")
WebDriverWait(driver, 10).until(
EC.visibility_of_element_located(
(By.CSS_SELECTOR, "[data-testid='page-pdp']")
)
)
driver.find_element(
By.CSS_SELECTOR, "[data-testid='pdp-add-to-cart']"
).click()
WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, "[data-testid='cart-count']"), "1"
)
)
finally:
driver.quit()Three details are worth calling out.
The driver is constructed bare with webdriver.Chrome() — Selenium Manager handles the driver download. For headless CI you would pass options=Options() with --headless=new, but for the smallest possible recipe we stay headed so you can watch the flow on first run.
Every wait is explicit. visibility_of_element_located for the PDP readiness wrapper, then text_to_be_present_in_element for the cart count. Neither is a time.sleep — they poll until the condition is true, which makes the script robust against varying network and hydration latency without padding the happy path.
The locators are CSS attribute selectors against data-testid. QA Shop guarantees these testids exist on every interactive element, and they encode user intent rather than implementation detail — pdp-add-to-cart describes what the button does, not what it looks like, so a visual refactor of the buy box does not break the test.
§ 03 · FAQ
FAQ
Common questions when running this recipe or adapting it.
Construct from selenium.webdriver.chrome.options import Options, set opts = Options(); opts.add_argument("--headless=new"), and pass webdriver.Chrome(options=opts). The QA Shop CI harness does the same in TypeScript — see tests/recipes/selenium/setup.ts.
Replace WebDriverWait(driver, 10) with WebDriverWait(driver, 30). Ten seconds is plenty for a local dev server; thirty is a safer ceiling on a constrained CI runner or against the hosted demo over a slow link.
The cart contract — page-pdp, pdp-add-to-cart, cart-count — is the same for every product on QA Shop. Swap the slug in driver.get(...) to any seeded product and the rest of the script keeps working.
Related
For the same flow in Playwright (TypeScript), see the add-to-cart Playwright recipe. For the broader Playwright vs Selenium vs Cypress picture, see the QA Shop testing guide.
The Java and TypeScript Selenium counterparts are coming soon — placeholder slugs are /recipes/selenium/java-add-to-cart and /recipes/selenium/typescript-add-to-cart.
Frequently asked questions
Last verified: