w3c / webdriver

Remote control interface that enables introspection and control of user agents.
https://w3c.github.io/webdriver/
Other
682 stars 195 forks source link

input clear: trigger an input event so that the empty string value is picked up by user code #1630

Open jedwards1211 opened 3 years ago

jedwards1211 commented 3 years ago

AFAICT, running the clear algorithm on an <input> sets the value to '' but doesn't cause it to emit an input event. I'm not sure if I fully understand the purpose of the clear algorithm (or if webdriver.io should be using it for this purpose) but it seems bad for it to be able to change the value of an input without application code getting notified. Not all applications will rely on polling/reading the value from the input.

This has led to a confusing situation where using webdriver.io's setValue function (which clears the input, then types in a new value) doesn't work with React and react-final-form. Instead of clearing and replacing the input's value, it ends up just appending the new value to the existing value. Here's how it happens:

Related issues

webdriver.io issue: https://github.com/webdriverio/webdriverio/discussions/7650 Selenium issue: https://github.com/SeleniumHQ/selenium/issues/6741 chromedriver issue: https://bugs.chromium.org/p/chromedriver/issues/detail?id=2702&q=&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary

christian-bromann commented 3 years ago

To clarify the thread as there is a lot of WebdriverIO specifics in here: the element clear command doesn't trigger an input change event causing applications written in React to behave unexpectedly as the internal state is not updated because the component will be re-rendered with previous state. WebdriverIO calls element clear and element set keys as combination in one command called setValue. It seems to be the most efficient way to set a value within an input while rejecting all previous values.

Another option would be to use the actions command and send a set of backspace keys to the input but that would require much more communication between client and remote end.

The most efficient option might be to enhance the element send keys command to clear the input value before setting it via a parameter that defaults to false.

shs96c commented 3 years ago

This should be handled by the unfocus steps. We may just need to make clear in the spec that these need to be run.

whimboo commented 3 years ago

So I assume we have to update this section of the spec and add that we have to send an input event?

jedwards1211 commented 3 years ago

This should be handled by the unfocus steps. We may just need to make clear in the spec that these need to be run.

The input event should be dispatched before the blur event, even if both are dispatched by the unfocus steps, right?

jedwards1211 commented 3 years ago

@christian-bromann

The most efficient option might be to enhance the element send keys command to clear the input value before setting it via a parameter that defaults to false.

For the most robust testing, to the app the set of events should look indisinguishable from real user interaction, right? Meaning along with an input event when the element is cleared, there should be key events for select all and backspace? (Unless you're simulating a user clearing the input by some other means?)

whimboo commented 3 years ago

Interestingly there is also issue #445 from years ago which handles the exact same topic but was closed. @shs96c might be good if you could follow-up here so that it's clear what to do, and if we can do it.

jedwards1211 commented 3 years ago

Copying my comment from #445:

@shs96c

The javadocs for "clear" are unambiguous that this isn't exactly emulating user behaviour

It was designed to allow a test to quickly reset the state of an input element or contentEditable without much mucking around, and the events it fires are based on a long history of bug reports and people expecting certain events to fire ("onchange" being the most notable)

If element clear isn't intended to be an emulation of user behavior, then should we add another type of clear command to the WebDriver spec that is an emulation of user behavior?

The problem is, to authors of clients (e.g. webdriver.io), element clear seems ideal to use for building a command to change the value of an input, so they end up using it. Then years later a few of us run into problems, and only if we dig deeply into why they're happening do we discover out that element clear actually isn't good for the common use case.

Also, I think emulating a user changing the value of an input is complex enough that it would be good for the WebDriver spec to provide a command for that, so that we have a reliable way of doing it regardless of which client we use.

Zaykona commented 2 years ago

Hi , any updates here?

blutorange commented 1 year ago

A command to change the value of an input would be awesome.

To add an example to the discussion, Selenium IDE has a type command which supposed to "change the value of an input". It's currently implemented as

element.clear() element.sendKeys(value)

At first this seems good, but today I noticed an issue with this approach: First, the element is cleared, which triggers change and blur events etc. Only after those events are processed, the sendKeys command is executed. When the user focuses the input, presses backspace, then enters the desired value, events are fired only once the new value was entered. This can result in different behavior when the web page has registered an event handler on the input element that potentially modifies the the value of the input itself.