Как напечатать массив в JavaScript, который имеет элемент, вставленный в него асинхронно? - PullRequest
2 голосов
/ 22 мая 2019

Я работаю над комплексными тестами пользовательского интерфейса, используя транспортир для неуглового применения. У меня есть куча тегов LI внутри тега UL, который отображается на веб-странице. и мне нужно получить значение всех тегов LI и сохранить их в массиве, а затем проверить, отсортирован ли этот массив или нет.

checkResultList() {
        // element locator for UL
        const listResult = element(by.xpath('//*[@id="flightModuleList"]'));
        browser.wait(EC.visibilityOf(this.listResult), 60000);

        // Get All the LIs as ElementArrayFinder
        let items = listResult.all(by.xpath('//li//div[@class="uitk-col all-col-shrink"]//div[contains(@class,"primary-content")]//span[contains(@class, "full-bold")]'));

        let prices = [];
        items.each(function(ele, index) {
            ele.getText().then(function(text) {

                // get floating point numbers from string
                const price = text.match(/[+-]?\d+(\.\d+)?/g).map(function(v) {

                    prices.push(parseFloat(v));
                    return parseFloat(v);
                });

            })
        })

        expect(prices.length).toBe(80); // prints 0

    }

Я ожидаю, что в массиве цен будет передано все значение, прежде чем я проверю его длину.

1 Ответ

1 голос
/ 22 мая 2019

Вот пример, который может дать вам некоторое вдохновение. Код ниже сначала ожидает текст элемента, а затем получает любые цифры из текста. Затем он ожидает разрешения всех элементов, прежде чем сгладить массив (используя reduce) на один уровень.

// mock for items
class Item {
  constructor(value) {
    this.value = value;
  }
  
  getText() {
    return Promise.resolve(this.value);
  }
}

let items = ["foo", "bar +12.54", "baz -1.29", "1.23 4.56"]
  .map(str => new Item(str));

// answer
(async function () {
  let prices = items.map(async item => {
    let text = await item.getText();
    let prices = text.match(/[+-]?\d+(\.\d+)?/g) || [];
    return prices.map(parseFloat);
  });
  
  prices = await Promise.all(prices);
  prices = prices.reduce((acc, arr) => acc.concat(arr));

  console.log(prices);
})();

В качестве альтернативы вы можете упростить это, ожидая сначала всех результатов. Однако, поскольку сопоставление с регулярным выражением и анализ с плавающей точкой независимы для каждого элемента, который я выбрал , а не , чтобы сделать это. Приведенный выше код сопоставит регулярное выражение со строкой, как только обещание разрешится, вместо того, чтобы ждать разрешения всех обещаний, а затем сопоставит каждый элемент с регулярным выражением (как показано ниже).

Код (более компактный, менее оптимальный) для этого будет:

(async function () {
  let texts = await Promise.all(items.map(item => item.getText()));
  let prices = texts
    .map(text => text.match(/[+-]?\d+(\.\d+)?/g) || [])
    .reduce((acc, arr) => acc.concat(arr))
    .map(parseFloat);
  console.log(prices);
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...