how to get value of 'value' attribute of a disabled input - java

I am trying to get the value 'Accept' using webdriver. But I always get blank. I tried all By options such as id, name, xpath etc.
<input type="submit" value="Accept" id="nid" name="n" class="c" disabled="disabled">
Webdriver
WebElement aButton = driver.findElement(By.xpath("//*[#name='n']"));
System.out.println(aButton.getText()); #=> blank
System.out.println(aButton.getAttribute("value")); #=> blank

Selenium docs clearly saying about gettext() is:
Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace
So you could not directly use it but you could try the executeScript method of WebDriver, Write some js script that fetch the hidden element value and execute that script using this method. It could help.

Related

How to upload file through an 'input' element with type="hidden" using Selenium and Java?

I want to use Java Selenium to upload the file in the following input element(upload element).
<input type="hidden" ng-model="model[options.key || index]"
id="formly_21_fileupload_args_content_substrate_surface_media_documentURL_0"
name="formly_21_fileupload_args_content_substrate_surface_media_documentURL_0"
formly-custom-validation="options.validators"
class="ng-pristine ng-untouched ng-invalid ng-invalid-wizard-validation">
I have tried to use 'sendKeys' but got the error informatoion:
upload.sendKeys("filePath"); // element is invisible
then I tried to use JavascriptExecutor in the script to change the visibility of the Element (type="file"), but still got the same error: element is invisible:
JavascriptExecutor jsexec = (JavascriptExecutor) driver;
jsexec.executeScript("arguments[0].type='file'", upload);
I also tried to use the parent element 'div' to do the upload, but got the error "cannot focus the element".
is there anyone can help me to solve this problem?
As per your question and the HTML you have shared the <input> tag is having the attribute type="hidden". To invoke sendKeys() on the <input> tag you can use the following solution:
WebElement uploadElement = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[#class='ng-pristine ng-untouched ng-invalid ng-invalid-wizard-validation'][contains(#name,'_fileupload_args_content_substrate_surface_media_documentURL_')]")));
String jse = "arguments[0].type='file'";
((JavascriptExecutor)driver).executeScript(jse, uploadElement);
uploadElement.sendKeys("absolute_path_of_the_file_to_be_uploaded");
What I'm guessing your issue to essentially be, is that there is probably a wrapper object to beautiful the default input element. It is common for web developers to 'hide' this default input element and as such, Selenium will fail to click on this object because its display attribute is set to 'none'.
We may need to look at the other HTML tags within that DOM hierarchy, but I suspect there is probably another input tag nested 1 or 2 levels below, that looks something like this. It should at least have a display attribute set to none:
<input display: none;> </input>
To upload a file, you will need to sendKeys directly to this element instead. But first, you will need to make it visible:
//the 'upload' variable here refers to the input element with display: none;
JavascriptExecutor jsexec = (JavascriptExecutor) driver;
//First, change the display to inline to expose the underlying input element
jsexec.executeScript("arguments[0].display='inline;', upload);
After the above code is executed you should see a raw input element appearing. This is the element you would want to sendKeys to:
//After that you can go ahead to upload the file:
upload.sendKeys("path of the file");
In all honesty, without seeing the entire DOM, I am not able to advise whether the below line is necessary. You will need to try and see for yourself:
jsexec.executeScript("arguments[0].type='file'", upload);
If no such nested input element exists, just try the code above with the current input element you found.

Unable to replace value in a table column

Unable to send values in the table column. I got different errors while I am trying to insert a value in the column using Selenium.
I tried to set a new value in the table's column. It shows the error as The element must be user-editable in order to clear it.
WebElement.clear();
WebElement.sendKeys("value");
(or)
WebElement.sendKeys(Keys.DELETE);
WebElement.sendKeys("value");
Then to click and edit the value.
Actions actions = new Actions(getWebDriverEx());
WebElement TableColumn = Driver.findElement(By.id("element"));
actions.moveToElement(TableColumn);
actions.click().build().perform();
actions.sendKeys(Keys.BACK_SPACE+b+b);
actions.sendKeys("value");
The value which was passed is not inserted in the Tables column. But I can able to click the Tables column. Here my test passed.
Then tried to set value. It shows the error as timed out.
WebElement.sendKeys(Keys.DELETE);
WebElement.sendKeys("15000");
Again I used the div/span combination as XPath and I have edited the value. But it does not reflect in the table.
JavascriptExecutor js = (JavascriptExecutor) getDriver();
js.executeScript("document.getElementById('element').innerHTML="+15000);
Here I do not get any errors. But the value not reflected after save.
I gave element to various formats.
div//[id]
div//span
XPath
id alone (which was in the div)
HTML:
<div id="element" class="tables_second_column">
<div class="class_name">
<div class="class_name">
<div class="class_name"><span>5000</span></div>
</div>
</div>
</div>
Try on the following and it's working for me:
js = "document.querySelector('#element .class_name .class_name .class_name>span').innerHTML = '15000';"
driver.execute_script(js)
Hope it helps you!
This should be sufficient
WebElement textBox = driver.findElement(By.xpath("//span[text()='5000']"));
textBox.clear();
textBox.sendKeys("");
textBox.sendKeys("15000");
I do send a empty space in order to get the textbox active as sometime the DOM might not reflect immediately as this element is quiet nested.
As per the HTML you shared, the table column is within a <span> which is inside several <div> tags. Hence we need to construct an unique xpath to identify the WebElement and first send clear() method then use sendKeys() method as follows :
driver.findElement(By.xpath("//div[#id='element']/div[#class='class_name']/div[#class='class_name']/div[#class='class_name']/span[text()='5000']")).clear();
driver.findElement(By.xpath("//div[#id='element']/div[#class='class_name']/div[#class='class_name']/div[#class='class_name']/span[text()='5000']")).sendKeys("15000");
Update
As you mentioned Text which was passed in the span is not predictable so we would simply omit the clause [text()='5000']. As you have provided a sample HTML with sample classnames I have constructed a nearly absolute xpath. So our code will be :
driver.findElement(By.xpath("//div[#id='element']/div[#class='class_name']/div[#class='class_name']/div[#class='class_name']/span")).clear();
driver.findElement(By.xpath("//div[#id='element']/div[#class='class_name']/div[#class='class_name']/div[#class='class_name']/span")).sendKeys("15000");
Thanks for your reply
It works for me with the below method
webElement.sendKeysByAction(value)

GetText() clarification - xpath not returning the value

Html:
<strong class="text-xl ng-binding" ng-bind="summary.PublishedIssuedRecent">5</strong>
my xpath:
#FindBy(how = How.XPATH, using = "//strong[#ng-bind='summary.PublishedIssuedRecent']")
public WebElement countRecentlyPublishedApplication;
String pubCount = countRecentlyPublishedApplication.getText();
my Expectation
i want to extract the value of 5
but i'm getting empty value in the pubCount String, Please suggest if any mistake in my xpath
From attribute ng-bind I'm guessing you're trying to scrap angularJS application and you're using selenium web driver.
Problem with angular is, it is rendered by javascript after the page loads. So on beginning element you want to scrap might not be there. Solution might be to wait a second until angulars finishes rendering and then try to find element.
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
WebElement pubCount = driver.findElement(By.xpath( "//strong[#ng-bind='summary.PublishedIssuedRecent']")).getText();
The XPath expression in itself is correct, it selects your node as expected. A simple test with xmllint gives:
> xmllint --xpath "//strong[#ng-bind='summary.PublishedIssuedRecent']" ~/test.html
<strong class="text-xl ng-binding" ng-bind="summary.PublishedIssuedRecent">5</strong>
So the error is outside your XPath expression.
By the way, if you just need the text of the node, you can use
> xmllint --xpath "//strong[#ng-bind='summary.PublishedIssuedRecent']/text()" ~/test.html
5

clear() function does not erase the default value of input web element

I am a very beginner to use Java and Selenium to write a test.
I have this web element:
<input type="number" name="yield_target"
placeholder="Yield Target" value="0.00" min="0" step="any">
But I can not clear it by:
WebElement we = wait.until(ExpectedConditions.visibilityOfElementLocated
(By.xpath("//input[#placeholder='Yield Target']")));
we.clear();
But I can write into it, for example if I use:
action.sendKeys(we, "223").build().perform();
it will be 0.00223 instead of 223.
I'm not sure why we.clear() isn't working but you can clear and set in a single call (assuming that JavaScript on the page does not prevent you from using CTRL+A to select all of the contents of the number input field):
we.sendKeys(Keys.chord(Keys.CONTROL, "a"), "223");

How to find input field is readonly or not in using selenium webdriver with java

I am using selenium webdriver with java to write the script. However, we have few fields which are getting disabled after click on button. We need to find this field are getting readonly mode or not. I have use isEnabled and isDisplayed but it is not working, the system displays NoSuchElementFound expection. Is there any way to handle this?
You can achieve this without having to execute JS, all you need to do is to get the DOM Attribute of the element which is "ReadOnly" this can be achieved using:
WebElement readOnly = driver.findElementBy(locator);
Assert.assertTrue(readOnly.getAttribute("readOnly").equals("true"),"Element ReadOnly")
Hope this helps....
You can do the following steps.
1. Use the WebDriverWait wait statement to make sure that the element is indeed present before you are doing the check.
2. Go through the HTML script and check what attribute is causing the HTML element to be read only. In the application that I use the attribute is'disabled'. When the value of the attribute 'disabled' was TRUE the element was disabled. For you it might be a different attribute. Then fetch the value of this attribute and you will find out if the element is enabled or disabled.
System.out.println(driver.findElement(By.xpath(txt_Username)).getAttribute("disabled"));
Using javascript, you can get this attribute value like -
var isReadOnly = document.getElementById("field").readOnly;
alert(isReadOnly); //displays true OR false
Please check browser compatibility for this attribute. :-)
<div class="col-sm-8 col-md-9 currency">
<input id="test" type="<some type>" value="777.00" class="read-only" readonly="true">
<input id="some_input_id_here" type="text" value="<some string value here>" name="<some name here>" class="read-only" readonly="true">
</div>
Lets use the above as example, which i have a form and i'm checking the elements using Chrome's DevTools (or any other preferred tool). Say i've got the css selector for the disabled fields that contains '777.00' in value and the element type 'css selector' is: #sampleForm > fieldset > div:nth-child(1) > div.col-sm-5.col-md-6 > input
Then my code to check on this element being read-only is:
//i have stored my elements somehwere on a file as String
String disElement = "#sampleForm > fieldset > div:nth-child(1) > div.col-sm-5.col-md-6 > input"
assertTrue(WebDriver.findElement(By.cssSelector(disElement)).getAttribute("class").equalsIgnoreCase("read-only"));
Note that i'm accessing the element's class layer and verify that it is "read-only" using TestNG assertTrue after getting the element's attribute of "class". The asserTrue boolean will return false if the element is not read only. Also check the layers of element you're accessing whether or not it is the parent, child, span, etc. Hope this can be of any help as well. thanks.
This code is working with my application:
public boolean runScript(String str){
String script ="if($("+'"'+"#City"+'"'+").attr("+'"'+str+'"'+")){return true}else{return false}";
System.out.println(script);
JavascriptExecutor js = (JavascriptExecutor) driver;
return (Boolean) js.executeScript(script);
}
int k=0;
do{
if(!runScript("HouseNo")){
System.out.println("Field is in readonly mode");
break;
}
Thread.sleep(1000);
}while(k<60);

Categories