在puppeteer中Selenium getText()兼容textContent?

时间:2018-04-13 15:20:46

标签: selenium puppeteer

在硒中,getText()会返回normalised text。在以下情况中,它返回Unit Tests 15

<div test-id="something">
  <div>Unit Tests</div>
  <div>15</div>
</div>

我正在将1000行测试代码从selenium转换为puppeteer,并且将something.textContentUnit Tests 15进行比较失败,因为textContent返回Unit Tests15而不是{ {1}}。

所以我希望在木偶戏中模仿selenium的getText()。目前有什么事吗?

我认为我的选择是:

  • 删除空格,然后比较(不理想)
  • 在page.evaluate()回调(低效)
  • 中实现getVisibleText
  • 另一种选择?

2 个答案:

答案 0 :(得分:0)

这是我实现的解决方法的最终版本,它尽可能地模拟getText()。它可能不是100%,但它对我现有的测试运行良好。

await page.goto(url);
await page.evaluate(`
  window.dalang = {
    _isBlock: function(el) {
      var display = getComputedStyle(el).display;
      if (display) {
        switch (display) {
          case "block": return true;
          case "inherit": break;
          default: return false;
        }
      }
      switch(node.nodeName.toLowerCase()) {
      case "span": case "b": case "i":
        return false;
      }
      return true;
    },
    getVisibleText: function(el) {
      var text = '', s, cns = el.childNodes;
      for (var i = 0; i < cns.length; i++) {
        var node = cns[i];
        var sep = ' ';
        if (node.nodeType == 1) {
          switch(node.nodeName.toLowerCase()) {
          case "style": case "script": break;
          default:
            s = this.getVisibleText(node);
            if (this._isBlock(node)) sep = '\\n';
            break;
          }
        } else if (node.nodeType == 3) {
          s = node.textContent;
        } else {
          s = '';
        }
        s = s.replace(/[\\n]+/g,'\\n').replace(/^[ \\t\\n]+|[ \\t\\n]+$/,'');   // trim only soft space
        if (s) {
          text = (text && text + sep) + s;
        }
      }
      return text.replace(String.fromCharCode(160),' ');
    },
  };
`);

然后,当我想要将文本与我的测试值进行比较时......

await page.evaluate(el => dalang.getVisibleText(el), element)

答案 1 :(得分:0)

html-to-text看起来像是一个解决方案。以下是此软件包的问题实现:

const puppeteer = require('puppeteer');
const { fromString } = require('html-to-text');

const html = `
<html>
  <body>
    <div test-id="something">
      <div>Unit Tests</div>
      <div>15</div>
    </div>
  </body>
</html>`;

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(`data:text/html,${html}`);

  const somethingToTest = await page.$('[test-id="something"]');

  const pureText = fromString(
    await page.evaluate(el => el.innerHTML, somethingToTest)
  );

  console.log(pureText); // Unit Tests 15

  await browser.close();
})();