Portfolio-ready QA automation project for UI testing, API testing, manual test design, reporting, and CI-friendly execution.
This framework demonstrates a practical QA automation workflow: manual test design, Selenium UI automation, REST API checks, reusable page objects, reusable API client code, reporting hooks, lightweight Postman workspace scaffolding, and CI-ready execution.
It is intentionally built as a portfolio project, so the repo shows both the finished test code and the QA thinking behind it: coverage planning, test data choices, validation strategy, and current suite health.
The current automated API suite covers JSONPlaceholder /posts through a reusable client in api/base_api_client.py. Broader future API scenarios are tracked in the manual workbook and Postman scaffolding, but those cases are not implemented in pytest yet.
Status: Active work in progress. New scenarios and documentation are being added as the framework grows.
This project was built with AI assistance.
AI supported parts of the development process, including implementation, refactoring, debugging, documentation, and iteration. Project direction, framework design, test coverage decisions, review, and final validation were all handled by the repository owner.
Any AI-generated output was reviewed, adjusted, and validated before being accepted. Final responsibility for the code, documentation, and test behavior remains with the repository owner.
| Area | What This Shows |
|---|---|
| UI automation | SauceDemo login, inventory, cart, and checkout workflows |
| API automation | Current JSONPlaceholder /posts coverage via reusable client, plus Postman scaffolding for future REST expansion |
| Test design | Manual UI + API workbook with 18 documented cases |
| Framework structure | Pytest fixtures, Selenium Page Object Model, reusable API client |
| Reporting | Console progress logs, HTML reports, Allure results, failure screenshots |
| CI readiness | GitHub Actions workflow for headless Chrome UI execution with HTML and JSON report artifacts |
| Quality signal | 14 logical tests total (10 UI, 4 API); default pytest runs the 10 UI tests across Chrome and Firefox |
| Portfolio Asset | Link |
|---|---|
| Manual UI and API workbook | docs/saucedemo_manual_test_cases_with_api.xlsx |
| API testing scope (current automated scope) | test_artifacts/api_posts_test_cases.md |
| Login UI test notes | test_artifacts/ui_login_test_cases.md |
| Checkout UI test notes | test_artifacts/ui_checkout_test_cases.md |
| API test implementation (current automated scope) | tests/api/test_posts_api.py |
| Checkout test implementation | tests/ui/test_checkout.py |
| API client | api/base_api_client.py |
| Postman workspace scaffold | .postman/resources.yaml |
| Postman environment scaffold | postman/environments/New Environment.environment.yaml |
| Postman globals scaffold | postman/globals/workspace.globals.yaml |
| UI tests | tests/ui/ |
| Page objects | pages/ |
| CI workflow | .github/workflows/python-test.yml |
The manual workbook tracks broader future API scenarios under TC_API_001 through TC_API_008; the current automated API suite in this repo still targets JSONPlaceholder /posts.
| Layer | Tools |
|---|---|
| Language | Python |
| Test runner | Pytest |
| UI automation | Selenium WebDriver, Chrome, Firefox, webdriver-manager |
| API automation | requests |
| Reporting | pytest-html, pytest-json-report, allure-pytest |
| Architecture | Page Object Model, shared fixtures, reusable client classes |
| CI | GitHub Actions |
| Suite | Coverage | Automated Checks |
|---|---|---|
| Login UI | Standard and locked-out user paths | Redirect validation, inventory load checks, error message checks |
| Inventory UI | Product sorting and product details | Price ordering, item count stability, detail page data consistency |
| Cart UI | Add, remove, and reset state | Badge count, cart contents, removal sync, reset app state behavior |
| Checkout UI | Successful checkout, validation, and error_user behavior |
Overview item consistency, required-field validation, completion state observation |
| API automation | Current JSONPlaceholder /posts coverage through the shared API client |
GET /posts, GET /posts/1, POST /posts, and DELETE /posts/1 with response validation |
See test_artifacts/api_posts_test_cases.md for the current automated API scope. Broader future API coverage is documented in the workbook and Postman assets, not yet implemented in tests/api/test_posts_api.py.
The workbook and Postman scaffolding reserve future API cases under TC_API_001 through TC_API_008.
Those cases are planned project scope, not part of the current automated pytest API suite.
Latest verified single-browser full-suite checkpoint:
HEADLESS=True pytest -m "ui or api" --browser chromeLatest verified result:
13 passed, 1 xfailed
The expected xfail documents SauceDemo error_user checkout behavior. It is intentionally tracked because the abnormal behavior is useful QA evidence, not a hidden failure.
Default pytest behavior is different from the checkpoint above: pytest.ini excludes api by default, and the root conftest.py fans UI tests out across chrome,firefox.
The current workbook is docs/saucedemo_manual_test_cases_with_api.xlsx.
It replaces the previous docs/manual_test_cases.xlsx workbook and includes:
| Manual Suite | Count | Case IDs |
|---|---|---|
| SauceDemo UI | 10 | TC_LOGIN_001, TC_LOGIN_002, TC_INV_001, TC_INV_002, TC_CART_001, TC_CART_002, TC_CART_003, TC_CHECKOUT_001, TC_CHECKOUT_002, TC_CHECKOUT_003 |
| API scenarios | 8 | TC_API_001 through TC_API_008 |
| Summary tracker | 1 sheet | Execution status, priority, and automation readiness |
The UI automation now maps to the current login, inventory, cart, and checkout case IDs in the workbook.
qa-automation-framework/
βββ .github/
β βββ workflows/
β βββ python-test.yml
βββ api/
β βββ base_api_client.py
βββ config/
β βββ config.py
βββ docs/
β βββ saucedemo_manual_test_cases_with_api.xlsx
βββ allure-results/
βββ pages/
β βββ base_page.py
β βββ cart_page.py
β βββ checkout_page.py
β βββ inventory_page.py
β βββ login_page.py
βββ reports/
βββ test_artifacts/
β βββ api_posts_test_cases.md
β βββ saucedemo_manual_test_cases_regenerated.md
β βββ ui_checkout_test_cases.md
β βββ ui_login_test_cases.md
βββ tests/
β βββ api/
β β βββ test_posts_api.py
β βββ ui/
β βββ test_cart.py
β βββ test_checkout.py
β βββ test_inventory.py
β βββ test_login.py
βββ utils/
β βββ driver_factory.py
βββ conftest.py
βββ pytest.ini
βββ requirements.txt
βββ README.md
- Python 3.9+
- pip
- Chrome or Firefox for UI execution
git clone <repository_url>
cd qa-automation-framework
pip install -r requirements.txtThe framework reads settings from environment variables in config/config.py.
| Variable | Purpose | Default |
|---|---|---|
BASE_URL |
UI base URL placeholder | http://www.example.com |
API_BASE_URL |
API base URL | http://jsonplaceholder.typicode.com |
BROWSER |
Browser selection for UI tests. Supports chrome, firefox, all, or comma-separated values |
chrome,firefox |
HEADLESS |
Run browser headless | False |
IMPLICIT_WAIT |
Selenium implicit wait seconds | 6 |
EXPLICIT_WAIT |
Selenium explicit wait seconds | 10 |
SCREENSHOT_PATH |
Screenshot output directory | screenshots |
LOG_LEVEL |
Logging level placeholder | INFO |
CHROMEDRIVER_PATH |
Optional ChromeDriver executable path | unset |
GECKODRIVER_PATH |
Optional GeckoDriver executable path | unset |
Notes:
BASE_URLexists in config, but the current SauceDemo page objects still use direct page URLs.- UI tests select browsers with the pytest
--browseroption or theBROWSERenvironment variable. Supported values arechrome,firefox,all, or comma-separated values such aschrome,firefox. The command-line option takes precedence. - The GitHub Actions workflow sets
HEADLESS=truefor CI runs. - The shared API client now returns raw responses so negative REST cases can assert expected error payloads such as
400,404, and later422directly in pytest.
| Goal | Command |
|---|---|
| Default UI matrix run across Chrome and Firefox | pytest |
| All UI tests across Chrome and Firefox | pytest tests/ui |
| UI tests in Chrome | pytest tests/ui --browser chrome |
| UI tests in Firefox | pytest tests/ui --browser firefox |
| UI tests in both browsers explicitly | pytest tests/ui --browser chrome,firefox |
| Full suite in one browser | pytest -m "ui or api" --browser chrome |
| Full suite with default UI browser matrix | pytest -m "ui or api" |
| API tests only | pytest -m api |
| Login tests | pytest tests/ui/test_login.py |
| Checkout tests | pytest tests/ui/test_checkout.py |
| API posts tests | pytest tests/api/test_posts_api.py -m api |
PowerShell headless full-suite run:
$env:HEADLESS="True"; pytest -m "ui or api"Run specific examples:
pytest tests/ui/test_login.py::TestLogin::test_successful_login_TC_LOGIN_001
pytest tests/ui/test_checkout.py::TestCheckout::test_successful_checkout_with_valid_customer_information_TC_CHECKOUT_001
pytest tests/api/test_posts_api.py::TestPostsApi::test_get_single_post -m api| Report Type | Command / Behavior |
|---|---|
| Console progress | Built into pytest hooks in conftest.py |
| HTML report | pytest tests/ui --html=reports/ui-report.html --self-contained-html |
| Failure screenshots | Captured automatically for UI failures |
| Allure results | pytest tests/ui --alluredir=allure-results |
| Static Allure report | allure generate allure-results --clean -o allure-report |
Serve Allure locally after installing the Allure CLI:
allure serve allure-resultsThe GitHub Actions workflow in .github/workflows/python-test.yml currently:
- runs on pushes and pull requests to
main - installs dependencies
- executes UI tests only, in headless Chrome, with JSON and self-contained HTML reporting enabled
- uploads the generated
reports/directory as a build artifact
The workflow sets:
BASE_URL=https://www.saucedemo.comBROWSER=chromeHEADLESS=true
| Asset | Purpose |
|---|---|
| docs/ | Manual test workbooks and higher-level project materials |
| test_artifacts/ | Generated/manual QA assets and coverage notes |
| docs/saucedemo_manual_test_cases_with_api.xlsx | Current UI + API manual workbook |
| test_artifacts/api_posts_test_cases.md | Automated API testing scope |
| test_artifacts/ui_checkout_test_cases.md | Checkout UI testing scope |
| test_artifacts/ui_login_test_cases.md | Login UI testing scope |
| test_artifacts/saucedemo_manual_test_cases_regenerated.md | Manual SauceDemo E2E scenarios |
| .postman/resources.yaml | Postman local workspace registration |
| postman/environments/New Environment.environment.yaml | Starter Postman environment |
| postman/globals/workspace.globals.yaml | Starter Postman globals |
Generated runtime output may appear in reports/, allure-results/, and screenshots/; those outputs are ignored by Git except for placeholder files.
- This is an active portfolio project, so new automation and documentation will continue to be added.
- Current automated coverage focuses on representative UI and API flows rather than full application coverage.
- The suite documents both clean passing behavior and known abnormal behavior through an expected
xfail. - Generated report, screenshot, cache, virtual environment, and IDE files are ignored by Git.