Selenium: Drag and Drop from file system to WebDriver? Selenium: Drag and Drop from file system to WebDriver? selenium selenium

Selenium: Drag and Drop from file system to WebDriver?


It's possible with Selenium alone, but it's not simple. It requires to inject a new INPUT element in the page to receive the file through SendKeys. Then, the script needs to simulate the drop by sending the dragenter, dragover, drop events to the targeted area.

static void Main(string[] args){    var driver = new ChromeDriver();    driver.Url = "https://react-dropzone.js.org/";    IWebElement droparea = driver.FindElementByCssSelector("[data-preview='Basic example'] [style]");    DropFile(droparea, @"C:\Users\florent\Desktop\capture.png");    driver.Quit();}const string JS_DROP_FILE = "for(var b=arguments[0],k=arguments[1],l=arguments[2],c=b.ownerDocument,m=0;;){var e=b.getBoundingClientRect(),g=e.left+(k||e.width/2),h=e.top+(l||e.height/2),f=c.elementFromPoint(g,h);if(f&&b.contains(f))break;if(1<++m)throw b=Error('Element not interractable'),b.code=15,b;b.scrollIntoView({behavior:'instant',block:'center',inline:'center'})}var a=c.createElement('INPUT');a.setAttribute('type','file');a.setAttribute('style','position:fixed;z-index:2147483647;left:0;top:0;');a.onchange=function(){var b={effectAllowed:'all',dropEffect:'none',types:['Files'],files:this.files,setData:function(){},getData:function(){},clearData:function(){},setDragImage:function(){}};window.DataTransferItemList&&(b.items=Object.setPrototypeOf([Object.setPrototypeOf({kind:'file',type:this.files[0].type,file:this.files[0],getAsFile:function(){return this.file},getAsString:function(b){var a=new FileReader;a.onload=function(a){b(a.target.result)};a.readAsText(this.file)}},DataTransferItem.prototype)],DataTransferItemList.prototype));Object.setPrototypeOf(b,DataTransfer.prototype);['dragenter','dragover','drop'].forEach(function(a){var d=c.createEvent('DragEvent');d.initMouseEvent(a,!0,!0,c.defaultView,0,0,0,g,h,!1,!1,!1,!1,0,null);Object.setPrototypeOf(d,null);d.dataTransfer=b;Object.setPrototypeOf(d,DragEvent.prototype);f.dispatchEvent(d)});a.parentElement.removeChild(a)};c.documentElement.appendChild(a);a.getBoundingClientRect();return a;";static void DropFile(IWebElement target, string filePath, double offsetX = 0, double offsetY = 0){    if (!File.Exists(filePath))        throw new FileNotFoundException(filePath);    IWebDriver driver = ((RemoteWebElement)target).WrappedDriver;    IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;    IWebElement input = (IWebElement)jse.ExecuteScript(JS_DROP_FILE, target, offsetX, offsetY);    input.SendKeys(filePath);}

Source: https://gist.github.com/florentbr/349b1ab024ca9f3de56e6bf8af2ac69e


The previous answer is correct and works perfectly with the Chrome driver, however might have problems with Mozilla Gecko driver, which throws org.openqa.selenium.ElementNotVisibleException

In order to avoid that, remove input.style.display = 'none';

You can use input.style.opacity = 0; if you need to make it disappear.


If you're using Selenide:

    public static void dragAndDropFileUpload(File file, SelenideElement target) throws IOException {    String inputId = "seleniumDragAndDropInput";    // Create the FileList    executeJavaScript(inputId + "_files = [];");        executeJavaScript(inputId + "_files.push(new File([new Blob(['" + file.getAbsolutePath() + "'], {type: '" + Files.probeContentType(file.toPath()) + "'})], '" + file.getName() + "'));");    String targetId = target.getAttribute("id");    // Add an id if the target doesn't have one    if (targetId == null || targetId.isEmpty()) {        targetId = "seleniumDragAndDropInput_target";        executeJavaScript("sId=function(e, i){e.id = i;};sId(arguments[0], arguments[1]);", target, targetId);    }    // Add the item function the the FileList    // Create the drop event and dispatch it on the target    String initEventJS = inputId + "_files.item = function (i) {return this[i];};"            + "var eve=document.createEvent(\"HTMLEvents\");"            + "eve.initEvent(\"drop\", true, true);"            + "eve.dataTransfer = {files:seleniumDragAndDropInput_files};"            + "eve.preventDefault = function () {};"            + "eve.type = \"drop\";"            + "document.getElementById('" + targetId + "').dispatchEvent(eve);";    executeJavaScript(initEventJS);    if (targetId == "seleniumDragAndDropInput_target") {        executeJavaScript("document.getElementById('seleniumDragAndDropInput_target').id = null");    }}