Что такое локатор by.js для Protractor/WebDriverJS?

Недавно я заметил, что новый новый локатор добавлен в документацию Protractor - by.js():

Располагает элементы, оценивая выражение JavaScript, которое может быть либо функцией, либо строкой.

Я понимаю, что предоставляет этот локатор, но мне не хватает реальных случаев использования, когда этот локатор может быть полезен. Когда я предпочитаю использовать by.js вместо других встроенных локаторов, например by.css?

Ответ 1

Я считаю, что использование элементов с использованием основных функций javascript, когда css и другие локаторы элементов не помогут или не имеют свойств, которые мы могли бы использовать. Сценарии -

  • Если вы получаете элемент, использующий основные функции javascript, передавая его в browser.executeScript, тогда by.js может быть использован для его замены.

Пример: -

Предположим, вам нужно было получить элемент, который отображается сверху между ними, вы можете получить его таким образом -

var ele = element(by.js(function(){
    var ele1 = document.getElementById('#ele1');
    var ele2 = document.getElementById('#ele2');
    var val = ele1.compareDocumentPosition(ele2);
    if(val === 4) return ele1;
    else return ele2;
}));
  1. Если вы хотите получить элемент, используя его значения css, такие как цвет, шрифт и т.д. Хотя в этом случае можно использовать filter, но by.js также поддерживает его.
  2. Если элементы недоступны css или xpath или любые другие локаторы, например псевдоэлементы, которые имеют анимации или переходы.

Пример: -

Предположим, что если элемент, имеющий переходы :before и :after -

.element:before {
    color: rgb(255, 0, 0);
}

Чтобы проверить цвет элемента, мы могли бы использовать by.js, проходящий в выражении javascript, чтобы получить элемент -

var ele = element(by.js(function(){
    return window.getComputedStyle(document.querySelector('.element'), ':before');
}));
expect(ele.getCssValue('color')).toEqual('rgb(255, 0, 0)');

Надеюсь, что это поможет.

Ответ 2

Я думаю, что случаи для этого довольно тонкие, но я вижу, что это полезно, когда на клиенте недоступны данные (или, что недопустимо), через селен.

В примере на странице документации содержится ссылка на offsetWidth:

spans[i].offsetWidth > 100

Используется в контексте:

var wideElement = element(by.js(function() {
  var spans = document.querySelectorAll('span');
  for (var i = 0; i < spans.length; ++i) {
    if (spans[i].offsetWidth > 100) {
     return spans[i];
    }
  }
}));
expect(wideElement.getText()).toEqual('Three');

В качестве альтернативы, может существовать прецедент, если в окне есть какой-либо сторонний API или какая-либо другая служба, которая может помочь найти элемент.