Invalid element state: Element must be user-editable in order to clear it error trying to click and insert a date on a dropdown-toggle using Selenium
I'm guessing your error is being thrown at the lines:
webElement.clear();webElement.sendKeys(value)
We can try to work around that by setting values through Javascript instead:
// updated selector for webElement to grab the p element which contains the date stringWebElement webElement = driver.findElement(By.xpath("//*[@id=\"enddate-dropdown\"]/p[@ng-if='displayEndDate']"));// try setting inner HTML which is the text inside the p((JavascriptExecutor) driver).executeScript("arguments[0].innerHtml = '" + value + "';", webElement)// alternative option is to try setting value instead// ((JavascriptExecutor) driver).executeScript("arguments[0].value = '" + value + "';", webElement)
This error message...
invalid element state: Element must be user-editable in order to clear it.
...implies that the element identified was not in a user-editable state to invoke clear()
method.
To insert a date with in a dropdown-toggle with an Angular element there are two approaches:
- Either you can
click()
on the calendar and insert a date usingsendKeys()
- Or you can use
executeScript()
to invokeremoveAttribute()
the readonly attribute.
However, as per the HTML you have shared it seems the element which gets populated with the date string i.e. 2019/11/21 is not readily available within the HTML DOM. So we can infer that the following element gets added to the DOM Tree as a result of interaction with other WebElements which is as follows:
<p ng-if="displayEndDate" class="ng-binding ng-scope">2019/11/21</p>
Hence the best approach would be,
- First to invoke
click()
on the element readily available within the HTML inducing WebDriverWait. - Next to invoke
sendKeys()
on the newly created element WebDriverWait. Code Block:
//element -> myclass.SetDateByXpath("//a[@class='dropdown-toggle' and @id='enddate-dropdown']"// observe the change in the ^^^ xpath ^^^//value -> myclass.GetDate("yyyy/MM/dd", mydate));public void SetDateByXpath(String element, String value){ WebElement webElement = ExplicitWaitOnElement(By.xpath(element)); webElement.click(); WebElement webElement_new = ExplicitWaitOnElement(By.xpath("//a[@class='dropdown-toggle' and @id='enddate-dropdown']//p[@class='ng-binding ng-scope' and @ng-if='displayEndDate']")); webElement_new.clear(); webElement_new.sendKeys(value);}
Reference
You can find a relevant discussion in: