如何在量角器中为元素存在与否创建条件
我正在使用Protractor JS。 该网站是用Angular JS编写的。
所以我有一个拨动开关。 我注意到,当你关闭或打开时,切换开关的值从true变为false,false变为true。
我正在尝试在Protractor访问我的页面时创建一个条件,当它看到切换开关’关闭’它将打开它’。 如果拨动开关已经“打开”,它将首先将其关闭,然后再将其打开。
我提出了这个代码,但由于某种原因它无法正常工作:
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:找不到使用locator的元素:By.cssSelector(“[value = \”false \“]”)
那么我试过了
.isPresent()
而不是.isDisplayed()
我不再收到上述错误,但由于某些原因,当使用.isPresent()时,它总是转到if语句并且只运行那个,而不是else语句。 没有显示错误。
如果有更好的方法请告诉我。 这似乎非常有限,因为无法在此框架中创建适当的条件。
请记住isDisplayed()
返回一个promise,您可以尝试:
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中的许多方法都返回一个承诺 ,根据定义它是“truthy”,这使得很难调试这样的问题。
让我们通过一个例子来更好地理解。
想象一下,你有以下代码,乍一看可能看起来没问题:
var elm = $("#myid"); if (elm.isDisplayed()) { // do smth } else { // do smth else }
现在,它有一个严重的问题。 因为elm.isDisplayed()
不是一个布尔值,所以永远不会达到do smth else
部分 – 它是一个承诺。 即使未显示元素,您仍然会执行// do smth
部分。
相反,如果需要检查isDisplayed()
的值以在条件表达式中使用,则必须使用then()
显式解析promise :
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(...)
。