mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 12:55:09 +00:00
fix: use CDP selectAll command for cross-platform field clearing
clearField() used Control+A to select all text before deleting, but on macOS Chrome, Ctrl+A is the Emacs "beginning of paragraph" binding — not select-all. This meant the clear tool never actually cleared field content. Use CDP's `commands: ['selectAll']` parameter on dispatchKeyEvent to trigger the browser's editing command directly, bypassing platform-specific keyboard shortcut mappings. Also adds a dedicated Browser.clear() method so the clear tool no longer routes through fill() with an empty string. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -821,6 +821,22 @@ export class Browser {
|
||||
return coords
|
||||
}
|
||||
|
||||
async clear(page: number, element: number): Promise<void> {
|
||||
const session = await this.resolveSession(page)
|
||||
await elements.scrollIntoView(session, element)
|
||||
try {
|
||||
await elements.focusElement(session, element)
|
||||
} catch {
|
||||
try {
|
||||
const { x, y } = await elements.getElementCenter(session, element)
|
||||
await mouse.dispatchClick(session, x, y, 'left', 1, 0)
|
||||
} catch {
|
||||
logger.warn('Could not focus element for clear')
|
||||
}
|
||||
}
|
||||
await keyboard.clearField(session)
|
||||
}
|
||||
|
||||
async pressKey(page: number, key: string): Promise<void> {
|
||||
const session = await this.resolveSession(page)
|
||||
await keyboard.pressCombo(session, key)
|
||||
|
||||
@@ -180,31 +180,31 @@ export async function typeText(
|
||||
}
|
||||
|
||||
export async function clearField(session: ProtocolApi): Promise<void> {
|
||||
// Use the CDP `commands` parameter to trigger the selectAll editing command
|
||||
// directly, bypassing platform-specific keyboard shortcut mappings
|
||||
// (Ctrl+A doesn't select all on macOS Chrome — it's the Emacs "beginning of paragraph" binding)
|
||||
await session.Input.dispatchKeyEvent({
|
||||
type: 'keyDown',
|
||||
type: 'rawKeyDown',
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
modifiers: 2,
|
||||
windowsVirtualKeyCode: 65,
|
||||
commands: ['selectAll'],
|
||||
})
|
||||
await session.Input.dispatchKeyEvent({
|
||||
type: 'keyUp',
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
modifiers: 2,
|
||||
windowsVirtualKeyCode: 65,
|
||||
})
|
||||
await session.Input.dispatchKeyEvent({
|
||||
type: 'keyDown',
|
||||
key: 'Delete',
|
||||
code: 'Delete',
|
||||
windowsVirtualKeyCode: 46,
|
||||
type: 'rawKeyDown',
|
||||
key: 'Backspace',
|
||||
code: 'Backspace',
|
||||
windowsVirtualKeyCode: 8,
|
||||
})
|
||||
await session.Input.dispatchKeyEvent({
|
||||
type: 'keyUp',
|
||||
key: 'Delete',
|
||||
code: 'Delete',
|
||||
windowsVirtualKeyCode: 46,
|
||||
key: 'Backspace',
|
||||
code: 'Backspace',
|
||||
windowsVirtualKeyCode: 8,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ export const clear = defineTool({
|
||||
element: z.number(),
|
||||
}),
|
||||
handler: async (args, ctx, response) => {
|
||||
await ctx.browser.fill(args.page, args.element, '', true)
|
||||
await ctx.browser.clear(args.page, args.element)
|
||||
response.text(`Cleared [${args.element}]`)
|
||||
response.data({ action: 'clear', page: args.page, element: args.element })
|
||||
response.includeSnapshot(args.page)
|
||||
|
||||
Reference in New Issue
Block a user