Reputation: 27
I try to drag and drop the content into search-textbox in selenium,but it perform drag operation but it not drop it into search-textbox.so my question is how to drop into textbox.
driver.get("http://stackoverflow.com/questions/42159265/drag-and-drop-content-into-textbox-by-using-selenium");
WebElement from = driver.findElement(By.xpath("//*[@id='qinfo']/tbody/tr[1]/td[2]/p/b"));
Actions builder = new Actions(driver);
builder.doubleClick(from).perform();
Thread.sleep(1000);
WebElement to = driver.findElement(By.name("q"));
Action dragAndDrop = builder.clickAndHold(from).moveToElement(to).release(to).build();
dragAndDrop.perform();
Upvotes: 0
Views: 4499
Reputation: 463
Apparently this applies in some cases (when HTML5 draggable attribute is used). Here is what I found: https://elementalselenium.com/tips/39-drag-and-drop
Here is my solution, I modified the javascript file a bit, so it will make use of executeScript
optional args
and not use string concatenation.
var source = arguments[0];
var target = arguments[1];
(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);
$(source).simulateDragDrop({ dropTarget: target});
With this, you can simple call it with parameters now:
JavascriptExecutor js = (JavascriptExecutor) getDriver();
String script = Utils.readFileContents("/dragAndDrop.js");
// First Drag & Drop
js. executeScript(script, dndPage.getColumnA(), dndPage.getColumnB());
assertThat(dndPage.getColumnAHeaderText()).isEqualTo("B");
assertThat(dndPage.getColumnBHeaderText()).isEqualTo("A");
Hope this helps someone.
Upvotes: 0
Reputation: 227
So this thing made me crazy for a couple of days but I have found an answer.
Made a video about it
https://www.youtube.com/watch?v=hOprGzKBD9I&feature=youtu.be
To explain also in words/code what needs to be done
1 - You need to import an external JS file resources/drag_and_drop.js 2 - After you need to run make a function that will execute JS
Below is mine -
This method implement the drag and drop action use selenium webdriver
The strings need to be CSS Locations
public void dragIT (String Fromlocator, String ToLocator)
String filePath = "resources/drag_and_drop.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();
String commandToExecute = "$('"+Fromlocator+"').simulateDragDrop({ dropTarget: '"+ToLocator+"'});";
javaScript = javaScript + commandToExecute;
((JavascriptExecutor)driver).executeScript(javaScript) }
Upvotes: 1
Reputation: 882
First WebDriver/Selenium DragAndDrop does not appear to work anymore, at best it goes between working and not working depending on release of drivers, browsers and selenium. I do not find that any of the java workarounds actually work.
clickAndHold() moveToElement() release() // solutions don't work
I put together a working Java example after viewing the below mentioned sites. My solution is using rcorreia's javascript
Elemental Selenium Drag N Drop - example app for testing Drag N Drop rcorreia/drag_and_drop_helper.js - rcorreia's javascript helper code
RomanIsko/elemental-selenium-tips - a csharp implementation
I figured out how to integrate the javascript file by looking at romanisko csharp code.
JSDriver.ExecuteScript(dnd_javascript + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});");
From the above I came up with the following Java Solution:
DragAndDropJsHelper.java
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 {
// the javascript file must be read into a single string no line breaks
try (BufferedReader br = Files.newBufferedReader(Paths.get(getURIFromURL(jsFile)))) {
dragndrop_js = br
.lines()
.collect(Collectors.joining(" "));
} catch (IOException e) {
log.error(e.getMessage());
}
}
// helper method, I'm using maven my js file is in src/test/resources
@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);
}
}
Part of my DragAndDropTest.java
@Test
public void dragAtoBTest() {
try {
WebElement weA = driver.findElement(DragNDropPage.COLUMN_A);
WebElement weB = driver.findElement(DragNDropPage.COLUMN_B);
DragAndDropJsHelper ddh = new DragAndDropJsHelper("drag_and_drop_helper.js");
ddh.dragDrop(driver, "#column-a", "#column-b");
log.info("wait for opacity to change 1, indicating move complete");
wait.until(ExpectedConditions.attributeToBe(weA, "opacity", "1"));
assertThat(weA.findElement(page.columnHeader).getText(), containsString("B"));
} catch (Exception e) {
e.printStackTrace();
log.error(e);
Assert.fail("FAILED validLoginTest");
}
}
NOTE: Using the drag_and_drop.js requires the src and dst to be css selector strings, I don't know if xpath would work. It would be nicer if it would handle WebElement and/or BY for input parameters. Unfortunately, my javascript is not deep enough to make that modification.
see also:
Selenium Actions drag and drop not working on chrome browser
Drag and drop support for an object via Gwen DSL
Upvotes: 2
Reputation: 1
You can try:
Actions dragAndDrop= new Actions(driver);
dragAndDrop.clickAndHold(DragFrom).moveToElement(DragTo).release().build().perform();
Upvotes: 0