Code Mage LogoCode Mage

— Writing

Blog

Deep dives, tutorials, and real-world breakdowns on Python, automation, and software dev.

AllCareerProject BreakdownPython Deep DiveTest AutomationWeb Scraping

43 posts

Test Automation

TypeScript Generics for Testers: Writing One Helper Instead of Five

Most testers learn just enough TypeScript to get by, and generics are usually the first thing skipped. They're also the exact tool that turns five nearly-identical helper functions into one that actually stays type-safe.

Sep 17, 20267 min
Read
Project Breakdown⭐ Featured

The 404 That Broke Three Test Frameworks

A navigation pattern that looked completely normal was quietly broken in Playwright, WebdriverIO, and my own tutorial content — and it took a real HTTP request, not a stack trace, to find it.

Sep 17, 20267 min
Read
Test Automation

The Testing Pyramid vs. the Testing Trophy: Two Real Strategies, Not One Right Answer

Mike Cohn's Testing Pyramid and Kent C. Dodds's Testing Trophy disagree about where most of your testing effort should go, and both have a real, specific argument for their answer. The mistake is treating either one as a universal law instead of a strategy that fits a particular kind of application.

Sep 17, 20266 min
Read
Test Automation

What 'Test Isolation' Actually Means, and the Vocabulary for Getting It Right

'Tests should be isolated' is advice everyone repeats and almost nobody defines precisely. Gerard Meszaros's xUnit Test Patterns gives it exact vocabulary — Fresh Fixture, Shared Fixture, Erratic Test — that turns a vague virtue into a concrete design decision.

Sep 17, 20266 min
Read
Test Automation

Mocks, Stubs, and Fakes: The Test Double Vocabulary Almost Everyone Gets Wrong

Nearly everyone says 'mock' when they mean 'stub.' The distinction sounds pedantic until you notice it's actually describing two fundamentally different ways of verifying that code did the right thing.

Sep 17, 20268 min
Read
Test Automation

SOLID Principles, Applied to Test Automation Code

SOLID gets taught as application-architecture advice and almost never applied to the test code sitting right next to that architecture — even though test suites rot for exactly the same five reasons production code does.

Sep 17, 20267 min
Read
Test Automation

Race Conditions: A Mental Model That Actually Explains Your Flaky Tests

'Race condition' gets used as a catch-all excuse for any flaky test nobody's bothered to diagnose. The actual definition is precise, comes from concurrent systems theory, and — once you know it properly — tells you exactly where to look.

Sep 17, 20267 min
Read
Test Automation

Pure Functions and Why They're Easier to Test (a Precise Explanation, Not a Slogan)

'Pure functions are easier to test' is repeated constantly and rarely explained. The actual reason is a specific property called referential transparency, and once you can spot it, you can also spot exactly which parts of your codebase resist testing and why.

Sep 17, 20267 min
Read
Test Automation

"Program to an Interface, Not an Implementation" — What That Actually Means for Test Code

It's the first principle in the Gang of Four's Design Patterns book, printed in italics as the foundational rule everything else in that book builds on. Most people who've heard the phrase can't explain what an 'interface' means here, or why it matters outside application architecture.

Sep 17, 20267 min
Read
Test Automation⭐ Featured

The Locator Hierarchy, From First Principles

Every framework's docs tell you to prefer role-based selectors over CSS classes. Almost none of them explain why, in a way that actually transfers when you hit a case the cheat sheet didn't cover. Here's the reasoning underneath the rule.

Sep 17, 20268 min
Read
Test Automation

Immutability and the Aliasing Bug That Only Shows Up Three Functions Later

The most confusing bugs to debug aren't the ones that crash loudly — they're the ones where a value changed and nothing in the stack trace tells you where. Immutability doesn't eliminate bugs in general. It eliminates this one specific, disproportionately confusing category of them.

Sep 17, 20267 min
Read
Test Automation

Idempotency: Why Your Tests (and the APIs They Call) Should Survive Running Twice

Idempotency is a real, precisely-defined engineering concept — not a synonym for 'safe' — and it explains both why your CI retries can silently create duplicate data and why a well-designed API makes that impossible in the first place.

Sep 17, 20267 min
Read
Project Breakdown⭐ Featured

I Said Allure 'Works' in Three Tutorials. Then I Actually Ran It.

Every reporting chapter on this site described Allure setup that had never once been run. Actually running it found a plugin that silently crashes Cypress 16, a Java dependency nobody mentions until it fails, and a flaky test that only a real repeated run would have caught.

Sep 17, 20268 min
Read
Test Automation

DRY in Test Code: What the Principle Actually Says, and Where It Backfires

Andy Hunt and Dave Thomas's actual definition of DRY is narrower and more useful than the 'never repeat code' slogan it got flattened into — and test suites are exactly where the flattened version causes the most damage.

Sep 17, 20267 min
Read
Test Automation

Design Patterns Beyond Page Object Model: Factory and Strategy

Page Object Model gets all the attention in testing tutorials, but it's one pattern out of dozens of well-established solutions to well-established problems. Two more — Factory and Strategy — solve problems every growing test suite eventually hits.

Sep 17, 20268 min
Read
Test Automation

Dependency Injection: Why Playwright's Fixtures Exist, and How to Design Your Own

Playwright's fixture system feels like a testing-specific convenience until you recognize it as dependency injection wearing a test framework's clothes — a pattern with a name, a history, and rules that explain why fixtures behave the way they do.

Sep 17, 20267 min
Read
Test Automation⭐ Featured

Classes, Objects, and Why Page Objects Are Just OOP

Most test automation tutorials teach Page Object Model as a testing pattern with its own special rules. It isn't one — it's four ordinary object-oriented programming concepts, applied to a browser. Once you see that, half the 'best practices' debates around it stop being mysterious.

Sep 17, 20269 min
Read
Test Automation

Async/Await and the Event Loop: What's Actually Happening When You Write await page.click()

Every test you've ever written is full of await. Most people using it correctly still can't explain what it actually does to their code at runtime — which is fine, until you hit a bug that only makes sense once you can.

Sep 17, 20266 min
Read
Career

Seven Merged PRs: My Real WebdriverIO Open Source Footprint

A full, honest accounting of everything I have actually shipped upstream to the WebdriverIO org — one feature, four docs fixes, one bug fix, one config cleanup — and what each one actually took.

Sep 16, 20266 min
Read
Career

What Mentoring Junior Engineers on Test Frameworks Actually Taught Me

Mentoring teammates on a framework I built taught me more about its design flaws than a year of writing tests in it myself.

Sep 15, 20267 min
Read
Test Automation⭐ Featured

Page Object Model Is Still Right (Just Not the Way Most Tutorials Teach It)

The common complaints about POM are real — but they're usually complaints about three specific anti-patterns, not about POM itself.

Sep 14, 20268 min
Read
Project Breakdown

JSON Diffing Is Harder Than It Looks: Building a Comparison Tool

What started as "just diff two JSON strings" turned into a small tree-walking algorithm with more edge cases than I expected.

Sep 13, 20268 min
Read
Project Breakdown

Django Channels and WebSockets: Real-Time Features in a Full-Stack App

Adding live task updates to Task Nest meant admitting that plain Django request/response was never going to cut it.

Sep 13, 20269 min
Read
Project Breakdown

Open Source, Freelance, Full-Time: Where wdio-wait-for Came From

How chasing the same wait-condition bug across a full-time job and a freelance contract turned into an upstream contribution to a WebdriverIO community package.

Sep 12, 20267 min
Read
Test Automation

Selenium Grid on a Budget: Local Distributed Testing Without Cloud Costs

When a self-hosted Selenium Grid beats BrowserStack or Sauce Labs, when it genuinely doesn't, and a real Grid 4 setup with Chrome, Firefox, and Appium nodes.

Sep 12, 20269 min
Read
Project Breakdown

What I Learned Contributing to WebdriverIO's Official Docs

I wrote the official file-download best-practices page for webdriver.io because I kept hitting the same undocumented problem in production — here's what I learned about the problem and about contributing docs to a real OSS project.

Sep 11, 20267 min
Read
Project Breakdown

Building a VPN Client From Scratch: A Python ShadowSocks Desktop App

Why I built ProxyPal, a macOS ShadowSocks client in Python, and what it actually takes to manage a background proxy process without losing your mind.

Sep 10, 20269 min
Read
Test Automation

Cypress 16: What's New (and What Broke)

A practical upgrade guide to Cypress 16 — the breaking changes you have to fix, the flakiness fixes worth having, and an honest look at the new AI features.

Sep 9, 20269 min
Read
Test Automation

Playwright's UI Mode Is Now How I Debug Everything

How Playwright UI Mode replaced console.log, --debug, and headed-mode guesswork as my default way to write and fix tests.

Aug 26, 20267 min
Read
Career⭐ Featured

From Full-Stack to Framework Architect: How My Role Actually Changed

My career has moved through three genuinely different kinds of engineering, not one continuous upward line — here is what actually transferred between them and what did not.

Aug 12, 20267 min
Read
Career

Freelancing While Full-Time: What a Year and a Half on Upwork Taught Me

For a year and a half I worked a full-time job and freelanced on Upwork at the same time. Here is what that actually taught me, and what it cost.

Jul 29, 20267 min
Read
Web Scraping⭐ Featured

Building an Anti-Detection Scraping Engine: What Actually Beats Cloudflare and reCAPTCHA

A layer-by-layer breakdown of how modern bot detection actually works — network, browser, and behavioral — and the countermeasures that actually hold up in production.

Jul 15, 202612 min
Read
Test Automation

One Framework, Three Platforms: WebdriverIO for Web, Android, and iOS

How a factory pattern let one WebdriverIO codebase drive web, Android, and iOS tests instead of maintaining three separate suites.

Jul 1, 20267 min
Read
Project Breakdown

Recursive vs. Loop-Based Traversal for Variable-Depth Automation Flows

A fixed-depth loop breaks the moment your flow has variable depth. Here is why recursion fixed it, and the real limits on when recursion is the right call.

Jun 17, 20266 min
Read
Project Breakdown

Building a FastAPI Microservice for PDF Data Extraction

How and why I pulled PDF data extraction out of our scraping bots into its own FastAPI service, and the factory pattern that lets it handle wildly different document layouts.

Jun 3, 20269 min
Read
Project Breakdown

Credential Management at Scale: A State Machine for Thousands of Bot Accounts

Managing thousands of bot accounts taught me that "just retry with a different password" is not a strategy — it is how you get every account you own banned in a week.

May 20, 20269 min
Read
Test Automation

Migrating From Cypress to Playwright Without Touching a Test File

How an adapter layer let us swap Cypress for Playwright by changing one file instead of rewriting hundreds of tests — and what that approach quietly doesn't solve.

May 6, 20268 min
Read
Project Breakdown⭐ Featured

From 8 Hours to 2: Cutting a WebdriverIO Suite's Runtime by 75%

How I took an inherited 100+ file WebdriverIO suite down to 60 files and an 8-hour runtime down to 2, and where each hour of savings actually came from.

Apr 22, 20267 min
Read
Project Breakdown⭐ Featured

How I Unified 23 Payer Integrations Into One System in 2 Weeks

I inherited 23 separate bot integrations, each built differently, each with its own way of dying. Here is how I unified them into one system without missing the deadline.

Apr 8, 20268 min
Read
Web Scraping⭐ Featured

What is Patchright? The Playwright Fork Nobody's Talking About

Patchright is a patched version of Playwright that fixes the detection leaks that get your scrapers blocked. Same API, same code — just undetectable.

Mar 25, 20268 min
Read
Test Automation

CI/CD for Playwright Tests: A Real GitHub Actions Setup

A production-grade GitHub Actions workflow for Playwright — parallel sharding, caching, HTML reports as artifacts, and Slack notifications when tests fail.

Mar 5, 20266 min
Read
Python Deep Dive⭐ Featured

Python Type Hints: A Practical Guide for Test Engineers

Type hints aren't just for application code. Used well, they make your test helpers, fixtures, and page objects dramatically easier to maintain.

Feb 3, 20268 min
Read
Test Automation⭐ Featured

Why I Switched from Selenium to Playwright (And What I Got Wrong About Selenium 4)

Three years of Selenium, then a switch to Playwright that stuck. A full comparison — including the Selenium 4 features that have genuinely closed part of the gap, and the one architectural difference that hasn't.

Jan 10, 20268 min
Read