Skip to content

fix(capture): apply device viewport before tab-capture starts#804

Merged
Kikobeats merged 1 commit into
masterfrom
cursor/critical-bug-investigation-7e0c
Jun 26, 2026
Merged

fix(capture): apply device viewport before tab-capture starts#804
Kikobeats merged 1 commit into
masterfrom
cursor/critical-bug-investigation-7e0c

Conversation

@cursor

@cursor cursor Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Bug and impact

#803 starts tab recording before goto runs. Tab-capture constraints pin exact minWidth/minHeight/maxWidth/maxHeight from the target device viewport. When the page still has the browser's default viewport (e.g. Macbook Pro 13 at 2560×1600) but capture requests a different device (e.g. iPhone 13 at 1170×2532), getUserMedia can fail with OverconstrainedError because minHeight: 2532 exceeds the tab's actual height (1600). Capture completely fails for a common custom-device use case.

Root cause

resolveViewport computed constraints from goto.getDevice() but did not apply the viewport to the page before extension.startRecording() called getUserMedia in the extension. goto's page.setViewport() only ran later inside the onStarted hook.

Fix

Rename to prepareViewport and call page.setViewport(device.viewport) before starting the recorder. Navigation still happens after recording starts, so load animations are captured from t=0.

Validation

  • Added regression test: custom device viewport is applied before recording starts
  • All 24 @browserless/capture tests pass
Open in Web View Automation 

Note

Low Risk
Narrow timing fix in capture setup with a regression test; navigation and recording order are unchanged aside from earlier viewport application.

Overview
Fixes tab extension capture failing with OverconstrainedError when a custom device viewport does not match the page’s default size before getUserMedia runs.

prepareViewport (formerly resolveViewport) now await page.setViewport(device.viewport) from goto.getDevice() before the recorder starts, while navigation still runs in onStarted after recording begins. The shared ffmpeg recorder drops its redundant pre-frame setViewport and documents that sizing is applied upstream.

Adds a regression test that asserts the device viewport is set at START_RECORDING, not only after goto.

Reviewed by Cursor Bugbot for commit b28298e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coveralls

coveralls commented Jun 25, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 86.336% (+0.02%) from 86.313% — cursor/critical-bug-investigation-7e0c into master

Tab capture pins exact width/height from the target device, so
`getUserMedia` overconstrains and fails with OverconstrainedError when
the page still has the browser's default viewport. `resolveViewport`
computed the device viewport but never applied it before the extension
mode started recording.

Rename to `prepareViewport` and `page.setViewport(device.viewport)`
before any mode starts, so the page always matches the constraints.
Navigation still runs after recording starts, so load animations are
captured from t=0. This centralizes the viewport application for all
modes, making the frame recorder's own setViewport redundant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Kikobeats Kikobeats force-pushed the cursor/critical-bug-investigation-7e0c branch from f57ccce to b28298e Compare June 26, 2026 06:35
@Kikobeats

Copy link
Copy Markdown
Member

Rebased onto current master and reimplemented against the refactored capture package.

The original diff targeted packages/capture/src/index.js, but that file was split into per-mode entry points (extension/screencast/screenshot) since this branch was opened, so it no longer applied. The underlying bug was still present, though: create-capture.js's resolveViewport computed the device viewport but never applied it, so the extension (tab-capture) mode called getUserMedia before page.setViewport and could fail with OverconstrainedError.

Changes:

  • create-capture.js: resolveViewportprepareViewport (async), now page.setViewport(device.viewport) before any mode starts — centralizing the fix so all three modes are covered.
  • recorder/index.js: dropped the now-redundant setViewport (frame modes get it from prepareViewport).
  • test/index.js: regression test asserting the viewport is applied at the moment recording starts (verified it fails without the fix).

All 24 @browserless/capture tests pass + the new one; standard lint clean.

@Kikobeats Kikobeats marked this pull request as ready for review June 26, 2026 06:36
@Kikobeats Kikobeats merged commit a39c856 into master Jun 26, 2026
32 of 33 checks passed
@Kikobeats Kikobeats deleted the cursor/critical-bug-investigation-7e0c branch June 26, 2026 07:18
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.

2 participants