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

1

Изображение 174551 Я пытаюсь получить два значения с сайта, который я автоматизирую. Я перебираю массив элементов и пытаюсь сравнить значение раскрывающегося списка с тем, что находится на странице, чтобы убедиться, что они совпадают друг с другом. Одно из значений может быть доступно только .getValue(). Доступ к .getText() осуществляется с помощью .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 равными chunkView result.value. Токовый выход может регистрировать только два отдельных значения.

  • 0
    Вы хотите, чтобы ваше утверждение пришло после browser.getText() ? Я также предполагаю, что chunkView еще не установлен к тому времени, когда он получает это утверждение?
  • 0
    Из любопытства вы / ваша команда только начинаете использовать ночные часы? Вы связаны с этим, или вы могли бы перейти на другую тестовую среду? А какую клиентскую среду вы используете (React, Angular и т. Д.)?
Показать ещё 1 комментарий
Теги:
nightwatch.js

3 ответа

1

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

Возможно, вы захотите привыкнуть работать с Promise JavaScript. Так как движки 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}'');
            });
        }
    });
  • 0
    Поэтому в настоящее время я получаю сообщение об ошибке при использовании client.assert. Я немного исследовал, потому что я делаю это больше на стороне сервера с узлом, и я изменил клиента на console.assert. Теперь все, что я вижу, является ошибкой утверждения. Мне нравится решение Promise, и оно имеет смысл. Дайте мне знать, если вы что-нибудь придумаете. Пожалуйста, смотрите прикрепленный скриншот.
  • 0
    Да, client.assert , вероятно, client.assert , потому что client не определен в вашем (или моем) коде, и на самом деле, похоже, что я использовал его в первую очередь, когда посмотрел на api docs. Согласно документам ( nightwatchjs.org/api#assertions ) объект assert является расширением встроенного объекта nodejs assert. Вы захотите использовать browser.assert.strictEqual ( nodejs.org/api/… ). Я обновлю свой ответ.
Показать ещё 2 комментария
0

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

0

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

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

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!')
    }
})
  • 0
    Таким образом, они кажутся одинаковыми, но я обнаружил, что этот код даже не выполняет оператор if в конце.
  • 0
    @ Джек, если вы говорите о втором фрагменте кода, можете ли вы попробовать обновленный код?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню