Unable to use send keys for disabled Element in selenium - java

The input field for which I am trying to write the code in selenium:
input class="tt-hint" type="text" disabled="" spellcheck="off" autocomplete="off" style="position: absolute; top: 0px; left: 0px; border-color: transparent; box-shadow: none; background: none repeat scroll 0% 0% rgb(255, 255, 255);"
My code is:
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys(new String[] { "mo" });
But the above code does not work. The error I keep getting is:
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: Element is disabled and so may not be used for actions
Any help is appreciated.
I have modified my code to
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("mo");
I get the output as

The exception says it all. The element is not ready to accept any interaction and DISABLED. JavaScript is only option here. I would remove the disabled attribute and then use sendKeys()
String script = "document.getElementsByClassName('tt-hint')[1].removeAttribute('disabled')";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys("Whatever");

Javascript is the only option as said by #Saifur.However you do like this also
Either remove the disabled attribute or go with javascript to set the value itself
WebElement inp = driver.findElement(By.className("tt-hint"));
//Option 1 remove the disabled attribute
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("val");
//Option 2 go for javascript set value
js.executeScript("arguments[0].value=arguments[1]",inp,"val");

The below is the code for Selenium C#, for a hidden Textbox/TextArea
IWebElement element;
IJavaScriptExecutor js = (IJavaScriptExecutor)Driver;
js.ExecuteScript("arguments[0].value=arguments[1]", element, inputValueYouWantToPlace);
Some controls won't recognize the given text and gives error like 'please provide input value'- in this case Enable the element just before sending the value using SendKeys()
`
js.ExecuteScript("arguments[0].removeAttribute('disabled')", input);
js.ExecuteScript("arguments[0].click()", element);
element.SendKeys(inputValueYouWantToPlace);
`

Related

How to find element by xpath that has same class, name etc

There are two buttons with same class, text etc. I have to find and click each.
<a class="jsx-1291462554"><button style="padding: 12px 15px 10px; border-radius: 4px; font: 500 15px / 16px hind; color: white; background-color: rgb(18, 83, 181); justify-content: center; text-align: center; cursor: pointer; text-decoration: none; outline: none; border: none; width: 162px;"><span class="jsx-1291462554 magzter__buttonText">Choose</span></button></a>
//section[contains(#class,'chooseplanTitle')]//button[1]
//section[contains(#class,'chooseplanTitle')]//button[2]
to enable the automatic clicking of a button, we use the XPath function, which is in the class By.
1.Version
driver.FindElement(By.XPath("//button[#class ='CLASS NAME']")).Click();
2.Version
driver.FindElement(By.XPath("//div[normalize-space(.)='NAME']/button")).Click();
To enable an automatic input into the text field we can also use the function CssSelector which is located in the class By.
IWebElement usernameInput = driver.FindElement(By.CssSelector("input[name='username']"));
IWebElement passwordInput = driver.FindElement(By.CssSelector("input[name='password']"));
usernameInput.SendKeys("YourUsername");
passwordInput.SendKeys("YourPassword");
find first and second element that matches the below locator :
(//a[#class="jsx-1291462554"]/button)[1]
(//a[#class="jsx-1291462554"]/button)[2]
find all elements with tag button and is a first child of 'a' with class specified:
//a[#class="jsx-1291462554"]/button[1]
css equalent of first xpath :
a.jsx-1291462554>button:nth-of-type(1)
a.jsx-1291462554>button:nth-of-type(2)
css equalent of second xpath :
a.jsx-1291462554>button:nth-child(1)
Both the elements are a dynamic elements. So to click() on the first Choose you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
xpath:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//p[starts-with(., 'Choose the plan that')]//following::a[1]/button/span[text()='Choose']")));
If is possible, put something to differentiate the buttons's mapping. But if it isn't possible, these mappings will solve
(//section[contains(#class, 'twocol')]/a)[1]
(//section[contains(#class, 'twocol')]/a)[2]
List<WebElement> links = driver.findElements(By.xpath("//a[#class='jsx-1291462554']"));
links.get(0).click();
//Wait here for some action to happen
links.get(1).click();
The xpath varies depending on what you actually want to click, if the button element replace with:
//a[#class='jsx-1291462554']/button
If the button's click action changes the DOM you might encounter a StaleElementReference, in which case you may need to refetch (findElements) again before selecting the 2nd one.

How to fix the ElementNotVisibleException in Edge browser using Selenium?

I am currently testing a GWT web application similar to MS Paint and the problem which I am facing is that my test case passes on the browsers like Chrome, Firefox, and IE but sadly, it fails in the Microsoft Edge browser. I am unable to find out how to fix this issue after searching the whole Internet and trying out many methods which are written on the Stack Overflow and Google Groups, I am feeling extremely hopeless. Meanwhile, here is my code:
public class Insert_Element_in_Edge {
private static WebDriver driver;
#Test
public void main() throws InterruptedException, IOException
{
// TODO Auto-generated method stub
System.setProperty("webdriver.edge.driver", "D:\\SELENIUM\\Drivers\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.manage().window().maximize();
Thread.sleep(3000);
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
Thread.sleep(3000);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert = driver.findElement(By.xpath(InsertPath));
Thread.sleep(3000);
Insert.click();
}
}
Here's the error which I am facing:
org.openqa.selenium.ElementNotVisibleException: Element not displayed (WARNING: The server did not provide any stacktrace information)
Given below is the HTML code of the element which I am trying to locate in the Edge browser.
<div id="isc_2Q" eventproxy="isc_XXXIconButton_SClient_1" role="button" aria-label="xxx"
onfocus="isc.EH.handleFocus(isc_XXXIconButton_SClient_1,true);"
onblur="if(window.isc)isc.EH.handleBlur(isc_XXXIconButton_SClient_1,true);"
tabindex="1020" style="position: absolute; left: 0px; top: 54px; width: 40px;
height: 34px; z-index: 201152; padding: 0px; opacity: 1; overflow: visible;
cursor: pointer;" onscroll="return isc_XXXIconButton_SClient_1.$lh()" class="iconHoverZindex">
<div id="isc_2R"
eventproxy="isc_XXXIconButton_SClient_1" style="position: relative;
-webkit-margin-collapse: separate separate; visibility: inherit;
z-index: 201152; padding: 0px; cursor: pointer;">
<table role="presentation" cellspacing="0" cellpadding="0" width="40px" height="34px">
<tbody>
<tr>
<td nowrap="true" class="iconButton" style="background-color:transparent;"
align="center" valign="middle" onfocus="isc_XXXIconButton_SClient_1.$47()">
<img src="Insert Element.png" width="24" height="24" align="TEXTTOPundefined"
class="iconButtonHIcon" eventpart="icon" border="0"
suppress="TRUE" draggable="true"/>
<span style="vertical-align:middle;align-content:center;"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
This element is visible in other 3 browsers and is clicked successfully. But I just got stuck in Edge. Also, in Edge, the HTML5 canvas is also not displayed using Selenium. Please help.
You can add wait statement before click on it as given below.
wait.until(ExpectedConditions.ElementIsVisible(By.xpath(InsertPath)));
You have to use element to be clicable as it is a button
WebDriverWait wait = new WebDriverWait (driver, 50);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert= wait.until(ExpectedConditions.elementToBeClickable(By.xpath(InsertPath)));
Insert.click();
In the past I aslo had some trouble location elements with xPath in Edge, GWT and Selenium
Sadly I didnt found a solution but a workaround:
We gave every Element an ID
for example:
panel.getElement().setId("panel-id");
and then used the ID-Locator to find the Element:
findElement(By.id("panel-id"))
I read answers to your question that should solve your problem.
But noone asked you (and you did not provide us, in your question) informations about the version of your MicrosoftWebDriver, Selenium, and Browser that are you using.
From Microsoft WebDriver download, are you using a version that should be supported from your browser?
From EdgeHTML issue tracker, I found only 2 issues (that are fixed) with key element ElementNotVisibleException.
In these cases I usually take a screenshot just before the line where exception occurs and save it somewhere to further investigation. Then I mostly have to add a scrollUp()/scrollToVisible() function before this line to fix the problem.
I would suggest a few tweaks in your code block as follows:
First of all we will try to get rid of all the Thread.sleep(n) calls.
Now, to address the reason for ElementNotVisibleException, we will scroll the element of our interest within the Viewport and then invoke click() method.
Your final code block will may look:
driver = new EdgeDriver();
driver.manage().window().maximize();
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
WebElement Insert = driver.findElement(By.xpath("//div[#id='isc_2R']//td/img[#class='iconButtonHIcon' and contains(#src,'Insert Element.png')]"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Insert);
Insert.click();
Other than above suggestions,
Make sure that "Your Element" that you are looking for is physically visible in your Browser screen. Meaning, if element is not visible , user needs to scroll down in order to see it. Driver behaves similar. In order to prevent "ElementNotVisiable" exception make sure it is also visible on browser page
Try This,
Select elm = new Select(driver.findElement(By.Xpath("Your element's Absolute Xpath")));
//Thread.sleep(100);
elm.selectByValue("Dropdown Value which you want to select");
I've exactly the same problem with GWT. For any reason there's no way to call click directly.
Workaround that worked for me
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click()", element);

Selecting a value from <md-select> tag using Selenium Webdriver

I am using Selenium Webdriver and working on automating an AngularJS Web App on Chrome. It was going pretty well until I hit a dropdown list on the app.
My test keeps crashing everytime I try to select a value from it. I have been doing my research on this and I have only seen 2 solutions (both of which I have tried but don't work)
Use the Select object. This doesn't work because the html tag is not <select>, its <md-select> and this fails the test.
I then tried to just click on the dropdown element and click on the value - driver.findElement(By.xpath("xpath to dropdown list")).click(); and driver.findElement(By.xpath("xpath do dropdown value")).click();
With example 2, I also tried creating it as a WebElement variable and calling click() separate, but this did not work either.
Any ideas on how I can solve this issue?
Update
HTML for the dropdown list
<div ng-switch-when="dropdown" class="ng-scope">
<zf-form-dropdown>
<div class="dropdown">
<div layout="row">
<div flex="50" class="quote-label">
<p ng-bind-html="::label" class="ng-binding">Title</p>
</div>
<div ng-show="false" flex="10" class="tooltip-icon ng-hide" ng-click="showToolTip(field.get('toolTip'))" role="button" tabindex="0" aria-hidden="true"><img src="img/item-question#2x.png"></div>
<md-select flex="" ng-disabled="quote.isRated() || !input.enabled" ng-change="onDropdownChange()" ng-model="input.value" class="ng-valid md-default-theme ng-touched ng-dirty" role="combobox" id="select_0Q9" aria-haspopup="true" aria-expanded="false" aria-labelledby="select_label_0I1" tabindex="0" aria-disabled="false" aria-invalid="false" aria-owns="select_menu_0Q8"><md-select-label class="md-select-label md-placeholder" id="select_label_0I1"><span></span><span class="md-select-icon" aria-hidden="true"></span></md-select-label></md-select>
</div>
</div>
</zf-form-dropdown>
</div>
HTML for the value I want to select
<md-option ng-value="::item.val" ng-selected="item.checked" ng-repeat="item in getOpts()" tabindex="0" class="ng-scope" role="option" aria-selected="false" id="select_option_0QD" value="MR">
<div class="md-text ng-binding">Mr</div>
<div class="md-ripple-container"></div>
</md-option>
The xpath for the dropdown list is //*[#id="select_0Q9"]
The xpath for the dropdown value is //*[#id="select_option_0QD"]
If you are sure that your Xpath is fine then you can also click using javascriptexecutor so try it out like below:-
WebElement element= driver.findElement(By.xpath("//md-option[#id='select_option_0QD']/div[1]"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Please feel free to locate the element in above code as per your convenience .
As per me your xpath of dropdown should be like below:-
//md-option[#id='select_option_0QD']
And xpath of first div which I suppose want to click is:-
//md-option[#id='select_option_0QD']/div[1]
Change [1] to [2] if you want 2nd value.
In an another aspect you can also store all your element in the list(As you know you can't use select) and click them as per your need or all.
For that you need to use xpath like:-
//md-option[#id='select_option_0QD']/div
Now implement it into code:-
List<WebElement> allelemts = driver.findElements(By.xpath("//md-option[#id='select_option_0QD']/div"));
for(WebElement ele: allelemts){
driver.findElement(By.xpath("//md-option[#id='select_option_0QD']")).click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", ele);
}
Hope it will help you :)
Since you are receiving a NoSuchElementException exception, I believe the issue lies in Selenium not able to identify the element. Try any of the following wait methods and then try to click the element.
Explicit Wait: (Most Preferred)
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("elementID")));
or
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("elementID")));
Implicit Wait:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Sleep: (Try to avoid this unless absolutely necessary)
Thread.sleep(1000);
EDIT: Added code to check for element's presence using findElements method.
Before using any of these wait methods you could also check for the presence of your element using findElements method.
List<WebElement> element = driver.findElements(By.id("elementId"));
if (element.size() == 0) {
System.out.println("Element not found");
} else{
System.out.println("Element found");
}
I have finally solved the issue!
I got the Selenium IDE and recorded a session where I got as far as selecting the dropdown menu and selecting my value. I then exported the file as a java test case and was able to read the lines where it selected the values, and they were;
driver.findElement(By.cssSelector("#select_08D > #select_label_005 > span.md-select-icon")).click();
driver.findElement(By.id("select_option_08H")).click();
So first off they both do not use xpath to find the elements, the dropdown menu itself is found with the cssSelector and the value is found by the id.
I am just cross referencing again and the id for the value is select_option_08H but while I am looking at Google Console I can see the id for the value is select_option_189

Cannot interact with input (role=combobox) using Selenium WebDriver (Firefox)

I'm studying Selenium WebDriver and testing my skills on a public site. The issue is that I cannot interact with input element with role='combobox' using Selenium WebDriver + Java.
I need to interact (select 2d option) for the first element of calculator ("Калькулятор"-"Тип расчета" - combobox near this text). Firefox shows the code for it:
<div class="select2-search">
<label class="select2-offscreen" for="s2id_autogen2_search"></label>
<input id="s2id_autogen2_search" class="select2-input" type="text" aria-autocomplete="list" aria-expanded="true" role="combobox" spellcheck="false" autocapitalize="off" autocorrect="off" autocomplete="off" aria-owns="select2-results-2" placeholder="" aria-activedescendant="select2-result-label-17"></input>
When I try to click or sendkeys for it it writes that element (both selects and selects2) is not visible although it is visible and interactable manually. CSS is not transformed. I found that JS can change property to make the element visible, but I tried - and nothing changed, isDisplayed() shows false and I cannot select 2d item of the combobox.
Here is the code (I have left only main part)):
WebDriver driver = new FirefoxDriver();
driver.get("http://sberbank.ru/ru/person/credits/money/consumer_unsecured");
try{
Thread.sleep(1500);
}catch(Exception e)
{System.out.println("Error in Sleep.");}
List<WebElement> selects = driver.findElements(By.cssSelector(".select2-search"));//(".select2-results"));
List<WebElement> selects2 = driver.findElements(By.xpath("//input[#class='select2-input']"));
System.out.println("xpath: "+selects2.size());
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollTo(0,1000);");
System.out.println("value:"+selects2.get(0).getAttribute("value"));
((JavascriptExecutor) driver).executeScript("arguments[0].style.display='inline';arguments[0].style.visibility='visible';arguments[0].style.height = '20px';arguments[0].style.width = '80px';",selects2.get(0));
System.out.println("visible: "+selects2.get(0).isDisplayed());
System.out.println("enabled: "+selects2.get(0).isEnabled());
System.out.println("height: "+selects2.get(0).getAttribute("height")+",width: "+selects2.get(0).getAttribute("width"));
selects2.get(0).click();
selects2.get(0).sendKeys("По среднемесячному доходу");
It writes:
xpath: 7
value:
visible: false
enabled: true
height: 0,width: 0
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
I also tried to trigger keyevent with JQuery but it didn't help:
((JavascriptExecutor) driver)
.executeScript("var s=window.document.createElement('script');" +
"s.src='D:\\Data\\Selenium\\jquery-1.11.3.min.js';" +
"window.document.head.appendChild(s);");
((JavascriptExecutor)driver).executeScript("arguments[0].focus();var e = jQuery.event.trigger({ type : 'keypress', which : 65 });arguments[0].trigger(e);", selects2.get(0));
It writes "Exception in thread "main" org.openqa.selenium.WebDriverException: arguments[0].trigger is not a function"
Please help me to fix my code to be able to set 2d item of this combobox.
Finally got it working -
driver.get('http://sberbank.ru/ru/person/credits/money/consumer_unsecured')
driver.find_element_by_xpath('//*[#id="s2id_autogen1"]/a').click()
driver.find_element_by_xpath('//ul[#class="select2-results ps-container"]/li[2]').click()

Selenium webdriver : How to get embedded image data using JavaScripts?

I have to get the src from below mentioned html, please let me know how can I get the embedded image data? Is this possible using JS? If there is any way to show to the hide elements? I am using Selenium web driver with Java.
<div id="sc859" class="atv4 alc sc-view c-image sc-hidden" style="left: 0px; right: 0px; top: 0px; bottom: 0px">
<img style="height: 100%; width: 100%;" src="data:image/gif;base64,R0lGODlhAQABAJAAAP///wAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==" class="alc-img"/>
</div>
My code:
JavascriptExecutor jse = (JavascriptExecutor)driver;
WebElement element = driver.findElement(By.cssSelector("#sc859"));
String imgeJs = (String) jse.executeScript("document.getElementsById('sc859')[0].getAttribute('src');", element);
System.out.println(imgeJs);
Try this:
WebElement div = driver.findElement(By.id("sc859"));
String image = div.findElement(By.className("alc-img")).getAttribute("src");
System.out.println(image);
I never had luck using document.getElementsById('sc859')[0].getAttribute('src');" before. I always execute script directly like the following. Hope this is what you wanted. And, src does not exist on div rather on following img tag so your selector was wrong.
String src = (String) ((JavascriptExecutor)driver).executeScript("return document.querySelector(\"#sc859>img\").getAttribute(\"src\");");
System.out.println(src);
Print
data:image/gif;base64,R0lGODlhAQABAJAAAP///wAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==
No need to use JavaScript, also, you can shorten Francesco's answer like this:
String src = driver.findElement(By.cssSelector("#sc859 > img.alc-img")).getAttribute("src");
There are 3 things u r doing wrong -
1 - getElementsById its getElementById which will return you only single element not a collection of it. There is no method getElementsById as far as i know.
2 - you are missing return in your executeScript method.
3 - There is no src attribute attached to div element whose id you have passed. src is attached to only img attribute.
So finally your code should be something like:
String imgeJs = jse.executeScript("return document.getElementById('sc859').childNodes[1].getAttribute('src')").toString();
or you can also achieve it by:
WebElement element = driver.findElement(By.cssSelector("#sc859" > img.alc-img));
String imgeJs = jse.executeScript("return arguments[0].getAttribute('src')", element).toString();
Or else follow rest of the answers where you can simply get it done by element.getAttribute("src") method of WebElement interface.

Categories

Resources