Javascript 如何使用react检查实际的DOM节点

Javascript 如何使用react检查实际的DOM节点,javascript,dom,reactjs,enzyme,Javascript,Dom,Reactjs,Enzyme,有没有一种方法可以获取实际的DOM节点,这样我就可以使用DOM api来查询它,而不是使用Ezyme的api,它只适用于边缘情况,例如,我需要声明有关DOM节点本身的内容。如果使用jsdom创建DOM,如下所示: import jsdom from 'jsdom'; const doc = jsdom.jsdom('<!doctype html><html><body></body></html>'); global.document

有没有一种方法可以获取实际的DOM节点,这样我就可以使用DOM api来查询它,而不是使用Ezyme的api,它只适用于边缘情况,例如,我需要声明有关DOM节点本身的内容。

如果使用jsdom创建DOM,如下所示:

import jsdom from 'jsdom';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.document = doc;
global.window = doc.defaultView;
从“jsdom”导入jsdom;
const doc=jsdom.jsdom(“”);
global.document=doc;
global.window=doc.defaultView;
然后你可以用酶来呈现你想要测试的任何东西

然后,您可以针对要查找的样式断言:


expect(包装器).to.have.style(“显示”、“无”)

也许您正在寻找酶的

我不明白这是为什么。如果您
console.log()

HTMLInputElement {
  '__reactInternalInstance$yt1y6akr6yldi': 
   ReactDOMComponent {
     _currentElement: 
      { '$$typeof': Symbol(react.element),
        type: 'input',
        key: null,
        ref: null,
        props: [Object],
        _owner: [Object],
        _store: {} },

我遇到了同样的问题。在我的例子中,我正在测试使用
react-aria-modal
构建的东西,它在DOM的不同部分呈现overlay-div,而不是使用
mount()
呈现的初始元素。为了测试这种渲染是否正确,我需要更全面地查看DOM。为此,我使用了
render()
attachTo
选项,以确保我的测试DOM在真正的浏览器中看起来应该是这样的。是文档中对该技术的一个很好的总体描述

根据您的需要,您可以使用Tyler Collier的方法来处理DOM的更多局部部分(
findDOMNode
,使用
instance()
),或者使用mine来获得更全局的视图

下面是我的用例的示例规范,展示了如何设置/使用/拆除模拟DOM:

import MyModalComponent from '../components/my-modal-component'
import React from 'react'
import { jsdom } from 'jsdom'
import { mount } from 'enzyme'

describe('<MyModalComponent /> Component', function(){

  let wrapper

  beforeEach(function(){
    window.document = jsdom('')
    document.body.appendChild(document.createElement('div'))
  })

  afterEach(function(){
    wrapper.detach()
    window.document = jsdom('')
  })

  it('renders the modal closed by default', () => {
    wrapper = mount(
      <MyModalComponent prop1={"foo"}
                        prop2={"bar"}
      />, { attachTo: document.body.firstChild }
    )
    expect(wrapper.html()).to.contain('Content in component')
    expect(document.body.innerHTML).to.not.contain('Content in overlay')
  })

})
从“../components/my modal component”导入MyModalComponent
从“React”导入React
从“jsdom”导入{jsdom}
从“酶”导入{mount}
描述(‘组件’,函数(){
让包装器
beforeach(函数(){
window.document=jsdom(“”)
document.body.appendChild(document.createElement('div'))
})
之后(函数(){
wrapper.detach()
window.document=jsdom(“”)
})
它('呈现默认关闭的模式',()=>{
包装=装载(
,{attachTo:document.body.firstChild}
)
expect(wrapper.html()).to.contain('组件中的内容')
expect(document.body.innerHTML).to.not.contain('覆盖中的内容')
})
})

您可以使用以下方法:

const dialog = component.find(Modal);
let modal = dialog.node._modal;
modal.getDialogElement().querySelector('#saveBtn')
基于react bootstrap web站点中的模态测试


您可以使用
wrapper.getDOMNode()


如果要打印整个DOM

const wrapper = shallow(<MyComponent/>);
console.log("DOM tree for humans", wrapper.text());
const wrapper=shallow();
log(“人类的DOM树”,wrapper.text());

据我所知,我正在使用使用jsdom的mount,但是如何获得实际包装器的DOM节点,以便我可以使用DOM api?例如,要查询className但不使用prop('className'),可能有更好的方法,但您可以始终在元素上调用
.html()
,然后使用类似于
DOMParser()
:当我尝试您的技术时,它似乎可以按预期工作。换句话说,
ReactDOM.findDOMNode(wrapper.instance())!=wrapper.instance()
。FWIW,我使用的是React 15和Ezyme 2.3.0。我不知道这是否是因为我使用了jsdom(或者,我认为我是。我很愚蠢,我没有对我运行的代码进行永久链接)。您正在使用jsdom吗?是的,我正在使用jsdom 9.1.0-很抱歉,我忘了提到这只适用于根包装器(React组件
mount()
ed或
shallow()
ed的根包装器)。有关更广泛适用的解决方案,请参见@tonyjmnz的答案。
const dialog = component.find(Modal);
let modal = dialog.node._modal;
modal.getDialogElement().querySelector('#saveBtn')
const wrapper = shallow(<MyComponent/>);
console.log("DOM tree for humans", wrapper.text());