Find 'li' element - java

Could someone please assist me in order to find 5th 'li' element since that receiving error when trying to locate it. Following is how looks on page:
<ul class="navigation-primary navigation-primary--right js-navigation-primary">
<li><a data-modal="login-modal" href="javascript:void(0);" data-modal-content-switch="login-options" class="is-button-group-right js-prevent-trigger modal-content-button"><span>Logga in</span></a></li>
<li></li>
<li>Svenska</li>
Actually, I need last one with following attribute
data-menu="language"
Since there are several languages - I suppose that it would solve with if loop:
if (driver.findElement(By.xpath("//*[#id="header"]/div[2]/div/ul[2]/li[5]/a") != null
driver.findElement(By.xpath("//*[#id="header"]/div[2]/div/ul[2]/li[5]/a").click();
else {
system.out.println("element not present");
}
Since that there are several languages and every has last li[5] - thought that lang name could solve it, but did not find solution.
Thank you in advance

I know you accepted an answer but it would be a lot cleaner and clearer if you used a simple CSS selector like
driver.findElement(By.cssSelector("a[data-menu='language']")).click();
or you could be more specific and find the element by language using XPath
driver.findElement(By.xpath("//a[#data-menu='language'][.='Svenska']")).click();
Also, you can't check if an element is null. If it's not there, .findElement() will just throw an exception. If you want to check if an elements exists, use .findElements() and check to see if the collection is empty
List<WebElement> links = driver.findElements(...);
if (links.isEmpty())
{
// element doesn't exist
}
else
{
// element exists
links[0].click(); // or whatever
}

As per the HTML you provided the following xpath/cssSelectorshould work:
driver.findElement(By.xpath("//ul[#class='navigation-primary navigation-primary--right js-navigation-primary']/li[contains(.,'Svenska')]"));
OR
driver.findElement(By.cssSelector("ul.navigation-primary.navigation-primary--right.js-navigation-primary > li.navigation-primary.navigation-primary--right.js-navigation-primary"));

At the risk of redefining your question, I'd be tempted to add some id tags into your html and call driver.findElement(By.id(name)).
The advantage is that if an extra item is added to the start of list then your tests will not break.

Related

How to check if located link contains a tag with a given text?

I need to check if located link contains <span class="extra-light"> with a given text.
The way I locate the link:
ExpectedConditions.elementToBeClickable(By.xpath("//a[#so-extra=\"x12fog\"]"))
How to make it?
You can use findElements method with XPath locator defining the desired element as following:
if(driver.findElements(By.xpath("//a[#so-extra='x12fog']//span[#class='extra-light' and contains(.,'stackoverflow')]")).size()>0){
System.out.println("Element found");
}
findElements method return a list of found matching elements. So, if there is such element the list will be non-empty (size>0), otherwise the returned list will be empty.
Try either of the xpath.
//a[.//span[#class='extra-light']]
Or
//a[.//span[#class='extra-light' and text()='stackoverflow']]
Or
//a[.//span[#class='extra-light' and contains(.,'stackoverflow')]]
Code should be
ExpectedConditions.elementToBeClickable(By.xpath("//a[.//span[#class='extra-light' and text()='stackoverflow']]"))
Or
ExpectedConditions.elementToBeClickable(By.xpath("//a[.//span[#class='extra-light' and contains(.,'stackoverflow')]]"))
or
ExpectedConditions.elementToBeClickable(By.xpath("//a[.//span[#class='extra-light']]"))

Dynamic element inside several 'li'

now I have more complicated (at least for me) and struggling to find element (which is dynamic one - changes on daily basis). Following is how it looks on page. On top is 'ul'
<ul class="feed-tips" id="Grid"
Below are 50 'li' with same name:
<li class="feed-item vevent tip-list-row"
Below one of those 'li' are
<div class="tip medium-9 small-12 column padding-reset dtstart tip-list-row__tip">
Heading4
So, link to a page & Heading4 (in 'href') are dynamic ones and it will be useless from i.e tomorrow.
Above is 5th 'li' in the list and I tried to find element with css selector but it does not work - here is what I tried:
//Open 5th from the list
driver.findElement(By.cssSelector("#Grid > li:nth-child(5) > div.tip.medium-9.small-12.column.padding-reset.dtstart.tip-list-row__tip > div.tip-match.medium-12.column > div.tip-teams > a")).click();
Thank you in advance.
In case you are trying to find the anchor element with dynamic href, you can use somewhat the xpath as below:
//ul[#id='Grid']/li//div[contains(#class, 'tip-teams')]//a[#href]
I did not understand the total problem, but it will list down all the links with attribute href within that hierarchy. In this case, do not use any sort of indexing. Also, not required to drill down all the levels of hierarchy.
//a[#href] - It will provide you all links with #href without comparing any value.

How can I get the inner text of an element in Selenium?

I'm working with a DOM node:
<input
type="form-control"
type="text"
data-bind="textInput: EnterpriseId"
disabled
autocomplete="off">
How can I get its value? I'm struggling since element.getText() does not work and returns a blank.
Try this:
WebElement element = driver.findElement(By.id("id value"));
String val = element.getAttribute("innerText")
I presume the element in question is an <input> element, so you may be able to use the element.getAttribute(String attribute) method like so:
String value = element.getAttribute("value");
This input tag is disabled, hence element.getText() returns a blank value.
Use element.getAttribute("textContent") instead.
You may be looking for the placeholder of an input text, because you might try:
element.getAttribute("placeholder");
You can go to your browser → open developer tools → inspect element you want to take attribute from → click Properties → check if that value is in InnerText.
Then do as it is mentioned in previous comments:
element_locator.get_attribute('InnerText')
I had the exact same issue! This post solved it for me:
How can I get the current contents of an element in webdriver
I used:
element = driver.find_elements_by_xpath(
'//button[#class="size-grid-dropdown size-grid-button"]')
element.text
As other's suggested, HTML's input nodes don't have a text attribute because they can store data in multiple formats in a value attribute.
This can be easily seen in the HTML input API specification where this form control can be of type radio, date, file upload and many more.
So, in your specific case, I'd suggest you check the webdriver's API for a method that's able to retrieve the value attribute.
As a bonus to evaluate innerText of an element within Selenium:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("yourEl")));
wait.until(ExpectedConditions.attributeToBe(By.id("yourEl"), "innerText", yourValue));
Documentation: attributeToBe
It works definitely, as I've tested it several times:
<input type="form-control" type="text" data-bind="textInput: EnterpriseId" disabled autocomplete="off">
In your example, you don’t have any innerText. So you can only get attributes as mentioned before with the existing attributes. In your case:
type, data-bind, EnterpriseId and autocomplete. No value will be as this attribute isn’t created.
If you want to get only existing, this should be fine:
String example = driver.findElement(ByLocator(("")).getAttribute("any attribute of your input");
System.out.println(example);

How remove specific code or attribute from html using java or jquery [duplicate]

I have a div <div id="masterdiv"> which has several child <div>s.
Example:
<div id="masterdiv">
<div id="childdiv1" />
<div id="childdiv2" />
<div id="childdiv3" />
</div>
How to clear the contents of all child <div>s inside the master <div> using jQuery?
jQuery's empty() function does just that:
$('#masterdiv').empty();
clears the master div.
$('#masterdiv div').empty();
clears all the child divs, but leaves the master intact.
jQuery('#masterdiv div').html('');
Use jQuery's CSS selector syntax to select all div elements inside the element with id masterdiv. Then call empty() to clear the contents.
$('#masterdiv div').empty();
Using text('') or html('') will cause some string parsing to take place, which generally is a bad idea when working with the DOM. Try and use DOM manipulation methods that do not involve string representations of DOM objects wherever possible.
I know this is a jQuery related question, but I believe someone might get here expecting a pure Javascript solution. So, if you were trying to do this using js, you could use the innerHTML property and set it to an empty string.
document.getElementById('masterdiv').innerHTML = '';
jQuery recommend you use ".empty()",".remove()",".detach()"
if you needed delete all element in element, use this code :
$('#target_id').empty();
if you needed delete all element, Use this code:
$('#target_id').remove();
i and jQuery group not recommend for use SET FUNCTION like .html() .attr() .text() , what is that? it's IF YOU WANT TO SET ANYTHING YOU NEED
ref :https://learn.jquery.com/using-jquery-core/manipulating-elements/
If all the divs inside that masterdiv needs to be cleared, it this.
$('#masterdiv div').html('');
else, you need to iterate on all the div children of #masterdiv, and check if the id starts with childdiv.
$('#masterdiv div').each(
function(element){
if(element.attr('id').substr(0, 8) == "childdiv")
{
element.html('');
}
}
);
The better way is :
$( ".masterdiv" ).empty();
$("#masterdiv div").text("");
$("#masterdiv > *").text("")
or
$("#masterdiv").children().text("")
$('#div_id').empty();
or
$('.div_class').empty();
Works Fine to remove contents inside a div
You can use .empty() function to clear all the child elements
$(document).ready(function () {
$("#button").click(function () {
//only the content inside of the element will be deleted
$("#masterdiv").empty();
});
});
To see the comparison between jquery .empty(), .hide(), .remove() and .detach() follow here http://www.voidtricks.com/jquery-empty-hide-remove-detach/
When you are appending data into div by id using any service or database, first try it empty, like this:
var json = jsonParse(data.d);
$('#divname').empty();
$("#masterdiv div[id^='childdiv']").each(function(el){$(el).empty();});
or
$("#masterdiv").find("div[id^='childdiv']").each(function(el){$(el).empty();});
try them if it help.
$('.div_parent .div_child').empty();
$('#div_parent #div_child').empty();

HTMLDocument: does Swing "optimize out" span elements?

I'm messing about with HTMLDocument in a JTextPane in Swing. If I have this situation:
<html>...
<p id='paragraph1'><span>something</span></p>
<span id='span1'><span>something else</span></span>
...</html>
(the extra <span> tags are to prevent Swing from complaining that I can't change the innerHTML of a leaf) or this situation
<html>...
<p id='paragraph1' />
<span id='span1' />
...</html>
I can call HTMLDocument.getElement() and find the element with ID 'paragraph1' but not the element with id 'span1'. If I change the tag for 'span1' from "span" to "p" then I'm fine. WTF is going on here? Is there another HTML element I can use instead that will allow me to access a particular portion of the document using the id attribute, that will not cause linebreaks? (span would have been perfect :( argh!)
edit: I think the solution is to re-examine what I'm trying to do, which was to leverage the fact that I know how to make GUIs + tables + displays in HTML a lot more than I do in Swing, so I'll ask a different question....
I don't know Swing, but
<p style="display: inline;"> does not line-break, the same as <span>
I have exactly this problem. My span elements disappear.
Whereas if i used div i can see them. But of course I don't want div elements, because it causes a line break.
Damn it! Damn java.
Edit!
STOP THE PRESS!!
Found the answer. At least, an answer which fixes it for me.
I was still able to determine that I had my span element. I will describe what I am doing, an d provide the code to how i did it.
I want to know what element the caret is in. So, this code exists within the caretUpdate function, which provides me with the caret position each time it moves.
#Override
public void caretUpdate(CaretEvent e)
{
System.out.println("caret event: " + e.toString());
Object source = e.getSource();
if (source instanceof JEditorPane)
{
JEditorPane jep = (JEditorPane)source;
Document doc = jep.getDocument();
if (doc instanceof HTMLDocument)
{
HTMLDocument hdoc = (HTMLDocument)doc;
int pos = e.getDot();
Element elem = hdoc.getCharacterElement(pos);
AttributeSet a = elem.getAttributes();
AttributeSet spanAttributeSet = (AttributeSet)a.getAttribute(HTML.Tag.SPAN);
// if spanAttributeSet is not null, then we properly found ' a span '.
// now we need to discover if it is one of OUR spans
if (spanAttributeSet!=null)
{
Object type = spanAttributeSet.getAttribute(HTML.Attribute.TYPE);
if (type !=null && type.equals("dragObject"))
{
// for our logging, we get the ref, which holds the source
// of our value later
System.out.println("the value is: " + spanAttributeSet.getAttribute("ref"));
}
}
}
}
}
Edit!!!
Scratch that... This almost works... except the idiots at Sun decided the key was going to be of type HTML.Attribute. Not only that, that the constructor for the HTML.Attribute is private, and it just so happens that the attribute type that I wanted doesn't exist within their privileged set of attributes. Bastards!
So, all is not lost... I can still get it via the enumerator.. but it is a little more difficult than it needed to be.
LAST EDIT!
Ok, I get it now. If the attribute is of a known type, it is stored in the AttributeSet as an instance of HTML.Attribute("type").
Otherwise, it is stored in the AttributeSet with a 'String' as the key.
Stupid. But i've got there.
I took a look at the javadoc for HTMLDocument, which pointed me to HTMLReader.
I don't see any mention of span in HTMLReader. Maybe it just doesn't know that element.
P probably isn't a good replacement for span. P is a block-level element and span is a text-level element (see description of those terms). Maybe try font (another text-level element) with no attributes?

Categories