A portfolio-style web automation framework demonstrating BDD patterns, Page Object Model architecture, and parallel cross-browser execution against a real public web application.
This suite targets the Wikipedia search flow:
- Search for a term → results page loads and is navigable
- Validate search results page elements are displayed correctly
- Cross-browser coverage on Chrome and Firefox via Selenium Grid
- Page Object Model (POM) for clean, maintainable test architecture
- Behaviour-Driven Development (BDD) using readable, business-oriented Gherkin scenarios
- Dockerized Selenium Grid for consistent and reproducible cross-browser execution
- Parallel execution via pytest-xdist for faster suite runs
- Allure reporting for rich, visual test reports
- Structured logging for traceability and debugging
- Failure-proofing techniques to increase test stability and reduce flakiness
- Python 3.12
- Selenium 4
- pytest-BDD
- pytest-xdist
- Pipenv
- Docker + Selenium Grid (4.21.0)
- Allure
- webdriver-manager
For users who want to run the project quickly:
# 1. Clone repo
git clone <repo-url>
cd web-automation
# 2. Install dependencies
pipenv install
# 3. Activate environment
pipenv shell
# 4. Generate and open an Allure session
allure generate --clean allure-resultsRun test via xdist (recommended for first checkup*):
# 5. Run tests
pipenv run pytest tests/test_fw.py
# Optional: run in parallel
pipenv run pytest -n 4 --ignore=tests/step_defs
# Optional: generate Allure report
allure serve allure-resultsRun test via BDD (Gherkin):
# 5. Start Selenium Grid
docker-compose up -d --scale chrome=2 --scale firefox=4
# 6. Run tests
pipenv run python -m pytest -k "web"
# Optional: run in parallel with a fixed browser mix (recommended once Grid is up)
pipenv run pytest -n 3 --dist=load -k "web" --browsers firefox,chrome
# Optional: run in parallel using the default browser only
pipenv run pytest -n 3 --dist=load -k "web"
# Optional: generate Allure report
allure serve allure-results
# Optional: verify the Grid
http://localhost:4444/grid/consoleThe following test runs against the Wikipedia search flow using the pytest-parametrize path (local WebDriver). It demonstrates POM usage, Allure step instrumentation, and multi-assertion coverage per scenario:
@pytest.mark.parametrize('phrase', ['python', 'polar bear'])
def test_basic_wikipedia_search(json_browser, phrase):
allure.dynamic.title(f"Basic Wikipedia search: {phrase}")
search_page = WikipediaSearchPage(json_browser)
result_page = WikipediaResultPage(json_browser)
with allure.step("Load Wikipedia home page"):
search_page.load()
with allure.step(f"Search Wikipedia for '{phrase}'"):
search_page.search(phrase)
with allure.step(f"Validate result page header contains '{phrase}'"):
header = result_page.header_value().lower()
assert phrase == header, f"Expected: '{phrase}', Actual: '{header}'"
with allure.step("Check that #bodyContent exists and is visible"):
assert result_page.body_content().is_displayed()
with allure.step(f"Validate page title contains '{phrase}'"):
assert phrase in result_page.title().lower()
with allure.step(f"Validate URL ends with '/wiki/{phrase}'"):
expected = f"wiki/{phrase.replace(' ', '_')}"
assert result_page.url().lower().endswith(expected)Each allure.step block appears as a named step in the Allure report with attachments — making failures immediately diagnosable without re-running the test.
web-automation/
│
├── pages/ # Page Object Model implementation
├── tests/
│ ├── features/ # BDD .feature files
│ └── step_defs/ # pytest-bdd step definitions
├── utils/ # Helpers (logging, etc.)
│
├── config.json
├── docker-compose.yml
├── Pipfile / Pipfile.lock
├── README.md
└── pytest.ini
Python setup can be complicated. This section documents how to set up your machine for Python test automation development.
Read more..
This application requires Python 3.12. You can download the latest Python version from Python.org. Follow the appropriate installation instructions for your operating system.
You should also have a good Python editor/IDE. Good choices include PyCharm and Visual Studio Code.
You will also need Git if you want to clone this repository locally. If you are new to Git, try learning the basics.
For Web UI tests, install the appropriate browser and WebDriver executable. These tests use Firefox and geckodriver.
Unfortunately, installing Python properly can be complicated,
especially if Python was previously installed on your machine.
To verify your Python installation, enter python --version at the command line.
You should see the proper version printed.
If the python command doesn't work or doesn't print the expected version number,
then try using the python3 command instead.
If that still doesn't work,
then the correct Python installation might not be included in your system path.
Find the directory into which Python was installed,
manually add it to the system path,
relaunch the command line,
and try running Python again.
- System Path Instructions for Windows
- System Path Instructions for macOS
- System Path Instructions for Linux
This application uses third-party packages that are not part of the Python Standard Library.
They must be installed separately using pip, the standard Python package installer.
You can install them all before you create your test project.
To install each package, enter pip3 install <package-name> at the command line.
For example: pip3 install pytest.
If you already have a package installed but need to upgrade its version,
run pip3 install --upgrade <package-name>.
Running pipenv install will install the pytest package locally inside the project ecosystem, while running pip3 install will install the pytest package globally for the whole system.
Installing Python packages globally is okay, but it typically isn't a best practice.
Instead, each project should manage its own dependencies locally using a virtual environment.
Virtual environments let projects avoid unnecessary dependencies and version mismatches.
This project uses Docker to ensure consistent and reproducible test environments.
Read more..
Download and install Docker Desktop for your operating system. After installation, verify it works by running:
docker --versionYou should see the installed Docker version printed.
This project does not include a Dockerfile or containerised test runner. Instead, it depends on Selenium Grid containers you run locally.
Start the Selenium Grid using the official images (version 4.21.0)
Windows/Linux:
docker network create grid
docker run -d --net grid --name selenium-hub -p 4444:4444 selenium/hub:4.21.0
docker run -d --net grid --name chrome-node -e SE_EVENT_BUS_HOST=selenium-hub \ selenium/node-chrome:4.21.0
docker run -d --net grid --name firefox-node -e SE_EVENT_BUS_HOST=selenium-hub \ selenium/node-firefox:4.21.0macOS (Apple Silicon + Intel):
docker network create grid
docker run -d --net grid --platform linux/amd64 \ --name selenium-hub -p 4444:4444 selenium/hub:4.21.0
docker run -d --net grid --platform linux/amd64 \ --name chrome-node -e SE_EVENT_BUS_HOST=selenium-hub selenium/node-chrome:4.21.0
docker run -d --net grid --platform linux/amd64 \ --name firefox-node -e SE_EVENT_BUS_HOST=selenium-hub selenium/node-firefox:4.21.0Once the containers are running, verify the Grid is ready: http://localhost:4444/grid/console
Allure Reporting provides rich, visual test reports generated from your framework.
Read more..
You must install Allure locally to view reports.
macOS (Homebrew):
brew install allureWindows: Download the Allure ZIP from the official distribution page, extract it, and add the bin folder to your system path.
Linux:
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update
sudo apt-get install allureVerify installation:
allure --versionAfter running your tests, an Allure results folder will be created. To generate and view the report:
allure serve allure-resultsThis command builds the report and opens it in your browser.
This project uses Dockerized Selenium Grid and Pipenv-based Python tooling to run the full automation suite.
After Docker Desktop is installed, pull the Selenium Hub image:
docker pull selenium/hub:4.21.0Verify the image:
docker imagesmacOS (Apple Silicon + Intel)
docker pull --platform linux/amd64 selenium/node-chrome:4.21.0
docker pull --platform linux/amd64 selenium/node-firefox:4.21.0Windows/Linux
docker pull selenium/node-chrome:4.21.0
docker pull selenium/node-firefox:4.21.0By verifying the images again docker images, you should see:
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
selenium/hub:4.21.0 f269ed6bcd3f 966MB 327MB
selenium/node-chrome:4.21.0 239eacca7175 3.02GB 931MB
selenium/node-firefox:4.21.0 549284752c8c 2.93GB 903MBStart Selenium Grid using Docker Compose:
docker-compose up -dScale browsers if necessary:
docker-compose up -d --scale chrome=2 --scale firefox=4Notes:
- This project is validated with Selenium images
4.21.0andplatform: linux/amd64indocker-compose.yml. - Avoid mixing tags (for example
latestfor nodes and pinned for hub) because it can cause node registration and session timeouts. - On Apple Silicon, the
linux/amd64images run under emulation. This is expected for the stable setup below.
Install project dependencies with Pipenv manually, if pipenv shell did not activate the environment:
pipenv install selenium pytest pytest-xdist webdriver-manager pytest-bdd pyyaml allure-pytestVerify the initial test:
pipenv run pytest tests/test_fw.pyAfter verifying that test_fw.py passes:
- Generate and open an Allure session:
allure generate --clean allure-results && allure open- Run Python tests targeting the @web tag:
pipenv run python -m pytest -k "web"- View the Allure report:
allure serve allure-resultsA collection of common issues and quick fixes for running the web-automation project.
Pipenv environment not activating
Symptom: pipenv run pytest fails or packages aren't found.
Fix:
pipenv --rm
pipenv install
pipenv shellConflicts with global Python installations
Symptom: python --version prints a different version than expected.
Fix: Force Pipenv to use Python 3.12:
pipenv --python 3.12.venv folder not created inside the project
Symptom: After running pipenv install, no .venv folder appears in the repository, even though the environment exists.
Cause: Pipenv stores virtual environments outside the project by default.
Fix (enable project-local venv):
export PIPENV_VENV_IN_PROJECT=1
pipenv --rm
pipenv installThis recreates the environment inside ./.venv/.
ModuleNotFoundError for project imports
Symptom: Imports like from pages.home_page import HomePage fail when running tests.
Fix: Add the project root to PYTHONPATH:
export PYTHONPATH=.macOS/Linux: add to .zshrc or .bashrc
Windows: add to Environment Variables → User Variables → PYTHONPATH
Pytest can't discover tests
Fix:
- Ensure test filenames follow:
test_*.py - Ensure the folder contains an
__init__.pyif needed - Run with explicit path:
pipenv run pytest tests/Parallel tests fail (xdist) Usually caused by WebDriver sessions overwriting each other.
Fix:
- Use isolated sessions per worker
- Or disable parallel for debugging:
pipenv run pytest -n 1Recommended, known-good Docker versions (stable baseline)
If tests are flaky after changing Docker images or tags, return to the known-good versions:
selenium/hub:4.21.0selenium/node-chrome:4.21.0selenium/node-firefox:4.21.0
In docker-compose.yml, keep platform: linux/amd64 for all services.
Then restart the Grid:
docker-compose down
docker-compose up -d --scale chrome=2 --scale firefox=4Selenium Hub not reachable
Symptom: selenium.common.exceptions.WebDriverException: hub unreachable
Fix:
docker-compose down
docker-compose up -dCheck containers:
docker psHub must be running at:
http://localhost:4444Nodes not registering to Hub
Symptom: /status shows only one browser type or zero available slots, and tests fail with SessionNotCreatedException or timeouts.
Cause: Version mismatch between hub and nodes, or platform mismatch on Apple Silicon.
Fix:
- Use the same Selenium version for hub and all nodes (recommended:
4.21.0). - Ensure
platform: linux/amd64is set on all services indocker-compose.yml(macOS Apple Silicon). - Restart the Grid after changes:
docker-compose down
docker-compose up -d --scale chrome=2 --scale firefox=4Optional: validate the Grid before running tests:
curl -s http://localhost:4444/status | python3 -m json.tool | grep -E '"browserName"|session'Browser crashes instantly
Memory limit too low.
Fix (Linux/macOS):
sudo sysctl -w kernel.shmmax=268435456No results appear in the report
Symptom: Allure opens a report with 0 tests.
Fix:
- Ensure pytest Allure plugin is installed:
pipenv install allure-pytest- Ensure tests were run before generating:
pipenv run pytestallure: command not found
Install Allure:
- macOS:
brew install allure- Windows: Add
allure\binto PATH - Linux:
sudo apt-get install allureGeckoDriver not found
Install with webdriver-manager (already in project):
pipenv install webdriver-managerUse GeckoDriverManager() instead of local binary.
Browser cannot start: "DevToolsActivePort file doesn't exist"
This happens in Docker or CI environments.
Fix: Add proper browser options (already included in most setups):
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")zsh: permission denied when running scripts
chmod +x <script_name>Windows: tests hang or fail silently
Run terminal as Administrator
OR
Disable long path restrictions.