Testing input.focus() in Enzyme

假如想象 提交于 2019-12-10 00:51:55

问题


Can anyone help me to test input.focus() in enzyme.I am writing the script with react.My code is below.

public inputBox: any;

componentDidUpdate = () => {
    setTimeout(() => {
        this.inputBox.focus();
    }, 200);
}

render() {
    return (
        <div>
            <input
                type = 'number'
                ref = {element => this.inputBox = element } />
        </div>
    );
}

回答1:


Other approach is to test if element gains focus, i.e. focus() is called on node element. To achieve this, focused element need to be referenced via ref tag like it takes place in your example – reference was assigned to this.inputBox. Consider example below:

const wrapper = mount(<FocusingInput />);
const element = wrapper.instance().inputBox; // This is your input ref

spyOn(element, 'focus');

wrapper.simulate('mouseEnter', eventStub());

setTimeout(() => expect(element.focus).toHaveBeenCalled(), 250);

This example uses Jasmine's spyOn, though you can use any spy you like.




回答2:


You can use mount instead of shallow. Then you can compare document.activeElement and the input DOM node for equality.

const output = mount(<MyFocusingComponent/>);

assert(output.find('input').node === document.activeElement);

See https://github.com/airbnb/enzyme/issues/316 for more details.




回答3:


Per React 16.3 updates... using createRef for anyone visiting this post today, if you rearrange the original component to use the new ref api

class InputBox extends PureComponent {
    constructor(props) {
        super(props);
        this.inputRef = React.createRef();
    }
    componentDidMount() {
        this.inputRef.current.focus();
    }
    render() {
        return (
            <input
                ref={this.inputRef}
            />
        );
    }
}

Then in your test spec

it("Gives immediate focus on to name field on load", () => {
    const wrapper = mount(<InputBox />);
    const { inputRef } = wrapper.instance();

    jest.spyOn(inputRef.current, "focus");

    wrapper.instance().componentDidMount();
    expect(inputRef.current.focus).toHaveBeenCalledTimes(1);
});

Notice the use of the inputRef.current attribute which references the currently assigned DOM node.




回答4:


I just had the same issue and solved using the following approach:

My setup is Jest (react-create-app) + Enzyme:

    it('should set the focus after render', () => {
      // If you don't create this element you can not access the 
      // document.activeElement or simply returns <body/>
      document.body.innerHTML = '<div></div>'

      // You have to tell Enzyme to attach the component to this
      // newly created element
      wrapper = mount(<MyTextFieldComponent />, {
        attachTo: document.getElementsByName('div')[0]
      })

      // In my case was easy to compare using id 
      // than using the whole element
      expect(wrapper.find('input').props().id).toEqual(
        document.activeElement.id
      )
    })



回答5:


This worked for me when using mount and useRef hook:

expect(wrapper.find('input').get(0).ref.current).toEqual(document.activeElement)



回答6:


Focus on the particular element can be checked using selectors.

const wrapper = mount(<MyComponent />);

const input = wrapper.find('input');
expect(input.is(':focus')).toBe(true);



回答7:


Selecting by data-test attribute or something similar was the most straight forward solution I could come up with.

import React, { Component } from 'react'
import { mount } from 'enzyme'

class MyComponent extends Component {
  componentDidMount() {
    if (this.inputRef) {
      this.inputRef.focus()
    }
  }

  render() {
    return (
      <input data-test="my-data-test" ref={input => { this.inputRef = input } } />
    )
  }
}

it('should set focus on mount', () => {
  mount(<MyComponent />)
  expect(document.activeElement.dataset.test).toBe('my-data-test')
})


来源:https://stackoverflow.com/questions/37694900/testing-input-focus-in-enzyme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!