5

I am trying to drag an element into another element using Selenium WebDriver but it's not working. I tried all the solutions which I can find on internet but none of the solutions seems to be working for me.

WebElement sourceelement = driver.findElement(By.cssSelector("XXX"));
WebElement destelement = driver.findElement(By.cssSelector("YYY"));

Code1:-

Actions builder = new Actions( _controls.getDriver());
builder.dragAndDrop(sourceelement, destelement);

Code2:-

Actions builder = new Actions(_controls.getDriver());
Action dragAndDrop =
builder.clickAndHold(sourceelement).moveToElement(destelement).release(destelement).build();
Thread.sleep(2000);
dragAndDrop.perform()

Code3:-

Point coordinates1 = sourceelement.getLocation();
Point coordinates2 = destelement.getLocation();  
Robot robot = new Robot();           
robot.mouseMove(coordinates1.getX(), coordinates1.getY());
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseMove(coordinates2.getX(), coordinates2.getY());
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(2000);

Code4:-

final String java_script =
"var src=arguments[0],tgt=arguments[1];var dataTransfer={dropEffe" +
                "ct:'',effectAllowed:'all',files:[],items:{},types:[],setData:fun" +
                "ction(format,data){this.items[format]=data;this.types.append(for" +
                "mat);},getData:function(format){return this.items[format];},clea" +
                "rData:function(format){}};var emit=function(event,target){var ev" +
                "t=document.createEvent('Event');evt.initEvent(event,true,false);" +
                "evt.dataTransfer=dataTransfer;target.dispatchEvent(evt);};emit('" +
                "dragstart',src);emit('dragenter',tgt);emit('dragover',tgt);emit(" +
                "'drop',tgt);emit('dragend',src);";

        ((JavascriptExecutor)_controls.getDriver()).executeScript(java_script, sourceelement, destelement);
        Thread.sleep(2000);

None of the above code is working for me. All the above runs without any error but drag and drop is not happening in the application. Anyone having any other solution ? Thanks.

Browser :- IE

  • 1
    dragAndDrop function does't work with java 1.8 or later. – Sandeep Sep 12 '16 at 11:22
  • Really ? Never heard about this issue in the internet. Also, I am able to drag and drop on the different site. Facing issue with this specific site. – Naseem Sep 12 '16 at 11:25
  • Naseem, can you add exact error you are facing? – NarendraC Sep 12 '16 at 16:32
  • @NarendraC ... Code is running without any error but drag and drop is not happening in the application – Naseem Sep 12 '16 at 16:54
  • :) That means we are yet to reach to correct step or method, isn't it? – NarendraC Sep 19 '16 at 13:53
4

I have used the following solution (only tested with Chrome, but should be compatible with IE):

The javascript was borrowed from: https://www.packtpub.com/books/content/javascript-execution-selenium

Save the following javascript in a file somewhere in your solution - it makes reuse easier.

function createEvent(typeOfEvent) {
    var event = document.createEvent("CustomEvent");
    event.initCustomEvent(typeOfEvent, true, true, null);
    event.dataTransfer = {
        data: {},
        setData: function (key, value) {
            this.data[key] = value;
        },
        getData: function (key) {
            return this.data[key];
        }
    };
    return event;
}
function dispatchEvent(element, event, transferData) {
    if (transferData !== undefined) {
        event.dataTransfer = transferData;
    }
    if (element.dispatchEvent) {
        element.dispatchEvent(event);
    } else if (element.fireEvent) {
        element.fireEvent("on" + event.type, event);
    }
}
function simulateHTML5DragAndDrop(element, target) {
    var dragStartEvent = createEvent('dragstart');
    dispatchEvent(element, dragStartEvent);
    var dropEvent = createEvent('drop');
    dispatchEvent(target, dropEvent, dragStartEvent.dataTransfer);
    var dragEndEvent = createEvent('dragend');
    dispatchEvent(element, dragEndEvent, dropEvent.dataTransfer);
}

I have used the following code to read in the javascript and execute the drag and drop.

protected void JavascriptDragAndDrop(IWebElement source, IWebElement target)
{
    string script = System.IO.File.ReadAllText("<Path To Javascript File>");
    script += "simulateHTML5DragAndDrop(arguments[0], arguments[1])";
    IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
    executor.ExecuteScript(script, source, target);
}

This is C# code, and it looks like you are working with Java, but it should be easy enough to translate. Just read the javascript file into a string, concatenate the line that actually calls the javascript function, and use a JavaScriptExecutor to execute the script.

The linked guide also provides an example of a wrapper method written in Java.

I've tried most of the methods you listed in the question, and this has been the only solution I found that is both reliable and concise.

| improve this answer | |
  • Can't try this out right now, but upvote nonetheless. Looking forward to the day I'll be needing this! The Selenium dragAndDrop has never worked except on canvas elements, which is not really applicable in a business environment. – FDM May 29 '17 at 5:35
  • This worked smoothly. – Vinaykumar Patel Nov 30 '18 at 10:03
  • I tried this on ag-Grid but it did not work. I got following error: e.dataTransfer.setDragImage is not a function. Am I doing something wrong? – H.D. Mar 6 at 2:00
  • Worked Perfectly for me :) thanks – Chaitanya Pujari Jun 18 at 7:18
0

(function( $ ) { $.fn.simulateDragDrop = function(options) { return this.each(function() { new $.simulateDragDrop(this, options); }); }; $.simulateDragDrop = function(elem, options) { this.options = options; this.simulateEvent(elem, options); }; $.extend($.simulateDragDrop.prototype, { simulateEvent: function(elem, options) { /Simulating drag start/ var type = "dragstart"; var event = this.createEvent(type); this.dispatchEvent(elem, type, event);

       type = 'dragover';
       var dragOverEvent2 = this.createEvent(type, {pageX: 200, pageY: 300});
        var $dragOverTarget2 = $(options.dropTarget);
        this.dispatchEvent($dragOverTarget2[0], type, dragOverEvent2);

        /*Simulating drop*/
        type = "drop";
        var dropEvent = this.createEvent(type, {});
        dropEvent.offsetX =800;
        dropEvent.offsetY =500;
        dropEvent.dataTransfer = event.dataTransfer;
        var target;
        if (options.dropTargetFrame) {
            target = $(document.querySelector(options.dropTargetFrame).contentDocument.querySelector(options.dropTarget))[0];
        }
        else {
            target = $(options.dropTarget)[0];
        }
        this.dispatchEvent(target, type, dropEvent);

        /*Simulating drag end*/
        type = "dragend";
        var dragEndEvent = this.createEvent(type, {});
        dragEndEvent.dataTransfer = event.dataTransfer;
        this.dispatchEvent(elem, type, dragEndEvent);
    },
    createEvent: function(type) {
        var event = document.createEvent("CustomEvent");
        event.initCustomEvent(type, true, true, null);
        event.dataTransfer = {
            data: {
            },
            types: [],
            setData: function(type, val){
                this.types.push(type)
                this.data[type] = val;
            },
            getData: function(type){
                return this.data[type];
            }
        };
        return event;
    },
    dispatchEvent: function(elem, type, event) {
        if(elem.dispatchEvent) {
            elem.dispatchEvent(event);
        }else if( elem.fireEvent ) {
            elem.fireEvent("on"+type, event);
        }
    }
});

})(jQuery);

| improve this answer | |
  • This solution worked for drag and drop web element to canvas – vinay nama Jul 8 '19 at 10:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.