web-dev-qa-db-ja.com

条件をどのように待つことができますか?

私は分度器の初心者で、e2eテストを実装しようとしています。これが正しい方法であるかどうかはわかりませんが、...テストするページは完全なangularページベースではないため、...いくつかの問題を抱えています。

私の最初の仕様では:

_describe('should open contact page', function() {
var ptor = protractor.getInstance();

beforeEach(function(){

   var Login = require('./util/Login');
   new Login(ptor);
});
_

このLoginクラスを作成しましたが、ログイン後に連絡先ページを開きたいのですが、分度器はページが完全に読み込まれる前にすぐに要素を見つけようとします。

私は使用しようとしました:

_browser.driver.wait(function() {

    expect(browser.findElement(by.xpath("//a[@href='#/contacts']")).isDisplayed());
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();

});
_

しかし、それは機能しません...ページがロードされる前に常に要素を見つけようとします。私もこれを試しました:

_browser.driver.wait(function() {
    expect(ptor.isElementPresent(by.xpath("//a[@href='#/contacts']")));          
    ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});
_

私はbrowser.sleep();を使用してそれを行うことができますが、私はそれが良いオプションだとは思いません。何か案が?私のログインクラスには次のものがあります:

_ptor.ignoreSynchronization = true;
_

分度器がクリックする前に、この_@href='#/contacts_を待つにはどうすればよいですか?

48
Muratso

分度器を使用している間、あなたが最も長く抱えていたのと同じ問題を抱えていました。私のe2eテストでは、非angularアプリで開始し、次にangular部分に入り、次に非angular部分。物事をトリッキーにしました。鍵は約束とその仕組みを理解することです。このコードの悪い習慣は、これを自由に改善してください。

angularを使用するには

var ptor;
var events = require('events');
var eventEmitter = new events.EventEmitter();
var secondClick = require('./second-click');

beforeEach(function () {
    browser.driver.get('http://localhost:8080/');
},10000);

it("should start the test", function () {
    describe("starting", function () {
        it("should find the  link and start the test", function(){
            var elementToFind = by.linkText('Start'); //what element we are looking for
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                expect(isPresent).toBe(true); //the test, kind of redundant but it helps pass or fail
                browser.driver.findElement(elementToFind).then(function(start){
                    start.click().then(function(){ //once we've found the element and its on the page click it!! :) 
                        ptor = protractor.getInstance(); //pass down protractor and the events to other files so we can emit events
                        secondClick(eventEmitter, ptor); //this is your callback to keep going on to other actions or test in another file
                    });
                });
            });
        });
    });
},60000);

angularでは、このコードは機能します

 describe("type in a message ", function(){
        it("should find and type in a random message", function(){
            var elementToFind = by.css('form textarea.limited');
            browser.driver.isElementPresent(elementToFind).then(function(isPresent){
                element(elementToFind).sendKeys(randomSentence).then(function(){
                    console.log("typed in random message");
                    continueOn();
                });
            });
        });
    },15000);

角を出た後

browser.driver.wait(function(){
   console.log("polling for a firstName to appear");
   return    browser.driver.isElementPresent(by.name('firstName')).then(function(el){
         return el === true;
       });
     }).
   then(function(){
       somefunctionToExecute()
    });

いくつかのガイダンスを提供し、あなたを助けることを願っています!

23
asherrard

分度器1.7.0は、新機能 Expected Conditions も導入しました。

明示的に待機する定義済みの条件がいくつかあります。要素が現れるのを待ちたい場合:

var EC = protractor.ExpectedConditions;

var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);

expect(e.isPresent()).toBeTruthy();

こちらもご覧ください:

51
alecxe

私はついに見つけました...

   var waitLoading = by.css('#loading.loader-state-hidden');

   browser.wait(function() {
       return ptor.isElementPresent(waitLoading);
   }, 8000);

   expect(ptor.isElementPresent(waitLoading)).toBeTruthy();

   var openContact = by.xpath("//a[@href='#/contacts']");
   element(openContact).click();

この分度器では、読み込みページが消えるまでその要素を待つことができます。 XDを助けようとした人たちに感謝します。

33
Muratso
browser.driver.wait(function() {
    return browser.driver.isElementPresent(by.xpath("//a[@href='#/contacts']"));
});

これは私にも機能します(タイムアウトパラメータなし)。

詳細については、 http://angular.github.io/protractor/#/api?view=webdriver.WebDriver.prototype.wait を参照してください

9
Henry Neo

上記の回答のおかげで、これは私の簡略化され更新された使用法でした

function waitFor (selector) {
  return browser.wait(function () {
    return browser.isElementPresent(by.css(selector));
  }, 50000);
}
1
Kirk Strobeck

誰もこのソリューションを追加していないことに驚いています。基本的に、モーダルダイアログを使用している場合、要素が表示されてクリックできるようになりますが、モーダルダイアログが前面にあるため、クリックできません。これは、分度器がangularより速く移動し、angularがモーダルを閉じている間に次の要素をクリックする準備ができているためです。

私は使用することをお勧めします

public async clickElementBug(elementLocator: Locator) {
const elem = await element(elementLocator);
await browser.wait(
  async function() {
    try {
      await elem.click();
      return true;
    } catch (error) {
      return false;
    }
  },
  this.TIMEOUT_MILLIS,
  'Clicking of element failed: ' + elem
);

}

0
Raymond Kelly

ng-app の中に <html>タグ(コードのこの部分はあなたの管理下にあると仮定)?これにより、初期化のタイミングに関する多くの問題が解決されました。

0

テストケースが失敗した場合に特定の要素に適切なエラーメッセージを表示するのに役立つ分度器で待機条件を使用する最適な方法

const EC = ExpectedConditions;
const ele = element(by.xpath(your xpath));

return browser.wait(EC.visibilityOf(ele),9000,'element not found').then(() => {
            ele.click();
         });
0
rohit saini