Как создать условие в транспортире, когда существует элемент или нет
Я использую Protractor JS. И сайт написан в Angular JS.
Итак, у меня есть тумблер. И я заметил, что значение в тумблере переключается с true на false и
false, когда вы выключаете или выключаете.
Я пытаюсь создать условие, когда Protractor посещает мою страницу, когда он видит тумблер "выключен", он превратит его в 'on'. Если тумблер уже 'on', он сначала выключит его, а затем снова закроет его 'on'.
Я придумал этот код, но по какой-то причине он не работает:
if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
element(By.id('toggle-switch')).click();
console.log('in the if')
}
else{
element(By.id('toggle-switch')).click();
browser.sleep(3000);
element(By.id('toggle-switch')).click();
console.log('in the else')
}
Этот код работает только для оператора if. По какой-то причине он никогда не пойдет на другое. Вот ошибка, которую я получаю:
NoSuchElementError: элемент не найден с использованием локатора: By.cssSelector( "[value = \" false\ "]" )
Итак, я попробовал
.isPresent()
вместо .isDisplayed()
Я больше не получаю вышеуказанную ошибку, но по какой-то причине при использовании .isPresent() она всегда переходит к оператору if и запускает только это, и никогда не выполняет оператор else. Не отображаются ошибки.
Если есть лучший способ, дайте мне знать. Это кажется очень ограниченным, чтобы не создавать надлежащие условия в этой структуре.
Ответы
Ответ 1
помните, что isDisplayed() возвращает обещание, вы не можете попробовать:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});
Ответ 2
isDisplayed()
не работал у меня. Возможно, API был изменен. isPresent()
- мое решение:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
Ответ 3
Проблема заключается в том, что isDisplayed()
, так как множество методов в WebDriverJS/Protractor возвращает promise, который по определению является "правдивым", что затрудняет отладку таких проблем.
Давайте рассмотрим пример, чтобы лучше понять.
Представьте, что у вас есть следующий код, который может выглядеть с первого взгляда:
var elm = $("#myid");
if (elm.isDisplayed()) {
// do smth
} else {
// do smth else
}
Теперь у него есть серьезная проблема. do smth else
часть никогда не будет достигнута, так как elm.isDisplayed()
не является логическим значением - это обещание. Даже если элемент не отображается, вы все равно выполнили бы // do smth
.
Вместо этого, если вам нужно проверить значение isDisplayed()
для использования внутри условного выражения, вы должны явно выполнить обещание с помощью then()
:
var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
// do smth
} else {
// do smth else
}
});
Существует также способ поймать такие ошибки, даже не запуская код - статически с ESLint
и eslint-plugin-protractor
плагин. Существует соответствующее правило, которое отслеживает, если определенные методы Транспортатора используются внутри условий if
напрямую.
Вот что он вывел бы для кода выше:
$ eslint test.js
test.js
2:1 warning Unexpected "isDisplayed()" inside if condition protractor/no-promise-in-if
Ответ 4
Или попробуйте это решение, реализованное из верхней части моей головы, Запланируйте команду, чтобы проверить, присутствует ли элемент на странице. Если при оценке ожидания возникают какие-либо ошибки, им будет разрешено распространять.
function alwaysSwitchOn(element) {
browser.driver.isElementPresent(element).then(function(isPresent) {
if (isPresent) {
isPresent = true;
}
else {
browser.driver.wait(function () {
return browser.driver.isElementPresent(element);
}, 5000);
}
// to fail the test, then uncomment this line
//expect(isPresent).toBeTruthy();
}).then(function () {
if (element.getAttribute('value') === 'OFF') {
element.click();
}
else {
// turn it OFF
element.click();
// turn it back ON
element.click();
}
});
}
Использование fn - продолжать повторять попытку снова и снова в течение 5 секунд, пока не будет true
. если элемент не может быть найден в 5 sec
, тогда он приведет к ошибке; Нет такого элемента. Обратите внимание: если условие выполняется до ожидания (5s
), он быстро переместится на then(...)
.