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

天涯浪子 提交于 2020-01-14 13:57:06

问题


I'm trying to click on this calendar and insert a date automatically using selenium, but I got the error below:

invalid element state: Element must be user-editable in order to clear it.

HTML snippet

<a id="enddate-dropdown" class="dropdown-toggle" role="button" data-toggle="dropdown" data-target="">
                <p class="custom-datepickers__date-prefix ng-binding">To:</p>
                <!-- ngIf: displayEndDate -->
                <!-- ngIf: !displayEndDate --><div ng-if="!displayEndDate" class="custom-datepickers__no-date ng-scope"></div><!-- end ngIf: !displayEndDate -->
</a>

Code snippet

myclass.SetDateByXpath("//*[@id=\"enddate-dropdown\"]/p", myclass.GetDate("yyyy/MM/dd", mydate));

public void SetDateByXpath(String element, String value)
    {
        WebElement webElement = ExplicitWaitOnElement(By.xpath(element));       
        ((JavascriptExecutor) driver).executeScript(
                "arguments[0].removeAttribute('readonly','readonly')",webElement);
        webElement.clear();
        webElement.sendKeys(value);
    }

If I set the date manually, this is the HTML:

<a id="enddate-dropdown" class="dropdown-toggle" role="button" data-toggle="dropdown" data-target="">
                <p class="custom-datepickers__date-prefix ng-binding">To:</p>
                <!-- ngIf: displayEndDate --><p ng-if="displayEndDate" class="ng-binding ng-scope">2019/11/21</p><!-- end ngIf: displayEndDate -->
                <!-- ngIf: !displayEndDate -->
</a>

Probably the website changed, but now I don't know how can I set this value. Any help will be appreciated.

Thanks


回答1:


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 using sendKeys()
  • Or you can use executeScript() to invoke removeAttribute() 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:

  • InvalidElementStateException invalid element state: Element must be user-editable in order to clear it" error while sending text with Selenium Python



回答2:


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 string
WebElement 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)


来源:https://stackoverflow.com/questions/58881440/invalid-element-state-element-must-be-user-editable-in-order-to-clear-it-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!