What a Browser Extension's Test Suite Cannot Reach
Longshot is a Firefox screenshot extension I wrote to replace FireShot: full page, visible area, drag region and element capture, an editor with eleven annotation tools, export to PNG, JPEG, WebP and PDF, and local OCR that produces a searchable text layer. It has no runtime dependencies. The code is not public, so this is a description rather than an invitation to read it. At one point it had 130 passing Node assertions across six suites, zero failing. Printing could not open a dialog at all. Not "printed the wrong thing". The print command hung indefinitely and no dialog ever appeared. The suites did not go amber, or flake, or report a warning. They reported 130 passed, 0 failed, which is what they had reported the day before and what they would have gone on reporting. Why nothing caught it printCanvas encoded each slice of the image to a blob URL and awaited img.decode() . That call does not resolve for an image inside a display:none subtree, and the print stylesheet creates exactly such a subtree by design, since the container has to be hidden on screen. So the await never returned, and the dialog never opened. Every part of that failure is a meeting point between my code and the browser: the decode promise's behaviour, the stylesheet's effect on the subtree, and the ordering between them. None of it is reachable by a function you can call from Node. The six suites test band arithmetic, canvas dimension limits, filename sanitising, the background module graph under stubbed extension APIs, PDF structure and scan geometry. All of that is worth testing and none of it goes near a real DOM. The second bug in the same batch has the same shape one level in. Choosing PDF broke "Open in editor", because deliver() handed the editor the PDF blob and createImageBitmap cannot decode one. That is not a browser boundary; it is one internal stage handing another something it cannot accept. Both stages were tested; the seam between them was not. That is the pattern worth naming.