Unable to "click()" on an element in Selenium test - java

I have recorded an automatic test with Selenium, exported it into JAVA code and now I am fighting to complete it. The problem is that I cannot get click(); done.
This is my code, a part of it:
try {
assertTrue(driver.findElement(By.xpath("//*[text()='Nowa oferta dokument']"))
.getText().matches("^Nowa oferta dokument$"));
} catch (Error e) {
verificationErrors.append(e.toString());
}
driver.findElement(By.xpath("//*[text()='Nowa oferta dokument']")).click();
First I find the element using xpath and then using xpath I want to click on it so its settings open.
I have tried many ways to solve it, and still can't figure it out. Do you see any solution for this one?
HTML:
<p class="photo"><img src="img/document.png"></p>
<p class="name">Nowa oferta dokument</p>
<p class="price">123 zł</p>
<div class="rate ctrlViewRateOffer" data-value="0.0000">
<span class="stars"></span>
<span class="stars"></span>
<span class="stars"></span>
<span class="stars"></span>
<span class="stars"></span>
</div>
<p class="date"></p>
<div class="hide info">
<p></p>
<p><a class="ctrlClickSubmit delete" title="Usuń" data-value="delete_1007" data-form="formManageOffer" href="#"></a></p>
<p></p>
<p class="type">e-book</p>
<p>To jest opis nowo tworzonej oferty - dokumentu, który wystawię na sprzedaż, a następnie u...</p>
</div>
<div class="bgInfo"></div>

Most probable reason is that
By.xpath("//*[text()='Nowa oferta dokument']")
is matching more than one element...
Also, check if the returned element/s is clickable

Well, your selector is wrong for one:
driver.findElement(By.xpath("//*[#class='name'][text()='Nowa oferta dokument']")).click();
Should hopefully work. If not, your element is probably not clickable due to other elements in front of it.
In which case, you can simulate the click using javascript:
driver.executeScript("arguments[0].click()", driver.findElement(By.xpath("//*[#class='name'][text()='Nowa oferta dokument']")));
Your CURRENT selector IS matching multiple elements. Since the element you are trying to select is at least two elements in, it is matching every parent object in the tree above the element you actually want, since they ALL contain that as the text().

Related

Find element's siblings with selenium webdriver

I have a structure like this:
<div>
<div>
<span class="">TextA</span>
</div>
<div>
<span class="">TextB</span>
</div>
</div>
I can find element span with TextA, and from there, I want to find span with textB, then click on it (which is not available to find it alone). So I used xpath like this:
webDriver.findElement(By.xpath("//span[contains(.,'TextA')]/following-sibling::span")).click();
I got exception Element is not found. I assumed these spans are siblings ?!. Can anyone help me in this case. Thanks
I got exception Element is not found. I assumed these spans are siblings ?
These two spans are not siblings - they are children of different elements and cannot be siblings.
Instead of following-sibling, you may use the following axis:
//span[contains(.,'TextA')]/following::span
Or, you may get the div element that contains the span with TextA text and then get it's following sibling:
//div[contains(span, 'TextA')]/following-sibling::div/span
The <span>'s aren't siblings. if the <span>'s were siblings, they'd have to be adjacent.
for example:
<div>
<div>
<span class="">TextA</span>
<span class="">TextB</span>
</div>
</div>
In this case, they are siblings and your selector would work.
The elements that are actually siblings, are the <div>s.
The xpath that could work for you, would be:
//span[contains(.,'TextA')]/../following-sibling::div/span

element.getText() method is not working in java selenium

<span class="label label-danger" style="font-size : 13px; font-weight : 400;">Critical</span>
Below is the xpath which I am using:
.//tr[#data-index='0']/td/span
I have a line in HTML source like above. So, I have used corresponding Xpath and used getText() method to get the text i.e. Critical. I am succeed in that.
But, I have another line in another page like this.
<div class="col-xs-12">
<div id="project-update-success-information" class="panel-confirmation success" style="display: none;">
<span class="fa fa-check"/>
Project Updated
</div>
Below is the xpath which I am using:-
.//*[#id='project-update-success-information']/span
I have used the corresponding Xpath and getText(),but unfortunately it doesn't retrieve the text for me. I doubted that there is no </span> close tag in the second line which causes the problem. Is there any other way to get the text?
This question has many answers already, but none of them really explains the problem. First, let us get your initial confusion about self-closing elements out of the way, before moving on to the real problem: No, it is not a problem that an element like
<span class="fa fa-check"/>
does not have a </span> tag. There is no need to indicate where it ends because the /> already tells you that this element does not contain anything and closes at this point.
Then let's look at only the fragment of the document that you show:
<div class="col-xs-12">
<div id="project-update-success-information" class="panel-confirmation success" style="display: none;">
<span class="fa fa-check"/>
Project Updated
</div>
</div>
An XPath expression like (note that most likely you do not need the . at the very beginning of the expression):
//*[#id='project-update-success-information']
will return the inner div element with all that it contains. What it does contain is, exactly in this order:
a whitespace-only text node
a self-closing span element with no content other than an attribute
the text node that contains "Project Updated"
So, it is not at all surprising that when you select the inner div and use .getText(), you end up with 2 text nodes in the result. Another way to get at the text content of an element is by using text() in the XPath expression:
//*[#id='project-update-success-information']/text()
which will return (individual elements separated by --------):
[whitespace-only text node]
-----------------------
Project Updated
The solutions are either
use getText() to retrieve all text nodes and later exclude those that only contain whitespace or
use an XPath expression that targets text nodes directly and excludes the ones that only contain whitespace. The standard way of doing this is with [normalize-space()]:
//*[#id='project-update-success-information']/text()[normalize-space()]
Note that, in general, there is no guarantee that the text content of an element will be in one single text node. It is very likely that you will sometimes encounter HTML or XML where elements have several text nodes, all of them containing non-whitespace characters, e.g.:
<div>
Project
<span/>
Updated
</div>
Try this text() method like below:-
//span[#class='fa fa-check']/text()
Hope it will help you :)
The element is empty and thus contains no text
<span class="fa fa-check"/>
If on the other hand it was like
<span class="fa fa-check">Some content</span>
then it would, as in yor first attempt, contain some text.
Without knowing more of the content I would try another xpath method: following-sibling.
Try:
driver.findElement(By.className("panel-confirmation success")).getText();

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.

Click on Tabs in Selenium webdriver

I am trying to open different section of page. These Section will open on click of different tabs.
Below is HTML Structure of Page
<div id="MainContentPlaceHolder_divMainContent">
<div id="MainContentPlaceHolder_tbCntrViewCase" class="Tab ajax__tab_container ajax__tab_default" style="width: 100%; visibility: visible;">
<div id="MainContentPlaceHolder_tbCntrViewCase_header" class="ajax__tab_header">
<span id="MainContentPlaceHolder_tbCntrViewCase_tbPnlCaseDetails_tab" class="ajax__tab_active">
<span id="MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle_tab" class="ajax__tab_hover">
<span class="ajax__tab_outer">
<span class="ajax__tab_inner">
<a id="__tab_MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle" class="ajax__tab_tab" style="text-decoration:none;" href="#">
<span>Vehicle</span>
</a>
</span>
</span>
</span>
and I have Written Below Lines but these are not working
driver.findElement(By.id("__tab_MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle")).click();
driver.findElement(By.xpath("//a[text()='Vehicle']")).click();
I got Source Not Found Error
As per the OP's comments, I am posting the xpaths that can be used to locate the concerned element :
1- //span[#id='MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle_tab']//span[.='Vehicle']
This will locate the span element with innerHTML/text as Vehicle which is a descendant of span with id MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle_tab
OR
2-//span[#id='MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle_tab']//span[.='Vehicle']/..
This will locate the parent of span element with innerHTML/text as Vehicle which is a descendant of span with id MainContentPlaceHolder_tbCntrViewCase_tbPnlVehicle_tab which in this case is an a element.
Please check if this works for you. Else, let me know how many matching nodes does it show, when you use them. We will sort this one out.

How to check for second element with class name and click it if it exists in Selenium Java

So I am writing automation tests using selenium and I am having a lot of trouble selecting the second element in a list of divs with the same class names
Boolean isExists2Accounts = driver.findElements(By.xpath("(//div[contains(#class, 'item-name')])[2]")).size() < 0;
if(isExists2Accounts)
{
//Finds second div element that has classname of item-name and clicks on it
driver.findElement(By.xpath("(//div[contains(#class, 'item-name')])[2]")).click();
}
else
{
driver.get("javascript:alert('There isn't a second account or you don't know how to select it!');");
Thread.sleep(5000);
org.testng.Assert.fail("transferTest6() Failed due to There isn't a second account or you don't know how to select it!");
}
HTML structure looks like this:
<div class="item-list">
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area</div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
</div>
Not really sure what I am doing wrong here, I looked at the html and there are 5 divs with the specified class name. Very new to selenium in general, using eclipse/junit/webdriver.
I have seen several questions similiar to this, and trying solutions people have posted have not worked. I have seen some suggestions to use .get(2) and I will try and implement that in the mean time.
Any help you could give would be good.
get(2) is THIRD element, not the second, as the countage begins from 0.
So:
driver.findElements(By.cssSelector(".item-name")).get(1).click();
OR depending on where is yr clickable
driver.findElements(By.cssSelector(".item-name div:not(.button-wrap)")).get(1).click();
Hey all the answer that was given by Stanjer works, I tested it with different markup, the developer that built the system I am testing through a random mousedown event (not click) for the html I am trying to interact with which was causing the problem.
So final solution with problem if it was a click event would be:
driver.findElements(By.cssSelector(".item-name")).get(1).click();
Just like he said.
However in this case I am instead going to send Javascript to the console to work with functions that have already been created by the developer.

Categories