web-dev-qa-db-ja.com

要素が存在するかどうかの分度器で条件を作成する方法

Protractor JSを使用しています。そして、サイトはAngular JS。

トグルスイッチがあります。また、トグルスイッチの値は、オフまたはオンに切り替えると、trueからfalse、falseからtrueに変わることに気付きました。

分度器がトグルスイッチが「オフ」になり、「オン」になったときに、ページにアクセスしたときに条件を作成しようとしています。トグルスイッチがすでに「オン」になっている場合、最初に「オフ」にし、次に「オン」にします。

私はこのコードを思いつきましたが、何らかの理由で機能していません:

_ 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ステートメント。エラーは表示されません。

もっと良い方法があれば、教えてください。これは、このフレームワークで適切な条件を作成できないことを非常に制限しているようです。

24
adbarads

isDisplayed()がpromiseを返すことを忘れないでください:

element(anyFinder).isDisplayed().then(function(result) {
    if ( result ) {
        //Whatever if it is true (displayed)
    } else {
        //Whatever if it is false (not displayed)
    }
});
33
Lautaro Cozzani

isDisplayed()は機能しませんでした。 APIが変更された可能性があります。 isPresent()は私の解決策です:

    var logoutButton =  element(by.css('[ng-click="log_out()"]'));
    logoutButton.isPresent().then(function(result) {
    if ( result ) {
        logoutButton.click();
    } else {
        //do nothing
    }
    });
20
Ebru Yener

問題は、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_ plugin で静的にコードを実行することなく、この種のエラーをキャッチする方法もあります。特定の分度器メソッドがif条件内で直接使用されているかどうかを監視する 関連ルール があります。

上記のコードに対して出力される内容は次のとおりです。

_$ eslint test.js
test.js
  2:1  warning  Unexpected "isDisplayed()" inside if condition  protractor/no-promise-in-if
_
6
alecxe

または、私の頭の上から実装されたこのソリューションを試してください。ページに要素が存在するかどうかをテストするコマンドをスケジュールします。待機の評価中にエラーが発生した場合、エラーの伝播が許可されます。

_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の使用法は、trueになるまで5秒間繰り返し試行することです。 _5 sec_内で要素が見つからない場合、エラーコードが返されます。そのような要素は見つかりません。注意、待機前に条件が満たされると(_5s_)、すぐにthen(...)に移動します。

1
Simple-Solution