我正在使用量角器 JS。该网站是用Angular JS编写的。
所以我有一个拨动开关。我注意到拨动开关中的值从真变为假,当您将其关闭或打开时,假变为真。
我正在尝试创建一个条件,当量角器访问我的页面时,当它看到切换开关"关闭"时,它会将其"打开"。如果拨动开关已经"打开",它将首先将其"关闭",然后再次"打开"。
我想出了这段代码,但由于某种原因它不起作用:
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 语句。未显示任何错误。
如果有更好的方法,请告诉我。这似乎非常有限,无法在此框架中创造适当的条件。
请记住,isDisplayed()
返回一个承诺,您可以尝试:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});
isDisplayed()
对我不起作用。API 可能已更改。 isPresent()
是我的解决方案:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
问题是isDisplayed()
,就像WebDriverJS/Protractor中的许多方法一样,返回一个根据定义是"真实"的承诺,这使得调试这样的问题变得困难。
让我们通过一个例子来更好地理解。
想象一下,您有以下代码,乍一看可能看起来不错:
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
或者尝试从我的头顶实现的这个解决方案, 计划一个命令来测试页面上是否存在元素。如果在评估等待时发生任何错误,将允许它们传播。
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(...)
。
如果你在 2021 年或以后几年
忘记.then()
.请改为执行以下操作:
it('test case', async () => {
if (await element(anyFinder).isDisplayed()) {
// Whatever if it is true (displayed)
} else {
// Whatever if it is false (not displayed)
}
});