AlpineF30
AlpineF30

Reputation: 95

InvalidElementStateException when attempting to clear text through Selenium

The web application I am testing requires confirmation when deleting a record.

I have created a test to enter in a valid reason for deleting this record.

The code to do this is as follows:

DeleteFieldButton.
            Click();
        WaitMethods.WaitForElementToBeDisplayed(RemovalReason, 20);
        RemovalReason
            .Click();
        RemovalReason
            .Clear();
        RemovalReason
            .SendKeys("Automated Test - Delete Field");

The XPath to the text box is as follows:

private Label RemovalReason = new Label(By.XPath("//*[@placeholder = 'Removal reason']"));

Whenever the test is run the following exception is returned.

OpenQA.Selenium.InvalidElementStateException
HResult=0x80131500
Message=Cannot clear By.XPath: //*[@placeholder = 'Removal reason'] as it is 
not declared as a writable text element
Source=web
StackTrace:
at web.Elements.Common.Element.Clear()
at Daera.Efs.Test.E2e.PageObjects.ApplicationSummary.DeleteField(String 
FieldIDToDelete) in 
C:\Code\Local\WebApp.E2e\PageObjects\ApplicationSummary.cs:line 280
 at Test.E2e.Tests.ApplicationSummaryTest.Delete_Wider_General_Field_From_Application_Summary() in C:\Code\Local\WebApp.E2e\Tests\ApplicationSummaryTest.cs:line 45

Below is the HTML of the element on the web application:

<input ng-keypress="dialog.keypress($event)" md-autofocus="" ng-model="dialog.result" placeholder="Removal reason" class="ng-valid md-input ng-not-empty md-autofocus ng-touched ng-dirty ng-valid-parse" aria-label="Removal reason" id="input_22" aria-invalid="false" style="">

Upvotes: 1

Views: 2950

Answers (3)

Gucu112
Gucu112

Reputation: 957

In my case the error was thrown due to input being disabled. Here are simple extension methods that I am using to check whether element is disabled or editable:

public static bool IsDisabled(this IWebElement element)
{
    if (!element.Displayed || !element.Enabled)
    {
        return true;
    }

    var isDisabled = element.GetDomAttribute("disabled") is not null;

    if (bool.TryParse(element.GetDomAttribute("aria-disabled"), out var isAriaDisabled))
    {
        isDisabled = isAriaDisabled || isDisabled;
    }

    return isDisabled;
}

public static bool IsEditable(this IWebElement element)
{
    if (IsDisabled(element))
    {
        return false;
    }

    return element.GetDomAttribute("readonly") is null;
}

However, it is necessary to look into source HTML and understand how disable and readonly states are populated for fields by the JS framework and update above functions.

Upvotes: 0

Shari Valenta
Shari Valenta

Reputation: 21

I was having the same issue, only I was trying to enter a dash in a date field that didn't allow dashes. I figured this out by manually entering a date with a dash and it did not populate. (The field also doesn't accept letters - just numbers). Now, my test enters a date without a dash and it passes successfully!

Upvotes: 0

undetected Selenium
undetected Selenium

Reputation: 193208

As per the HTML you have shared the <input> element with placeholder attribute as Removal reason is an Angular element and as you have to send text, you have to induce WebDriverWait for the element to be clickable as follows :

IWebElement myElem = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//input[@class='ng-valid md-input ng-not-empty md-autofocus ng-touched ng-dirty ng-valid-parse' and starts-with(@id,'input_') and @placeholder='Removal reason']")));
myElem.Click();
myElem.Clear();
myElem.SendKeys("Automated Test - Delete Field");

References

You can find a couple of relevant discussions in:

Upvotes: 1

Related Questions