Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS e2e Testing: How To Get value of repeater().count()?

Problem

Calling repeater('#myTable tr','Rows').count(); returns a Future, not an integer. I need to get the integer value so I can confirm that an additional row was added to a table.

Code

it('should add a new user when save button is clicked',function()
    {
        showModal();

        //here I'm trynig to store the row count of my table into  a local variable.
        //a future is returned who's 'value' field is undefined.
        var memberCount = repeater('#memberTable tr','Member Rows').count();

        //this outputs 'undefined'
        console.log(memberCount.value);


        input('editedMember.name').enter('John');
        input('editedMember.grade').enter(5);
        input('editedMember.ladderPosition').enter(3);

        element('#saveMemberButton').click();
        sleep(1);
        expect(element(modalId).css('display')).toBe('none');

        //here is where I want to do the comparison against the above stored memberCount
        expect(repeater('#memberTable tr', 'Member Rows').count()).toBe(memberCount.value + 1);


    });

Test Result

Chrome 25.0 e2e should add a new user when save button is clicked FAILED
    expect repeater 'Member Rows ( #memberTable tr )' count toBe null
    /Users/jgordon/learning/chessClub/web-app/test/e2e/scenarios.js:45:3: expected null but was 6
Chrome 25.0: Executed 2 of 2 (1 FAILED) (1 min 4.117 secs / 1 min 3.773 secs)
like image 559
John Gordon Avatar asked Jan 28 '13 16:01

John Gordon


3 Answers

Drilling into the source code for Angularjs' e2e support reveals that you have to call execute() on the Future to have it populate its value. Also, when you call execute you have to provide a "done" function to the execute() otherwise Testacular will (oddly enough!) skip your test.

Code

var rowCountFuture = repeater('#memberTable tr','Member Rows').count();
        
        rowCountFuture.execute(function(){
        });
        
        var memberCount = rowCountFuture.value;

While I'm jazzed to see this works, I'm concerned there may be some asynchronous bugs that could come out of this, also, I feel like this is a hack and not the right way to do it. Any ideas?

like image 170
John Gordon Avatar answered Sep 20 '22 23:09

John Gordon


Based on the latest Protractor version:

it('should add a new user when save button is clicked', function() {
    var memberCount;
    element.all(by.repeater('#memberTable tr','Member Rows')).count().then(function(value) {
        memberCount = value;
    });
    ...
    // then do all your entering user info, saving etc.
    ...
    browser.refresh(); // or however you want to load new data
    expect(element.all(by.repeater('#memberTable tr','Member Rows')).count()).toEqual(memberCount + 1);
});
like image 43
zewt112 Avatar answered Sep 21 '22 23:09

zewt112


I've run into the same issue, and have seen confusing results when testing value returned after calling execute(). I've found this method works more reliably:

var getCount = repeater('ul li').count();
getCount.execute(function(value) {
    expect(value).toEqual(3);
});
like image 29
David Woods Avatar answered Sep 20 '22 23:09

David Woods