Skip to content

Support Element#drop for files and strings#316

Open
myabc wants to merge 3 commits into
rubycdp:mainfrom
myabc:feature/element-drop
Open

Support Element#drop for files and strings#316
myabc wants to merge 3 commits into
rubycdp:mainfrom
myabc:feature/element-drop

Conversation

@myabc

@myabc myabc commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

Implements Node#drop so Element#drop can drop files and strings onto an element, un-skipping the 5 Capybara Element#drop shared specs.

Why

Element#drop was force-skipped in spec/spec_helper.rb — Cuprite had no way to dispatch an HTML5 drop carrying a DataTransfer. This is the Element#drop portion deferred from #315 (HTML5 drag-and-drop).

How

Node#drop(*args) forwards to Browser#drop(node, *args), mirroring Capybara's Selenium html5_drop:

  • Files (path-string args) — a hidden <input type=file> is synthesized, files are attached through Cuprite's existing select_file (CDP DOM.setFileInputFiles), then a drop is dispatched carrying DataTransfer.files.
  • Strings ({type => data} args) — a DataTransfer is built via items.add/setData and a drop is dispatched.

The three JS helpers (dropString, attachDropInput, dropFile) are ported from Capybara's Selenium html5_drag.rb (DROP_STRING/ATTACH_FILE/DROP_FILE) and carry provenance comments.

Notes

  • Uses only public Ferrum API — no raw CDP command() or reach-ins (per Cuprite 1.0 #307).
  • Node#drop is a single-line endless method to stay within the existing Metrics/ClassLength budget on node.rb.
  • Stacked on Support HTML5 drag-and-drop and drag modifier keys #315 — until that merges, this PR's diff also shows the drag-and-drop commits; it narrows to the two Element#drop commits once Support HTML5 drag-and-drop and drag modifier keys #315 lands.
  • Known minor follow-up (inherited from Capybara's approach): if select_file raised mid-drop the synthesized input would not be cleaned up. Kept faithful to the upstream port for now; can harden separately.

Testing

  • The 5 previously-skipped Element#drop specs (2 string + 3 file) now pass.
  • Drag + drop together: 26 examples, 0 failures.
  • Full suite: no new failures versus the base branch (the two #has_field validation-message failures are pre-existing — Chrome locale wording).
  • bundle exec rubocop clean.

Part of #307. Follow-up to #315.

🤖 Authored with agent assistance.

myabc added 2 commits July 9, 2026 17:09
`Node#drag_to` drove only real mouse events, which never fire the HTML5
drag sequence (dragstart/dragover/drop/dragend + DataTransfer), so
suites exercising HTML5 drag-and-drop had to fall back to Selenium.

Route drag_to between two paths after the initial mouse-down: a legacy
path (real Ferrum mouse events, now applying held modifier keys via the
public mouse modifier bitfield) and an HTML5 path (a JS emulation
dispatching the drag events with a shared DataTransfer). Detection
mirrors Capybara: a draggable source or ancestor takes the HTML5 path,
otherwise legacy. The emulation is ported from Capybara's Selenium
Html5Drag extension and lives in javascripts/drag.js.

Un-skips the 15 Capybara shared drag specs (12 HTML5 + 3 mouse
modifier). Uses only public Ferrum API. Element#drop (files/strings)
remains out of scope.

Closes rubycdp#314
Copilot AI review requested due to automatic review settings July 9, 2026 17:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds HTML5 drag-and-drop support required by Capybara shared specs by (1) routing Node#drag_to through a DataTransfer-backed JS emulation when appropriate and (2) implementing Node#drop/Browser#drop so Element#drop can drop files and strings, allowing previously force-skipped Capybara specs to run.

Changes:

  • Un-skips Capybara shared specs for #drag_to and Element#drop previously filtered out in spec/spec_helper.rb.
  • Updates Node#drag_to to pass drop modifier keys and options through to an updated Browser#drag, with an HTML5 emulation path via lib/.../javascripts/drag.js.
  • Implements Node#drop and Browser#drop, adding JS helpers in index.js to synthesize a DataTransfer for dropped strings/files.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
spec/spec_helper.rb Removes forced skips for drag/drop shared specs so the suite exercises the new behavior.
lib/capybara/cuprite/node.rb Adds modifier aliasing for drag and forwards new drop command to the browser.
lib/capybara/cuprite/javascripts/index.js Adds JS helpers for drag detection and DataTransfer-backed drop for strings/files.
lib/capybara/cuprite/javascripts/drag.js Introduces the HTML5 drag/drop emulation script (ported from Capybara Selenium).
lib/capybara/cuprite/browser.rb Implements updated drag API + HTML5 path and new drop implementation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/capybara/cuprite/browser.rb
Comment thread lib/capybara/cuprite/javascripts/index.js
@myabc myabc changed the title Support Element#drop for files and strings Support Element#drop for files and strings Jul 9, 2026
@myabc myabc force-pushed the feature/element-drop branch from 1de480e to c4abb7e Compare July 9, 2026 18:40
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