如何在量角器中为元素存在或不存在创建条件

How to create a condition in protractor for when an element exists or not

本文关键字:存在 不存在 创建 条件 元素 量角器      更新时间:2023-09-26

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

还有一种方法可以在不运行代码的情况下捕获此类错误 - 使用 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(...)

如果你在 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)
  }
});