Nightwatchjs: как проверить, существует ли элемент без создания ошибки/сбоя/исключения
На странице, которую я тестирую, могут отображаться две кнопки: BASIC или ADVANCED.
Я хочу узнать, отображается ли кнопка ADVANCED - и если да, щелкните по ней.
Если отображается кнопка BASIC, я ничего не хочу делать и продолжу свой тест.
Все параметры Nightwatchjs, которые я экспериментировал, генерируют сообщение об ошибке. Например, если я "waitforpresent" или "waitforvisible", и кнопки там нет, он генерирует ошибку/сбой. Я просто хочу знать, какая кнопка присутствует, поэтому я могу принять решение в своем коде.
Вот что я пробовал:
try {
browser.isVisible('#advanced-search', function(result) {console.log(result.state); })
} catch (myError)
{
console.log(myError);
}
Мысли?
Ответы
Ответ 1
Вы можете достичь этого, используя элемент "Selenium protocol" и функцию обратного вызова, чтобы проверить статус результата, чтобы определить, был ли найден элемент, Например:
browser.element('css selector', '#advanced-search', function(result){
if(result.status != -1){
//Element exists, do something
} else{
//Element does not exist, do something else
}
});
Ответ 2
Синтаксис может быть немного выключен. Не очень хорошо знаком с NightWatchJS. Однако концепция остается той же.
//I would not wait for a element that should not exist
//rather I would find the list of the element and see if the count is greater than 0
//and if so, we know the element exists
browser.findElements(webdriver.By.css('#advanced-search')).then(function(elements){
if(elements.length> 0){
console.log(elements.length);
}
});
См. еще один пример здесь
Ответ 3
Кажется, вы на правильном пути с isVisible. Из документа nightwatch мы видим, что в обратном вызове вы можете проверить свойство result.value
, чтобы увидеть, был ли этот элемент видимым, т.е.
browser.isVisible('#advanced-search', results => {
if (results.value) { /* is visible */ }
else { /* is not visible */ }
});
В качестве альтернативы вы можете использовать подход, предложенный Сайфуром. Вызовите команду selenium api .elements
, а затем проверьте длину массива результатов:
browser.elements('css selector', '#advanced-search', results => {
if (results.value.length > 0) { /* element exists */ }
else { /* element does not exist */ }
});
Это фактически можно было бы обернуть в пользовательскую команду:
// isPresent.js
module.exports.command = function (selector, callback) {
return this.elements('css selector', selector, results => {
if (results.status !== 0) { // some error occurred, handle accordingly
}
callback(results.value.length > 0);
});
};
то в нормальном коде вы можете называть его следующим образом:
browser.isPresent('#advanced-search', advancedSearchPresent => {
// make decisions here
}
Если вы будете делать дополнительные вызовы api в обратном вызове, может быть разумным обернуть все это при вызове .perform
:
browser.perform((_, done) => {
browser.isPresent('#advanced-search', advancedSearchPresent => {
// ...do more stuff...
done();
});
});
Что касается необходимости .perform
, возможно, this.
Ответ 4
Моя команда использует одну функцию для аутентификации с помощью нескольких разных форм signin, и мы используем пользовательскую команду под названием ifElementExists
для выполнения логики ветвления для понимания того, в какой форме мы находимся. Мы также используем это на нескольких других страницах, которые не имеют лучшего метода для определения текущего состояния.
import { CustomCommandShorthand } from './customCommands';
import { isFunction } from 'lodash';
exports.command = function ifElementExists(this: CustomCommandShorthand, selector: string, ifTrue: Function, ifFalse?: Function) {
this.perform(() => {
if (!isFunction(ifTrue)) {
throw new Error(`The second argument must be callable. You passed a ${typeof ifTrue} instead of a function.`);
}
this.element('css selector', selector, function ifElementExistsCallback({ status }) {
if (status !== -1) {
return ifTrue();
}
if (isFunction(ifFalse)) {
ifFalse();
}
});
})
}