How to search node by exact text match using Xpath in webdriver - java

I need a little help regarding searching an exact text using xpath in webDriver.
Suppose i have the html as follows..
<html><body>
<table>
<tr>
<td><button>abcd</button></td>
<td><button>abc</button></td>
</tr>
</table>
</body></html>
Now i want to click button "abc"
I used xpath as //button[contains(text(),'abc')] but it is always performing on button "abcd" as it also contain the text "abc". In this regards I need a predicate or some other procedure which can search exact text instead of containing text.
I also tried with //button[matches(text(),'abc')], //button[matches($string,'abc')], //button[Text='abc')], //button[.='abc')] and many more but none of these worked out to identify "abc" button.
I do not know if there is any problem regarding my xpath version as I'm not aware of the version. But I'm using java 1.6 JDK.
Though my exact scenario is not the example shown but similar logic needs to be applied.
Hence any help or suggestion would be highly appreciated.

I would use next xpath //button[text()='abc']. You have mentioned text() function but I'm not sure syntax was correct. Also you tried to use contains() -- it searches partial text and WebDriver gets first element found. I your case it is <button>abcd</button> button

To find the element 'abcd' you can simply use:
//button[contains(text(),'abcd')]
To find 'abc' use the normalize-space() function which will clean up your text for comparison purposes.
//button[normalize-space(text())='abc']

For exact search:
button[text()='abc']
For pattern matching search:
button[starts-with(.,'abc')]

//button[.="abc"]
The dot before the equality operator will do the text comparison. Another example is /PROJECT[.="MyProject"] from the xPath Java tutorial.

Try with ends-with instead of contains. If the buttons dont have unique attributes, you can add the parent hierarchy as well. Like //table/tr/td[1].

Using something like below worked perfectly fine for me.
//button[(contains(.,'abc')) and not(contains(.,'abcd'))]

For exact search:
.//button[./text()='abc']
Note: make you there is no space is available into

Related

Selenium (Java): ordered list of webelements but with nested divs

I am working with JavaSE and Selenium WebDriver within Chrome. My task is to find a set of input fields and do stuff with them. The issue is that I have to do stuff in the presented order they are available on the web page.
So I would find them via XPATH, because that's what works in the given web page. Let's say that I have a set of inputs on the following path: .../form/div/div/div
However for reasons I cannot say, certain type of input fields (such as text and numbers) are in the following path: .../form/div/div
The problem is that one set of the inputs are one div 'deeper' than the others, so when I save them to a List<WebElement> with driver.findElements, i can't really save their order.
I thought of finding the inputs with id, but the id names have a space in it which Selenium apparently dislikes. I am not sure if relative XPATH could be of help in this case.
Your comments are appreciated.
I made the mistake of not reading enough about XPATH. What I was looking for was the 'and' operand within an xpath expression. If you are a beginner like me, please read about it on w3schools.
Basically the following code solved my issue, as a workaround:
driver.findElements(By.xpath("//input[#required=''] | //select[#required='']"));

Xpath. Unable to select text of label - when another element like <input> is between the <label> tags

Java dev and new to Xpath. Googled and RTFM-ed quite a bit but stuck. Company has a large webapplication written in Java, using the Java Wicket framework. Using Selenium in combination with Cucumber and Junit for testing. Hence Lots of Xpath expressions are needed to be written. Stuck with the following.
A screen with a form and two toggles () and text behind it . Relevant snippet.
<label>
<input id="idf1" name="removeConditionViaTreeStep:resultsRadioGroup" value="radio3" checked="checked" type="radio">
Safe to delete
</label>
<label>
<input id="idf2" name="removeConditionViaTreeStep:resultsRadioGroup" value="radio4" type="radio">
Unsafe to delete
</label>
Note: Using the Wicket framework means that the attributes id and value are/can be different each time the application runs so can NOT use them. Can NOT change the html either.
Plan A
I wanted to select a specific toggle (and emulate clicking/selecting it) by using the label text as a uniq selector but the fact that between the tags there are .. gives me problems. In clean label situations I can select a certain label without problems.
Can't get things like //label[contains(text(),'Unsafe to delete')] to work in this case.
Gave up and went for plan B.
Using firepath addon for firebug for testing and came up with the following: //input[#name='removeConditionViaTreeStep:resultsRadioGroup']
This results in firepath in two matches. I hoped to use something like [2] to select the second toggle, but could not figure it out.
Plan C - resorting to Java and Xpath worked.
List elements = findElementsByXpath("//input[#name='removeConditionViaTreeStep:resultsRadioGroup']");
elements.get(1) // select second toggle.
Have this feeling "//label[contains(text(),'Unsafe to delete')]" does not work because everything is streamed and nothing is held in memory by the Webdriver of selenium. Hence the element breaks the stream or something like that......
Perhaps someone can give a few hints and pointers or even a solution for plan A and B.
Edit corrected the closing parenthesis typo as mentioned by Bill Hileman.
I know you said you can not change the HTML, but maybe you can run the application in wickets development mode on the test environment? This way, if I remember correctly, wicket:id should be rendered and you would have an easier time to select elements.
Your xpath attempt as you typed it is:
//label[contains(text(),'Unsafe to delete']
Unless that was a typo here only, you missed a closing parenthesis.
//label[contains(text(),'Unsafe to delete')]
That xpath should work.

Selenium - how to select an element with variable text

<div class="order-number">
<h3>"Order number: "<strong>123-123123</strong> </h3>
</div>
Any idea how to select the order number? I use Selenium 2. I tried this:
driver.findElement(By.xpath(".//*[matches(text(),'\\d+-\\d+']"));
But it's not working. Does Xpath2 support regex?
The number of the order is always different, but the style of XXX-XXXXXX is always the same.
A different approach would be to search by CSS selector instead:
By.cssSelector(".order-number H3 STRONG")
It's a bit more frail if the page structure changes though.
A better solution (if you are able to change the page code) is to put an ID on the <strong> tag and use By.id. That's much quicker, less frail, and more readable than XPaths or CSS-Selectors.
Simply try
driver.findElement(By.xpath("//div[#class='order-number']//strong")).getText();
Also note that selenium supports matches() in XPath. The cause of your issue seem to be missing closing parenthesis:
now
matches(text(),'\\d+-\\d+'
should be
matches(text(),'\\d+-\\d+')
working one
//h3/strong[matches(text(),'\d+-\d+')]

Object inside inner html not getting identified by selenium web driver

I want to select and click on the object present inside inner html (shown in the image). But the object is not getting identified. I am using Java.
Note --> my application not opening with any browser except Internet Explorer and I can't verify xpath from console/debugger so I have to verify it through code only.
Code I have tried so far but not working for me-->
option 1 -->
driver.switchTo().frame("nav");
driver.findElement(By.xpath("//a href[#text='Administrate']")).click();
option 2 -->
driver.switchTo().frame("nav");
driver.findElement(By.xpath("//a[#text='Administrate']")).click();
option 3 -->
driver.findElement(By.xpath("/html/frameset/frame[1]/html/body/ul/li/ul/li[1]")).click();
You are checking for exact text match, use contains instead
driver.findElement(By.xpath("//a[contains(text(), 'Administrate')]")).click();
Or
driver.findElement(By.xpath("//a[contains(., 'Administrate')]")).click();
Please note the difference between text() and #text
You need to change your XPath like
driver.switchTo().frame("nav");
driver.findElement(By.xpath("//a[text()='Administrate system']")).click();
Note:- Here you need to pass complete string for better learning please refer Firepath to create and evaluate your xpath
Also can use contains method to find an element on partial text basis

How to access the text field that do not have id property in selenium

i am working in selenium i want access a text field and fill with any value but that field do not have any id attribute, so tell me how to locate that field.
You can use Cssselector or xpath.
you can find lots more on google . one useful link is -
http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/dotnet/Selenium.html
If you cannot add id to element, then you can use other options:
use other attributes (e.g.name or any other you have) - it is not reliable, because attributes can change in time. Example:
//div[#name='some_name']
use your HTML layout to locate element - it's even less reliable, because your HTML layout may be changed in time. Example:
//footer//div[position()=2]
In order to make it easy to write your custom XPath expression I would suggest to use FireFinder for FireBug FireFox plugin. It supports both CSS and XPath expressions and makes writing expressions really straightforward.
For typing into a textbox there is no need to have an ID. You can do it with XPath or CSS.

Categories