Есть ли способ перебирать и сравнивать элементы dom в nodejs?

Я пытаюсь получить два значения с сайта, который я автоматизирую. Я перебираю массив элементов и пытаюсь сравнить значение раскрывающегося списка с тем, что находится на странице, чтобы убедиться, что они совпадают друг с другом. Одно из значений может быть доступно только .getValue(), Доступ к другому .getText(), Я хотел бы сохранить result.value из этих функций обратного вызова и сравнить результаты.

Я пытался console.log оба эти значения, и я получаю их обратно, но я не могу ничего вернуть из этой функции обратного вызова. Я также не могу сохранить его значение в переменной и вернуть его либо. Я пытался сделать это в простом JavaScript с document.getElementById() но это работает для JavaScript на стороне клиента, а не на стороне сервера, как nodejs. Просто пытаюсь сравнить два значения вместе

for (let i = 1; i <= 20; i++) {
  browser
    .element('css selector', `mat-nav-list > a:nth-child(${i})`,
      function(result) {
        if (result.value && result.value.ELEMENT) {
          browser.isVisible(`mat-nav-list > a:nth-child(${i})`,
            function(result) {
              if (result.value === true) {

                browser.click(`mat-nav-list > a:nth-child(${i})`)
                let chunkView = '#mat-input-0';
                let sideBar = `body > gps-app-root > div > div.sidebar-desktop > gps-app-sidebar-menu > div > div.product-list-wrap > mat-nav-list > a:nth-child(${i}) > div`

                browser.getValue(chunkView, function(result) {
                  chunkView = result.value
                  console.log(chunkView)
                })

                browser.getText(sideBar, function(result) {
                  console.log(result.value);
                })
              }
            })
        }
      })
  //.pause(2000)
  //.pause(10000)
}

Когда я перебираю цикл, я ожидаю получить два значения sideBar result.value равному chunkViewresult.value, Токовый выход может регистрировать только два отдельных значения.

3 ответа

Решение

Я обнаружил, что если я вложил.getValue() и.getText и назначил переменные, я смог сравнить их.

Я не использовал Nightwatch.js раньше, поэтому я основываю свой ответ на предположении, что browser.click, browser.getValue, а также browser.getText работать асинхронно, как это довольно часто встречается в тестовых средах UI и UI, и, если бы они выполнялись синхронно, не было бы никакого смысла в использовании обратных вызовов.

Вы, вероятно, захотите привыкнуть работать с JavaScript Promise, Так как движки JavaScript являются однопоточными, нет возможности спин-блокировки / спящего режима, в то время как другой поток обрабатывает некоторые изменения (например, обновление пользовательского интерфейса после события click). Promise позволяет обойти это, работая с обратными вызовами и обрабатывая события за кулисами.

Затем вы можете связать обещания, используя promise.then() которые передают возвращенное значение следующему обратному вызову.

В вашем случае, однако, я бы обернул две функции, которые получают значения в обещаниях, а затем использовал Promise.all(), Это позволяет им выполнять в любом порядке, что может улучшить производительность.

browser.isVisible(`mat-nav-list > a:nth-child(${i})`,
    function(result) {
        if (result.value === true) {
            browser.click(`mat-nav-list > a:nth-child(${i})`);
            let chunkView = '#mat-input-0';
            let sideBar = `body > gps-app-root > div > div.sidebar-desktop > gps-app-sidebar-menu > div > div.product-list-wrap > mat-nav-list > a:nth-child(${i}) > div`;

            let valPromise = new Promise(resolve => {
                browser.getValue(chunkView, resolve);
            });

            let textPromise = new Promise(resolve => {
                browser.getText(sideBar, resolve);
            });

            Promise.all([valPromise, textPromise]).then(([valueResult, textResult]) => {
                browser.assert.strictEqual(valueResult.value, textResult.value, 
                    `Server-side value '${value.result}' does not match client-side value '${text.result}'`);
            });
        }
    });

Вы всегда можете использовать.execute() из nightwatch и запускать любой javascript, который хотите на странице.

client.execute(
  function (data) { 
    // this is runned in browser
  },
  [what_you_pass_to_the_function_above_as_data], // multiple parameters = multiple elements in array
  function (result) {
    // result.status == -1 if error happend 
    // here you cand compare what you want... result.value is the returned things from the browser executed function.
  }
);

Использовать perform метод, так что обратные вызовы должны быть выполнены до следующей команды. (см. https://github.com/nightwatchjs/nightwatch/wiki/Understanding-the-Command-Queue)

Что-то вроде этого

browser.getValue(chunkView, function(result) {
  chunkView = result.value
  console.log(chunkView)
}).perform(function() {
  // here you have access to chunkView so you can compare it
  browser.getText(sideBar, function(result) {
    console.log(result.value);
    if (chunkView === result.value) {
      console.log('They are the same!');
    }
  })
});

или вы могли бы цепь perform команды, чтобы вы могли сделать сравнение в конце относительно количества промежуточных шагов.

let chunkView = '#mat-input-0',
    chunkViewResult;
let sideBar = `body > gps-app-root > div > div.sidebar-desktop > gps-app-sidebar-menu > div > div.product-list-wrap > mat-nav-list > a:nth-child(${i}) > div`,
    sideBarResult;

browser.getValue(chunkView, function(result) {
    chunkViewResult = result.value
    console.log(chunkView)
}).getText(sideBar, function(result) {
      sideBarResult = result.value
      console.log(sideBarResult);

}).perform(function() {
    if (chunkViewResult === sideBarResult) {
        console.log('They are the same!')
    }
})
Другие вопросы по тегам