Using Selenium with Java, Using dynamically drag-and-drop with attribute 'draggable' - java

Recently I was trying to use the traditional drag-and-drop operation using 'Action' object, I tried it using it straight-forward afterwards I understood that the elements of which I want to drag are changing dynamically.
before the element looks like this:
<div data-v-a030b586 tabindex="-1" class="v-list-item theme--light">...</div>
after clicking on the element it changes to:
<div data-v-a030b586 tabindex="-1" class="v-list-item theme--light" draggable="false">...</div>
When holding the element it changes to:
<div data-v-a030b586 tabindex="-1" class="v-list-item theme--light sortable-chosen" draggable="true">...</div>
I tried to do this by using this code:
List<WebElement> elems = driver.findElements(By.cssSelector("div[class*='row']:nth-child(2) [class*='col-md']:nth-child(3) div[tabindex='-1'] div[class='v-list-item__icon icon-item-wrap'] i"));
Actions builder = new Actions(driver);
for(WebElement elem: elems){
System.out.println(elem.getText());
elem.click();
}
elems = driver.findElements(By.cssSelector("div[draggable]"));
WebElement sourceElm = elems.get(2);
WebElement destElm = elems.get(0);
builder.clickAndHold(sourceElm);
builder.clickAndHold(destElm);
builder.clickAndHold(sourceElm).moveToElement(destElm).click().release(destElm).build().perform();
But as I tried it nothing is happening. What is wrong ? or what is the correct way of doing it, if possible of course...?
**************************** EDIT *********************************
This is how the dom looks when you hold an element of if clicking on it as I described above:

Related

How to select a nested webelement in html?

I would like to retrieve a webelement out of a nested html path using either css selectors or xpath. My specific use case is that I would like to select the i element in the following snippet:
<td class="headerActionsTd" data-rolename="Speaker">
<div class="headerActions">
<span class="addNewParticipantSection">
<i class="icon fa fa-user-plus" title="Add New"></i>
</span>
How do I obtain the i webelement for this using either css selector or xpath?
Use this xpath: //td[#data-rolename='Speaker']//div//span//i[#title='Add New'] or
css : div.headerActions i
driver.findElement(By.cssSelector("div.headerActions i"));
for multiple elements :
List<WebElement> users = driver.findElements(By.xpath("//td[#data-rolename='Speaker']//div//span//i[#title='Add New']"));
A simple one would be this :
CSS_SELECTOR
i.icon.fa.fa-user-plus[title='Add New']
Note that, if there is multiple element with this css selector, then you have this facility to differentiate between them:
:first-child
:nth-child(n)
:nth-last-child(n)
More can be found at this link
XPATH : would be :
//td[#data-rolename='Speaker']/descendant::span[#class='addNewParticipantSection']/i
Hope that helps.
Since you said data-role only changes in the comment of the other person, here is the xpath you can use
"//td[#data-role='Speaker']//i"
Or
"//td[#data-role='Speaker']/div/span/i"
Another option is that you can attempt to locate elements inside other elements. For example, you could store the addNewParticipantSection div in a WebElement, then use that WebElement's findElement method to locate the i element within it. Like so:
WebElement section = driver.findElement(By.className("addNewParticipantSection"));
WebElement icon = section.findElement(By.tagName("i"));
icon.click();

Clicking on <li> list item not using Selenium Java

The following list represents page navigation buttons:
<div class="list">
<ul class="pageNav">
<li class="paginate_button ">
1</li>
<li class="paginate_button ">
2</li>
<li class="paginate_button ">
3</li>
</ul>
</div>
To go to the second page for instance, I am using this Selenium Java code:
//after setting up webdriver
List<WebElement> li = driver.findElements(By.className("pageNav"));
System.out.println(li.get(2).getText());
li.get(2).click();
It's printing the text correctly "2", but not clicking or navigating correctly as if I was manually doing it on the actual website. I also tried replacing the link with an actual link like:
Visit our page
But still no luck. What am I doing wrong?
Thank you in advanced!
Try any of these below code.
In your tried code, I have noticed that you were using class locator to click on links element. But your <ul> tag does not contains the link. Inside <ul> tag, <li> tag is present and each <li> tag contains separate <a> tag.
so, here you should go with xpath or cssSelector locator.
Method 1) By using xpath locator
List<WebElement> links = driver.findElements(By.xpath("//ul[#class='pageNav']/li/a"));
System.out.println(links.size());
links.get(1).click(); //indexing start from 0, if you want to click on second link then pass indexing as 1.
Suggestion:- Instead of using absolute xpath, use relative xpath.
Method 2) By using cssSelector locator
List<WebElement> links = driver.findElements(By.cssSelector("ul.pageNav>li>a"));
System.out.println(links.size());
links.get(1).click(); //indexing start from 0, if you want to click on second link then pass indexing as 1.
Try below code
//getting all the anchor tag elements and storing in a list
List<WebElement> links = driver.findElements(By.xpath("//ul[#class='pageNav']//li[starts-with(#class,'paginate_button')]/a"));
System.out.println(links.size());
//performs click on second links
links.get(1).click();
If you're facing any abnormal difficulty which you are not able to handle directly , then you can first try to move to that element using actions class then click it as below:
WebElement we = driver.findElement(By.cssSelector("div.list > ul.pageNav li:nth-child(2));
Actions action = new Actions(driver);
action.moveToElement(we).click().build().perform();

Child elements not found in page object after adding them in the html in Selenium

I have in my program a loop that prints a structure like this in each iteration:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<button>show more</button>
</div>
</div>
But after clicking the button the structure changes to:
<div class="grand-father">
<div class = "father">
<myTag>1</myTag>
<myTag>2</myTag>
<myTag>3</myTag>
</div>
</div>
So in my tests with page object model I'm trying to evaluate every myTag element in each "grand-father" element by doing:
List<WebElement> grandFathers = driver.findElements(By.xpath("//div[#class='grand-father']"));
for(WebElement gf : grandFathers){
//**Click the button of this father element to show more**
List<WebElement> myTagElements = gf.findElements(By.xpath(".//div[#class='father']/myTag"));
System.out.println(myTagElements.size());
}
My problem is that the last findElements for the myTag elements doesn't seem to be finding all the elements that weren't there before the "show more" button was pressed :( it's only counting one element even though all elements are already shown :/
Is there any way to tell selenium to "update" the variable according to the new html changes that weren't there when we first fetched the element? (Because I think that the problem might be that one)
Thanks if anyone can help!
It looks like you may have the answer already but for future readers, I would do something like this...
Grab all the DIVs with the class grand-father and loop through them looking for child BUTTONs. Click the BUTTON and then count the myTags.
List<WebElement> gfs = driver.findElements(By.cssSelector("div.grand-father"));
for (WebElement gf : gfs)
{
gf.findElement(By.tagName("button")).click();
System.out.println(gf.findElements(By.tagName("myTag")).size());
}
I solved the issue by refactoring all the code and clicking the "Show More" button when using findElements for the "father" elements, waay before using the findElements method for the myTag elements.
Keep this in mind when dealing with elements that will eventually show up in your DOM: First make all the operations that involve showing and processing data, then use Selenium to evaluate them :)

Selenium, JAVA - how to find such element?

Do you know how to find and click at an element like this:
<div class="offer ctrlOpenOfferInfo">
<a class="linkOffer" href="offer_view.html?id=1007"/>
<p class="photo">
<p class="name">New offer</p>
<p class="price">123</p>
<div class="rate ctrlViewRateOffer" data-value="0.0000">
<p class="date"/>
<div class="hide info">
<div class="bgInfo"/>
using Selenium WebDriver and using the name of the element as there are few very similiar elements on the page?
Here's what I've tired so far:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[text()='New offer']")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[#id='formDevelopmentElementAdd'][text()='New offer']")));
driver.findElement(By.xpath(".//*[#id='formDevelopmentElementAdd']/div/p[2][text()='New offer']")).click();
or:
driver.findElement(By.xpath("//p[#class='name'][text()='New offer']")).click();
or:
String address = driver.findElement(By.xpath("//*[contains(text(), 'New offer') and #class='name']")).getAttribute("href");
driver.get(baseUrl + address);
or:
driver.findElement(By.xpath("//a[Text()='New offer']")).click();
I've tried these with text, class, xpath...
Assuming you want to click the p tag containing New offer:
I would think this element is not inside an iframe. If so, you must use driver.switchTo().frame("name or xpath or css for frame locator"); first before start looking for element.
Now, how can you find that element. Consider the following options:
Using xpath text based search
//p[.='New offer']
//to be more precise you can do
//p[#classs='name'][.='New offer']
You can use By.className('name') to identify that element even though that name does not look like unique to me
Using cssSelector
.name
using nth-child() function of cssSelector
.offer.ctrlOpenOfferInfo>a>p:nth-child(2)

How to change the style of an element using selenium

I have an image in my code. When I click on it, I want its style to be changed.
The field looks like this :
<a class="myField" href="#" style="left: 0%;"></a>
I can get the element by class and click on it. But I don't know how to change the style.
WebElement webelement = driver.findElement(By.className("myField"));
webelement.click();
//Change the style to 'left:40%;'
I am new to selenium. Any help appreciated.
You can do that using javascriptExecutor:
((JavascriptExecutor)driver).executeScript("document.getElementsByName('myField')[0].style.left='40%'");

Categories