0
votes

The code below is used for testing drag and drop functionality using WebDriver. The trouble which I am facing with the code is that it is unable to detect the XPath.

public class draganddrop
{
    public static void main(String[] args) throws InterruptedException
    {
        // opening site for practicing user interaction by mouse using webdriver and action class
        WebDriver driver = new ChromeDriver();
        String URL = "http://www.dhtmlx.com/docs/products/dhtmlxTree/index.shtml";
        driver.get(URL);

        // It is always advisable to Maximize the window before performing DragNDrop action
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10000, TimeUnit.MILLISECONDS);
        WebElement From = driver.findElement(By.xpath(".//*[@id='treebox1']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"));
        WebElement To = driver.findElement(By.xpath(".//*[@id='treebox2']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"));
        Actions builder = new Actions(driver);
        Action dragAndDrop = builder.clickAndHold(From).moveToElement(To).release(To).build();
        dragAndDrop.perform();

        Thread.sleep(2000);
    }
}

The error message

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":".//*[@id='treebox1']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"}

3

3 Answers

1
votes

I don't know what lead you to that XPath but it doesn't seems right based on the source code.

Replace

WebElement From = driver.findElement(By.xpath(".//*[@id='treebox1']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"));

for

WebElement From = driver.findElement(By.xpath(".//*[@id='treebox1']"));

It should be able to detect the specified divs after that.

1
votes

Here's some working code. I cleaned up some of your code, took out the unnecessary bits, etc.

driver.get("http://www.dhtmlx.com/docs/products/dhtmlxTree/index.shtml");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement from = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//span[text()='Thrillers'])[1]")));
WebElement to = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//span[text()='Bestsellers'])[2]")));
driver.findElement(By.xpath("//h2[text()='Live Demo']")).click(); // this moves the screen down
Actions builder = new Actions(driver);
builder.dragAndDrop(from, to).build().perform();

You should do some reading on .implicitlyWait(). You don't want to use it the way you are and definitely not with that large of a timeout. I would recommend you get rid of it altogether and just use explicit waits.

Waiting for both elements at the beginning of the code is likely overkill. If you just wait for the first, the second is most likely already there... but just in case.

Using XPaths that are that long is asking for trouble. If anything changes on the page within that long XPath, your script will stop working. Do some reading on XPaths and CSS selectors and learn how to use them efficiently. It will make your scripts more resilient.

In Actions, there is already a dragAndDrop() method. Just use it instead of making your own.

I had to click on the Live Demo heading. The problem was that when the drag and drop was executed, the screen would scroll and the drop would hit the menu that appears after the page is scrolled causing it to not work. The fix was to scroll the screen before the drag and drop so that both the source and target are on the screen and not hidden by the top nav menu, etc. There are other ways to scroll the screen but this one works just fine.

You also want to avoid Thread.sleep(). Read up on WebDriverWait and ExpectedConditions and learn how to use it if you need to wait for something to happen. You can see me using it above for an example.

0
votes

I changed only implicitlyWait parmater below is your code with modification

   public static void main(String[] args) throws InterruptedException
    {
        System.setProperty("webdriver.chrome.driver","G:\\java programme\\SendkeysExample\\lib\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        String URL = "http://www.dhtmlx.com/docs/products/dhtmlxTree/index.shtml";
        driver.get(URL);

        // It is always advisable to Maximize the window before performing DragNDrop action
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        WebElement From = driver.findElement(By.xpath(".//*[@id='treebox1']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"));
        WebElement To = driver.findElement(By.xpath(".//*[@id='treebox2']/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td[4]/span"));
        Actions builder = new Actions(driver);
        Action dragAndDrop = builder.clickAndHold(From).moveToElement(To).release(To).build();
        dragAndDrop.perform();

        Thread.sleep(2000);
    }