Unable to replace value in a table column - java

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)

Related

How to check href of an element found using xpath contains text()

I'm trying to find an element by the text it contains, then check that that element also has a link to a particular place. I'm using selenium/java.
I'm trying to find elements by text when I can to minimise how many changes I will need to make if the UI is updated (reduce test maintenance costs).
I've tried the following, but the assert fails as the getAttribute ends up being null.
WebElement newsHeadlineTemplate = driver.findElement(By.xpath("//*[contains(text(), 'News Headline')]"));
Assert.assertEquals("Template not clickable", "/news/create/new", newsHeadlineTemplate.getAttribute("href"));
HTML for element I'm trying to find/use:
<div class="columns">
<div class="column is-one-third">
<p>News Headline</p>
</div>
</div>
I'm still fairly new to selenium so any help is very much appreciated.
Your XPath selector is a little bit wrong, you're matching <p> tag and you need to match the <a> tag which is the following-sibling for the <p> tag.
So you need to amend your expression to look like:
//p[text()='News Headline']/following-sibling::a
More information:
XPath Tutorial
XPath Axes
XPath Operators & Functions

How can I get the inner text of an element in Selenium?

I'm working with a DOM node:
<input
type="form-control"
type="text"
data-bind="textInput: EnterpriseId"
disabled
autocomplete="off">
How can I get its value? I'm struggling since element.getText() does not work and returns a blank.
Try this:
WebElement element = driver.findElement(By.id("id value"));
String val = element.getAttribute("innerText")
I presume the element in question is an <input> element, so you may be able to use the element.getAttribute(String attribute) method like so:
String value = element.getAttribute("value");
This input tag is disabled, hence element.getText() returns a blank value.
Use element.getAttribute("textContent") instead.
You may be looking for the placeholder of an input text, because you might try:
element.getAttribute("placeholder");
You can go to your browser → open developer tools → inspect element you want to take attribute from → click Properties → check if that value is in InnerText.
Then do as it is mentioned in previous comments:
element_locator.get_attribute('InnerText')
I had the exact same issue! This post solved it for me:
How can I get the current contents of an element in webdriver
I used:
element = driver.find_elements_by_xpath(
'//button[#class="size-grid-dropdown size-grid-button"]')
element.text
As other's suggested, HTML's input nodes don't have a text attribute because they can store data in multiple formats in a value attribute.
This can be easily seen in the HTML input API specification where this form control can be of type radio, date, file upload and many more.
So, in your specific case, I'd suggest you check the webdriver's API for a method that's able to retrieve the value attribute.
As a bonus to evaluate innerText of an element within Selenium:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("yourEl")));
wait.until(ExpectedConditions.attributeToBe(By.id("yourEl"), "innerText", yourValue));
Documentation: attributeToBe
It works definitely, as I've tested it several times:
<input type="form-control" type="text" data-bind="textInput: EnterpriseId" disabled autocomplete="off">
In your example, you don’t have any innerText. So you can only get attributes as mentioned before with the existing attributes. In your case:
type, data-bind, EnterpriseId and autocomplete. No value will be as this attribute isn’t created.
If you want to get only existing, this should be fine:
String example = driver.findElement(ByLocator(("")).getAttribute("any attribute of your input");
System.out.println(example);

Selenium sees textbox as hidden even if I can see it in the browser

I have a password textbox that is something like this
<input class="blahblah" id="someId" type="password"></input>
I am able to see this textbox in the browser and am able to manually insert password.
However when I test this ui using selenium, although it finds the element correctly, but when it tries to click the element, it throws an error
"org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with"
I did a check in code using
Boolean isDisplayed=el.isDisplayed();//false
Boolean isEnabled=el.isEnabled();//true
The isDisplayed came up false and isEnabled came up true. There is a 15 second delay added to give the page enough time to load (the page loads instantly). So adding a delay will not fix the problem.
I verified using firefox developer tools that the id it was finding was of the correct element.
Why does selenium think its invisible even if I am able to see it in the browser? Could it be that one of the parent elements has some style attribute that selenium doesn't like? Or is it a bug in the selenium driver?
I am using selenium driver for java version 2.45.0
The problem is that the desired input is really invisible due to the display: none being set on it's parent table:
<table title="Type a password."
class="dxeTextBoxSys dxeTextBox_MyCompany "
id="ctl00_ctl00_MasterContent_MainContentPlaceHolder_ViewCredentials_TopicPanel1_credentialGrid_editnew_4_txtPassword_P_PB"
style="width: 100%; border-collapse: collapse; display: none;"
border="0" cellpadding="0" cellspacing="0">
Most likely, the table is becoming visible on a particular user action that you need to determine.
But, alternatively, you can make the table visible through javascript:
WebElement table = driver.findElement(By.id("ctl00_ctl00_MasterContent_MainContentPlaceHolder_ViewCredentials_TopicPanel1_credentialGrid_editnew_4_txtPassword_P_PB"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].style.display = 'block';", table);
In case the above doesn't make any difference.
There is an another hidden password input that can be important:
<input value=""
name="ctl00$ctl00$MasterContent$MainContentPlaceHolder$ViewCredentials$TopicPanel1$credentialGrid$editnew_4$txtPassword$P$PB$CVS"
type="hidden">
You can try making it visible and sending keys to it:
WebElement password = driver.findElement(By.name("ctl00$ctl00$MasterContent$MainContentPlaceHolder$ViewCredentials$TopicPanel1$credentialGrid$editnew_4$txtPassword$P$PB$CVS"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].setAttribute('type', 'text');", password);
password.sendKeys("MyPassword");
In case the above doesn't work.
You can set the input value through javascript:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.getElementById('ctl00_ctl00_MasterContent_MainContentPlaceHolder_ViewCredentials_TopicPanel1_credentialGrid_editnew_4_txtPassword_P_PB_I').setAttribute('value', 'MyPassword');");
Possibly, Selenium is going too fast through your DOM. Has happened with me several times and your element hasn't fully loaded into DOM.
I am more familiar with the PHP/PHPUnit libraries available for Selenium, but perhaps you can introduce a temporary wait with a command similar to waitForElementPresent.
Also, if you have control of the code, can you give a 'name' attribute to your input field as well? It could not hurt anything to do so.
Have a look at the DOM elements and verify that there is no parent element with a display: none etc, when i encountered an issue like this that was the problem.
Are you able to get information from the element by XPath? This was my work around.
I have faced this kind of issue many times. the first thing comes into my mind is probably the selector you are using is not unique or not returning THE element you are looking for. Since,
Boolean isDisplayed=el.isDisplayed();//false
Boolean isEnabled=el.isEnabled();//true
does not return NoSuchElement exception I do not think it's a element load issue. A quick check can tell you what's going on
driver.findElements(By.cssSelector("the css")).size(); and see how many count it returns.

How to count HTML child tag in Selenium WebDriver using Java

In Selenium JAVA WebDriver - How can I count child tags?
Example:
<div class="subcategory_container">
<div class="products_container">
<div class="product_row">
<form class="product_container">
<form class="product_container">
<form class="product_container">
</div>
</div>
</div>
I want to count how many form tag are there under product_row div?
Thanks
You find the parent div first, then locate all target elements, then count them.
List<WebElement> forms = driver.findElements(By.cssSelector(".product_row form"));
int count = forms.size();
Here are two solutions:
You could either select by xpath
driver.findElements(By.xpath("//div[#class='product_row']/form"))
or you could select by CSS query as mentioned by user1177636
driver.findElements(By.cssSelector(".product_row>form"))
You can find the size of elements by using the following statement:
System.out.println(driver.findElements(By.xpath("//div[#class='product_row']/form")).size());
Where .findElements method returns count value that all elements in that a page consists with xpath //div[#class='product_row']/form
In your case it will return "3" as result
Every element has an attribute called childElementCount.
You can use WebElement.getAttribute() function to get an immediate value.
WebElement element = driver.findElement(By.className("product_row"));
int numberOfChilds = Integer.parseInt(element.getAttribute("childElementCount"));
Because getAttribute() returns a String, we have to cast it to an int.
In general, I would use some way to find all of the elements that I want, either using xpath or css selectors, and then just count how many results are returned.

Select by "name" in JSoup

I have multiple div's in a webpage URL that I have to parse which have the same class name but different names with no id's.
for eg.
<div class="answer" style="display: block;" name="yyy" oldblock="block" jQuery1317140119108="11">
and
<div class="answer" style="display: block;" name="xxx" oldblock="block" jQuery1317140119108="11">
I want to select data and parse from only one of the div's say namely (name="yyy") (the content inside the div's are <href> links which differ for each class.
I've looked up the selector syntax in the Jsoup webpage but can't get a way to work around it. Can you please help me with this or let me know if I'm missing something?
Use the [attributename=attributevalue] selector.
Elements xxxDivs = document.select("div.answer[name=xxx]");
// ...
Elements yyyDivs = document.select("div.answer[name=yyy]");
// ...

Categories