enzyme: React 16 fragments (rendering arrays and strings) unsupported
React 16 added a new return type of an array with many fragments of JSX, see React 16 blog post
Enzyme v3.0.0 with React 16 adapter 1.0.0 throws an error with this sample code
Error
/node_modules/react-dom/cjs/react-dom-server.node.development.js:2776
var tag = element.type.toLowerCase();
^
TypeError: Cannot read property 'toLowerCase' of undefined
Failing test
import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow } from 'enzyme';
import React from 'react';
import test from 'tape';
function Fragments() {
return [
<li key="A">First item</li>,
<li key="B" id="item">Second item</li>,
<li key="C">Third item</li>
];
}
test('One element parent', (assert) => {
configure({ adapter: new Adapter() });
const wrapper = shallow(<Fragments />);
const actual = wrapper.html();
const expected = undefined;
assert.notEqual(actual, expected, 'Has ID selector');
assert.end();
});
Passing test
import Adapter from 'enzyme-adapter-react-16';
import { configure, shallow } from 'enzyme';
import React from 'react';
import test from 'tape';
function NotFragments() {
return (
<ul>
<li key="A">First item</li>,
<li key="B" id="item">Second item</li>,
<li key="C">Third item</li>
</ul>
);
}
test('One element parent', (assert) => {
configure({ adapter: new Adapter() });
const wrapper = shallow(<NotFragments />);
const actual = wrapper.find('#item').is('li');
const expected = true;
assert.equal(actual, expected, 'Has ID selector');
assert.end();
});
-=Dan=-
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 55
- Comments: 32 (8 by maintainers)
Commits related to this issue
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- Remove not needed <div> Enzyme 3 fails with fragments, see https://github.com/airbnb/enzyme/issues/1213#issuecomment-335057075 — committed to tkrotoff/react-form-with-constraints by tkrotoff 7 years ago
- ChildTasks: add bread crumbs to easily access parent tasks This adds parent task bread crumbs to both the task show view and the focus view. **Notes** - Because `ParentTaskBreadCrumbs` is a recursi... — committed to mockdeep/questlog by mockdeep 7 years ago
Temporary hack that seems to work well enough:
Best solution I’ve found so far: wrap fragments with
<div>
for the tests only.I have came across another issue when using
<Fragment />
only the first children is rendered:Modal.component
Modal.test
console.log(component.debug())
Running the same tests but changing the fragment to a div:
Modal.component
Modal.test
And last but not least the output from debug
console.log(component.debug())
React 16.2.0 arrived with new fragments syntax. Any progress here to support it by enzyme?
@heathzipongo Fragment support was added to enzyme in v3.4. Try upgrading.
Looks like support for this just landed https://github.com/airbnb/enzyme/pull/1733 and now released 😃
Much the same as others have mentioned, a rendering like:
when
mount()
is used, the.html()
and.text()
functions return only the content of the first element within the fragment, eg:However, when
shallow()
is used, the.html()
and.text()
functions return the full text and expected content of the complete Component. In both cases,.debug()
returns the expected output.Or more simply put:
Output:
See #1178, #1149
TL;DR for now you can use
.at(0).find('div')
to search fragments, lists, or plain old JSX elements.For what it’s worth, I think the strangest thing here is that
at(0).find()
works butat(0).children().find()
doesn’t.any update on this issue? or should I just wrap it in a div?
You can shallow-render a component that renders a Fragment, but not a Fragment itself. Either way, that’s unrelated to this issue, which is about rendering arrays and strings.
Oops, sorry. Will totally do that!
An option for now is
In that case, the
span
tag is added, but we are covering the cases withReact.Fragment
or not sinceTestWrapper
is respectively using the mocked React.Fragment when and if it exists. So your test is doing a proper assertion.<React.Fragment>
as a wrapper is working for me (React 16.2.0 & Enzyme 3.3.0):log output:
Which is exactly what I expect.