how to deal with Line Break <br/> when working with xpath - selenium

I am trying to find xpath for the links(Anchor tags <a>) from below HTML code.
Note: I don't want to use absolute xpath, so I am using xpath's contains() function
<div class="productList">
<table class="product-listing-table">
<thead>
<tr>
<th class="product-desc">
<a class="pt_sort">Product & Description</a>
</th>
<th>
<a class="pc_sort">
Product
<br/>
Category
</a>
</th>
</tr>
</thead>
</table>
</div>
Below xpath gives me 'Product & Description', But in similar way if I am trying to find the next product with text as 'Product Category', it gives me error
.//th/a[contains(text(),'Product & Description')]
Above xpath Works
.//th/a[contains(text(),'Product Category')]
This one does not works.
Can somebody help?

Try with below xpath
"//a[contains(text(),'Product') and contains(.,'Category')]"
Here contains(.,'Category') check for the inner text of any child tags of given tag

Related

Selenium XPath multiple selection

I want to find all elements in the table that match the following conditions:
-div text contains '2019';
-div class='excellent';
here is the HTML code excerpt:
<tr>
<td>Name of Person1</td>
<td>
<div class="testDate">21/12/2019</div>
<div class="excellent"></div>
</td>
</tr>
<tr>
<td>Name of Person2</td>
<td>
<div class="testDate">01/12/2017</div>
</td>
</tr>
I tried this solution:
//tr/td[2][div/text()='21/12/2019'][div[#class='starred']]
but I need the year only and not entirely date.
Use the below xpath.
//tr/td[div[contains(.,'2019')]and div[#class='excellent']]
Screenshot:

How to locate the parent element of a child element identified through innerText?

I need to select a row in a table where I have a text, hence I would like to leverage the option of selecting a text and then eventually selecting the parent
Now the page looks like:
<tr class=" tableRow1" id="_pu5ufb" dr="1" _awtisprimaryrow="1">
<td width="1" class="tableBody w-tbl-cell" align="center"><span
class="selectColumnMarker">
<div class="w-chk-container">
<input bh="CHKINP" hasaction="false" class="w-chk-native"
id="_m7iynb" value="1" type="checkbox" elementid="_jw4lmb"
issender="false" awnomitcomponent="true" name="_jw4lmb"><label
bh="CHK" class="w-chk w-chk-dsize"></label>
</div>
</span>
</td>
<td align="left" class="tableBody w-tbl-cell">
<span>
<table role="presentation" class="mls" cellpadding="0"
cellspacing="0">
<tbody><tr>
<td class="" id="_tz87e" tabindex="0"><a id="_3iqrbb" href="#"
bh="HL" _sf="true">Analyst</a>
</td>
</tr>
</tbody></table>
</span>
</td><td class="tableBody w-tbl-cell">
</td>
<td class="tableBody w-tbl-cell">
</td>
</tr>
I need to find the text Analyst and then find the associated <tr> class and select the <tr> class.
Any help would be highly appreciable
First, whenever you have mixed content (text and markup) it is better to compare elements' string value than text nodes because inline markup might be splitting the compared text into different text nodes.
Second, you can use:
//tr[td='Analyst']/#class
Note: node-set comparison is an existencial comparison. It means that you are asking if there is some node (some td element in this case) with string value equal to 'Analyst'.
Of course, in HTML there are elements for which white space is not significant for rendering (it's not preserved) despite its presence in the source document. In that case you can use this simple XPath 1.0 expression:
//tr[td[normalize-space()='Analyst']]/#class
Do note: a node-set has a false boolean value if and only if it's empty; you can "nest" predicates (properly, a predicate can be any XPath expression).
I need to find the text Analyst and then find the associated tr class and select the tr class.
XPath 2.01
This XPath,
//tr[td/normalize-space() = "Analyst"]/#class
will select all #class attributes of tr elements containing a td with a space-normalized string value of "Analyst".
Do note, however, that in your sample HTML, such a tr has no #class.
1Thanks for correction, #DebanjanB
Fix your XML file to
<?xml version="1.0"?>
<!DOCTYPE stylesheet [
<!ENTITY nbsp " ">
]>
<root>
<tr class=" tableRow1" id="_pu5ufb" dr="1" _awtisprimaryrow="1">
<td width="1" class="tableBody w-tbl-cell" align="center">
<span class="selectColumnMarker">
<div class="w-chk-container">
<input bh="CHKINP" hasaction="false" class="w-chk-native" id="_m7iynb" value="1" type="checkbox" elementid="_jw4lmb" issender="false" awnomitcomponent="true" name="_jw4lmb"/>
<label bh="CHK" class="w-chk w-chk-dsize"/>
</div>
</span>
</td>
<td align="left" class="tableBody w-tbl-cell">
<span>
<table role="presentation" class="mls" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="" id="_tz87e" tabindex="0">
<a id="_3iqrbb" href="#" bh="HL" _sf="true">Analyst</a>
</td>
</tr>
</tbody>
</table>
</span>
</td>
<td class="tableBody w-tbl-cell">
</td>
<td class="tableBody w-tbl-cell">
</td>
</tr>
</root>
Then, the expression you are looking for is
//tr[td/a/text()='Analyst']/#class
But because the tr element does not have a class attribute, the result is empty.
A bit unclear what exactly you meant by ...find the associated tr class and select the tr class... once you have found ...the text Analyst....
However, as the elements are dynamic element and to locate the element with text as Analyst you can use either of the following Java based Locator Strategies:
linkText
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Analyst")));
cssSelector:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("td.tableBody table.mls a[bh='HL']")))
xpath:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//td[contains(#class, 'tableBody')]//table[#class='mls']//a[text()='Analyst']")));
To extract the class attribute of the <tr> element with respect to the text as Analyst you can use the following Java based solution:
xpath:
String tr_class_attrib = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[contains(#class, 'tableBody')]//table[#class='mls']//a[text()='Analyst']//preceding::tr[1]"))).getAttribute("class");

How to click on this javascript element using selenium webdriver

<table>
<tbody>
<tr>
<th colspan="9">
<span id="pageText">
<a style="cursor:pointer;" onclick="javascript:setData(2,true)"><</a>
<a style="cursor:pointer;" onclick="javascript:setData(2,false)">></a>
</span>
</th>
</tr>
</tbody>
</table>
I tried this, but it does not work:
((JavascriptExecutor)driver).executeScript("document.getElementById('>').click()");
i want to click on ">" link.
First of all there is no id >. For id attached to an element see what is contained in the id attribute of the element, what u provided is the innerHTML or TextContent of the element.
Secondly you can achieve it using webdriver functions also as:
driver.findElement(By.xpath("//span[#id='pageText']/a[contains(.,'>')]")).click();

How to search by first td text and clicking in seconds td href by JUnit, Webdriver?

<div class="row">
<div class="row">
<table>
<tbody>
<tr>
<td class="list-text">
<div style="background-color: transparent;">Testing this function</div>
</td>
<td class="list-buttons" rowspan="2">
Config
<a class="edit-button" href="javascript:;">Edit</a>
<a class="save-button" href="javascript:;" style="display:none;">Save</a>
Delete
</td>
</tr>
<tr>
</tbody>
</table>
</div>
I need to find the element which contains the text "Testing this function" and click to link "Config".
Can't find a way to do it.
Edited: Found a way to do it:
By.xpath("//div[#class='row']/table/tbody/tr[td/div[contains(.,'Testing')]]/td[2]/a[contains(.,'Config')]")
But maybe someone has a better solution for this?
If you have to use text, my preference would be;
By.xpath("//div[contains(text(),'Testing')]]//a[contains(text(),'Config')]") .
I prefer using "text()" to "." just for readability. Apologies if "." is actually a better approach which I wasn't aware of.
Also unless you have a specific reason, I would avoid using tightly coupled xpath. E.g. I have not used " td[2]", instead I have said the"a" can be anywhere within in the "div"

Selenium, Unable to find element by containing text following child node

A little bit of background:
The HTML looks like this:
<table>
<thead>
<tr>
<th>Head1</th>
<th>Head2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span>
<span class="icon">S</span>
"Auto"
</span>
</td>
<td>
<span>
Cost, Time
</span>
</td>
</tr>
</tbody>
</table>
A simple version of the code looks like this: (run in pry)
[69] pry> e = driver.find_element(:xpath, "//table/tbody/tr/td/span")
=> #<Selenium::WebDriver::Element:0x7ba9a4d694458ec id=":wdc:1361791490676">
[70] pry> e.text
=> "SAutomotive"
[71] pry> e = driver.find_element(:xpath, "//table/tbody/tr/td/span[contains(text(),'Auto')]")
Selenium::WebDriver::Error::NoSuchElementError: The element could not be found
from /Users/ben/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.29.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'
I have no access to changing the HTML code
Although there is only one row in this table there is the possibility of more being added and I cannot predict the location of the row, this is why i am trying to find it by name
my normal code is:
e = driver.find_element(:xpath, "//table/tbody/tr[td/span[contains(text(),'Auto')]]")
The problem I am having is that I cannot find any way of getting the row in the table by the name given in the text of the first table cell.
Use below xpath
"//table/tbody/tr/td/span[contains(.,'Auto')]"