1
votes

I am trying to use java script workaround for to get Drag and Drop working with selenium Web driver with java on IE11 and Chrome?? I am using selenium 3.4 with java 1.8

Here is my code :

**Web Element Initialisation**
@FindBy(how = How.CSS, css =".work-card-description.searchable-field")
 private WebElement weDragFrom;


@FindBy(how = How.CSS,css = "div.resource-schedule.resource-ui-droppable div.hour-line:nth-of-type(11)")
private WebElement weDragTo;


**CODE**
protected void dragAndDrop( WebElement from, WebElement to)throws IOException,InterruptedException {
        String basePath = new File("").getAbsolutePath();

        String jquery_url = "http://code.jquery.com/jquery-1.11.2.min.js";
        final String JQUERY_LOAD_SCRIPT =(basePath + "/src/test/resources/jquery_load_helper.js");

        String jQueryLoader = readFile(JQUERY_LOAD_SCRIPT);

        driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);

        JavascriptExecutor js = (JavascriptExecutor) driver;

        js.executeAsyncScript(jQueryLoader,jquery_url);
    js.executeScript("jQuery(function($) { " + " $('input[name=\"q\"]').val('bada-bing').closest('form').submit(); "
                                    + " }); ");

        String filePath =(basePath + "/src/test/resources/drag_and_drop_helper.js");

        StringBuffer buffer = new StringBuffer();

        String line;

        BufferedReader br = new BufferedReader(new FileReader(filePath));

        while((line = br.readLine()) != null) {
            buffer.append(line);
        }

        String javaScript = buffer.toString();

         javaScript = javaScript + "$('"+from+"').simulateDragDrop({ dropTarget: '"+to+"'});";

        ((JavascriptExecutor)driver).executeScript(javaScript);
        Thread.sleep(1000);
}

Error

org.openqa.selenium.JavascriptException: Error: Syntax error, unrecognized expression: [[FirefoxDriver: firefox on ANY (a57f702c-e519-4a71-98f8-015da1fba509)] -> css selector: .work-card-description.searchable-field] Build info: version: '3.4.0', revision: 'unknown', time: 'unknown' System info: host: Driver info: org.openqa.selenium.firefox.FirefoxDriver rotatable=false, timeouts={implicit=0.0, pageLoad=300000.0, script=30000.0}, pageLoadStrategy=normal, platform=ANY, specificationLevel=0.0, moz:accessibilityChecks=false, acceptInsecureCerts=true, browserVersion=55.0.3, platformVersion=6.3, moz:processID=6420.0, browserName=firefox, javascriptEnabled=true, platformName=windows_nt}] Session ID: a57f702c-e519-4a71-98f8-015da1fba509 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:150) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:115) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:45) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:164) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:82) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:637) at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:573) at PageObject.OptimiseSchedulePage.dragAndDrop(OptimiseSchedulePage.java:180) at PageObject.OptimiseSchedulePage.dragDropJobIntoDiary(OptimiseSchedulePage.java:120) at WebAdmin.FunctionalityTest.DragAndDrop(FunctionalityTest.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108) at org.testng.internal.Invoker.invokeMethod(Invoker.java:661) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:744) at org.testng.TestRunner.run(TestRunner.java:602) at org.testng.SuiteRunner.runTest(SuiteRunner.java:380) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340) at org.testng.SuiteRunner.run(SuiteRunner.java:289) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301) at org.testng.TestNG.runSuitesLocally(TestNG.java:1226) at org.testng.TestNG.runSuites(TestNG.java:1144) at org.testng.TestNG.run(TestNG.java:1115) at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72) at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)


Please help me I have tried all the workaround for this , Action class is not working at all for me on both the browser

Some of the other workaround on internet just gets execute without any error and doing nothing

As per my knowledge in reading many posts i think using java-script(drag_and_drop_helper.js) will work for sure , i know somewhere am missing something.

 **JAVASCRIPT(Drag_and_drop_helper)**
    (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);

                            /*Simulating drop*/
                            type = 'drop';
                            var dropEvent = this.createEvent(type, {});
                            dropEvent.dataTransfer = event.dataTransfer;
                            this.dispatchEvent($(options.dropTarget)[0], 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: {
                                    },
                                    setData: function(type, val){
                                            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);
1
How is the drag n drop implemented in the page? - Florent B.
Drag and drop is implemented using Jquery in the page - TesterInUK
Since the page already has JQuery, you shouldn't inject jquery-1.11.2.min.js. You also need to call executeScript with the arguments from and to. - Florent B.
I Skip out the whole lot of jquery loader itself ?? - TesterInUK
Can you add the final script that got generated? print javaScript and add the generated script also to your questions - Tarun Lalwani

1 Answers

0
votes

My solution looks very similar to yours. However, the below solution works for me see: drag-and-drop-in-selenium-java

NOTE: You are passing WebElement(s) for the src/dst (to/from) to the js. I'm using css selector strings, e.g "#column-a", "#column-b" id(s). I don't know enough about the javascript to verify you can use WebElement. My guess is this is your problem.

I assume you are also using rcorreia/drag_and_drop_helper.js - rcorreia's javascript helper code.

import java.io.BufferedReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class DragAndDropJsHelper {
    Logger log = LogManager.getLogger(DragAndDropJsHelper.class.getName());

    String dragndrop_js = null;

    public DragAndDropJsHelper(String jsFile) throws IOException {
        try (BufferedReader br = Files.newBufferedReader(Paths.get(getURIFromURL(jsFile)))) {
            dragndrop_js = br
                    .lines()
                    .collect(Collectors.joining(" "));
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @SuppressWarnings("finally")
    private URI getURIFromURL(String fileName) {
        URI uri = null;
        try {
            URL url = this.getClass().getClassLoader().getResource(fileName);
            uri = url.toURI();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            return uri;
        }
    }

    /**
     * Solution from elemental-selenium-tips
     * https://github.com/tourdedave/elemental-selenium-tips/blob/master/39-drag-and-drop/csharp/DragAndDrop.cs
     * JSDriver.ExecuteScript(dnd_javascript + "$('#column-a').simulateDragDrop({
     * dropTarget: '#column-b'});");
     * 
     * NOTE: Seems fragile, not sure if this works for XPATH or other src/dst type strings
     * TODO: would be good if it worked with WebElement, or BY
     * 
     * @param driver
     * @param src
     *            - css string for source element
     * @param dst
     *            - css string for destination element
     */
    public void dragDrop(WebDriver driver, String src, String dst) {
        String js = String.format("$('%s').simulateDragDrop({ dropTarget: '%s'});",src,dst);
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        jse.executeScript(dragndrop_js + js);
    }

}