Back to selected work

05 · Quality engineering · UI + API

Orbit QA Framework

A repeatable Python test framework that keeps browser journeys, API contracts, test data, diagnostics and CI feedback cleanly separated.

2browser engines exercised in CI
2Python versions in the framework matrix
80%enforced branch-coverage floor
UI + APIchecks against the same bundled system

A framework that does not depend on someone else’s demo site

Public test sites change, disappear or throttle automated traffic. That makes them a weak foundation for a portfolio framework because an unrelated change can turn every build red.

Orbit QA includes a small deterministic commerce system as the target. The full UI and API suite can run locally after cloning, with no account, paid service or unstable third-party dependency.

The project is less about producing a large number of tests and more about showing how tests remain readable, repeatable and useful when something goes wrong.

Clear ownership inside the framework

01
Configuration + driver factoryValidated runtime settings and local or remote browser sessions.
RUNTIME
02
Page objectsSelectors, waits and user-level browser actions.
INTERACT
03
API clientJSON service calls and response-contract checks.
SERVICE
04
pytest fixturesInfrastructure startup, lifecycle and failure hooks.
CONTROL
05
Intent-focused testsAssertions stay close to the behaviour being checked.
VERIFY

Fixtures own infrastructure and cleanup. Page objects own browser mechanics. Tests own assertions. Keeping those responsibilities separate means a browser change, a page change and a product regression fail in recognisably different places.

Synchronisation and selectors chosen for stability

The UI uses stable data-testid selectors and explicit waits for the condition each action genuinely needs. There are no fixed sleeps or broad implicit waits hiding timing problems.

CHOICE 01

Explicit waits

Each wait describes the state required before the test continues.

CHOICE 02

Small page objects

Reusable actions remove repetition without swallowing useful Selenium errors.

CHOICE 03

Selenium Manager

Local drivers are resolved without a machine-specific path in source.

CHOICE 04

Versioned test data

Non-secret cases are readable and reproducible across environments.

Runtime options allow Chrome, Firefox, headed execution, a remote Grid, another compatible base URL and an adjustable explicit-wait timeout without changing test code.

A failed check should leave something useful behind

When a browser assertion fails, the driver fixture writes both a screenshot and the matching HTML source. The screenshot shows what a person saw. The DOM snapshot helps investigate selectors, hidden states and rendered markup.

HTML and JUnit reports are produced alongside coverage output. CI uploads these artifacts even after a failed job, so the evidence is not lost precisely when it matters most.

The framework emits portable JUnit XML rather than coupling directly to a live test-management account. A separate adapter can consume those results later without putting credentials or vendor configuration into the core suite.

Fast framework feedback separated from browser compatibility

The GitHub Actions workflow runs Ruff and unit/API tests on Python 3.10 and 3.12. Complete suites then run separately in Chrome and Firefox with HTML, JUnit and branch-coverage reporting.

This matrix keeps the signal specific. A Python compatibility issue, API-contract change and browser-specific regression do not collapse into one vague failed build. The 80% branch-coverage threshold acts as a quality gate, not a vanity badge.

PythonpytestSelenium 4Page objectsAPI contractsGitHub ActionsRuffJUnit
Next case studyFootball Results Automation