Sixteen new tests passed, and the header they relied on never reached the browser
Tests can agree with the fixtures you wrote and still be blind to what a browser enforces.
We fixed a privacy bug in Hireo: an anonymised CV was being saved under the candidate's real name. The fix read the server's chosen filename from a response header. Sixteen new tests passed. The browser would have hidden that header.
The fix that looked finished
A candidate's anonymised CV was downloaded with the real name in the filename. The fix named the file by what the server said, read from the response's Content-Disposition header, and the 16 new tests agreed.
What the browser does that a test does not
The page and the server live on different domains. A browser only lets a page read a handful of response headers from another domain unless the server lists the others as exposed, and ours listed none. So in a real browser the header reads as empty, and the new code could not run.
The test environment, jsdom, implements no such filtering. Every test handed the header over and saw it, so all of them were green by construction.
How it was caught
A review gate asked whether the header was readable across domains. It was not found by a test run and nobody drove a browser to see it. The same question found a second feature, a warning shown when an AI summary fails, that rests on a header with the same defect and could not have fired.
The first version of the fallback also re-created the leak it was written to close, and one test asserted the leak as intended behaviour.
What we changed
The shared CORS module now lists the exposed headers in one place, and a generated fixture pins the browser-side code to the server's rule so they cannot drift. The remaining check is the one that can fail: ask the server over the wire and confirm the header is exposed, after the function is redeployed.
What to take from it
- A green suite proves agreement with your fixtures. Not with the browser.
- Write the check that can fail first. For CORS that is a request on the wire.
- Review the assumptions, not only the code. A question found what 16 tests could not.
Want to know your tests can see what a browser enforces?
We run the real browser or the real wire check, not only the mock. The first month is a trial.