How fetch first element from json list in selenium java? - java

I have following list of ids in json format. I want to access first id in selenium using java. I tried using
String item = driver.findElement(By.xpath("//ul//li[1]")).getText();
but didn't help.
<body>
<div id="json">
<span class="collapser"></span>
{
<ul class="obj collapsible">
<li>
<span class="prop" title="<root>.hdps">
<span class="q">"</span>
hdps
<span class="q">"</span>
</span>
:
<span class="collapser"></span>
[
<ul class="array collapsible">
<li>
<span class="num">65085</span>
,
</li>
<li>
<span class="num">65089</span>
,
</li>
<li>
<span class="num">65711</span>
,
</li>
</ul>
]
</li>
</ul>
}
</div>

What i understand is you are trying to read the value of ID attribute of an element. I am really not sure the intent of your question . But this how you can get to the value of ID.
You will need to get reference to the element using one of the various element locators. In this case, you have leveraged By.xpath(). You can validate the correctness of the XPATH used by Firefox Xpath checker. Once you use correct XPATH , you will get reference of webElement.
WebElement wElement = driver.findElement(By.xpath("//ul//li[1]"));
// validate the correct XPATH using available tools - ex : firefox xpath checker etc.
You will need to get the value of id attribute of the element.
String requiredID = wElement.getAttribute("id");
Let me know if this works.

As pendem answered that, you can get first ID as you want by using xpath. But here I found that the xpath which you have used find 2 elements as there are two ul elements having li. If you use xpath having specific ul with class attribute as - .//ul[# class="array collapsible"]//li[1] will work.

If you have provided all the relevant HTML, it should be as simple as the below.
String id = driver.findElement(By.cssSelector("span.num")).getText();
This just returns the first instance of the IDs.
If that doesn't work, you'll have to do some more digging, e.g. is this in an IFRAME or is it a timing issue or ?

Related

Is there a way to parse an entire HTML tag in JSoup?

Hi I'm wondering if there's a way to parse an entire HTML tag using JSoup? In my example pictures below, the five elements (4 images and 1 string) are all inside the "li" container. However, when you open the "li" tag, there are multiple nested containers. Is there a way to parse it so that I have access to all 5 elements contained in this "li" tag? I'm thinking of using getElementsMatchingOwnText("Collins") but that seems to only get me "span class="text text_14 mix-text_color7">Panorama". Any help would be appreciated, thanks!
Yes, you can iterate over the children of your <li> tag using jsoup.
Here is a simplified version of the HTML in your screenshot, showing the 5 elements:
<li>
<span class="foo"><img src="bar" class="img"></span>
<span class="bar">Collins</span>
<i class="baz1"><img src="baz1" class="img"></i>
<i class="baz2"><img src="baz2" class="img"></i>
<i class="baz3"><img src="baz3" class="img"></i>
</li>
Assuming you have selected this specific <li> tag in your document, you can use the following approach:
String html = "<li><span class=\"foo\"><img src=\"bar\" class=\"img\"></span><span class=\"bar\">Collins</span><i class=\"baz1\"><img src=\"baz1\" class=\"img\"></i><i class=\"baz2\"><img src=\"baz2\" class=\"img\"></i><i class=\"baz3\"><img src=\"baz3\" class=\"img\"></i></li>";
Document document = Jsoup.parse(html);
Element element = document.selectFirst("li");
element.children().forEach(child -> {
// do your processing here - this is just an example:
if (child.hasText()) {
System.out.println(child.text());
} else {
System.out.println(child.html());
}
});
The above code prints the following output:
<img src="bar" class="img">
Collins
<img src="baz1" class="img">
<img src="baz2" class="img">
<img src="baz3" class="img">
UPDATE
If the starting point is a URL, then you would need to start with this:
Document document = Jsoup.connect("https://www...").get();
Then the exercise is about identifying a unique way to find your specific element. So, if we update my earlier example, let's assume your web page is like this:
<html>
<head>...</head>
<body>
<div>
<ul class="vList_4">
<li>
<span class="foo"><img src="bar" class="img"></span>
<span class="bar">Collins</span>
<i class="baz1"><img src="baz1" class="img"></i>
<i class="baz2"><img src="baz2" class="img"></i>
<i class="baz3"><img src="baz3" class="img"></i>
</li>
</ul>
</div>
</body
</html>
Here we have a class in a <ul> tag called vList_4. If that is a unique class name, we can use it to jump to that section of the HTML page (IDs are better than class names because they are guaranteed to be unique - but I did not see any ID names in your screenshot).
Now, instead of my previous selector:
Element element = document.selectFirst("li");
We can use this more specific selector:
Element element = document.selectFirst("ul.vList_4 li");
The same results will be printed as before.
So, it's all about you looking at the page structure and figuring out how to jump to the relevant section of the page.
See here for technical details describing how selectors are constructed.

href attribute of a li element coming up as null when there is data for the href

I am trying to iterate over a collection of li elements in an ordered list and then print the URL from each element.
The HTML:
<div id="global-atoz-navigation">
<nav role="navigation" aria-label="Suppliers">
<ol>
<li class="selected">
<span class="visuallyhidden">Suppliers starting with </span>
<strong>A</strong>
</li>
<li>
<span class="visuallyhidden">Suppliers starting with </span>
B
</li>
<li>
<span class="visuallyhidden">Suppliers starting with </span>
C
</li>
</ol>
</nav>
</div>
My code so far:
WebElement navDiv = driver.findElement(By.id("global-atoz-navigation"));
List<WebElement> links = navDiv.findElements(By.tagName("li"));
for (WebElement link : links) {
System.out.println(link.getAttribute("href"));
}
But for some reason this is printing 'null' for each li element. Any ideas why?
Your <li> elements don't have an href attribute. The <a> elements inside them do. Is there a reason you wouldn't do navDiv.findElements(By.tagName("a")) to find those instead? Or, if there could be anchors you want to avoid, either get all the anchors and filter the bad ones out, or get all the list items and do another li.findElements(By.tagName("a")) on each one.
Please note that <li> isn't short for "link". It's short for "list item".
Links are in the "anchor", or <a>, element.
Referencing from the answer here:
JSP getAttribute() returning null
"You are not typecasting it to String. request.getAttribute() will return an Object."
Try using this and see if it works:
String value = (String)link.getAttribute("href");
What's also true is ErikE's answer where you should be grabbing the attributes for the < a > tags not the < li > tags

Java: getAttribute in Selenium

Currently I am working with the following HTML snippet:
<div class="cardEntry">
<!-- Balance Block Section (R)-->
<div class="balanceBLock">
<ul>
<li class="balanceText">Actual Balance</li>
<li class="balance">
<strong id="155555520be0019actualBalance">$1.00</strong>
</li>
<li class="balanceText">Available Balance</li>
<li class="balance">
I am trying to get the balance: $1.00 using the XPath:
.//*[#id='155555520be0019actualBalance']
and then attempting to obtain the dollar value using the method .getText however this does not return anything.
I can identify the element just fine using this XPath but it does not return the dollar value with getText method.
Can someone explain how to obtain this value?
Thanks
Looks like id is dynamic here.. use xpath like below with partial id
//strong[contains(#id,'actualBalance')]
or else use
//li[. = 'Actual Balance']/following-sibling::li/strong
specified by alecxe in comment.
Try getAttribute() with any of the below values: "value", "innerText", "innerHTML"

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.

Store the attribute's value of a WebElement in Selenium Webdriver

Ive got a UL that is dynamically populated and the ID is also dynamically generated everytime you click on the "Action" button; is there a way to read the tag of the
<div class="class">
<ul id="dynamically generated">
<li class="li_class">
<li class="li_class">
<li class="li_class">
<li class="li_class">
<li class="li_class">
</ul>
</div>
Since you didn't mention any language, I'll go with the JAVA syntax:
// String object 'field_value' is created
String fieldValue;
// The field value is retrieved by the getAttribute("id") Selenium WebDriver predefined method and assigned to the String object.
fieldValue = _driver.findElement(By.ById("dynamically generated")).getAttribute("id")
It'll get the value of a the given attribute of the element. Will return the current value, even if this has been modified after the page has been loaded.
I know you already accepted an answer but if some portion of the ID is stable, you can search for partial matches. For example, say you have an element
<span id="ctl00_SomeStableTextGoesHere_12345" ...>
where 12345 is dynamically generated. You could search for the start of the ID using CSS Selectors.
driver.findElement(By.cssSelector("span[id^='ctl00_SomeStableTextGoesHere_']"));
There are other options:
^ begins with
$ ends with
* contains

Categories