Protractor: WebElement.clear() Does Not Update Model

Created on 26 Nov 2013  路  26Comments  路  Source: angular/protractor

Calling WebElement.clear() on an input element does not appear to update the associated model.

View:

<input ng-model="foo">
<div>{{foo}}</div>

Spec:

it("should update the model", function(){
    var input = element(by.css("input"));
    input.sendKeys("bar");
    input.clear();
    expect(element(by.css("div")).getInnerHtml()).toBe(""); // Fails, because it's still "bar"
});
bug

Most helpful comment

I had a similar issue with a directive I was using and sendKeys not updating the model. This solution worked for me though I am not sure if it will work for you all:

field.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, "a"));
field.sendKeys(protractor.Key.BACK_SPACE);
field.clear();

All 26 comments

Good catch. FYI as soon as you send further keys, the model updates.

Not sure what to do about this one, whatever the driver does to clear is not sending any trigger for Angular to $digest. Not seeing it as a huge issue so punting to post 1.0.

Hi!

Is there any workaround that could be used until it is fixed?

I've tried to use sendKeys() with an empty string but it did not work.

Edit:
Solved it by sending a String with a single whitespace. I guess I might work because Angular trims the input.

I have this exact same issue. For example, I'm testing my login form validation and sending a clear() to the password field in order to confirm the 'Password required error' message appears. I've tried calling clear() followed by sendKeys('') with an empty string but that doesn't trigger the model binding. Is there any workaround I've missed?

I had a similar issue with a directive I was using and sendKeys not updating the model. This solution worked for me though I am not sure if it will work for you all:

field.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, "a"));
field.sendKeys(protractor.Key.BACK_SPACE);
field.clear();

Genius! That works a treat. Thank you!

no problem. glad it worked for you!

@wlingke Just used that - good trick!

glad to be of help :)

Hello there guys,

Hm i have probably a little bit different problem. When i click the button the function that is executed must clear the model object (the functionality is unit tested so it's working).
When i use protractor, fill the form , click the button , there is no reason for the model not to be updated but still when i assert the values they are what i have filled out. So if i'm doing e2e testing it's not really acceptable to clear the form with these hacks.

If there is something wrong that i'm doing please tell me.
Best Regards,
George

I'm no longer seeing this issue, and have pushed a test verifying the correct behavior. Please open a new issue if it's still occurring for you!

@wlingke thank you,

you are genius

@wlingke thanks from 2017. I still have this issue on angular 2.

@EugeneSnihovsky Are you having problems with clear in a pure angular 2 application? I am having issues in a hybrid app with validation not triggering when using clear but wasn't sure if i have broken something or if it was related to hybrid application.

me too! on ng2

Still having this issue in 2017. On an input containing 'abc', .clear() followed by .sendKeys('d') on the empty input field and results in 'abcd' in angular's model using reactive forms.

@wlingke's solution works only as long as you don't try to run it on an operating system where CTRL is not set to the modifier key. It's probably safer to run protractor.Key.BACK_SPACE * length of input value for now.

@wlingke thanks from 2018, lol. Still having this problem on Angular 5 when I try doing:

field.clear() // works
field.sendKeys() //works
field.clear() // doesn't update my reactive form

Ok I've had to resort to a more complex workaround, but it's a lot more reliable. I've had no false test failures with this.


export const visibilityOf = (el: any) =>
  browser.wait(ExpectedConditions.visibilityOf(el) as any, 15000, 'Element taking too long to appear in the DOM')
const mapSerial = (fn: Function, list: any[]) => list.map(x => fn(x)).reduce((p, next) => p.then(next), Promise.resolve())

const clearInput = (name: string) => {
  const el = element(by.css('input[name=' + name + ']'))
  return visibilityOf(el)
   .then(() => el.getAttribute('value'))
   .then((text) => {
      const keysArray = text.replace(/ /g, '').split('')
      keysArray.push('')
      return mapSerial((key: string) => setTimeout(() => el.sendKeys(Key.BACK_SPACE), 0), keysArray)
    })
   .then(() => browser.wait(() => el.getAttribute('value').then(text => text.length === 0), 12000))
   .then(() => el)
}

I tried your solution @evanjmg and I'm still stuck with the focused input. Not cleared, no new content append.

I can confirm this is still an issue with Angular 7.2.3 and Protractor 5.4.0 on 73.0.3683.103.

@wlingke thanks much, your solution worked for me too.

Hi @juliemr I can confirm, that .clear() is still not working fine. I'm testing a form and the only way of making the test to work is by doing this:

it('should run validations', async function () {
  await password.sendKeys('a');  
  await password.sendKeys(protractor.Key.BACK_SPACE);  
  await username.click()  // this line triggers a blur event on the password field
  expect(await passwordError.getText()).toMatch('Password is required');
});

clear() makes my test to fail by updating the model in the wrong way.

I had a similar issue with a directive I was using and sendKeys not updating the model. This solution worked for me though I am not sure if it will work for you all:

field.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, "a"));
field.sendKeys(protractor.Key.BACK_SPACE);
field.clear();

@wlingke Thanks a lot! 2019 and this is still the way to go :)

I had a similar issue recently. The workaround is to select all the existing text, use backspace to clear the text

Guys.. If the above solutions does not work for you, then try below. It works..
send empty string with single space.
field.sendKeys(' ');

Noticed this problem when we tried to test some validation. It all works manually but using setKeys and clear doesn't seem to affect Angular to mark the input as touched or dirty.

I wonder if there validation component we are using is loaded too slowly and isn't actually loaded by the time the test has filled out the form, it's only 2 inputs in my case. I'll run a delay test tomorrow and see if that fixes it.

Was this page helpful?
0 / 5 - 0 ratings