Как получить доступ к атрибутам элементов NodeList в Protractor - PullRequest
0 голосов
/ 25 мая 2020

Я пытаюсь прочитать значения из довольно большой HTML таблицы в Protractor (около тысячи строк и 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
****** Текст элемента: undefined
****** Текст элемента: undefined
****** Текст элемента: undefined
****** Текст элемента: undefined
****** Текст элемента: undefined
******** Обработка строка: 570
****** Текст элемента: undefined
****** Текст элемента: undefined
****** Текст элемента: undefined
***** * Текст элемента: undefined
****** Текст элемента: undefined

Независимо от того, какой атрибут я прочитал (textContent, innerText, inner HTML ...), он всегда возвращает undefined . Я что-то не так делаю? Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Я наконец нашел решение этой проблемы, DublinDev указал мне в правильном направлении, когда он сказал, что executeScript не возвращает NodeLists. Поэтому я подумал об обработке NodeList внутри метода executeScript и о том, чтобы он возвращал массив текстов вместо фактического 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 ().

0 голосов
/ 25 мая 2020

Похоже, что нодлисты возвращаются методом executeScript как массив webElements, поэтому getText() должен работать. Вам также не нужно использовать .then(), когда что-то уже await ed. Можете ли вы попробовать приведенный ниже код?

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)
  }; 
}
...