Skip to content

fix(visual): stop silently dropping mobile screenshots of long pages - #9790

Merged
JSONbored merged 1 commit into
mainfrom
fix/mobile-screenshot-height-cap
Jul 29, 2026
Merged

fix(visual): stop silently dropping mobile screenshots of long pages#9790
JSONbored merged 1 commit into
mainfrom
fix/mobile-screenshot-height-cap

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

The bug

MAX_SCREENSHOT_HEIGHT was 10000 — a bound derived for the desktop viewport. Its sibling constant says so outright:

export const MAX_SCREENSHOT_PIXELS = 14_400_000; // 1440 × 10000, matching the full-page cap.

Applied unchanged to the 390-wide mobile viewport, it rejected captures costing a third as much. An ordinary long docs page renders ~10,850px tall at 390 wide — 4.2M pixels against a 14.4M budget, comfortably affordable — and was thrown away, with renderShot returning null.

Found on the live ORB, which logged it 64 times in a single hour, every one at width 390:

{"event":"render_screenshot_too_large","width":390,"height":10847,"maxHeight":10000,"maxPixels":14400000}

So the visual gate was quietly running desktop-only on long pages — losing coverage on exactly the viewport most likely to expose a responsive regression.

The renderer was never the constraint

I checked rather than assumed, against this deployment's own browserless (v2 / Chrome 149), full-page PNG at 390 wide:

height result
10,847 200, 90 KB
12,000 200, 100 KB
16,000 200, 129 KB
16,500 200, 132 KB
20,000 200, 157 KB

The 10,000 cap was a second, cruder cost proxy sitting next to the accurate one.

The fix

Raise the height bound to 20000 as a sanity limit against pathological infinite-scroll pages, and let MAX_SCREENSHOT_PIXELS remain the real cost ceiling — it judges a narrow-tall page by what it actually costs to render. MAX_SCREENSHOT_BYTES (5 MB) is untouched as the third bound.

Desktop is unaffected and the cost ceiling is not widened: 1440 × 10,847 is 15.6M pixels and still fails the pixel cap. An invariant test pins that, so this can't be misread as "we raised the limits."

Tests

3 new cases: a regression using the exact observed dimensions, an invariant proving desktop still fails the pixel cap at that height, and one asserting the height bound stays something the renderer can actually satisfy. 98 pass.

MAX_SCREENSHOT_HEIGHT was 10000, derived for the 1440-wide DESKTOP viewport --
MAX_SCREENSHOT_PIXELS is literally 1440 x 10000. Reusing that height bound for the
390-wide MOBILE viewport rejected captures costing a third as much: an ordinary
long docs page renders ~10850px tall at 390 wide, which is 4.2M pixels against a
14.4M budget. The shot was discarded and the function returned null.

On the ORB that was 64 mobile screenshots dropped in a single hour, weakening the
visual gate on exactly the viewport most likely to show a responsive regression.

The renderer was never the constraint. Verified against this deployment's own
browserless (v2 / Chrome 149): a 390 x 20000 full-page capture returns 200 in
~157KB. Raise the height bound to 20000 and let MAX_SCREENSHOT_PIXELS remain the
real cost ceiling, which judges a narrow-tall page by what it actually costs.

Desktop is unchanged: 1440 x 10847 is 15.6M pixels and still fails the pixel cap.
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Important

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏳ LoopOver is waiting…

LoopOver has seen this pull request and is waiting on CI checks to finish before reviewing it. This comment will update once the review runs.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟨 Waiting

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored JSONbored self-assigned this Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.48%. Comparing base (0fa52ed) to head (d4607ae).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9790      +/-   ##
==========================================
- Coverage   90.30%   89.48%   -0.82%     
==========================================
  Files         913      913              
  Lines      113595   113595              
  Branches    26963    26963              
==========================================
- Hits       102584   101654     -930     
- Misses       9682    10851    +1169     
+ Partials     1329     1090     -239     
Flag Coverage Δ
backend 94.09% <100.00%> (-1.48%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/review/visual/shot.ts 96.72% <100.00%> (ø)

... and 3 files with indirect coverage changes

@JSONbored
JSONbored merged commit fef8a8a into main Jul 29, 2026
7 checks passed
@JSONbored
JSONbored deleted the fix/mobile-screenshot-height-cap branch July 29, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant