admin管理员组文章数量:1391017
I'm trying to test a React ponent that renders an iframe and injects markup directly into that iframe. (I'm not trying to load a URL in the iframe.)
The ponent actually works quite well in a browser, but writing a test for it so far seems to be impossible. I'm not sure why.
Here is a shortened test case which proves the failure.
// Set up DOM
var jsdom = require( 'jsdom' ).jsdom;
global.document = jsdom( '' );
global.window = document.defaultView;
global.navigator = document.defaultView.navigator;
// Prepare React
var ReactTestUtils = require( 'react-addons-test-utils' );
var React = require( 'react' );
var Frame = React.createClass( {
ponentDidMount() {
console.log( 'iframe loaded. adding content' );
const iframe = this.refs.iframe;
console.log( 'adding content to', iframe.contentWindow ); // Should not be null
iframe.contentWindow.document.open();
iframe.contentWindow.document.write( 'Hello World!' );
iframe.contentWindow.document.close();
},
render() {
console.log( 'rendering iframe' );
return React.createElement( 'iframe', { ref: 'iframe' } );
}
} );
// Render the ponent
ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
To run this, you'll need the following npm packages installed: jsdom, react, react-addons-test-utils. You should be able to then run the above code using node.
I'm trying to test a React ponent that renders an iframe and injects markup directly into that iframe. (I'm not trying to load a URL in the iframe.)
The ponent actually works quite well in a browser, but writing a test for it so far seems to be impossible. I'm not sure why.
Here is a shortened test case which proves the failure.
// Set up DOM
var jsdom = require( 'jsdom' ).jsdom;
global.document = jsdom( '' );
global.window = document.defaultView;
global.navigator = document.defaultView.navigator;
// Prepare React
var ReactTestUtils = require( 'react-addons-test-utils' );
var React = require( 'react' );
var Frame = React.createClass( {
ponentDidMount() {
console.log( 'iframe loaded. adding content' );
const iframe = this.refs.iframe;
console.log( 'adding content to', iframe.contentWindow ); // Should not be null
iframe.contentWindow.document.open();
iframe.contentWindow.document.write( 'Hello World!' );
iframe.contentWindow.document.close();
},
render() {
console.log( 'rendering iframe' );
return React.createElement( 'iframe', { ref: 'iframe' } );
}
} );
// Render the ponent
ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
To run this, you'll need the following npm packages installed: jsdom, react, react-addons-test-utils. You should be able to then run the above code using node.
Share Improve this question asked Mar 16, 2016 at 0:17 Payton SwickPayton Swick 5901 gold badge6 silver badges9 bronze badges2 Answers
Reset to default 4I tested your code pretty thoroughly and ended up finding the issue to be ReactTestUtils.renderIntoDocument
.
ReactTestUtils.renderIntoDocument
creates a container for the Component, but doesn't attach to the DOM (anymore), thus why contentWindow
will be null for iframe
elements. If you read the ments in the ReactTestUtils
source you'll notice they are considering renaming renderIntoDocument
because technically it doesn't!
The solution, it seems, is to use directly ReactDOM
instead.
Here is a bit of code from the ReactTestUtils
source:
var ReactTestUtils = {
renderIntoDocument: function (instance) {
var div = document.createElement('div');
// None of our tests actually require attaching the container to the
// DOM, and doing so creates a mess that we rely on test isolation to
// clean up, so we're going to stop honoring the name of this method
// (and probably rename it eventually) if no problems arise.
// document.documentElement.appendChild(div);
return ReactDOM.render(instance, div);
},
}
Using ReactDOM
with your test case works:
// Set up DOM
var jsdom = require( 'jsdom' ).jsdom;
global.document = jsdom( '' );
global.window = document.defaultView;
global.navigator = document.defaultView.navigator;
// Prepare React
var ReactTestUtils = require( 'react-addons-test-utils' );
var React = require( 'react' );
var ReactDOM = require('react-dom')
var Frame = React.createClass( {
ponentDidMount() {
console.log( 'iframe loaded. adding content' );
const iframe = this.refs.iframe;
console.log( 'adding content to', iframe.contentWindow ); // Should not be null
iframe.contentWindow.document.open();
iframe.contentWindow.document.write( 'Hello World!' );
iframe.contentWindow.document.close();
// Should log "Hello World!"
console.log(iframe.contentWindow.document.body.innerHTML);
},
render() {
console.log( 'rendering iframe' );
return React.createElement( 'iframe', { ref: 'iframe' } );
}
} );
// Render the ponent
// NOPE
//ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
// YUP
ReactDOM.render(React.createElement(Frame), document.body)
It's too bad that this isn't mentioned in the docs for ReactTestUtils
.
You need to append the iframe to your document before contentWindow will bee available.
Check this code:
var iframe = document.createElement('iframe');
console.log(iframe.contentWindow);
document.body.appendChild(iframe);
console.log(iframe.contentWindow);
本文标签:
版权声明:本文标题:javascript - Why does rendering an iframe into jsdom with ReactTestUtils not provide a contentWindow? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744636600a2616858.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论