code is used is:
WebElement desc=driver.findElementByXPath(".//*[#label='Description']");
desc.sendKeys("testing");
desc.sendKeys(Keys.ENTER);
List<WebElement> button=driver.findElementsByXPath("(//div[#id='sv'])[1]");
for (WebElement buttonname : button)
{
System.out.println("buttonname: "+buttonname.getAttribute("id"));
String but = buttonname.getAttribute("id");
driver.findElementById(but).click();
}
Below is the html code of that textarea and button .
<td>
<textarea id="1992800000" label="Description" ft="12" mand="false"class="ic" maxlength="120" cols="13" rows="2"/>
</td>
......
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 40px; ">
<td class="pdl">
<div class="tbut" onclick="ir('Tas','tas','')" id="sv">Save</div>
</td>
Your XPath can only select one element, so there is no need to create a list and iterate through it.
Try something more like:
WebElement desc=driver.findElementByXPath("//*[#label='Description']");
desc.sendKeys("testing");
WebElement button=driver.findElementsByXPath("(//div[#id='sv'])[1]");
button.click();
Related
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");
I have a dropdown on a web page for selecting a country which has been rendered using the jQuery Chosen plugin. An extract of the html below,
<div>
<label for="phMainContent_EmployeeAdd1_ddlCountry" id="phMainContent_EmployeeAdd1_lblCountry" class="short required">Country*</label>:
<div id="phMainContent_EmployeeAdd1_ddlCountry_chzn" class="chzn-container undefined chzn-container-single" style="width: 199.44444px;">
<span>Please select ...</span><div><b></b></div>
<div class="chzn-drop" style="left: -9000px; width: 197.222px; top: 28px;">
<div class="chzn-search"><input type="text" style="width: 162px;"></div>
<ul class="chzn-results">
<li id="phMainContent_EmployeeAdd1_ddlCountry_chzn_o_0" class="active-result result-selected">Please select ...</li>
<li id="phMainContent_EmployeeAdd1_ddlCountry_chzn_o_1" class="active-result">United Kingdom</li>
<li id="phMainContent_EmployeeAdd1_ddlCountry_chzn_o_2" class="active-result">Afghanistan</li>
.......
If I use the Selenium IDE to record the actions to select the “United Kingdom” from the list the following script is recorded. Run snippet to see table with the commands in it.
<table border="1">
<tr>
<td>Command</td>
<td>Target</td>
</tr>
<tr>
<td>click</td>
<td>css=a.chzn-single > span</td>
</tr>
<tr>
<td>click</td>
<td>id=phMainContent_EmployeeAdd1_ddlCountry_chzn_o_1</td>
</tr>
</table>
I can run this script repeatably in the IDE and the UK is selected from the dropdown each time. However, if I export the C#/Nunit/Webdriver code below
driver.FindElement(By.CssSelector("a.chzn-single > span")).Click();
driver.FindElement(By.Id("phMainContent_EmployeeAdd1_ddlCountry_chzn_o_1")).Click();
and execute it, it fails on the 1st statement with the Selenium Element Not Visible exception.
Any advice on how to resolve this issue?
you can try xPath and select like //span[contains(.,'Please Select')]
Use explicit wait to make sure the dropdown is visible before the click
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement dropdown = wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("a.chzn-single > span")));
dropdown.Click();
driver.FindElement(By.Id("phMainContent_EmployeeAdd1_ddlCountry_chzn_o_1")).Click();
I am able to traverse through the menu items, but the final element is not clicked by WebDriver.
My code snippet:
WebElement hover0 = driver.findElement(By.id("td_Menu_0"));
WebElement hover = driver.findElement(By.xpath(".//*[#id='role6_Maintain']/table/tbody/tr/td[1]"));
action.moveToElement(hover0).moveToElement(hover);
action.moveToElement(driver.findElement(By.cssSelector("#menuClickable_0_6_0_0")))
.click().build().perform();
The final WebElement HTML:
<td onkeydown="return menuClickableOperation(this,event);"
onclick="javascript:deleteGrpWindowNode('menu_Maintain',0,'br_w_BusissPartner','BRGUI','Business Partner','','','HJHF');"
onmouseout="menuDeSelect(this);" onmouseover="menuSelect(this)"
onmousemove="DisplayIFrame();" tabindex="11" id="menuClickable_0_6_0_0"
class="menuNormal2">
<table width="100%">
<tbody>
<tr>
<td width="100%" style="">
<p title="Business Partner" class="MenuTxt">Business Partner</p>
</td>
</tr>
</tbody>
</table>
</td>
Try this code instead:
action.moveToElement(hover0).build().perform();
action.moveToElement(hover).build().perform();
new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#menuClickable_0_6_0_0")));//Waiting for 20 seconds for the final element to be visible.
action.moveToElement(driver.findElement(By.xpath("//td[#id='menuClickable_0_6_0_0']//p[.='Business Partner']"))).click().build().perform();
As you are already hovering on hover0 and hover, i am hoping the third object is available.
So why cant you perform direct click on the third object like
driver.findElement(By.xpath("//td[#id='menuClickable_0_6_0_0']//p[.='Business Partner']").click
The other way around your way is like
action.click(yourElement).build().perform()
<div class="row-fluid">
<table class="s-table table table-bordered table-striped table-hover">
<thead class="p-table-head">
<tbody class="p-table-body">
<tr>
<td>
<td>
<div id="div_2_1_2_1_2_r1" class="String CoachView CoachView_show" data-eventid="" data-viewid="Table_Column1" data-config="config_div_2_1_2_1_2_r1" data-bindingtype="String" data-binding="local.customerContacts[index].name" data-type="com.ibm.bpm.coach.Snapshot_a30ea40f_cb24_4729_a02e_25dc8e12dcab.String" data-bindingrt="local.customerContacts[0].name">
</td>
<td>
<td>
<td>
<td>
<td>
</tr>
How to identify td data exist inside div element and click on that?
These td elements will generate dynamically, we need find that it consists of contact details like name & phone number..
You can also do this. In the below example you can use ./td. This example search for a td which contains a value all. If it finds it, then click on the anchor inside the td.Might be useful for you.
List<WebElement> elements = driver.findElements(By.xpath("//table/thead/tr"));
for (Iterator<WebElement> iterator = elements.iterator(); iterator.hasNext();) {
WebElement webElement = iterator.next();
List<WebElement> findElement = webElement.findElements(By.xpath("./td"));
if( findElement.size() > 0 ){
if( findElement.get(0).getText() != null && findElement.get(0).getText().indexOf("all") != -1 ) {
List<WebElement> aElement = webElement.findElements(By.xpath("./td/a"));
aElement.get(0).click();
break;
}
}
}
Use id.
<td id="findme"> </td>
Also, it's true for any other tags. And don't forget closing opened TDs.
I have an element, which is kendo numeric textbox. It has values as well, I can get the value by using this code snippet driver.findElement(By.xpath("xpathlocator_value")).getAttribute("value"); but i want to clear the value and i want to update this element with another value. I tried
both the ways like using clear() and alsosendkeys(keys.control +"a",keys.delete)
but its not working.
The html code is
<form id="cashbookForm" class="form">
<div class="widget">
<table class="sTable taskWidget" width="100%" cellspacing="0" cellpadding="0">
<thead>
<tbody>
<tr data-bind="css:ExpenseID()==0?'non-printable':'',click:$root.CloseEditable">
<tr data-bind="css:ExpenseID()==0?'non-printable':''">
<td data-bind="text:Order">2</td>
<td>
<td>
<td>
<td>
<td>
<div style="float: right;">
<span class="k-widget k-numerictextbox noform required" style="text-align: right;">
<span class="k-numeric-wrap k-state-default">
<input class="k-formatted-value noform required k-input" type="text" style="text-align: right; display: inline;" tabindex="0" readonly="readonly">
<input class="noform required k-input" type="text" data-bind="kendoNumericTextBox: { value: Ca_TotalAmount, min: 0,format: '#.00'},uniqueName:true" style="text-align: right; display: none;" data-role="numerictextbox" role="spinbutton" tabindex="0" aria-valuemin="0" aria-valuenow="251.44" name="ko_unique_4">
<span class="k-select">
</span>
</span>
</div>
</td>
<td> </td>
<td class="removeOnPrint">
</tr>
<tr class="removeOnPrint">
Here the numeric textbox present at
<input class="k-formatted-value noform required k-input" type="text" style="text-align: right; display: inline;" tabindex="0" readonly="readonly">
You can use JavascriptExecutor to achieve the goal.
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("window.document.getElementById("elementID").setAttribute('value', ' ')");
or
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("window.document.getElementById("elementID").value = ' '");
If you want to use xPath:
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.evaluate('xpath_locator', document, null, 9, null).singleNodeValue.value = ' '");
This is a pretty old question, but I'm posting the answer here in case someone finds it useful. If you're using selenium and you want to remove attribute and not clear it, then here's what works:
public static void javascriptRemoveAttribute(WebElement element, WebDriver driver) {
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].removeAttribute('required');", element);
}
It is similar to the first answer but they key is removeAttribute. ExecuteScript basically expects an array of elements. So you pass the element when needs to be modified and then remove its attribute.
Using this function you can change the value of the element:
public void clearElementValueByJS(WebElement element, WebDriver driver, Stringvalue) {
try {
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("arguments[0].value='" + value + "'", element);
} catch (Exception e) {
e.printStackTrace();
}
}
OR you can change the inner html value of the element:
public void setInnerHTMLValue(WebElement element, String value) {
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("return arguments[0].innerText ='" + value + "'", element);
}