diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index e39eaa063..c1dd129f4 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -3860,6 +3860,28 @@ describeWithDOM('mount', () => { expect(constWrapper.text()).to.include('Foo'); expect(constWrapper.text()).to.include('Bar'); }); + + it('works with a nested component', () => { + const Title = ({ children }) => {children}; + const Foobar = () => ( + + Foo + Bar + + ); + + const wrapper = mount(); + const text = wrapper.text(); + expect(wrapper.debug()).to.equal(` + + <span> + Foo + </span> + + Bar +`); + expect(text).to.equal('FooBar'); + }); }); }); diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 422ee07f4..358191880 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -3820,6 +3820,26 @@ describe('shallow', () => { expect(constWrapper.text()).to.include('Foo'); expect(constWrapper.text()).to.include('Bar'); }); + + it('works with a nested component', () => { + const Title = ({ children }) => {children}; + const Foobar = () => ( + + Foo + Bar + + ); + + const wrapper = shallow(); + const text = wrapper.text(); + expect(wrapper.debug()).to.equal(` + + Foo + + Bar +`); + expect(text).to.equal('Bar'); + }); }); }); diff --git a/packages/enzyme/src/RSTTraversal.js b/packages/enzyme/src/RSTTraversal.js index 9148674bd..6c1aa450b 100644 --- a/packages/enzyme/src/RSTTraversal.js +++ b/packages/enzyme/src/RSTTraversal.js @@ -128,7 +128,21 @@ export function nodeMatchesObjectProps(node, props) { return isSubset(propsOfNode(node), replaceUndefinedValues(props)); } -export function getTextFromNode(node) { +function getTextFromHostNode(hostNode) { + if (typeof hostNode === 'string') { + return String(hostNode || ''); + } + if (!hostNode) { + return ''; + } + return hostNode.textContent || ''; +} + +function getTextFromRSTNode(node, { + getCustom, + handleHostNodes, + recurse, +}) { if (node == null) { return ''; } @@ -137,9 +151,33 @@ export function getTextFromNode(node) { return String(node); } - if (node.type && typeof node.type === 'function') { - return `<${node.type.displayName || functionName(node.type)} />`; + if (getCustom && node.type && typeof node.type === 'function') { + return getCustom(node); + } + + if (handleHostNodes && node.nodeType === 'host') { + return handleHostNodes(node); } + return childrenOfNode(node).map(recurse).join(''); +} - return childrenOfNode(node).map(getTextFromNode).join(''); +export function getTextFromNode(node) { + return getTextFromRSTNode(node, { + recurse: getTextFromNode, + getCustom({ type }) { + return `<${type.displayName || functionName(type)} />`; + }, + }); +} + +export function getTextFromHostNodes(node, adapter) { + return getTextFromRSTNode(node, { + recurse(item) { + return getTextFromHostNodes(item, adapter); + }, + handleHostNodes(item) { + const nodes = [].concat(adapter.nodeToHostNode(item, true)); + return nodes.map(getTextFromHostNode).join(''); + }, + }); } diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js index 6b6c9e3f0..546c6136f 100644 --- a/packages/enzyme/src/ReactWrapper.js +++ b/packages/enzyme/src/ReactWrapper.js @@ -23,6 +23,7 @@ import { childrenOfNode, parentsOfNode, treeFilter, + getTextFromHostNodes, } from './RSTTraversal'; import { buildPredicate, reduceTreesBySelector } from './selectors'; @@ -574,22 +575,7 @@ class ReactWrapper { */ text() { const adapter = getAdapter(this[OPTIONS]); - return this.single('text', (n) => { - const node = adapter.nodeToHostNode(n, true); - if (!node) { - return typeof n === 'string' ? n : node; - } - - const nodeArray = Array.isArray(node) ? node : [node]; - const textContent = nodeArray.map((item) => { - if (!item) { - return ''; - } - return item.textContent || ''; - }); - - return textContent.join(''); - }); + return this.single('text', n => getTextFromHostNodes(n, adapter)); } /**