Repository navigation
feat: native file drop and image paste verbs (drag carries no files, clipboard is text-only) #2326
Replies: 1 comment
|
Happy to pick this up. Confirmed both gaps on main: Plan is roughly what you sketched: |
|
Happy to pick this up. Confirmed both gaps on main: Plan is roughly what you sketched: |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Two gestures a QA agent is routinely asked to perform have no native verb: dropping a file from the OS onto a drop zone, and pasting an image from the clipboard.
upload <sel> <files...>covers the third file gesture (setting files on an<input type="file">throughDOM.setFileInputFiles), but a drop zone with no file input, and a paste handler readingclipboardData.items, are both unreachable.At 0.33.0:
drag <src> <dst>dispatches pointer events between two elements and carries noDataTransfer.files, so adroplistener readingevent.dataTransfer.filessees an empty list.clipboard write <text>takes a string only, andclipboard pastesimulates Ctrl+V of that text, so apastelistener readingclipboardData.items[i].getAsFile()gets nothing.Proposed verbs
dropcould useInput.dispatchDragEventwithDragData.filesso Chrome builds theDataTransferitself (the highest-fidelity path;Input.setInterceptDragsis the related CDP surface). Paste has no CDP primitive that carries a file, so the workable implementation is the same one Playwright documents for file drops: read the file, construct aFilein-page inside aDataTransfer, and dispatch a syntheticDragEvent/ClipboardEventat the element viaRuntime.evaluate. The event carriesisTrusted: false, which most drop and paste handlers do not read.Workaround in use
A wrapper script that does exactly that in-page dispatch through
eval --stdin --json(stdin rather than argv, because a base64-embedded file exceeds the per-argument limit on Windowscmd.exeand Linux's 128 KiBMAX_ARG_STRLEN). Verified against Chrome for Testing 152 on Linux: a synthesizedDragEvent('drop', { dataTransfer })delivers theFileto a nativedroplistener (defaultPrevented: true,files.length === 1), and aClipboardEvent('paste', { clipboardData })delivers it throughitems[i].getAsFile().eval --stdinaccepted a 1 MB script in ~200 ms.Environment
Related
All reactions