Clicking an element having same class name as others - java

I am trying to locate and click an element which is having same className as other elements. I am unable to differentiate that element from other to click that element. Here is the HTML code of that element:
<a href="/category/men/N-fh7rea" class="accord-header">
Men
</a>
In this code, classname is same as others elements and text "Men" is also same. So made an Xpath of this:
//a[#class='accord-header' AND contains(text(),'Men') ]

Tweak the xpath a bit and use :
//a[#class='accord-header' and #href='/category/men/N-fh7rea']
You can get more granular and use :
//a[#class='accord-header' and #href='/category/men/N-fh7rea' and contains(.,'Men')]
You can alos use :
//a[#class='accord-header' and #href='/category/men/N-fh7rea'][normalize-space()='Men']

if you can't find any difference you can always count whith one, from the same objects interest you. If its for example 3rd element, save all of them as a list using findElements, and then get third element from it.
List<WebElement> elems = driver.findElements(By.xpath("//a[#class='accord-header' and #href='/category/men/N-fh7rea' and contains(.,'Men')]"));
WebElement elementThatYouLookedFor = elems.get(2);
If You need to click all of elements of this kind just use foreach loop:
List<WebElement> elems = driver.findElements(By.xpath("//a[#class='accord-header' and #href='/category/men/N-fh7rea' and contains(.,'Men')]"));
for(WebElement we : elems){
we.click(); //or any other operation
}

Related

how to add the second css selector xpath where the same element appears more than once

how to add the second css selector or xpath where the same element appears more than once.
WebElement element = driver.findElement(By.cssSelector("span.mat-content"));
I need to add the same css selector again but for the 2nd element
how do it do that.
This is for the first one which I have added as seen above:
HTML:
<span class="mat-content ng-tns-c143-2587"> = first one
HTML which I need to add -
<span class="mat-content ng-tns-c143-2589"> = How do I add the css selector using this html tag.
WebElement element2 = driver.findElement(By.cssSelector("span.mat-content")); = In this place how do I add it for the second element
If this span.mat-content represent multiple web element in HTMLDOM.
You can use findElements to grab them all.
List<WebElement> elements = driver.findElements(By.cssSelector("span.mat-content"));
Now elements is a list in Java-Selenium bindings.
You could do, elements.get(1) and this shall represent the second web element.
or You can iterate the entire list like this:
for (WebElement element : elements){
element.getText(); //Note that each `element` is a web web element.
}
If you do not wish to have the above way. You can try xpath indexing.
(//span[contains(#class,'span.mat-content')])[1]
should represent the first element.
and
(//span[contains(#class,'span.mat-content')])[2]
should represent the second element and so on..
[3], [4], .... [n]
just replace css with xpath. xpath indexing is not preferred choice.
List<WebElement> elements= driver.findElements(By.cssSelector("span.mat-
content"));
WebElement element2 = elements.get(1);
Should work

How to find classname starting with a particular text and ending with a particular text through Selenium and Java

Below is the element and I need to find the class names matching with the first css- and ending with widget, How do i find it in selenium (java)?
Tried with the below code, but it didnt work
List<WebElement> list1 = driver.findElements(By.xpath("//body[starts-with(#class, 'css-')]"));
List<WebElement> list2 = driver.findElements(By.xpath("//body[contains(#class, 'css-')]"));
List<WebElement> list3 = driver.findElements(By.xpath("//body[ends-with(#class, 'widget')]"));
I use CSS selectors, to find any element of any type:
driver.findElements(By.CssSelector("[class^='css-'][class$='widget']"))
Where we find any element, which has a class attribute using [], that begins with ^= and ends with $=
To find a div:
driver.findElements(By.CssSelector("div[class^='css-'][class$='widget']"))
#elworthy's answer was in the right direction about the CssSelector which you can use and as per your code trials the following should work:
List<WebElement> list3 = driver.findElements(By.CssSelector("//body[class^='css-'][class$='widget']"));
However if you want to construct a xpath it is worth to mention Selenium supports xpath v1.0 and ends-with() is part of xpath v2.0. So the equivalent xpath will be:
List<WebElement> list1 = driver.findElements(By.xpath("//body[starts-with(#class, 'css-') and contains(#class, 'widget')]"));

How to find an element present in data-hook through selenium

I have the HTML code as:
<a class="a-size-base a-link-normal review-title a-color-base a-text-bold" data-hook="review-title" href="/gp/customer-reviews/R252N8IFRXV8TW/ref=cm_cr_getr_d_rvw_ttl?ie=UTF8&ASIN=B071NZZHF9">Security concern</a>
and i have to search the element by data-hook as the class name is common for other attributes also and href and link-text are dynamic as it is changing for the next element as there are multiple elements that i need to fetch.
Can i search it by data-hook. If yes could someone help me with it!
Sure you can.
CSS:
driver.findElement(By.cssSelector("a[data-hook='review-title']"));
Xpath:
driver.findElement(By.xpath("//a[#data-hook='review-title']"));
You can also use the below code if multiple data-hook item you need.
List<WebElement> list = driver.findElements(By.className("review-title"));
for(WebElement elem : list){
System.out.println(elem.getAttribute("data-hook"));
}
As per the HTML you have shared to find the element through data-hook attribute you can use the following line of code :
driver.findElement(By.xpath("//a[#data-hook='review-title']"));
Though you mentioned class name is common it will be a good practice to keep the class name attribute in the xpath as follows :
driver.findElement(By.xpath("//a[#class='a-size-base a-link-normal review-title a-color-base a-text-bold' and #data-hook='review-title']"));
Further, though you mentioned href is changing, I will suggest to use the combination of all the three attributes to uniquely identify the element as :
driver.findElement(By.xpath("//a[#class='a-size-base a-link-normal review-title a-color-base a-text-bold' and contains(#href,'/gp/customer-reviews/') and #data-hook='review-title']"));

How do I write a xpath with conditions to get a list of desired webelements for my requirement

I want to get a list of webelements for which I wrote a common xpath to retrieve all the webelements. Problem is the list contains a webelement, which I don't require in my code.
List<WebElement> tbodyTD2 = InitDriver.driver.findElements(By.xpath("//tr[#id='addBrandTbl']/td/table/tbody/tr/td"));
Which returns me 9 webelements. out of which 8 are required.
The xpath for the webelement which i don't want in my list is :
.//*[#id='addBrandTbl']/td/table/tbody/tr[3]/td
Is there any way to write my xpath so that I can get a list excluding the above element?
You can write an XPath predicate to exclude element in certain position index :
By.xpath("//tr[#id='addBrandTbl']/td/table/tbody/tr[position() != 3]/td")
You can just remove this element from the list
tbodyTD2.remove(3);
Try this one
List<WebElement> webElements = driver.findElements(By.xpath("//tr[#id='addBrandTbl']/td/table/tbody/tr/td"));
List requiredElementsList=new ArrayList();
for (WebElement element : webElements) {
if (!element.equals("unwantedWlement")) {
requiredElementsList.add(element);
}
}
Got
xpath: //tr[#id='addBrandTbl']/td/table/tbody/tr/td[not(#colspan)]

How to access the second element that has the same class name in selenium using java

When trying to automate our application, there are two buttons with same name.
I'm not able to find a way to recognize these. Please let me know what could be the other ways to identify these elements in selenium webdriver in java
You can use xpath indexing option.
By.xpath("(//input[#name='Button'])[2]")
You can go with xpath always if there is no uniqueness with attribute. For e.g. if you want to find an element which has text foo and name button then I'll prefer xpath as below if name is not unique there:
//*[#name='button' and text()='foo']
Or For different class but same name
//button[#name='button' and #class='xyz']
or For different text but same name
//input[#name='button' and contains(text(),'Click Here')]
or for different tags but same name
//button[#name='button']
//input[#name='button']
Just go with any unique property and make a customized xpath.
I hope you can also use java script for this as well for e.g.
WebElement butttonToClick = driver.findElement(By.name("button"));
((JavascriptExecutor)driver).executeScript("arguments[1].click();",butttonToClick );
Where arguments[1] means second element which has same name.
You can go with xpath methods like following-sibling/preceding siblings.
For example if the Button is located to any unique webelement try to identify that webelement first and by using different xpath methods like following-siblings, content, preceding siblings you can access the web element.
Iterating loop on button with same name and same class
List<WebElement> listofItems=
driver.findElements(By.className("actions"));
System.out.println(listofItems);
System.out.println(listofItems.size());
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
for (int s=1; s<=listofItems.size(); s++)
{
/*Getting the list of items again so that when the page is
navigated back to, then the list of items will be refreshed
again */
listofItems= driver.findElements(By.className("actions"));
//Waiting for the element to be visible
//Used (s-1) because the list's item start with 0th index, like in
an array
wait.until(ExpectedConditions.visibilityOf(listofItems.get(s-1)));
//Clicking on the first element
listofItems.get(s-1).click();
Thread.sleep(2000);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.print(s + " element clicked\t--");
System.out.println("pass");
driver.navigate().back();
}

Categories

Resources