开玩笑测试中未定义innerText

IT技术 javascript reactjs jestjs
2021-05-12 08:37:22

使用 jest 进行测试时,我看到该属性innerText未定义,而未在测试中它具有正确的值。

  it('get text from div', () => {
    const div = document.createElement('DIV')
    div.innerHTML = '<br>a<br>b<br>c'
    console.log('innerText', div.innerText) // undefined
    console.log('textContent', div.textContent) // 'abc'
    // expect(getTextFromDiv(div).length).toMatchSnapshot()
  })

但是当在笑话测试中使用相同的代码时,innerText 显示:

'a

b

c'

和 textContent 是'abc'.

为什么在玩笑中的innerText 是未定义的,当它不是在玩笑中时,它的值是真实的?

这是它工作的代码(不是开玩笑):

const addTextInRichTextToPdf = (doc, text, offsetY) => {
  const div = document.createElement('DIV')
  div.innerHTML = '<br>a<br>b<br>c'
  console.log('innerText', div.innerText) // print the real value
  console.log('textContent', div.textContent) // 'abc'
  ...
2个回答

如果您使用的是默认testEnvironment,那么你正在使用jsdom。

您可以检查这个问题,看看为什么它没有在 jsdom 中实现:https : //github.com/tmpvar/jsdom/issues/1245

主要问题是innerText依靠布局引擎进行指导,而jsdom没有布局引擎

如果您想要“完整”浏览器支持,您可以查看puppeteer

基于 Matthew Souther 的回答,这是我想出的代码片段,用于一次性获取多个 dom 子元素的文本:

const getInnerText = (element) => element?.textContent
          ?.split('\n')
          .filter((text) => text && !text.match(/^\s+$/))
          .map((text) => text.trim());

textContent 带来了很多噪音,当 html 元素没有文本(或只有空格的字符串)时,它返回一个空字符串。因此,我过滤空行和仅包含空格(或制表符)的行。我还修剪了结果条目。我在任何地方都使用问号(可选链接)的原因是,如果文本丢失,我更愿意得到“未定义”而不是抛出错误。

以下是该功能的使用方法:

const getInnerText = (element) => element?.textContent
          ?.split('\n')
          .filter((text) => text && !text.match(/^\s+$/))
          .map((text) => text.trim());

const div = document.createElement('DIV')
div.innerHTML = `
hello

world 👋
`;

const result = getInnerText(div);

// will display "world 👋"
console.log(result?.[1])