fill_input: clear via element.select() — synthetic Cmd/Ctrl+A never fires select-all - #570
Open
aiba wants to merge 2 commits into
Open
fill_input: clear via element.select() — synthetic Cmd/Ctrl+A never fires select-all#570aiba wants to merge 2 commits into
aiba wants to merge 2 commits into
Conversation
The select-all shortcut never fires over CDP. Measured on Brave 150: selectionEnd - selectionStart == 0 on an 11-char field, in every tab state (activated, background, background with focus emulation). Backspace then deletes at the caret rather than the selection, and the new text lands beside the old value instead of replacing it. The corruption is silent and caret-dependent, so it is not even consistent — two runs of the same call produced 'REPLACEDpreexisting' and 'preexistinREPLACED' where both should have been 'REPLACED'. Select with element.select() (selectAllChildren for contenteditable) instead. Skip the Backspace when the field is already empty: select() on an empty field leaves it in a state where subsequent characters don't insert at all. For clear_first=False, park the caret at the end — focus() puts it at 0, so appended text would otherwise be prepended. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G35BbXw4eNsefYAT5Yd45N
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
The clear path handles contenteditable via selectAllChildren, but the
clear_first=False path only called setSelectionRange, which contenteditable
elements do not have. The caret stayed at the browser default (position 0), so
"append" prepended instead:
<div id="ce" contenteditable>keep</div>
fill_input("#ce", "-more", clear_first=False)
# was '-morekeep', now 'keep-more'
Fall back to a Range collapsed to the end of the element's contents. Caught by
cubic-dev-ai review on browser-use#570 and confirmed against a live page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G35BbXw4eNsefYAT5Yd45N
Author
|
Valid, and fixed in babf1f6 — thanks. Confirmed against a live page before and after: # <div id="ce" contenteditable>keep</div>
fill_input("#ce", "-more", clear_first=False)
# before: '-morekeep'
# after: 'keep-more'Exactly as described: the clear path handled contenteditable via |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
fill_input(selector, text)does not replace the field's contents. It clears by dispatching a synthetic Cmd/Ctrl+A, but that shortcut never fires select-all over CDP, soBackspacedeletes at the caret instead of deleting a selection, and the new text lands beside the old value.The corruption is silent — no exception, no warning — and caret-dependent, so it isn't even consistent. Two runs of the same call on the same field:
Root cause
Measured directly, on an 11-character field:
selectionEnd - selectionStart == 0: nothing is selected.press_key("Backspace")then removes one character at the caret, or none if the caret is at position 0, and the subsequent characters insert wherever the caret happens to be.This is not environment-specific. I measured the same
0 / 11in all three tab states:visibilityStatevisiblehiddenEmulation.setFocusEmulationEnabledvisibleTested on macOS 15, Brave 150 (Chromium 150), dedicated debugging profile on a non-default port.
Fix
Select via
element.select()(selectAllChildrenforcontenteditable) instead of the key dance:select()on an empty field leaves it in a state where subsequent characters don't insert at all — so theBackspaceis skipped when there is nothing to clear.clear_first=Falseparks the caret at the end.focus()puts it at position 0, so appended text was previously prepended. This was a second, separate bug in the same function.Verified against a live page:
fill_input("#a", "REPLACED")over"preexisting"'preexistinREPLACED''REPLACED'fill_input("#b", "FRESH")on empty field'FRESH''FRESH'fill_input("#c", "-more", clear_first=False)over"keep"'-morekeep''keep-more'Tests
uv run --with pytest pytest -q→ 98 passed.The test asserting the old Cmd/Ctrl+A behaviour is replaced by two tests: one that clearing selects via JS and still sends
Backspace, and one that an empty field does not receive aBackspace.Relationship to other PRs
#498 contains an equivalent
fill_inputchange, bundled into a larger background-tabs-by-default redesign, and attributes the bug to focus-emulated background tabs. The measurements above show it reproduces on ordinary activated tabs too, so it is worth fixing independently of that work — this PR is just the bug fix, and does not touch tab activation,press_key, orclick_at_xy.Summary by cubic
Fixes
fill_inputso it replaces content by selecting viaelement.select()(orselectAllChildren) instead of synthetic Cmd/Ctrl+A. Also ensures append mode puts the caret at the end for both inputs andcontenteditable.clear_first=False, moves the caret to the end for inputs andcontenteditable(viasetSelectionRangeor a collapsed Range).contenteditableappend.Written for commit babf1f6. Summary will update on new commits.