【问题标题】:How to access attributes of NodeList elements in Protractor如何在量角器中访问 NodeList 元素的属性
【发布时间】:2020-09-12 01:32:23
【问题描述】:

我正在尝试从 Protractor 中一个相当大的 HTML 表中读取值(大约一千行和 5 列)。 Protractor 的 element.all().getText() 方法在这方面很慢,所以我决定实现一个解决方案,使用 browser.executeScript 直接读取值,例如:

async getTextFromHtmlTable(){
    try{
        var rows = element.all(by.css('table[id^="P"] tr'));
        var numRows = await rows.count();
        var arrRows = [];

        for (var i = 2; i <= numRows; i++){
            console.log("********Processing row: " + i);
            var css = 'table[id^=\"P\"] tr:nth-child(' + i + ') td div div';
            //**Slow solution: var arrRowsText = await element.all(by.css(css)).getText();

            //Faster:
            var arrRowsText = await browser.executeScript("return document.querySelectorAll('" + css + "')").then(function(elements){
                var arrayRes = [];
                for (var j=0; j<elements.length; j++){
                    console.log("****** Element text: " + elements[j].textContent);
                    arrayRes.push(elements[j].textContent);    
                }

                return arrayRes;
            });

            arrRows.push(arrRowsText.join(';').replace(/;\s/gm, ";"));

        }
        return arrRows; 
    }catch(err){
        console.log ('Some error: ' + err)
    }; 
}

但是,执行测试时的控制台输出是:

********处理行:569
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义
********处理行:570
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义
****** 元素文本:未定义

无论我阅读什么属性(textContent、innerText、innerHTML...),它总是返回“未定义”。我做错什么了吗?感谢您的帮助!

【问题讨论】:

    标签: javascript html protractor nodelist


    【解决方案1】:

    我终于找到了解决方案,当 DublinDev 说 executeScript 不返回 NodeLists 时,他指出了我正确的方向。所以我考虑在 executeScript 方法中处理 NodeList 并让它返回一个文本数组而不是实际的 NodeList:

    var arrRowsText = await browser.executeScript("return (function(){" +
                "var nodes = document.querySelectorAll('" + css + "');" +
                "var arrayRes = [];" +
                "for (var j=0; j<nodes.length; j++){" +
                "  arrayRes.push(nodes[j].innerText);" +
                "}" +
                "return arrayRes;" +
                "})();");
    

    现在它就像一个魅力,使用 innerText 读取元素文本比使用 getText() 快得多。

    【讨论】:

      【解决方案2】:

      似乎节点列表是通过executeScript 方法作为webElements 数组返回的,因此getText() 应该可以工作。当某些东西已经是awaited 时,您也不需要使用.then()。你可以试试下面的代码吗?

      async getTextFromHtmlTable(){
        try{
            var rows = element.all(by.css('table[id^="P"] tr'));
            var numRows = await rows.count();
            var arrRows = [];
      
            for (var i = 2; i <= numRows; i++){
                console.log("********Processing row: " + i);
                var css = 'table[id^=\"P\"] tr:nth-child(' + i + ') td div div';
                //**Slow solution: var arrRowsText = await element.all(by.css(css)).getText();
      
                //Faster:
                var arrRowsText = await browser.executeScript("return document.querySelectorAll('" + css + "')");
                let allEleText = [];
                for(let j = 0; j < arrRowsText.length; j++){
                  allEleText.push(await arrRowsText[j].getText());
                }
      
                arrRows.push(allEleText.join(';').replace(/;\s/gm, ";"));
            }
            return arrRows; 
        }catch(err){
            console.log ('Some error: ' + err)
        }; 
      }
      

      【讨论】:

      • 我尝试了你的建议并且它有效,但缺点是 getText() 非常慢,正如我所说(检索 1,000 行 5 列的文本大约需要 7 分钟),我想尝试不同且更快的方法,而不是使用 WebElements。那么也许没有办法使用 Protractor 访问 HTML 节点的属性?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 2012-05-08
      • 1970-01-01
      相关资源
      最近更新 更多