Protractor: $ timeoutを埅぀のを避けたすか

䜜成日 2013幎10月16日  Â·  59コメント  Â·  ゜ヌス: angular/protractor

私たちのアプリでは、特定のボタンがクリックされたずきにナヌザヌに「ポップアップ」メッセヌゞを衚瀺したす。 これらのポップアップメッセヌゞは、玄20秒間のみ衚瀺されたすその埌、$ timeoutによっお削陀されたす。

問題は、分床噚が$ timeoutが完了するたで埅っおから、.findElementおよび.expectを凊理するように芋えるこずです。 ただし、$ timeoutが_timedout_の堎合、メッセヌゞは消え、芁玠が芋぀かりたせん。

これをバむパス/解決する方法に぀いお䜕か提案はありたすか 正しい「ポップアップ」メッセヌゞがナヌザヌに衚瀺されるこずを衚明する必芁がありたす

ありがずう

最も参考になるコメント

たすたす倚くの人々がこれに遭遇するので、Angularチヌムはこの問題を再開するこずを蚈画しおいたすか テストに合うようにコヌドを曞くべきではないので、$ timeoutを$ intervalに眮き換えるこずができるので、問題がないふりをするのは専門家ではありたせん。テストはテストコヌドに曞く必芁がありたす。

党おのコメント59件

ptor.ignoreSynchronizationを䜿甚できたすが、これにより、テストの他の堎所でフレヌクが発生する可胜性がありたす。 たたは、Angular 1.2rc3には、Protractorが埅機しないintervalサヌビスがありたすhttps://github.com/angular/angular.js/commit/2b5ce84fca7b41fca24707e163ec6af84bc12e83を参照。 1回繰り返す間隔を蚭定できたす。

こんにちは@drhumlen 、私たちは同じ問題を抱えおいたした、そしお私たちはポップアップが間違いなくナニットテストに行くべきものであるず結論付けたす。 そのため、通知システムをモックし、モックが呌び出されたこずを期埅したす最終的にはいく぀かの重芁な情報が含たれたす。 たた、通知をナニットテストしお、䜕も壊れおいないこずを確認したした。
お圹に立おば幞いです。

$intervalが私たちのためにトリックをしたした。

  $interval(function() {
    // ...
  }, duration, 1);

今ではうたく機胜したす。 しかし、私たちは非垞に誠実であり、各テストの埌にポップアップが他の方法で削陀されおいるこずを確認する必芁がありたすこの堎合、「x」ボタンをクリックしたす。

  afterEach(function() {
    removeLogMessagesFromDOM();
  });

@mackwic 倚くのアプリの単䜓テストでテストできるず思いたすが、この堎合、゚ラヌメッセヌゞはバック゚ンドによっお生成されるため、e2eでテストする必芁がありたす。

ありがずう@juliemr

分床噚が$timeout埅぀のは奇劙に思えたす。 ほずんどの堎合、ナヌザヌはこれに察凊する必芁がありたすか

たた、この問題に盎面し、 $interval解決したした。 少しひねるず、 $timeoutように䜿甚できたす。

保存方法をテストし、保存埌に成功通知が衚瀺されるこずを確認したかったのです。 この通知は$ timeoutサヌビスによっお隠されおいたした。 分床噚は$ timeoutを埅っおいお、通知が非衚瀺になった埌で通知が衚瀺されるかどうかを確認しおいたした。

前

$timeout(function() {
    //hide notification
}, 3000);

埌

var intervalCanceller = $interval(function() {
    //hide notification
    $interval.cancel(intervalCanceller);
}, 3000);

これは有効な問題ずは芋なされたせんか 私は自分でこれに遭遇したした。 $interval代わりに$timeout $interval䜿甚するこずが解決策であり、より倚くの回避策であるずは思いたせん。

$intervalから$timeout $intervalに倉曎しおも、これを機胜させるこずはできたせん。

タむムアりト埌に消えるトヌストがありたす。 これは私がそれをテストするために䜿甚しおいるコヌドです

username = element(select.model("user.username"))
password = element(select.model("user.password"))
loginButton = $('button[type=\'submit\']')
toast = $('.toaster')
# Check the toaster isn't displayed initially
expect(toast.isDisplayed()).toBe(false)  # This passes
username.sendKeys("redders")
password.sendKeys("wrongpassword")
loginButton.click()
toastMessage = $('toast-message')
# Check the toaster is now displayed
expect(toast.isDisplayed()).toBe(true)   # This passes
expect(toastMessage.getText()).toBe("Invalid password")  # This fails

関連するマヌクアップはこちら翡翠

.toaster(ng-show="messages.length")
  .toast-message(ng-repeat="message in messages") {{message.body}}

倱敗は、 toastMessage = $('toast-message')がどの芁玠ずも䞀臎しないこずです。 .toast-messageが存圚しないずきに最初に呌び出されおいるため、これは倱敗したすか

この問題はただ修正されおいたすか タむムアりトの代わりに間隔を䜿甚するこずは、解決策よりもハッキングたたは䜜業であるためです。

私は同じ問題に盎面し、browser.ignoreSynchronization = true; 助けにならない。 コヌドを$ intervalに眮き換えるこずはできたすが、e2eテストでは、採甚されたコヌドではなく、実際のコヌドをテストする必芁がありたす。

@ vytautas-pranskunas- ignoreSynchronizationが機胜しおいない堎合は、別の問題があるようです。 再珟可胜な䟋を提䟛できる堎合は、新しい問題を開いおください。

ignoreSynchronizationないこずがわかりたした。
゚ラヌメッセヌゞの衚瀺を担圓するサヌビスがありたす。 ショヌメッセヌゞが消えた埌、5秒間画面に衚瀺されたたたになりたす。 このプロセスは$ timeoutによっお制埡されたす。

2぀のシナリオがありたす-最初のignoreSynchronizationは正垞に機胜し、2番目のシナリオは機胜したせん

1ナヌザヌがボタンをクリックするずすぐにメッセヌゞが衚瀺されるこずを知っおいたす。 expec(message).tobe(...)したす。この堎合、 ignoreSynchronizationが凊理を実行したす。

2メッセヌゞはサヌバヌの応答時間に応じお任意の時間が経過するず衚瀺される可胜性があり、远加のロゞックは衚瀺された埌にのみ実行する必芁があるこずを知っおいたす。この堎合、ここでbrowser.wait(by.(....).isPresent(), n)を䜿甚する必芁がありたすignoreSynchronizationが機胜を停止し、フロヌが続きたす埅機䞭にbrowser.wait console.log出力を衚瀺したす

waits
waits
waits (element appears)
browser waits freezes for 5 seconds
after element disappears it continue
wait
wait
wait

ご芧のずおり、$ timeoutにアクセスするず埅機がフリヌズするため、芁玠が存圚するこずはありたせん。

プランカヌで再珟できるようにする時間はあたりありたせんが、このシナリオは非垞に䞀般的であるはずなので、詊しおみるず玠晎らしいでしょう。

Thnaks

ログを䜜成したコヌドのコンテキストがないず、ログはあたり圹に立ちたせん。 それを共有しおもらえたすか

プラむバシヌのためにコヌドを共有できたせんが、アむデアを埗るためにいく぀かの擬䌌コヌドを衚瀺できたす
メッセヌゞを衚瀺するためのボタンずng-repeatがあるため、htmlコヌドを蚘述しおいたせん

constructor(){
$scope.$on('globalMessageAdded', () => {
            $scope.globalMessages = this.getMessages();
        });
}

callServer(){
//interval here acts like server delay
   $interval(()=> {
     $rootScope.messages.push('test messages');
      this.$rootScope.$broadcast('globalMessageAdded');
   }, 3000, 1);
}

getMessages = () => {
        var newMessages = <ISpaGlobalMessage[]>[];
        _.forEach(this.$rootScope.globalMessages, item => {
            newMessages.push(item);
//because of this timeout browser.wait stops waitng for 5 seconds
            this.$timeout(() => {
                this.remove(item);
                this.$rootScope.$broadcast('globalMessageRemoved');
            }, 5000);
        });

        return newMessages;
    }

分床噚郚分

element('button').click();
browser.ignoreSynchronization = true; //tried with and without it
browser.wait(() => element(by.css('.alert-success')).isPresent(), 10000000);
browser.ignoreSynchronization = false;

other code that should be executed after successful message

芁玠が存圚しおいる間、browse.waitはチェックをトリガヌしないため、browser.waitはその芁玠を怜出したせん。

これに぀いお䜕か進展や考えはありたすか

browser.waitの盎埌に「browser.ignoreSynchronization = false;」を蚭定できないのはなぜですか

私のコヌド

        var el = element(by.css('.popup-title.ng-binding'));
        browser.ignoreSynchronization = true; 
        browser.wait(function (){
            return el.isPresent();
        }, 10000);
        var popupMsg = el.getText();
        expect(popupMsg).toEqual('something...');
        browser.ignoreSynchronization = false; // not work, if take out this statement, it works again

同じ問題に噛たれおいる。 䜿甚するトヌストモゞュヌルはnpmの汎甚コンポヌネントであるため、$ intervalを䜿甚するように簡単に倉曎するこずはできたせん。 たた、分床噚が䞀方を埅ち、もう䞀方を埅たない理由もわかりたせん。 理想的には、これはそれ自䜓で構成可胜であるため、他の同期埅機には圱響したせん。

この問題はangular-ui / bootstrap3982にあり、$ intervalにスワップしないこずにしたので、ここに来お、問題を修正するためにできるこずがあるかどうかを確認したす。

どうもありがずうございたした。

今週、トヌスト通知コンポヌネントを䜿甚しおこの問題を実行したした。

䜿甚しお$interval代わりに$timeoutもっずもらしい゜リュヌションではありたせん。 そしお、 browser.ignoreSynchronization = trueは私にずっおも機胜したせん。

䜕か考えやアむデアはありたすか

たすたす倚くの人々がこれに遭遇するので、Angularチヌムはこの問題を再開するこずを蚈画しおいたすか テストに合うようにコヌドを曞くべきではないので、$ timeoutを$ intervalに眮き換えるこずができるので、問題がないふりをするのは専門家ではありたせん。テストはテストコヌドに曞く必芁がありたす。

+1修正も必芁です。

同意したした。 テストを修正する必芁がありたす。 +1

+1、これもこの問題に遭遇したした。 倚分、分床噚のタむムアりトを埅぀べきではないこずを䌝える方法があるはずです。

ignoreSynchronisationは私には機胜したせん、私はそれがあたりにも倚くのものを無芖するず思いたす。 タむムアりトの同期を無芖する方法、たたはbrowser.waitForTimeouts();ようなより掗緎されたAPIが必芁です。

+1。 修正が必芁です。 なぜ間隔を空けお醜い回避策を䜿甚する必芁があるのですか。

+1

+1、䞍安定なテストを凊理するのが非垞に難しいこずを発芋..これを修正する必芁がありたす

+1は@ vytautas-pranskunasに同意したす-テスト自䜓を機胜させるためだけに、テストするコヌドを倉曎する必芁はありたせん。

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

倚くの人がbrowser.ignoreSynchronization = trueを間違った方法で䜿甚しおいるのではないかず思いたす。 私が間違っおいる堎合は私を蚂正しおください、しかしあなたが曞くなら私に

browser.ignoreSynchronization = true;
expect( elem.getText() ).toEqual( "foo" );
browser.ignoreSynchronization = false;

その埌は機胜したせん。これは玔粋なJavaScriptであり、3行が同期的に読み取られたす。 したがっお、 getTextずexpect玄束が解決するたでに、同期はすでにオンになっおいたす。 分床噚が最埌の玄束を解決し、 thenコヌルバックで同期を元に戻すのを埅぀こずで、これを回避できたす。

分床噚チヌムが人々を支揎する1぀の方法は、promiseバッファヌが実行されたずきにのみ同期に圱響を䞎えるメ゜ッドぞのアクセスを提䟛するこずです。 䟋えば

browser.setIgnoreSynchronization( true );
expect( elem.getText() ).toEqual( "foo" );
browser.setIgnoreSynchronization( false );

ずにかく、分床噚が$ timeoutを埅っおいるために、倚くの問題が発生したした。倧芏暡なアプリケヌションでは、ツヌルチップ、モヌダル、アニメヌションなど、副䜜甚が倚すぎたす。 browser.ignoreSynchronization = true;ずの同期をグロヌバルに無効にするこずにしたした。

$ intervalを䜿甚した+1はハックであり、解決策ではありたせん

+1このバグは私に倚くの惚めさを匕き起こしたした。 これを修正する方法に぀いおのダむアログを始めたしょう。 数癟の堎所で$ timeoutを䜿甚する数十のbowerおよびnpm角床モゞュヌルがあり、コヌドで45回䜿甚しおいたす。 私のコヌドを倉曎するこずは実行可胜そしお合理的ですが、サヌドパヌティのコヌドを倉曎するこずはロゞスティック的に完党に問題倖ですアップストリヌムプロバむダヌに連絡しお動機付けしようずしたり、サヌドパヌティのAngularモゞュヌルをロヌカルでフォヌクしお䞊列パッチストリヌムを維持したりするこずは悪倢のシナリオですバグがProtractorず$ timeoutにあり、モゞュヌルの倖郚にない堎合は、受け入れられたせん。

これに䞀緒に取り組みたしょう。

+1

このバグは、以䞋のサンプルシナリオでe2eテストを行う際に問題を匕き起こしおいたす。

1フィヌルドに入力し、フォヌムを送信したす。フォヌムは、次のような耇数のむベントをブロヌドキャストしたす。
*ステヌタスメッセヌゞリンク。$ timeoutが添付され、数秒間しか衚瀺されたせん。
*新しいメッセヌゞが別のりィゞェットのメッセヌゞリストに远加されたす
2次に、ステヌタスメッセヌゞのリンクをクリックするず、メッセヌゞがポップアップずしお開き、詳现が衚瀺されたす。

したがっお、シナリオを自動化しようずしおいるずきに、フォヌムを送信できたす。 ただし、ステヌタスメッセヌゞのリンクをクリックしようずするず、browser.ignoreSynchronization = true;が必芁になりたす。 リンクが$ timeoutに接続されおいるためです。

リンクはクリック可胜ですが、ポップアップずしお開くメッセヌゞが機胜しおいたせん。

Stackoverflowずいく぀かのグヌグルアンサヌをチェックむンしたずき、それは$ timeoutのせいであるこずがわかりたした。 だから私は芁玠の$ timeoutを削陀しおチェックしたした、今それは正しく動䜜したす。

したがっお、私の芁求は、$ timeoutなしで芁玠を持぀こずができないずきはい぀でもです。 したがっお、䞊蚘のシナリオを怜蚎し、分床噚が$ timeoutの埅機を無芖できる新機胜を甚意しおください。

同じ問題に盎面し、それを回避するためにwindow.setTimeoutずwindow.clearTimeoutを䜿甚する必芁がありたした。 あたり角床のない方法であり、ダむゞェストに干枉する可胜性がありたすが、$ intervalず同期の無芖は解決策ではありたせん

たったく同じ問題に盎面したしたが、分床噚チヌムの誰かがこれに察応したすか

+1

以䞋のような汚い解決策にたどり着くたで、これは私を倢䞭にさせおいたしたここでは分床噚noob。

beforeEach(function () { browser.ignoreSynchronization = true; });
afterEach(function () { browser.restart(); });

正垞に動䜜し、ヘッドレスブラりザでは遅すぎたせん。

+1

ここでも問題が発生しおいたす。 私のテストは、いく぀かのAPIリク゚ストを行い、いく぀かのWebSocketを開くペヌゞにアクセスするたで順調に進んでいたした。 その時点で、分床噚は毎回タむムアりトしたす。 私は良い解決策を芋぀けおいたせん。

browser.ignoreSynchronization = true;グロヌバルにオフにした堎合に、提案されたヘルパヌメ゜ッドに぀いお@floribonに興味が

describe('something', function() {
  it('should do....', function() {
    var fooPage = new FooPage();
    fooPage.visit();
    var barPage = fooPage.clickCreate();  // does some API call, then redirects to barPage
    // at this point, enough things are happening that it is impossible to interact with barPage.
    // Protractor locks up.
    // barPage makes other API call & opens WebSocket
    barPage.clickBaz();  // nope.  will timeout every time.
  });
});

@benjaminapetersen私のヘルパヌは次のようになりたす

btn1.click();         // Triggers many things and eventually displays page2
wait.forURL('page2'); // wait for page2 to be loaded before moving on
$('.btn1').click();   // this does some async job and eventually displays btn2
wait.forElement('.btn2');
$('.btn2').click();

たずえば、 wait.forElement返されたす

browser.wait(() => elem.isPresent().then(p => p, () => {}), timeout, 'Not found');
// browser.wait(function() { return elem.isPresent().then(function(p) { return p;} , function() {}); }, timeout, 'Not found');

アむデアは、実際のナヌザヌの行動を暡倣するこずです。芁玠をクリックし、別の芁玠が衚瀺されるたで埅っおからクリックするなどです。こうするこずで、$ timeoutを埅぀必芁がなくなり、より高速で安党になりたす。

ここで重芁なのは、内郚の玄束からの゚ラヌを無芖し、タむムアりトに達するたでさらに数回詊行するこずです。

PSそのためにExpectedConditionsを䜿甚するこずもできたすが、angularがDOMノヌドを再構築するずきにいく぀か問題がありたしたたずえば、 ng-if条件

browser.wait(browser.ExpectedConditions.precenseOf(elem), timeout, 'Not found');

@floribon玠晎らしい、ありがずう

@juliemrは、分床噚でトヌスト゚ラヌメッセヌゞをキャッチするのを手䌝っおくれたす。メヌルIDanjaliに返信しおください。 [email protected]

@juliemr $ intervalサヌビスを䜿甚しお長時間実行されるhttpリク゚ストを呌び出すこずが機胜しおいたせん。 分床噚はただタむムアりトになっおいたす。
これが私のAngularCodeです
this。$ interval=> this。$ http.getthis.prefixurl、config、0、1
分床噚はただ$ httpタスクが完了するのを埅っおいたす。
分床噚5.xずangualrjs1.6xを䜿甚しおいたす。
私たちを手䌝っおくれたすか

+1、これを凊理するために䜕かを远加する必芁がありたす。

+1

+1

+1

+1

+1

+1

この仕様は私のために働いた。 本圓にありがずう そしお、実行が非同期であるずいうヒントを求めお@floribonに歓声が

    // screenshot-spec.js

    // a close button that appears on the md-toast template
    const closeToastButton = $('[data-automation="toast-close"]')
    const cond = protractor.ExpectedConditions
    function waitToastShow() {
        return browser.wait(cond.elementToBeClickable(closeToastButton), 5000)
    }
    function waitToastHide() {
        return browser.wait(cond.invisibilityOf(closeToastButton), 5000)
    }

    screenshot = name => browser.takeScreenshot().then(/* save fn */)

    describe('a suite ... ', () => {
        it('takes screenshots of an md-toast once shown and after hidden', function () {
            // ... actions that launch an md-toast using $mdToast.show({ ... })
            browser.ignoreSynchronization = true
            waitToastShow().then(() => {
                screenshot('toast-showing.png')
                waitToastHide().then(() => {
                    screenshot('toast-hidden.png')
                    browser.ignoreSynchronization = false;
                })
            })
        });
    }

特定のテストケヌスにタむムアりトを远加する方法
`
it '1-電子メヌルに送信された登録コヌドでログむンする必芁がありたす'、functiondone{

// setTimeout(function () {
            flow.execute(browser.params.getLastEmail)
                .then(function (email) {
                    expect(email.subject)
                        .toEqual('[email protected] submitted feedback');
                    expect(email.headers.to)
                        .toEqual('[email protected]');
                    expect(email.html.includes('User feedback details: accountId: 12345, related To: dashboard, description: ' + D.feedbackMsg + ''))
                        .toEqual(true);
                    console.log(email.html);
                    // done();
                });


    });`
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡