How to retrieve the text from an outer element using selenium webdriver? - selenium

How to retrieve the text 'caught jake' from the below code using selenium webdriver?
Am able to point to that text using the below xpath but am unable to print the text. :(
//*[#id='full-scorecard']/div[2]/div/table[1]/tbody/tr[3]/td[2]/child::text()
<div class="row">
<div class="large 20 columns">
<table class="batting-table innings" width="100%">
<tbody>
<tr class="tr-heading">
<tr>
<tr class="dismissal-detail" style="display: table-row;">
<td width="2%" />
<td colspan="8">
<b>12.6</b> caught Jake
<b>73/4</b>
<br/>

Using java you can retrieve from following lines:
String text = driver.findElement(By.xpath("//div[#class='large 20 columns']")).getText();
System.Out.print("Text= "+text);
Above line will return all inner tags string's of div element.
If you want to get only 12.6 text, then use below lines:
String text = driver.findElement(By.xpath("//table[#class='batting-table innings']/tr/tr/tr/td[2]/b")).getText();
System.Out.print("Text= "+text);
And be sure that there should be single element which has this xpath 'By.xpath("//table[#class='batting-table innings']/tr/tr/tr/td[2]/b")', otherwise you will get an exception.

depend on your language, you can use following xpath expression:
//div[#class='large 20 columns']/table/tbody/tr/tr/td[2]/child::text()
full Java code:
JavascriptExecutor js = (JavascriptExecutor) driver;
String jsx = "return document.evaluate(\"//*[#id='full-scorecard']/div[2]/div/table[1]/tbody/tr[3]/td[2]/child::text()\", document, null, XPathResult.STRING_TYPE, null).stringValue;";
String objList = js.executeScript(jsx);
System.out.println( (String) objList);

Related

Trying to access Parent and then the sibling element in selenium. Throws no element exception

Element structure
//table[#class='table-table-condensed']//tbody//tr...
<td class="ng-binding">TEXT1</td>
<td class="ng-binding">2020-04-17 18:55:58.022</td>
<td>
<span class="label label-default">Not Started</span>
</td>
<td>
<div class="pull-right">
<button class="btn-success"/>
<button class="run"/>
<button class="review"/>
</div>
</td>
Trying to access the button element :
If Text Matches for this Element :
WebElement we = driver.findElement.By(xpath("//table[#class='table-table-condensed']//tbody//tr//td[#class='ng-binding'][1]");
String str = we.text();
if(str.equals("TEXT1"))
{
WebElement ex = we.findElement(By.xpath("./parent::following:://button[#class='run']"));
ex.click();
}
this throws no element found exception, Tried following::sibling too. Can we use both the tags at a time here. How to access the button element.
Also, will following:: tag does not work, if I had to access the below tags in structure:
<td class ="ng-binding">2020-04-17 18:55:58.022</td> ( Need to extract this element to sort the list by Latest date)
AND
<span class ="label label-default">Not Started</span>
Try below solution
wait = WebDriverWait(driver, 10)
elementText= wait.until(EC.element_to_be_clickable((By.XPATH, "//table[#class='table-table-condensed']//tbody//tr/following-sibling::td[contains(text(),'Test1')][contains(#id, "ng-binding")]")))
button=wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#class='run']")))
if(elementText.text=="Test1"):
button.click()
else:
print "Not found!"
Your ./parent::following:://button[#class='run'] is not valid XPath!
The correct form is: axis::node[predicate]. You are not allowed to chain multiple axis together, and you must specify a node! Note that a wilcard * node is still valid.
What you are probably looking for is ./following-sibling::td//button[#class='run'] or possibly ./following::button[#class='run'].
Other approach, you can try to solve this by using tr[contains(., 'TEXT VALUE')]:
String text = "TEXT1";
WebElement element1 = driver.findElement(By.xpath("//table[#class='table-table-condensed']//tr[contains(., '" +text +"')]//td[2]"));
WebElement element2 = driver.findElement(By.xpath("//table[#class='table-table-condensed']//tr[contains(., '" +text +"')]//span"));
WebElement element3 = driver.findElement(By.xpath("//table[#class='table-table-condensed']//tr[contains(., '" +text +"')]//button[#class='run']"));
System.out.println(element1.getText());
System.out.println(element2.getText());
element3.click();

Selenium IDE: How to assert attribute exists

I'm using Selenium IDE.
I know how to test if an element's attribute has a certain value. But how do I test if the attribute exists in the first place?
Here is the line which successfully tests if the attribute has a certain value:
<tr>
<td>assertAttribute</td>
<td>id=_ctl0_MainPlaceHolder_dgMemberList_DXSelBtn0#disabled</td>
<td>disabled</td>
</tr>
Here is the line which unsuccessfully tests if the attribute exists in the first place:
<tr>
<td>assertElementPresent</td>
<td>id=_ctl0_MainPlaceHolder_dgMemberList_DXSelBtn0#disabled</td>
<td></td>
</tr>
How do I get it to work?
Thank,
-Ilya
You can use the "getAttribute" method, and if it returns "null" it means that there is no attribute at all...
From Selenium documentation:
WebElement.getAttribute( attributeName ) → Thenable<(string|null)>
Schedules a command to query for the value of the given attribute of the element. Will return the current value, even if it has been modified after the page has been loaded. More exactly, this method will return the value of the given attribute, unless that attribute is not present, in which case the value of the property with the same name is returned. If neither value is set, null is returned (for example, the "value" property of a textarea element). The "style" attribute is converted as best can be to a text representation with a trailing semi-colon.
For example:
HTML code:
<div id="a" >1</div>
<div id="a" x="xxx" >2</div>
<div id="a" x >3</div>
Test code in Nodejs:
var webdriver = require('selenium-webdriver');
var capabilitiesObj = {
'browserName' : 'firefox'
};
var driver = new webdriver.Builder().withCapabilities(capabilitiesObj).build();
driver.get('http://localhost/customer.js/temp/index60.html');
driver.findElements(webdriver.By.css('div[id=a]')).then((elements) => {
elements[0].getAttribute('x').then((att)=> {
console.log(att);
});
}).catch(console.log.bind(console));
driver.quit();
The result for each div will be different:
for div 1: null
for div 2: 'xxx'
for div 3: ''
I don't think the simple id locator handles the attribute. So switch to xpath:
This should work:
<tr>
<td>verifyElementPresent</td>
<td>xpath=//.[#id='id3' and #attribute1]</td>
<td></td>
</tr>
Note that if you change the specific id (id1, id2, id3) it will pass for the first 2 ids but fail for the 3rd:
<div id="id1" attribute1="xyz" style="background-color: transparent;">Some text</div>
<div id="id2" attribute1="" style="background-color: transparent;">Some text</div>
<div id="id3" style="background-color: transparent;">Some text</div>

Selenium java to find the right element

I want to find the the element for the Edit:
my java code is not working.
String xpathLocater = "//a[contains(text(),'onEditFilter('modifier')')]";
return driver.findElement(By.xpath(xpathLocater));
This is the source code for the element.
<tr class="listeven">
<td>
<a onclick="return onEditFilter('modifier');" href="#">Edit</a>
</td>
</tr>
something like
String xpathLocater = "//a[contains(#onclick,\"onEditFilter('modifier')\")]"

Unable to find number of rows in table using Xpath

When i am trying to find number of tr(class-tr-heading) in the 1st table,i am getting 2 tr as a result if i use Xpath(working fine with CSS Selector-returns 1 tr)
<div class="large 20 columns">
<table class="Red"><tbody>
<tr class="tr-heading"></tr>
<tr></tr>
</tbody></table>
<table class="Red"><tbody>
<tr class="tr-heading"></tr>
<tr></tr>
</tbody></table>
</div>
Below one return two tr,
WebElement tbl=dr.findElement(By.xpath("//div[#class='large 20 columns']/table[1]/tbody"));
List<WebElement> trs=tbl.findElements(By.xpath("//tr[#class='tr-heading']"));
System.out.println(trs.size());
This below code returns single tr,
WebElement tbl=dr.findElement(By.xpath("//div[#class='large 20 columns']/table[1]/tbody"));
List<WebElement> trs1=tbl.findElements(By.cssSelector("tr[class='tr-heading']"));
System.out.println(trs1.size());
It seems Xpath is taking the whole div and returns two tr.Can you please tell me why this difference is and how do i have to do using xpath.
Use dot(.)as it Selects the current node
WebElement tbl=dr.findElement(By.xpath("//div[#class='large 20 columns']/table[1]/tbody"));
List<WebElement> trs=tbl.findElements(By.xpath(".//tr[#class='tr-heading']"));
System.out.println(trs.size());
//Now it will print out 1 as in the current node there is only one tr tagwith the specified class name

Selenium webdriver-java: how to get javascript tooltip

I want to get tooltip information enabling on JavaScript. I have tried with below code but its shown null every time.
Java Code:
Actions action = new Actions(driver);
WebElement element = driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"));
action.moveToElement(element).build().perform();
System.out.println(driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a")).getAttribute("data-original-title"));
HTML Code is:
<tr class="single" name="Tasks_59c777d9-8d16-694a-7307-52caad36d751">
<td>
</td>
<td data-type="custom_task_name">
<span class="list" sfuuid="3840" data-original-title="">
<div class="ellipsis_inline" data-original-title="">
Task Testing
<br/>
Toney Harber
</div>
</span>
</td>
I have tried with span tag but this also shows null.
I am providing you 2 options try both.
Option 1
Please try below. It will return you a list. Loop through it. If there is only one span then you can get the element and then get the attribute value.
driver.findElements(By.xpath("//span[#data-original-title]"))
Option 2
Instead of
driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"))
use findElements
driver.findElements(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"))
It will return a list of web elements. Loop thorough it you might get more than one element.