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

Unable to enter numbers in an input using trigger() #484

Closed
AlexandreBonneau opened this issue Mar 23, 2018 · 15 comments
Closed

Unable to enter numbers in an input using trigger() #484

AlexandreBonneau opened this issue Mar 23, 2018 · 15 comments

Comments

@AlexandreBonneau
Copy link

AlexandreBonneau commented Mar 23, 2018

Version

1.0.0-beta.12

Reproduction link

https://codesandbox.io/s/n768kwm6wj
note: the dummy VueInput component and the spec code is correct, but I can't make vue-test-utils work there

Steps to reproduce

Following the keyboard example from the documentation, I'm trying to input arbitrary keys into an input.

  1. Have a component VueInput that generated a top level input DOM element <vue-input type='text'>
  2. With vue-test-utils, try to enter the keys home then 1 using:
describe('Dummy VueInput.vue', () => {
    it('should accept number keys', () => {
        const wrapper = mount(VueInput);
        const input = wrapper.find('input');
        expect(input.element.value).toEqual('');

        // Test inputting a number
        input.trigger('click'); //FIXME Is this really needed? Isn't the focus already on the input since it's the generated DOM element?
        input.trigger('keydown.home');
        input.trigger('keydown', { //FIXME Fails
            key: '1',
            keyCode: 49,
            which: 49,
        });
        expect(input.is('input')).toBe(true);
        expect(input.element.value).toEqual('1');
    });
});

What is expected?

The input element value should be 1.

What is actually happening?

The input element value is unchanged and still equal to "".

Bonus question:

Do we need to manually (and painfully) convert each key we want to enter to its keyCode (which value), or is there a quicker and better way to enter multiple keys one after another in one go (like 1, then 5, then 8, perhaps using something like wrapper.keys('158')? (see how it's done in Selenium-based webdriver.io in that example)).

@darrenjennings
Copy link

For me, which didn't work, but keyCode does when triggering keycodes.

@AlexandreBonneau
Copy link
Author

AlexandreBonneau commented Mar 23, 2018

Unfortunately, I added the three key, keyCode and which attributes to the keydown event just to be sure, and tried them separately, without success.

@AlexandreBonneau
Copy link
Author

AlexandreBonneau commented Mar 24, 2018

If you want to have a working reproducible example, you can checkout the code from the issue_1 branch of the vue-autonumeric repository (see here).

Then:

# Setup the repo
git clone -b issue_1  && cd vue-autoNumeric && yarn
# Build the component
yarn build
# Run the test with jest
yarn test

You'll see all the tests that are currently failing, and if you want to check only the test that is the subject of this particular issue, change it( to fit( on that line.

Note: the other tests are failing when they should not (you can check that everything works as expected when manually manipulating the examples page in ./examples/index.html).
So if you feel adventurous to tell us what is going wrong there, I'm all ears :)

@AlexandreBonneau
Copy link
Author

For info, 1.0.0-beta.13 did not fix this issue.

@eddyerburgh
Copy link
Member

eddyerburgh commented Mar 30, 2018

Dispatching an event with a keycode does not update an <input>'s value.

To test what happens when triggering an event on an element, you must set the value before calling trigger:

wrapper.element.value = 'some value'
wrapper.trigger('change')

There is an ongoing issue on testing v-model —#345

@AlexandreBonneau
Copy link
Author

I'm not sure to follow; what do you mean by you must set the value manually? Using theInputElement.value = '1234'?
If so, that defeats the purpose of testing input keys event isn't?

If simulating a keydown event with input.trigger('keydown', { which: 49 }) does not change the input value accordingly (nor the v-model if any), then I'd say there is a major issue in trigger(), since being able to enter values in <input> element is an essential need.

I think this issue should not be closed.

Anyway, does this means we currently have no way to test any vue components that allows a user to interacts with it (ie. component that mask the user input, or a password input that displays an help tooltip once 3 or more characters have been entered, etc.)?

@eddyerburgh
Copy link
Member

eddyerburgh commented Mar 31, 2018

Trigger is a wrapper around dispatchEvent, which dispatches a DOM event on an HTMLElement. If you dispatch a keydown event with a keycode, the keycode isn't added to an HTMLElement's value.

You need to set the value directly:

input.element.value = 'some value'

Anyway, does this means we currently have no way to test any vue components that allows a user to interacts with it

You can test those things by changing the value and making sure the component reacts correctly to it.

@AlexandreBonneau
Copy link
Author

I'm not seeing how "You can test those things by changing the value" in a case where masking is involved.

For instance with the vue-autoNumeric component, setting the input.value directly (using input.value = 'foo') is managed differently than when changing the input value manually.

In the former case, a watch on the value is used, while on the latter the keydown, keypress, keyup events are closely monitored by the AutoNumeric library.

Moreover, setting the value directly cannot allows to test some keys that do not produce a change in the input value; for instance when you have the default settings on a vue-autonumeric component and the value 1,234,567.89 in it, if the caret is placed here 1,234,5|67.89 and you enter a single ArrowLeft key, then the result should be 1,234|,567.89 (not 1,234,|567.89).

I guess if vue-test-utils trigger() function does not simulate key* events, all this is untestable.

Could you please confirm?

@pierremanceaux
Copy link

+1 @AlexandreBonneau , I'm currently facing exactly the same issue.

@DannyChambers
Copy link

This is closed, is that because it was fixed? I can't increment a value with trigger('keydown') either.

@MgHtinLynn
Copy link

Sets the value of a text-control input or select element and updates v-model bound data.

Its worked
const input = wrapper.find('input');
input.element.value = 'hello';
input.trigger('input');
input.trigger('keyup');
console.log(wrapper.vm.inputValue);

Output = 'hello'

Or

Can do this way
According to https://vue-test-utils.vuejs.org/api/wrapper/#setvalue

input.setValue('hello') is an alias of the following code

input.element.value = 'hello';
input.trigger('input');

So
input.setValue('hello');
input.trigger('keyup');
console.log(wrapper.vm.inputValue);
Output = 'hello'

@JannikWempe
Copy link

Why is this closed? I am preventing some inputs using the keydown event. How should I be able to test that with the suggested solutions? If I set the value beforehand and trigger the keydown event, the value is already set...

@sbedoyajc
Copy link

sbedoyajc commented Jul 28, 2020

@pinutz23 Maybe you can do something like:

const input = wrapper.find('input');

input.trigger('keydown', {
   key: '1',
};

Also, you can check this example: https://vue-test-utils.vuejs.org/guides/dom-events.html#keyboard-example

@dospunk
Copy link

dospunk commented Jun 16, 2021

I also think this should be reopened. I have a component that has to prevent certain keypresses because of the way number inputs work. This behavior is impossible to test by setting the value.

@YWoooo
Copy link

YWoooo commented Aug 10, 2021

Not sure if this is related to the topic, yet this is also unable in vue-test-utils-next. It would be nice if we can do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants