【问题标题】:How to get immediate text with webdriverIO如何使用 webdriverIO 获取即时文本
【发布时间】:2026-02-08 02:05:01
【问题描述】:

我有这样的 html DOM:

<div class="alert alert-danger">
    <button class="close" aria-hidden="true" data-dismiss="alert" type="button">×</button>
    Your username or password was incorrect.
</div>

我想获取Your username or password was incorrect. 文本。

如果我这样做:

$('.global-alerts div.alert-danger').getText()  

然后我得到这个×

有没有办法获取 div 元素中唯一的文本部分?

我设法做到了这样的事情:

getErrorMessageText() {
    return browser.execute(function () {
      const selector = '.global-alerts div.alert-danger';
      // @ts-ignore
      return $(selector).contents().not($(selector).children()).text().trim();
    });
  }  

而且它有效。
但是有人有更好的主意吗?还是更像这里的 webdriverIO 方法?

【问题讨论】:

  • 正在用新类将该行文本包装在一个 div 中,然后选择该 div 不是一个选项?
  • 不,不是一个选项,因为我无法更改被测应用的源代码

标签: css-selectors webdriver-io


【解决方案1】:

如果你使用这样的东西,它会起作用吗?

var innerHTML = $('.global-alerts div.alert-danger').getHTML(false);

false 参数表示是否在输出中包含选择器元素标签。

【讨论】:

  • It got me: 您的用户名或密码不正确.所以我可以测试它是否包含感觉更宽松的测试文本然后测试文本是否等于“您的用户名或密码不正确。”。但我会排除你的答案,因为它看起来比我设法得到的更简单:) 非常感谢你的建议!
【解决方案2】:

严重的解决办法

除了使用执行以从页面“获取”该信息外,我没有看到任何其他方法。 但是,我会将它放在浏览器命令中(要么在配置“before”挂钩中执行,要么添加一个在 before 挂钩中添加命令的服务) 这就是我最终将 typescript 视为主要语言,忽略了 jQuery 的使用,并考虑到您使用了 before 钩子:

/**
 * Gets executed before test execution begins. At this point you can access to all global
 * variables like `browser`. It is the perfect place to define custom commands.
 * @param {Array.<Object>} capabilities list of capabilities details
 * @param {Array.<String>} specs        List of spec file paths that are to be run
 * @param {Object}         browser      instance of created browser/device session
 */
before: function (_capabilities: any, _specs: any, browser: WebdriverIO.Browser) {
    browser.addCommand(
        'getNodeText',
        async function() {
            return this.execute(
                (selector: string) =>
                    Array.from( document.querySelector(selector).childNodes || [])
                         .filter((n: HTMLElement) => n.nodeType === n.TEXT_NODE)
                         .map(n => n.textContent)
                         .reduce(function(f, c) {return f+c;}, '')
                         .replace('\n', '')
                         .trim(),
                this.selector
            );
        },
        true
    );
},

使用这种方法,typescript 可能会抱怨传递给 webdriver 以执行的函数,因此您可以正确编写它,或者将其移动到 .js 文件并完成它。 只需注意 document.querySelector(selector),理论上它不应该为空,因为该命令是在 webdriver 元素已经找到的上执行的。

获取文本的方式就是await (await $('.alert.alert-danger').getNodeText()); 这应该从节点本身返回完整的字符串,而不是任何子子节点。

注意:如果你最终得到一个像 &lt;div id="mytxt"&gt;my text style is &lt;strong&gt;strong&lt;/strong&gt; and &lt;italic&gt; italic &lt;/italic&gt;. - html fan&lt;/div&gt; 这样的元素,并且你执行了这个 getNodeText(),你可能最终得到值 my text style is and . - html fan


“不要太在意”解决方案

这种方法还可以检查“x”按钮是否仍然存在。

await expect($('.global-alerts div.alert-danger')).toHaveText('xYour username or password was incorrect.')

【讨论】:

  • 非常感谢您的建议!我非常感谢:)