Unable to drag and drop using Java + Selenium WebDriver - java

Following is HTML for source element:
<li draggable-effect-allowed="copy" draggable-data="business.domain.view.RecordViewComponentType" draggable="view-designer-drop-zone-content" class="list-group-item ng-scope ng-binding" ng-dblclick="insertComponentType(component)" ng-repeat="component in componentTypes" draggable="true">Record</li>
and following is HTML for target element:
<div droppable-on-drop="onDropComponent($event, $draggableEl, $droppableEl)" droppable="view-designer-drop-zone-content" class="layoutSection ContentAreaLayoutSection" id="CONTENT"></div>
Hence I've:
source = driver.findElement(By.xpath("//li[text()='Record']"));
target = driver.findElement(By.ID("CONTENT"));
Actions action = new Actions(driver);
In order to achieve drag and drop, I tried with following apis, but no luck:
1. action.dragAndDrop(source, target).build().perform();
2. action.clickAndHold(source).moveToElement(target).release(target).build().perform();
3. action.moveToElement(source).clickAndHold(source).moveToElement(target).release(target).build().perform();
4. action.moveToElement(source).clickAndHold().moveToElement(target).release().build().perform();
5. action.clickAndHold(source).moveToElement(target).build().perform();
Thread.sleep(3000);
action.release(target).build().perform();
I also tried with moveToElement(target, x-offset, y-offset) still didn't work.
When I tried with all of the above, it didn't throw any error and next code starts executing and visually, I can see source element is dragged but looks when it's moved to target element, it's not dropped to target element still no error is thrown.
Actually, I was expecting some error here if there is an issue with Selenium WebDriver and browser version compatibility.
If someone knows solution or workaround for this, please do answer.

The below code is working for me, try this:
Actions act = new Actions(driver);
WebElement srcElement = driver.findElement(By
.id(locator));
Thread.sleep(3000);
WebElement targetElement =driver.findElement(By
.id(locator));
Thread.sleep(3000);
act.dragAndDrop(srcElement, targetElement);
Thread.sleep(3000);
act.build().perform();
Thread.sleep(3000);

Related

Selenium | Unable to locate input element

No idea how to address this input text field element with selenium / Java (openjdk 11 2018-09-25).
I tried xpath, cssSelector etc. it never works. Its always "Unable to locate element".
<slot name="input">
<input part="value" tabindex="0" aria-labelledby="vaadin-text-field-input-3">
</slot>
This did NOT work:
driver.findElement(By.xpath("//input[#aria-labelledby='vaadin-text-field-input-3']")).sendKeys("test");
Is there a solution for this?
UPDATE:
This thread solved partly my problem. The solution that worked for me can be found here link.
To send a character sequence to the element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following locator strategies:
css_selector:
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(
By.cssSelector("div.vaadin-text-field-container div[part=input-field][id^='vaadin-text-field-input'] slot[name='input'] > input[part='value'][aria-labelledby^='vaadin-text-field-input']")
)).sendKeys("pixelhead");
xpath:
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(
By.xpath("//div[#class='vaadin-text-field-container']//div[#part='input-field' and starts-with(#id, 'vaadin-text-field-input')]//slot[#name='input']/input[#part='value' and starts-with(#aria-labelledby, 'vaadin-text-field-input')]")
)).sendKeys("pixelhead");
Xpath:
//div[#class='vaadin-text-field-container']//descendant::input[#part='value' and starts-with(#aria-labelledby, 'vaadin-text-field-input')]
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
If this is unique //div[#class='vaadin-text-field-container']//descendant::input[#part='value' and starts-with(#aria-labelledby, 'vaadin-text-field-input')] then you need to check for the below conditions as well.
Check if it's in any iframe/frame/frameset.
Solution: switch to iframe/frame/frameset first and then interact with this web element.
Check if it's in any shadow-root.
Solution: Use driver.execute_script('return document.querySelector to have returned a web element and then operates accordingly.
Make sure that the element is rendered properly before interacting with it. Put some hardcoded delay or Explicit wait and try again.
Solution: time.sleep(5) or
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='vaadin-text-field-container']//descendant::input[#part='value' and starts-with(#aria-labelledby, 'vaadin-text-field-input')]"))).send_keys("test")
If you have redirected to a new tab/ or new windows and you have not switched to that particular new tab/new window, otherwise you will likely get NoSuchElement exception.
Solution: switch to the relevant window/tab first.
If you have switched to an iframe and the new desired element is not in the same iframe context then first switch to default content and then interact with it.
Solution: switch to default content and then switch to respective iframe.
You can start debugging from step1.
Update:
Solution specific to the problem:
Thread.sleep(2000);
WebElement inputButton = (WebElement) ((JavascriptExecutor)driver).executeScript("return document.querySelector('#TextFieldTitle').shadowRoot.querySelector('#vaadin-text-field-input-3 > slot:nth-child(2) > input')");
inputButton.sendKeys("test");
in the place of paste query selector here you will have to go to dev tools again in goog chrome by pressing F12, and then
Go to that input box
Do a right click
Select copy
Select copy JS path.
Ctrl + v into notepad to see what you've got from the dev tool.
It'd be something like this:
document.querySelector("#vaadin-text-field-input-3 > slot:nth-child(2) > input")
replace this paste query selector here with the stuff that is wrapped inside ""
Per the html provided, this works:
driver.find_element(By.XPATH, "//input[#part='value' and contains(#aria-labelledby, 'vaadin-text-field-input')]"]
x = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#part='value' and contains(#aria-labelledby, 'vaadin-text-field-input')]")))
x.send_keys('This is typed here by selenium')
print(f"the typed text in input box is: {x.get_attribute('value')}")
Output:
the typed text in input box is: This is typed here by selenium
Process finished with exit code 0
Looks like part of HTML looks like:
<div class="vaadin-text-field-container">
<label part="label" id="vaadin-text-field-label-3"></label>
<div part="input-field" id="vaadin-text-field-input-3">
<slot name="prefix"></slot>
<slot name="input">
<input part="value" tabindex="0" aria-labelledby="vaadin-text-field-input-3">
</slot>
</div>
</div>
Much better is to build your XPATH locator from some id field:
//div[#id='vaadin-text-field-input-3']//input[contains(#aria-labelledby, 'vaadin-text-field-input')]"]
Also, as mentioned earlier have to check:
if it is unique for this page
if the input element is not dynamic
If you found solved that comment you could move to the code part and use the founded locator with WebDriver:
driver.findElement(
By.xpath("//div[#id='vaadin-text-field-input-3']//input[contains(#aria-labelledby, 'vaadin-text-field-input-3')]"]"
)).sendKeys("test");
Also, keep in mind that you have to know that element is already loaded on a page. As suggested before you could use some explicit wait for your element.

Selenium getting text input of Twingly (Java Code)

Please check out the element of this website.
It has a form, and along with 2 text input and 1 submit button.
I dont know which one from those 2 inputs that is actually used when the user type-in some urls over there.
But when I tried this (using firefoxDriver) to get the element:
WebElement textfieldURL = driver.findElement(By.id("ping-url")); // even ping-box not working
The result's unable to locate the element.
Then I change my code to this :
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
WebElement textfieldURL = driver.findElement(By.id("ping-url")); // even ping-box not working
The result's still unable to locate the element.
Any clues?
You haven't mentioned the exception which you are facing. As your input tag present under iframe so you need to first switch into frame and than have to perform actions -
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
//or you can use frame index as well
driver.switchTo().frame(0);
your element is available with the id ping-box . Try the following complete code -
System.setProperty("webdriver.gecko.driver","D:/Application/geckodriver.exe");
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.twingly.com/ping");
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.switchTo().frame(driver.findElement(By.className("ping-iframe")));
driver.findElement(By.id("ping-box")).sendKeys("http://www.google.com");
driver.findElement(By.id("ping-button")).click();
Same is working for me.

Selenium Java - How to Select a Dropdown Element that Has No ID

I am using Selenium - Java WebDriver (ChromeDriver) as a new user.
While trying to select an item from a dropdown menu using Java, I couldn't do it because of the error message. Please note that I've tried variations of Select and WebElement options but not having the expected result: clicking the link from the drop down menu that should take me to the target page.
Here is the error message shown in eclipse:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"link text","selector":"Payment"}
Here is the relevant code segment:
Select dropdown2 = new Select(webDriver.findElement(By.linkText("Payment")));
dropdown2.selectByVisibleText("Payment");
I have also tried the following with no success:
WebElement element = webDriver.findElement(By.cssSelector("a[class='glyphicon glyphicon-credit-card']"));
element.click();
Also, the following code that didn't work:
WebElement element = webDriver.findElement(By.partialLinkText("Payment"));
Select mySelect= new Select(element);
mySelect.selectByVisibleText("Payment");
The segment of html is shown below:
Hoping to get feedback.
Thank you.
As I'm seeing in provided screenshot HTML, this is not a <select> element, so you can't use Select() class here to work with dropdown.
You should try using simple finder with WebDriverWait as below :-
WebDriverWait wait = new WebDriverWait(driver,10);
//First click on dropdown down to open options
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("li.dropdown > a.dropdown-toggle"))).click();
//Now select opened option
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("ul.dropdown-menu > li > a[href*='Billing']"))).click();
Or
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Payment"))).click();
Or
wait.until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Payment"))).click();

Selenium - Java - Unable to click a link

My problem mainly is that my code doesn't run, I tried for more than 2 hours. I have seen many posts also, but some are written in different computer languages (not in Java), so I am confused now.
Below is my code for just clicking a button. All I want to do is click a button and go to new page.
WebDriver driver = new HtmlUnitDriver();
driver.get("file:///C:/Users/Sanya/Desktop/New%20folder%20(2)/page%203%20alerts.htm");
WebElement element = driver.findElement(By.partialLinkText("Alert"));
element.click();
Try this it works fine for me:
WebElement menuHoverLink = driver.findElement(By.id("your_id"));
actions.moveToElement(menuHoverLink).perform();
You can try the below one...
Actions action = new Actions(driver);
action.click(driver.findElement(By.partialLinkText("Alert"))).build().perform();
It was worked for me :-)
You can use XPath for instance to locate the element on your page:
By locator = By.xpath("//li[#title='Alerts']/a");
WebElement element = driver.findElement(locator);
Here is more information about how XPath works.

Selenium / Firefox: Command ".click()" doesn't work with a found element

I tried to find a solution to this thing and I spent a lot of time, but it is almost imposible to me to do that.
The matter: I am using Selenium with Java in Firefox. I need to find an element (a listbox) and click on it. So, the code finds the element, but click action does not work. It works fine in Google Chrome every time, and just sometimes in Firefox (with the same Java code sometimes works, and sometimes does not).
There is the part of code with the element when the program enters on the page:
<div id="size-btn" class="size-btn">
<span class="selected-size">SELECCIONA TALLA </span>
<div class="size-select" style="display: none;">
<table>
<tbody>
<tr id="selecsize_2" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051607">
<tr id="selecsize_3" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051608">
<tr id="selecsize_4" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051609">
<tr id="selecsize_5" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051610">
</tbody>
</table>
<button class="size-guide gaViewEvent gaTrack" data-ga-props="{action:'Seleccionar_Talla', opt_label:'Guia_de_tallas'}" data-href="http://www.anyweb.com/webapp/wcs/stores/servlet/ProductGuideSizeAjaxView?catalogId=24052&categoryId=358056&langId=-5&productId=1047599&storeId=10701">Guía de tallas</button>
</div>
</div>
And there is the part of code that changes when the element is clicked:
<div id="size-btn" class="size-btn opened">
I tried many solutions and sometimes it works, but the next time I run the program, it does not work again.
Some solutions:
It finds the element, but does not run click action. I checked with xpath and cssSelector, and there are unique elements found with those expressions.
driver.findElement(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span")).click(); // Also checked with By.cssSelector("span.selected-size")
I though it was because of the time, so I tried to solve it that way.
WebElement we = driver.findElement(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span")); // By.cssSelector("span.selected-size")
Thread.sleep(3000);
we.click();
Finally, I was a little bit desperate, and I created a new function to try to do this almost 60 times, looking for the change on the element code and if there was any change, just tried to do click action again.
clickAndWaitWhileElementIsNotPresent(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span"),By.xpath("//div[#class='size-btn opened']/span")); // By.cssSelector("span.selected-size")
private void clickAndWaitWhileElementIsNotPresent(By by1, By by2) throws Exception {
for (int second = 0;; second++) {
if (second >= 60)
fail("timeout");
try {
if (isElementPresent(by2))
{
break;
}
else
{
driver.findElement(by1).click();
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
There are the images of the element:
Does anybody know how to do that?
Finally I found an answer that works with Firefox as well as Google Chrome.
WebElement we = this.driver.findElement(By.id("size-btn"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", we);
waitForElementPresent(By.xpath("//div[#id='size-btn' and contains(#class,'opened')]/span"));
I am not sure why are you using this Xpath, if you have freedom to change Xpath then record the element using selenium IDE and use Xpath::position from drop down list of target(it picks unique path relative to html header), it will solve problem of dynamic locator. And try below mentioned events.
1- Use clickAt.
2- Use fireevent(focus) and then click. Sometime it happens some element in back ground is getting loaded, when it gets loaded, focus move there hence elementNotVisible error.
3- Use mouseDownRight.
I have the same problem in Firefox. The trick is to click the text inside of not the button itself.
I have some solution, make a class with a robot put there TAB event keys, then call that class. What it does its like a back to focus to the page. For some razon the page lost focus and never find that botton.
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
} catch (AWTException e) {e.printStackTrace();}
You can try to use the Actions class from org.openqa.selenium.interactions:
WebElement element = driver.findElement(By.id("size-btn"));
Actions builder = new Actions(driver);
builder.moveToElement(element).click(element);
builder.perform();
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.click(element);
Action action = actions.build();
action.perform();
This worked for me.

Categories

Resources