[ Case study ]
The vendor's building-operator web UI had grown for a decade with no automated tests; releases froze features for a month while QA clicked through 200 screens, and two of the last four releases shipped regressions that reached buildings.
CLIENT a building-management systems vendor — FOCUS Test the spine, screenshot the rest
Representative examplesEvery case study in this library is an illustrative composite of the kind of engagement we deliver — written to show our method and standards, not to name clients.
Building-automation software ages like infrastructure: the web UI this vendor ships with its controllers has grown for a decade across dozens of supported device types, and nobody on staff can say what every screen does anymore. Releases had frozen feature work for a month while QA clicked through two hundred screens by hand, and the last few releases still shipped regressions that reached real buildings — alarms misrouting, schedules not taking. The QA team knows the product cold but has no coding background, and building operators do not forgive a broken schedule the way a phone user forgives a broken button.
The vendor's building-operator web UI had grown for a decade with no automated tests; releases froze features for a month while QA clicked through 200 screens, and two of the last four releases shipped regressions that reached buildings.
We proposed a two-layer harness matched to where risk actually lives: behavioral end-to-end tests over the critical spine — alarms, schedules, setpoints — and visual regression coverage over the long tail of screens where layout regressions hide. The harness had to be QA-native from the first commit: scenarios written in the QA team's vocabulary, page objects they could extend without reading application code, and CI failures that explain themselves in plain terms. The pipeline and preview environments would land in week three, so release cadence improves during the engagement rather than after it.
Just as important is what we ruled out, and why:
Critical paths — alarms, schedules, setpoints — got behavioral end-to-end tests; the long tail got visual regression coverage, so coverage lands where risk lives.
Scenarios are written in the QA team's vocabulary with page objects they can extend, and CI failures explain themselves in plain terms.
The CI/CD pipeline with preview environments landed in week three, so releases improved every week of the engagement, not at the end.
Delivered by the systems pod — 2 engineers over 12 weeks, with working increments reviewed with the client every week.
Obstacle
The first visual baselines were captured from an in-flight development branch, so the suite absorbed an active regression as its definition of correct and passed it for two runs.
Handled: We re-baselined from a tagged release, added a rule that baselines regenerate only from release builds, and documented the discipline inside the harness itself.
Obstacle
Tests written against the simulated controller fleet passed while the same flows failed against one real controller family with different firmware timing.
Handled: We added that controller family to the weekly hardware-in-the-loop run, tightened the auto-waiting strategy it exposed, and made the differential part of release gating.
Obstacle
QA initially treated harness failures as engineering noise rather than signals; the first weeks produced more triage arguments than caught regressions.
Handled: We rewrote failure messages to name the user-visible symptom instead of the selector, and held a weekly triage where QA, not engineering, classified every failure.
The headline: releases shipping weekly behind the harness, with the two shipped regressions' class caught in ci — Monthly release freeze → weekly cadence, read from CI run history. A second check: qa cycle per release at 12 days → 2 days.
Release day is ordinary work now. The freeze week is gone, features land continuously, and QA spends it investigating the failures the harness found instead of clicking through screens. The QA lead's checklist became a test suite the whole team can read, so the knowledge survives her vacation and eventually her retirement. Engineers touch the old modules again because something other than a building will tell them they broke it. The two shipped-regression classes from the previous year now fail in CI before any operator ever sees them.
The result was read from CI run history against the pre-engagement baseline over the stated window, with a guardrail check on qa cycle per release. Where platform-reported numbers and business outcomes differ, this record says which layer it is quoting.
What we would do differently
We would baseline the visual suite on a tagged release, not on main — the first baselines absorbed an in-flight regression, which taught us the baseline discipline the hard way.
[ Related service ]
[ Related builds ]
0 pilot-ready productBooking MVP live with the first pilot cohort scheduled and samples reconciled through the ops console
Status calls self-serve portalHouseholds onboarded at contract signature, with stage changes visible within minutes of ops updating the board
[ Next step ]
Next case study