Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrapper.setSelected() triggers a change event even if the option is already selected #1339

Closed
vvanpo opened this issue Nov 2, 2019 · 8 comments · Fixed by #1380
Closed

Comments

@vvanpo
Copy link
Contributor

vvanpo commented Nov 2, 2019

Version

1.0.0-beta.29

Reproduction link

https://codepen.io/vvanpo/pen/MWWroOK

Steps to reproduce

  1. Mount a component with a <select> element.
  2. Call setSelect() multiple times on one of the select element's options.
  3. Observe the <select> element wrapper's emitted('change').length is equal to the number of times setSelect() was called.

What is expected?

A <select> element emits a change event only when the element value has actually changed.

What is actually happening?

setSelected() triggers a change event every time it is called, regardless of whether the underlying value was changed.

@vvanpo
Copy link
Contributor Author

vvanpo commented Nov 2, 2019

I hesitated to open this as a bug, as the documentation is explicit in saying that trigger('change') is called every time: https://github.com/vuejs/vue-test-utils/blob/v1.0.0-beta.29/docs/api/wrapper/setSelected.md

However, I believe setSelected() is generally used to mimic user interaction, not programmatic interaction. So it follows that setSelected() should behave in the same way as a user interacting with a <select> element's <option>s, which I believe will only ever fire a change event if the selection has been modified.

@dobromir-hristov
Copy link
Contributor

You are correct, it only emits change event if select another option. It shouldnt be hard to see if an option is selected.

@codebryo
Copy link
Contributor

@vvanpo as you said and the docs explicitly state it triggers the change event every time I don't think this is a bug. I don't think the test-utils should keep track of data and know if something has changed between two calls. If setSelected() gets called multiple times, it's fair that it does it job multiple times.

@dobromir-hristov
Copy link
Contributor

dobromir-hristov commented Dec 17, 2019

@codebryo I am a bit split here. I agree with you on that one, yet I saw that selecting the same option does not trigger an event... Do we want to emulate a user action or explicitly do what the action states.. hmmmm @afontcu @JessicaSachs Opinions here?

@afontcu
Copy link
Member

afontcu commented Dec 17, 2019

If I'm not mistaken, setChecked is not sending the event if the element is already checked

if (this.element.checked === checked) {
return

...even though docs say the exact same thing regarding it being an alias of setting the right value and emitting the event.

I'd say all setXXXX methods to behave the exact same way. We could make them emulate the user or not, but in a consistent way. For the record, I'd like them to stay closer to the users.

@vvanpo
Copy link
Contributor Author

vvanpo commented Dec 19, 2019

@afontcu good find, it seems clear to me that emulating user actions is the most intuitive and useful behaviour, here.

Interestingly, that same is not true when calling setChecked() on an <input type="radio" />. It used to be, but was removed in ef66c26#diff-f8b21801dcf5dee76bc9f5f22e227ea8L516, which looks to me like a regression.

@vvanpo
Copy link
Contributor Author

vvanpo commented Dec 19, 2019

If there are no objections, I'll open a PR for this.

@JessicaSachs
Copy link
Collaborator

Yes please, @vvanpo

lmiller1990 added a commit that referenced this issue Jan 3, 2020
fix: Ensure setChecked() and setSelected() only trigger DOM events when state is changed (fix #1339)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants