diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
index 8d0a8fe85..19473ba15 100644
--- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
@@ -85,6 +85,48 @@ describeWithDOM('mount', () => {
expect(spy).to.have.property('callCount', 1);
});
+ describe('wrapping invalid elements', () => {
+ itIf(is('>= 16'), 'should throw when mounting Portals', () => {
+ const portal = createPortal(
+
,
+ { nodeType: 1 },
+ );
+
+ expect(() => mount(portal)).to.throw(
+ Error,
+ 'ReactWrapper can only wrap valid elements',
+ );
+ });
+
+ it('should throw when mounting plain text', () => {
+ expect(() => mount('Foo')).to.throw(
+ Error,
+ 'ReactWrapper can only wrap valid elements',
+ );
+ });
+
+ it('should throw when mounting multiple elements', () => {
+ expect(() => mount([])).to.throw(
+ TypeError,
+ 'ReactWrapper can only wrap valid elements',
+ );
+ });
+ });
+
+ it('should mount built in components', () => {
+ expect(() => mount()).not.to.throw();
+ });
+
+ it('should mount composite components', () => {
+ class Foo extends React.Component {
+ render() {
+ return ;
+ }
+ }
+
+ expect(() => mount()).not.to.throw();
+ });
+
describeIf(is('>= 16.3'), 'uses the isValidElementType from the Adapter to validate the prop type of Component', () => {
const Foo = () => null;
const Bar = () => null;
diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
index 0d74d92bc..d4286d9eb 100644
--- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
@@ -20,6 +20,7 @@ import './_helpers/setupAdapters';
import {
createClass,
createContext,
+ createPortal,
createRef,
Fragment,
forwardRef,
@@ -77,6 +78,48 @@ describe('shallow', () => {
expect(wrapper.children().type()).to.equal('div');
expect(wrapper.children().props().bam).to.equal(undefined);
});
+
+ describe('wrapping invalid elements', () => {
+ itIf(is('>= 16'), 'should throw when shallow rendering Portals', () => {
+ const portal = createPortal(
+ ,
+ { nodeType: 1 },
+ );
+
+ expect(() => shallow(portal)).to.throw(
+ Error,
+ 'ShallowWrapper can only wrap valid elements',
+ );
+ });
+
+ it('should throw when shallow rendering plain text', () => {
+ expect(() => shallow('Foo')).to.throw(
+ Error,
+ 'ShallowWrapper can only wrap valid elements',
+ );
+ });
+
+ it('should throw when shallow rendering multiple elements', () => {
+ expect(() => shallow([])).to.throw(
+ TypeError,
+ 'ShallowWrapper can only wrap valid elements',
+ );
+ });
+ });
+
+ it('should shallow render built in components', () => {
+ expect(() => shallow()).not.to.throw();
+ });
+
+ it('should shallow render composite components', () => {
+ class Foo extends React.Component {
+ render() {
+ return ;
+ }
+ }
+
+ expect(() => shallow()).not.to.throw();
+ });
});
describe('context', () => {
diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js
index b7129320a..d40e8c17a 100644
--- a/packages/enzyme/src/ReactWrapper.js
+++ b/packages/enzyme/src/ReactWrapper.js
@@ -85,8 +85,13 @@ class ReactWrapper {
const options = makeOptions(passedOptions);
if (!root) {
+ const adapter = getAdapter(options);
+ if (!adapter.isValidElement(nodes)) {
+ throw new TypeError('ReactWrapper can only wrap valid elements');
+ }
+
privateSet(this, UNRENDERED, nodes);
- const renderer = getAdapter(options).createRenderer({ mode: 'mount', ...options });
+ const renderer = adapter.createRenderer({ mode: 'mount', ...options });
privateSet(this, RENDERER, renderer);
renderer.render(nodes, options.context);
privateSet(this, ROOT, this);
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index ff1c5e40b..4c1801952 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -170,6 +170,10 @@ class ShallowWrapper {
// mounting a ShallowRender component
if (!root) {
+ if (!adapter.isValidElement(nodes)) {
+ throw new TypeError('ShallowWrapper can only wrap valid elements');
+ }
+
privateSet(this, ROOT, this);
privateSet(this, UNRENDERED, nodes);
const renderer = adapter.createRenderer({ mode: 'shallow', ...options });