Finding element by using data test id in Selenium Java - java

This is my HTML tree:
<div data-focusable="true" tabindex="0" class="css-1dbjc4n" data-testid="nav-Look up items-item"><div class="css-1dbjc4n"><div class="css-1dbjc4n" data-testid="nav-Look up items-item-Look up items-icon"><div class="css-1dbjc4n"><div dir="auto" class="css-901oao r-1awozwy" data-testid="nav-Look up items-item-Look up items">Look up items</div>
I am trying to locate the element by data-testid
I have used css selector and xpath which looks like the following:
#FindBy(css = "div[data-testid='nav-Look up items-item']")
#FindBy(xpath = "//div[#data-testid='nav-Look up items-item']")
But it is not able to locate the element.
Can anyone please help? Thank you.

I'm just going to re-write your tree here because this is easier for me to understand this way.
<div data-focusable="true" tabindex="0" class="css-1dbjc4n" data-testid="nav-Look up items-item">
<div class="css-1dbjc4n">
<div class="css-1dbjc4n" data-testid="nav-Look up items-item-Look up items-icon">
<div class="css-1dbjc4n">
<div dir="auto" class="css-901oao r-1awozwy" data-testid="nav-Look up items-item-Look up items">Look up items</div>
</div>
</div>
</div>
</div>
You could always try selecting the className with something like this:
WebElement element = driver.findElement(By.className("css-901oao"));
or
WebElement element = driver.findElement(By.className("r-1awozwy"));
If that doesn't work you could try using a Chrome Extension like xPath Finder to try to find the absolute xPath and find it using something like:
WebElement element = driver.findElement(By.xpath("/html/body/div/div/div/div/div"));
But as your trying to select a div the className is more likely to work

You should use it like this
#FindBy(xpath = "//div[#data-testid='nav-Look up items-item']")
WebElement lookUpItems;
and you can (let's say wanna perform .click)
lookUpItems.click();

Related

Element not visible error with XPath

I got the problem with an XPath.
I can use this xpath: //*[#id='name']//*[#class='class']//div[1] -> can run ok.
But I want use div[2] ex: //*[#id='name']//*[#class='class']//div[2] , it gives error that element is not visible.
Anyone help me plz, I don't know why div[1] can run but div[2] is not visible.
My HTML code here:
<div class="class">
<div class="action-item" data-id="24" data-actioncode="STT">
<i class="fa fa-play"></i>
S T T
</div>
<div class="action-item" data-id="29" data-actioncode="FULL">
<i class="fa fa-play"></i>
FULL
</div>
<div class="action-item" data-id="30" data-actioncode="TEACHER">
<i class="fa fa-play"></i>
TEACHER
</div>
</div>
Code I have tried:
WebElement btnElement = driver.findElement(By.xpath("//[#id='name']//[#class='class']//div[2]"));
WebDriverWait wait= new WebDriverWait(driver,10 );
wait.until(ExpectedConditions.visibilityOf(btnElement));
btnElement.click();
You can try out this code :
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#data-actioncode='FULL']")));
driver.findElement(By.xpath("//div[#data-actioncode='FULL']")).click();
As per the HTML you have shared to click on the element with text as FULL you have to induce WebDriverWait for the element to be clickable and you can use either of the following locators :
css_selector (attribute based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.class div.action-item[data-actioncode='FULL']"))).click();
xpath (attribute based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='class']//div[#class='action-item' and #data-actioncode='FULL']"))).click();
xpath (text based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='class']//div[#class='action-item'][normalize-space()='FULL']"))).click();
You can use CSS selector path as well like for div 2 it is :
div.action-item:nth-child(2)
Thanks.
You can make use of the action-item class to validate.
use x-path to identify the classname and then do an n-th child:
xpath("//[#id='name']//[#class='class']//[#class='action-item']:nth-child(2)"));
or you can use the index value as well, as these are inside the same class.
difference is, the index value for the second item is gonna be 1.
alternately, you can use cssContainText as well to identify by the text.

cannot navigate to the target tag in DOM by using numbers in bracket, like div[4]

I am using Java and Selenium to write a test. I have this at DOM:
...
<div class='a'>
<div class='b'>
<div class='1'></div>
<div class='2'></div>
</div>
/div>
...
I am using this Xpath:
//div[#class='a']//div[2]
to get to <div class='1'></div>
but I am taken to:
<div class='2'></div>
in simple words please explain why and how to handle this situation. I do know I can use the class attribute to get to an element like :
//div[#class='1']
but I want to use numbers in bracket style like div[and-a-number-here]
Is there any way to get all divs under a tag and the select the one by the number?
In your xpath:
//div[#class='a']//div[2]
you are searching for any div which is second descendant of the div with a class=a. That's why it's returning you the 2nd div with class=2.
To get the desired element use xpath like this:
//div[#class='a']/div/div[1]

getText() returning blank

<div class="header"> Account</div>
<div class="header"> Email</div>
<div class="value ng-binding">$50</div>==$0
Above is the HTML snippet, i am trying to fetch text: $50, with getText().To locate the element i have used className and xpath.
The problem that i am facing is that, Selenium is able to locate the element but return blank,in place of $50.
it is a good practice if u use 'id' to fetch data in javascript. For your problem you can try like the code below:
<div class="header"> Account</div>
<div class="header"> Email</div>
<div id="value" class="ng-binding">$50</div>==$0
and then try
driver.findElements(By.cssSelector("#value.ng-binding")).getText();
You should instead try using .getAttribute("innerHTML"); on the ClassName to return $50.
agree with Saurabh Gaur
C#
IWebElement div = driver.FindElement(By.CssSelector(".value.ng-binding"));
Console.WriteLine(div.Text);
Use following approach :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".value.ng-binding")));
String text = el.getText();
System.out.println(text);
Output: $50
Hope it will help you..:)

differentiate two html elements with same class

I have this html code below and I want to differentiate between these two PagePostsSectionPagelet as I only want to find web elements from the first PagePostsSectionPagelet. Is there any way I can do it without using <div id="PagePostsSectionPagelet-183102686112-0" as the value will not always be the same?
<div id="PagePostsSectionPagelet-183102686112-0" data-referrer="PagePostsSectionPagelet-183102686112-0">
<div class="_1k4h _5ay5">
<div class="_5sem">
</div>
</div>
<div id="PagePostsSectionPagelet-183102686112-1" class="" data-referrer="PagePostsSectionPagelet-183102686112-1" style="">
<div class="_1k4h _5ay5">
<div class="_5dro _5drq">
<div class="clearfix">
<span class="_5em9 lfloat _ohe _50f4 _50f7">Earlier in 2015</span>
<div id="u_jsonp_3_4e" class="_6a uiPopover rfloat _ohf">
</div>
</div>
<div id="u_jsonp_3_4j" class="_5sem">
<div id="u_jsonp_3_4g" class="_5t6j">
<div class="_1k4h _5ay5">
<div class="_5sem">
</div>
</div>
Tried using //div[#class='_1k4h _5ay5']//div[#class ='_5sem'] but it will return both.
Using //div[#class='_5dro _5drq']//span[contains(#class,'_5em9 lfloat _ohe _50f4 _50f7') and contains(text(), '')] will help me find the second PagePostsSectionPagelet instead.
you need to use the following xpath:
//div[contains(#class,'_1k4h') and contains(#class,'_5ay5')]
as selenium doesn't work properly with search of several classes in one attribute.
I mean By.Class("_1k4h _5ay5") will found nothing in any case and By.Xpath("//div[#class='_1k4h _5ay5']") can also found nothing in case of class will be "_5ay5 _1k4h" or " _5ay5 _1k4h".(as they possibly generated automatically, its may be have different position on page reload)
But for the best result by performance and by correctness I think will be the following xpath:
".//div[contains(#id, 'PagePostsSectionPagelet')][1]" -- for first div
".//div[contains(#id, 'PagePostsSectionPagelet')][2]" -- for second div
I see that dynamic in the div id is only the number so you can use something like:
WebElement element = driver.FindElements(By.XPath("//div[contains(.,'PagePostsSectionPagelet')])")[1];
This will take only the first web element.
Try using a css selector as below and refine further if required.
The code below returns a List of matching WebElements and then you grab the first one in the List.
List<WebElement> listOfElements = driver.findElements(By.cssSelector("div[data-referrer]"));
WebElement myElement = listOfElements.get(0);
Hint: use the Chrome console to test your css and xpath selectors directly. e.g. use
$$("div[data-referrer]") in the console to reveal what will get selected.

Find Element By Class with Spaces Not Working

I'm attempting to locate the following WebElement by class name:
<div class="aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content">
And since it has a space, I've attempted to use both css and xpath to find it like so ...
WebElement folderActions = driver.findElement(By.xpath("//div[#class='aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content ']"));
WebElement folderActions = driver.findElement(By.cssSelector("div[class='aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content ']"));
But both solutions are returning a NoSuchElementException. Any suggestions as to what I'm doing wrong?
Edit: Here is some adjacent html ...
<div id="aui_3_2_0_11858" class="portlet-body">
<div class="top-links-container">
<div id="aui_3_2_0_11857" class="aui-layout ">
<div id="aui_3_2_0_11856" class="aui-layout-content ">
<div class="taglib-header ">
<span class="header-back-to">
<h1 class="header-title">
</div>
<div class="aui-column aui-w75 lfr-asset-column lfr-asset-column-details aui-column-first ">
<div class="aui-column-content aui-column-content-first lfr-asset-column-content lfr-asset-column-details-content ">
</div>
<div id="aui_3_2_0_11855" class="aui-column aui-w25 lfr-asset-column lfr-asset-column-actions aui-column-last">
<div class="aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content">
</div>
</div>
</div>
Try using contains() function with xpath. And, as #Shoham A mentioned it does look like as multiple classes. Provide more html so we can help you with writing more perfect selector.
//div[contains(#class,'aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content')]
And, use explicit wait to make sure the element is present before started using that.
By byXpath = By.xpath("//div[contains(#class,'aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content')]");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(byXpath ));
Edit
//div[contains(#class,'aui-column-content-last')] should be enough to search for the target div. At least for the html provided by OP.
NOTE: Thinking the aui-column-content-last is unique on the page
The Xpath expression in your question would work if there was no whitespace character at the end of it:
//div[#class='aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content']
this will definitely find this div element. I'm not saying that this is the best method to locate it, but everybody seems to think path expressions somehow do not work with multiple classes.
EDIT
You have updated the question. Now, the div again looks slightly different and only
//div[contains(#class,'aui-column-content aui-column-content-last lfr-asset-column-content lfr-asset-column-actions-content')]
will find it. Any reason you cannot use the #id attribute of that div?
Have you met jQuery ? I do not have much experience with XPath, but it makes selecting elements easier, as:
$(".classname")
for CSS,
.aui-column-content.aui-column-content-last...
{
color: black;
}
should do it. Hope I helped!

Categories