为什么使用 ReactTestUtils 将 iframe 渲染到 jsdom 中不提供 contentWindow
Why does rendering an iframe into jsdom with ReactTestUtils not provide a contentWindow?
我正在尝试测试一个渲染iframe并将标记直接注入该iframe的React组件。(我没有尝试在 iframe 中加载 URL。
该组件实际上在浏览器中运行良好,但到目前为止似乎不可能为其编写测试。我不知道为什么。
这是一个缩短的测试用例,它证明了失败。
// 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( {
componentDidMount() {
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 component
ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
要运行它,你需要安装以下 npm 包:jsdom、react、react-addons-test-utils。然后,您应该能够使用 node 运行上述代码。
我非常彻底地测试了您的代码,最终发现问题ReactTestUtils.renderIntoDocument
。
ReactTestUtils.renderIntoDocument
为组件创建了一个容器,但不再附加到 DOM,因此contentWindow
对于iframe
元素为 null。如果您阅读ReactTestUtils
源中的评论,您会注意到他们正在考虑重命名renderIntoDocument
因为从技术上讲它没有!解决方案似乎是直接使用ReactDOM
。
以下是来自ReactTestUtils
源的一些代码:
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);
},
}
将ReactDOM
与测试用例一起使用可以:
// 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( {
componentDidMount() {
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 component
// NOPE
//ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
// YUP
ReactDOM.render(React.createElement(Frame), document.body)
太糟糕了,这在ReactTestUtils
的文档中没有提到.
您需要在
contentWindow 可用之前将 iframe 附加到文档中。
检查此代码:
var iframe = document.createElement('iframe');
console.log(iframe.contentWindow);
document.body.appendChild(iframe);
console.log(iframe.contentWindow);
相关文章:
- 在Twitter上用ie9中的空白src访问iframe的contentWindow
- contentWindow.document.body is null
- JSDom未加载相关脚本
- 为什么iframe.contentWindow==为null
- iframe contentDocument and contentWindow is null
- 摩卡+柴+jsdom Can't加载自定义模块目录
- 在cloudfoundry上进行JSDOM刮擦;不起作用
- jsdom:dispatchEvent/addEventListener似乎不起作用
- Jsdom 为某些 URL 抛出错误
- 使用JSDOM,我想获得所有具有相同名称的输入标记
- 如何从其contentWindow引用iframe
- 使用[jsdom+qs]抓取html
- 如何使用jsdom从节点REPL解析DOM
- Jsdom如何从网站抓取信息
- 使用 JSDom 在节点测试环境中正确接近“窗口”
- 为什么使用 ReactTestUtils 将 iframe 渲染到 jsdom 中不提供 contentWindow
- JSDOM/Cheerio 大大改变了 HTML
- JSDOM - 硬核方式 - 添加外部脚本并使用它
- 在 JSDom 中检测 301 重定向或 404
- 在 jsdom 加载的脚本中设置全局变量