UI Testing Modernization
Tests that live outside the inner loop don't protect anything.
The Settings test framework existed but sat outside the dev inner loop, which meant it wasn't running at the moment it mattered — PR time. Two properties kept it out. It was slow, and it failed for reasons unrelated to the code under test. I had never worked in automation or testing before this, which turned out to be useful: I had no attachment to how it already worked.
I replaced fixed wait() operations with smart waiters, cutting suite runtime by a considerable margin, and migrated off simulated Click() calls in favor of programmatic invocation. I chose programmatic invocation over hardening the input-simulation path because simulated clicks depend on machine state no test can own — any non-Settings action on the test machine can steal the interaction. That trades away some fidelity to real user input, which I accepted: a test that fails randomly teaches people to ignore it.
I built the framework modular and documented so other engineers could extend it rather than route around it, with the target being tests running automatically on PR submission.
The reframing mattered more than any of the individual changes. These tests navigate the same UIA tree Narrator uses, with much the same protocols, so a test that breaks is advance warning that Narrator scenarios will break too. One investment, two guarantees. What I'd do differently: this work ran past its planned schedule and I flagged the slip late. I now surface schedule risk at the midpoint, when it's still information rather than an apology.
That reframing turned test infrastructure from a chore into a customer-experience investment.