Skip to main content

Building a Maintainable Automation Framework: Field Notes from an Architect

Organize tests around risk, isolated state, useful evidence, and small tools whose limits you understand.

3 min read
Building a Maintainable Automation Framework: Field Notes from an Architect
On this page

A framework becomes useful when another engineer can understand a failure, reproduce it, and change one part without destabilizing the rest. These field notes collect the boundaries that matter most in the browser, API, mobile, and legacy workflows behind my open-source tools.

Keep four responsibilities visible

LayerResponsibility
TestsState the requirement and assert the outcome
Business operationsPage components, service clients, and domain workflows
Runtime supportDriver lifecycle, configuration, bounded waits, and data factories
InfrastructureCI, environment provisioning, logs, and report artifacts

These layers reduce coupling; they do not guarantee that a product change never affects tests. A changed requirement should change the assertion. A helper should not hide that change merely to keep the suite green.

Choose small tools for concrete gaps

ProblemTool and boundary
Page activity before Selenium interactionsWaitless: thresholds complement outcome assertions
Repeated authenticated setupSelenium Teleport: supported current-origin state, not complete browser restoration
Bot-defense behavior on an authorized test targetSB Stealth Wrapper: bounded recovery with explicit failures
Visual changesVisual Guard: compare approved screenshots with reviewed thresholds
Nested shadow rootsLumos: convenience traversal; Selenium also has native shadow-root access
Remote desktop pixelsVisual Sonar: focus-difference heuristics require an interactive session
Test reportingpytest-glow-report: preserve runner outcomes; online enhancements use CDNs

Keep state isolated

Use separate test accounts or unique data keys when tests run in parallel. Share expensive infrastructure only if each test still gets a controlled starting state. A fixture should release the resource even when an assertion fails.

python
import pytest
from selenium import webdriver

@pytest.fixture
def browser():
    driver = webdriver.Chrome()
    try:
        yield driver
    finally:
        driver.quit()

Wait for the requirement, not just a quiet page

Use explicit conditions for the state that matters: an order persisted, the expected account authenticated, or a background job completed. Stabilization can help before interaction, but neither page quietness nor a successful click proves the business result.

Retry only when the operation permits it

A retry policy should name the transient errors it handles, have a finite bound, and expose each attempt. A failed read is often safer to retry than an ambiguous write. For an external side effect, check whether the previous attempt completed or use a destination idempotency key.

Put fast checks below expensive journeys

A test pyramid generally has many focused unit tests, a useful service and integration layer, and fewer end-to-end journeys. There is no universal API/UI percentage. Select layers based on where a defect can be detected faithfully and where user-visible integration risk remains.

Reports should explain the failure

Preserve the test phase, traceback, relevant log excerpt, application revision, and useful screenshot or trace. A polished score cannot decide whether the product is ready to release. Current release articles explain Glow’s reporting boundary, Teleport’s restore checks, and Waitless’s signals.

Keep model assistance advisory first

A model can summarize a failure or propose a patch. Do not silently replace an assertion, skip a test, or execute a new selector after the original action failed. Use a reviewable proposal boundary and preserve the original failure.

Measure maintenance cost

  • Time to a useful diagnosis.
  • First-attempt pass rate and unresolved flakes.
  • Time spent updating fixtures after product changes.
  • Missing evidence in failed CI runs.
  • Review corrections and repeated defects.

Open-source software removes license fees, but ownership, infrastructure, integration, and support still cost time. Adopt a tool when its benefit in your environment exceeds that cost, then keep its contract small enough to verify.

Dhiraj Das

About the Author

Dhiraj Das is an Automation Consultant with over a decade of experience building systems that expose failures, reduce flakiness, and make complex workflows repeatable. He applies that discipline to AI-agent validation, LLM testing, and postmortems.

He shares small open source utilities from real automation work, including: waitless (flaky tests), sb-stealth-wrapper (bot detection), selenium-teleport (state persistence), selenium-chatbot-test (AI chatbot testing), lumos-shadowdom (Shadow DOM), and visual-guard (visual regression).

Share this article: