简体   繁体   English

如何使用Selenium或Protractor获取HTML中嵌套元素的文本以实现自动化?

[英]How do i get the text of a nested element in HTML for automation using Selenium or Protractor?

I have below HTML code with me. 我跟下面有HTML代码。 I need to console log or print only the desc class text - "Print this" and not the spell class text in protractor or selenium. 我需要控制日志或仅打印desc类文本 - “打印此”而不是量角器或selenium中的spell类文本。

<span class="desc">
Print this
    <a class="new-link" href="#">
        <span class="spell">And not this</span>
    </a>
</span>

I tried to getText() but it prints the complete statement with below code - 我试着getText()但是它用下面的代码打印完整的语句 -

Print this And not this 打印这不是这个

In Protractor using Javascript: 在使用Javascript的Protractor中:

element(by.css('.desc')).getText().then(function(text){
    console.log(text);
});

In Selenium using Java: 在Selenium中使用Java:

System.out.println(driver.findElement(by.xpath('//*[@class=".desc"]')).getText());

How do i print the first part of the text only(ie, "Print this")? 如何仅打印文本的第一部分(即“打印此”)?

Any suggestions or help will be appreciated? 任何建议或帮助将不胜感激? Thanks. 谢谢。

ElementFinder.getText() calls innerHTML on the element and removes leading and trailing whitespaces, but innerHTML also includes all child elements of any level of nesting. ElementFinder.getText()在元素上调用innerHTML并删除前导和尾随空格,但innerHTML还包括任何嵌套级别的所有子元素。 There is no special property in DOM to get only first level text, but it is possible to implement by yourself. DOM中没有特殊属性可以只获取第一级文本,但可以自己实现。 Text in DOM is also a node and is stored in DOM tree, the same way as any tag element, it just has different type and set of properties. DOM中的文本也是一个节点,存储在DOM树中,与任何标记元素的方式相同,它只是具有不同的类型和属性集。 We can get first level children of the element of all the types with the property Element.childNodes , then iterate over them and keep only the text nodes, then concatenate their content and return the result. 我们可以使用属性Element.childNodes获取所有类型元素的第一级子元素,然后迭代它们并仅保留文本节点,然后连接它们的内容并返回结果。

In Protractor I've decided to add a custom method to the prototype of ElementFinder to make it easy to use, so any Protractor element would have it. 在Protractor中,我决定在ElementFinder的原型中添加一个自定义方法,使其易于使用,因此任何Protractor元素都可以使用它。 It's up to you where to place this extension code, but I'd suggest to include it somewhere before your tests, maybe in protractor.conf.js . 这取决于你在哪里放置这个扩展代码,但我建议在你的测试之前把它包含在某个地方,也许是在protractor.conf.js中

protractor.ElementFinder.prototype.getTextContent = function () {
    // inject script on the page
    return this.ptor_.executeScript(function () {
        // note: this is not a Protractor scope

        // current element
        var el = arguments[0];
        var text = '';

        for (var i = 0, l = el.childNodes.length; i < l; i++) {
            // get text only from text nodes
            if (el.childNodes[i].nodeType === Node.TEXT_NODE) {
                text += el.childNodes[i].nodeValue;
            }
        }

        // if you want to exclude leading and trailing whitespace
        text = text.trim();

        return text; // the final result, Promise resolves with this value

    }, this.getWebElement()); // pass current element to script
};

This method will return a Promise, which resolves with a value of text variable. 此方法将返回Promise,它使用text变量值解析。 How to use it: 如何使用它:

var el = $('.desc');

expect(el.getTextContent()).toContain('Print this');

// or 

el.getTextContent().then(function (textContent) {
    console.log(textContent); // 'Print this'
});

I used Michael's solution and embedded into my test spec without calling the function. 我使用Michael的解决方案并嵌入到我的测试规范中而不调用该函数。 It would still be better to use it as a separate function if the need to use is recurring. 如果需要重复使用它作为单独的功能仍然会更好。 However if you want an inline solution, Here's how to do it - 但是,如果您需要内联解决方案,请按以下步骤操作 -

it("Get First part of text", function(){
    browser.executeScript(function () {
        var el = arguments[0], text = '';
        for (var i = 0, l = el.childNodes.length; i < l; i++)
            if (el.childNodes[i].nodeType === Element.TEXT_NODE)
                text += el.childNodes[i].nodeValue;
        return text.trim();
    },$('.desc').getWebElement()).then(function(text){
        //use expect statements with "text" here as needed
    });
});

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM