diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a97178d..3d0841d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ the browser; a failed `IO.close` is raised to the caller. ### Fixed +- Mouse moves sent while a button is held now include the active `button` value, allowing Chrome to start drag sessions + and emit `Input.dragIntercepted` [#635] - An out-of-process iframe, e.g. Chrome's PDF viewer for an embedded PDF, appearing while a web worker was connected raised `'Page.enable' wasn't found` in the event thread. Only pages and iframes are now searched for its parent [#640] - A browser that stopped reading its websocket froze the whole client: a large command blocked in a socket write diff --git a/lib/ferrum/mouse.rb b/lib/ferrum/mouse.rb index 6e5a8f9e..b4f2042c 100644 --- a/lib/ferrum/mouse.rb +++ b/lib/ferrum/mouse.rb @@ -156,12 +156,14 @@ def move(x:, y:, steps: 1) steps.times do |i| new_x = from_x + ((@x - from_x) * ((i + 1) / steps.to_f)) new_y = from_y + ((@y - from_y) * ((i + 1) / steps.to_f)) + button = BUTTON_MASKS.find { |_name, mask| mask.positive? && @buttons.anybits?(mask) }&.first || "none" @page.command("Input.dispatchMouseEvent", slowmoable: true, type: "mouseMoved", x: new_x, y: new_y, + button: button, buttons: @buttons) end diff --git a/spec/mouse_spec.rb b/spec/mouse_spec.rb index e823bbbc..c1ad5452 100644 --- a/spec/mouse_spec.rb +++ b/spec/mouse_spec.rb @@ -57,6 +57,29 @@ end describe "#move" do + it "preserves the pressed button for drag interception" do + browser.go_to("/simple") + browser.execute(<<~JS) + const source = document.createElement("div"); + source.draggable = true; + source.style.cssText = "position:fixed;left:0;top:0;width:100px;height:100px"; + document.body.appendChild(source); + JS + + intercepted = Queue.new + browser.page.on("Input.dragIntercepted") { |params| intercepted << params } + browser.page.command("Input.setInterceptDrags", enabled: true) + + browser.mouse.move(x: 10, y: 10) + .down(button: :left) + .move(x: 80, y: 80, steps: 5) + + expect(intercepted.pop(timeout: 1)).not_to be_nil + ensure + browser&.mouse&.up(button: :left) + browser&.page&.command("Input.setInterceptDrags", enabled: false) + end + it "splits into steps" do browser.go_to("/simple") browser.mouse.move(x: 100, y: 100)