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

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

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.

How fetch first element from json list in selenium 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 ?

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"

Issue selecting an xpath when it is unknown if it will be on the page

I have this piece of selenium code I am trying to write, where it will select a page number indicator at the bottom of the page and count the elements on it. However, this number indictor does not appear if there is only one page, and it will be updated in the future and eventually contain more than one page.
How can I make a piece of selenium code will select the last page if it finds that the page number indicator is there? I have it search the webpage for a piece of text that only appears if the indictor appears, but I am stuck on what to do after that to make it select the last page in the page number indicator.
<div class="view view-blog view-id-blog view-display-id-page_1 view-dom-id-3e6e5f93bb52f8bc5f35e55c6da86526">
<div class="view-filters">
<form id="views-exposed-form-blog-page-1" class="views-exposed-form-blog-page-1" accept-charset="UTF-8" method="get" action="/blogs">
</div>
<div class="view-content">
<div class="item-list">
</div>
<h2 class="element-invisible">Pages</h2>
<ul class="pager">
<li class="pager__item pager__item--current">1</li>
<li class="pager__item">
<li class="pager__item">
<li class="pager__item">
<li class="pager__item">
<li class="pager__item">
<li class="pager__item pager__item--next">
<li class="pager__item pager__item--last">
<li class="pager__item pager__item--last"> is the text that coressponds to the button I want to select.
In this there is 5 pages, so it would go to page 5, but I am trying to write it so that it just goes to the last page in the current list, so that I dont have to hardcode a number to jump to.
My current code is just
if (driver.getPageSource().contains("pager")) {
WebElement k = driver.getPageSource().findElement("pager__item pager__item--last");
The pager__item pager__item--last is the string inside of the code that corresponds to the button I want to select <li class="pager__item pager__item--last">
What would be a good way to do this search for this string and then click on the button it corresponds to if you are unsure it even exists inside of your code?
Thanks
Taking Google search result as an example
Write a conditional statement for Page Number indicator
When the condition is satisfied, using FindElements method get all the <a> tags representing Page Numbers
Get the Last element from the list which will be the last page
Do a Click of element
The Best way is using try catch..
try{
driver.findElementByXpath("Your xpath of last page button").click();//you can use any other locator
}catch(NoSuchElementException e){
//if you get exception then it means that element is not present(it means there is only one page)
//if you have multiple page then that button will be present and it'll not through any exception and it will trigger click event in that element and you'll get navigated to last page
}

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.

Categories