I am setting the focus of an element within a simple Jasmine test
var node = React.findDOMNode(component.refs.input);
node.focus();
but when I check the focused element with
document.activeElement
it is always the <body> element that is in focus. I'm guessing this is either because the element is not gaining focus or the document isn't referring to the real document.
I have tried to grab the active element using without any luck:
node.ownerDocument.activeElement
Why doesn't the document's active element ever change?
You don't give us a whole lot of information about your test, but I'm going to assume that you're using TestUtils.renderIntoDocument(), and if this is the case, then that is why you are experiencing this problem.
Remember that TestUtils.renderIntoDocument() renders the component into a detached DOM node. So it's quite difficult to test the functionality of focusing/blurring nodes, or finding nodes by class name or ID without using another TestUtils function, which uses the detached DOM node that you give it.
As an example, let's say you have a sample component that looks like this:
var Foo = React.createClass({
render : function () {
return (
<div className='foo'>
Sample Component
</div>
)
}
});
And a test like this:
it('renders a div with className of "foo"', function () {
var foo = TestUtils.renderIntoDocument(<Foo />); //creates detached DOM node
var array1 = TestUtils.scryRenderedDOMComponentsWithClass(foo, 'foo');
var array2 = document.getElementsByClassName('foo');
expect(array1.length).toEqual(1); //passes
expect(array2.length).toEqual(1); //fails
});
The first expect statement would pass because you're using the TestUtils function, which looks in the detached DOM node you created for the class name, and finds it just fine. The second expect statement, however, would fail, because the document's root node doesn't actually have any children with a class name of 'foo'.
There is a way around this though. In my project, I have a few React components that focus/blur nodes, and use a few document functions that you just can't test with TestUtils. So for those specific tests, I've been using a library called jasmine-react. Using this, you can render components into attached DOM nodes using jasmineReact.render(), and it takes care of the cleanup for you when your test is finished.
So, re-writing that test from earlier give you something like this:
it('renders a div with className of "foo"', function () {
var jasmineReact = require('jasmine-react-helpers');
var foo = jasmineReact.render(<Foo />, document.body);
var array1 = TestUtils.scryRenderedDOMComponentsWithClass(foo, 'foo');
var array2 = document.getElementsByClassName('foo');
expect(array1.length).toEqual(1); //passes
expect(array2.length).toEqual(1); //passes
});
I suppose it's worth mentioning that this owner of the jasmine-react repo isn't actively maintaining it (at least at the time I wrote this), but it seems to work for the time being.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With