You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm testing a radiology application which assigns different meaning to mousedrag vs shift+mousedrag.
Currently that requires dropping all the way down from capybara to node.native.browser.page.command("Input.dispatchMouseEvent", to add the modifiers bitfield to the mousemove call.
Would a PR be accepted adding support for this?
My first thought is extending mouse.rb so you could call
Ferrum::Mouse.with_modifier_key(:shift) do
# within this block, all mouse events have the shift modifier added
end
Looked into this more closely. The gap is real: Mouse#down, #up and #click accept modifiers:, but Mouse#move doesn't, so there's no public way to do a modified drag. Even click(modifiers:) sends the preceding mousemove without them.
I'd rather not go with Ferrum::Mouse.with_modifier_key(:shift) { } though:
It's class-level, so the state would be shared across all pages/threads instead of belonging to a page.
It keeps keyboard and mouse state separate, while in a real browser holding Shift affects both. Today keyboard.down(:shift) followed by keyboard.down("a") doesn't carry the modifier either, since each call starts from scratch.
Proposal, similar to how Puppeteer/Playwright model it:
Keyboard tracks held modifiers: keyboard.down(:shift) sets the bit, keyboard.up(:shift) clears it. Both key events and all mouse events (move, down, up, click) pick it up automatically.
Mouse#move gets an explicit modifiers: option like down/up, overriding the held state when given.
On top of that we could add an instance-level helper, e.g. page.keyboard.hold(:shift) { ... } with up in an ensure, if it turns out to be handy. This would also let Cuprite support Capybara's drag_to(..., drop_modifiers: [:shift]).
If that works for you, PR is welcome, otherwise I'll pick it up.
Activity
route commentedon Oct 17, 2026
Looked into this more closely. The gap is real:
Mouse#down,#upand#clickacceptmodifiers:, butMouse#movedoesn't, so there's no public way to do a modified drag. Evenclick(modifiers:)sends the precedingmousemovewithout them.I'd rather not go with
Ferrum::Mouse.with_modifier_key(:shift) { }though:keyboard.down(:shift)followed bykeyboard.down("a")doesn't carry the modifier either, since each call starts from scratch.Proposal, similar to how Puppeteer/Playwright model it:
Keyboardtracks held modifiers:keyboard.down(:shift)sets the bit,keyboard.up(:shift)clears it. Both key events and all mouse events (move,down,up,click) pick it up automatically.Mouse#movegets an explicitmodifiers:option likedown/up, overriding the held state when given.Your case then needs no new API:
On top of that we could add an instance-level helper, e.g.
page.keyboard.hold(:shift) { ... }withupin anensure, if it turns out to be handy. This would also let Cuprite support Capybara'sdrag_to(..., drop_modifiers: [:shift]).If that works for you, PR is welcome, otherwise I'll pick it up.
feat(keyboard): hold modifiers for keyboard and mouse input inside a …
feat(drag): hold drop modifiers while moving to the target
feat(drag): hold drop modifiers while moving to the target (#344)