Hi, I'm Cosmin

Software tester by day, tinkerer by night. I write about test automation, 3D printing, microcontrollers, and making my home smarter one hack at a time.

File ownership stops two agent sessions editing the same file, but nothing stops them at commit time. A pathspec on git add is not a pathspec on git commit, a pathspec bounds files rather than hunks, and stash sweeps the whole repository. Six sessions on one shared tree kept shipping each other's work until every one of these was proven by hand.

15 min read

A comment gets written once and almost nobody revisits it while the code keeps moving. A slimming pass cut 5,880 comment lines to 3,820 across fourteen spec files, proved with a grep filter that zero non-comment lines changed, fixed five confidently wrong rationales, and shipped a ratchet guard so the density cannot regrow.

15 min read
Software Testing

Your suite has too many tests

Sep 14, 2026

A consolidation campaign folded 246 near-duplicate tests out of a 4,911-test Playwright suite without losing a single traceability tag. A token similarity report finds mechanical duplicates in seconds; everything else needs a full reading pass, and every estimate needs adversarial verification before it is trusted.

14 min read

A red assertion proves the app disagrees with the test, not with the intended behaviour. Of six defect candidates in one batch, four turned out to be the test's own wrong assumptions. This is the six-rung evidence ladder, cheapest rung first, that separates a real defect from a confident mistake.

13 min read

Five separate incidents against a shared test environment looked exactly like an outage. None were: a missing Bearer prefix, an unmatched gateway route, a dropped DNS resolver, a schema-valid empty response, and a zero-byte compiled test cache. One known-good 200 through the same client would have settled each one before the ticket was filed.

14 min read

Deleting a schema-drift toleration looks like a one-line diff: remove an array entry, done. Five traps say otherwise, from a runtime discovery check that silently orphans an emptied array to a freshness guard that diffs the working tree against the git index.

15 min read
Testing Series 54% 22 of 41 posts live · #22 shipped 12 Aug
Theme v2.2.4 /blog shows every post · reveal stagger cycles

last reading: · 3 months ago · STALE

Automated Playwright Authentication with Microsoft SSO Push Notifications in CI/CD

Security said no to TOTP, no to service accounts, no to disabling MFA. So I built a solution that uses OAuth2 refresh tokens to maintain Playwright browser sessions in CI/CD, without ever triggering push notification MFA after the initial setup. Here's the COSMIC Auth Pattern.

// Renew the session without ever waking the phone
const { refreshToken, clientId } = await readCognitoTokens(page);

const res = await page.request.post(AUTH_DOMAIN + "/oauth2/token", {
  form: {
    grant_type: "refresh_token",
    client_id: clientId,
    refresh_token: refreshToken,
  },
});
if (!res.ok()) throw new Error("Token refresh failed: " + res.status());
// Fresh access + ID tokens. No push notification. No human.
"You don't need to bypass MFA — you just need to not trigger it after the first login."

One human approves one push notification, once, on a laptop. After that a scheduled job refreshes the tokens every 12 hours through the OAuth2 endpoint and writes the new state straight back into the CI/CD variable, so the pipeline authenticates against the real identity provider forever without a phone in the loop — and without a single token in git.

read the full build →