如何在量角器中为元素存在与否创建条件

我正在使用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 } }); 

还有一种方法可以捕获这些错误,甚至无需运行代码 – 静态使用ESLinteslint-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(...)