'selenium webdriver: upload file by drag and drop

On a web page I'm trying to test, we implemented drag and drop file upload. I've looked at the drag and drop API for selenium action chain API. It looks like it supports only dragging and dropping between 2 elements on a page. How to emulate dragging from a file manager?



Solution 1:[1]

To perform an HTML5 file drop with Selenium:

static final String JS_DROP_FILE =
    "var tgt=arguments[0],e=document.createElement('input');e.type='" +
    "file';e.addEventListener('change',function(event){var dataTrans" +
    "fer={dropEffect:'',effectAllowed:'all',files:e.files,items:{},t" +
    "ypes:[],setData:function(format,data){},getData:function(format" +
    "){}};var emit=function(event,target){var evt=document.createEve" +
    "nt('Event');evt.initEvent(event,true,false);evt.dataTransfer=da" +
    "taTransfer;target.dispatchEvent(evt);};emit('dragenter',tgt);em" +
    "it('dragover',tgt);emit('drop',tgt);document.body.removeChild(e" +
    ");},false);document.body.appendChild(e);return e;";

WebDriver driver = new FirefoxDriver();
driver.get("http://html5demos.com/file-api");

WebElement drop_area = driver.findElement(By.id("holder"));

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(JS_DROP_FILE, new Object[] {
        drop_area
    }).sendKeys("C:\\image.png");

Solution 2:[2]

AutoIt has the DLL wrapper. I use it directly from C#/Selenium code.

Solution 3:[3]

Drop file using jsExecutor

public void dropFile(File filePath, WebElement target) {
    if (!filePath.exists())
        throw new WebDriverException("File not found: " + filePath.toString());

    JavascriptExecutor jse = (JavascriptExecutor) getDriver();

    String JS_DROP_FILE =
        "var target = arguments[0]," +
        "    offsetX = arguments[1]," +
        "    offsetY = arguments[2]," +
        "    document = target.ownerDocument || document," +
        "    window = document.defaultView || window;" +
        "" +
        "var input = document.createElement('INPUT');" +
        "input.type = 'file';" +
        "input.style.display = 'none';" +
        "input.onchange = function () {" +
        "  var rect = target.getBoundingClientRect()," +
        "      x = rect.left + (offsetX || (rect.width >> 1))," +
        "      y = rect.top + (offsetY || (rect.height >> 1))," +
        "      dataTransfer = { files: this.files };" +
        "" +
        "  ['dragenter', 'dragover', 'drop'].forEach(function (name) {" +
        "    var evt = document.createEvent('MouseEvent');" +
        "    evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);" +
        "    evt.dataTransfer = dataTransfer;" +
        "    target.dispatchEvent(evt);" +
        "  });" +
        "" +
        "  setTimeout(function () { document.body.removeChild(input); }, 25);" +
        "};" +
        "document.body.appendChild(input);" +
        "return input;";

    WebElement input = (WebElement) jse.executeScript(JS_DROP_FILE, target, 0, 0);
    input.sendKeys(filePath.getAbsoluteFile().toString());
    waitFor(ExpectedConditions.stalenessOf(input));
}

Solution 4:[4]

Use AWT Robot class for performing drag and drop:

Robot robot=new Robot();
// drag
robot.mouseMove(x1, y1);
robot.mousePress(InputEvent.BUTTON1_MASK);
// drop
robot.mouseMove(x2, y2);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 upe
Solution 2
Solution 3 upe
Solution 4 upe