Reputation: 13
I'm trying to write a test where I check the ammount of items in a ng-repeat. After that I add 1 item to that ng-repeat and I want to see if the old value+1 is equal to the new value.
This is my html:
<tr ng-repeat="list in listData.myLists">...</tr>
And my test
describe("list test", function(){
it('Description of the test', function(){
browser.get('app/#/list');
var list = element.all(by.repeater('list in listData.myLists'));
var ammount;
list.count().then(function(c) {
ammount = c;
});
... Here I add an item
var secondAmmount = element.all(by.repeater('list in listData.myLists')).count();
expect(secondAmmount).toEqual(ammount + 1);
});
});
But I'm getting 7 is not equal to NaN.
I have also tried just adding the list.count() + 1 directly into the toEquals method but then I get an object instead of a number.
Is there something I'm doing wrong here? Thanks for any help in advance
Upvotes: 1
Views: 2743
Reputation: 2205
Yep! What's tripping you up is asynchronous programming. The problem with your test is that the second half of the test (after Here I add an item
) is evaluated before ammount = c;
is evaluated, because your first then()
statement is still waiting for count()
to come back. So when the expect()
statement is hit, ammount
still doesn't have a value and adding 1 to it won't work (because it's still null, at least for a few milliseconds). It's funny, but that's how promises work.
The following code will do the trick:
describe("list test", function(){
it('Description of the test', function(){
browser.get('app/#/list');
var list = element.all(by.repeater('list in listData.myLists'));
list.count().then(function(amount) {
// ... Here I add an item ...
var secondAmount = element.all(by.repeater('list in listData.myLists')).count();
expect(secondAmount).toEqual(amount + 1);
});
});
});
It's important to wait for the list.count()
promise to come back (asynchronously) before trying to do something with the value it returns. That's what the then()
statement is for; it forces the rest of the test to wait for the count()
to finish. That way everything happens in the order you expect.
This is necessary because you are using amount + 1
. Protractor's expect()
statements understand how to use promises, but not if you are modifying the return values. We can put the secondAmount
promise directly inside the expect()
statement without a then()
function, but we cannot put list.count() + 1
inside an expect()
statement.
For more details, you can see this answer. Try to gain a strong understanding of Node.JS asynchronous programming and Javascript promises and it will make your Protractor life so much better!
Upvotes: 10
Reputation: 429
Protractor element functions run asynchronously and return promises. try this...
describe("list test", function() {
it('Description of the test', function () {
browser.get('app/#/list');
element.all(by.repeater('list in listData.myLists')).count()
.then(function (amount) {
// ... Here You add an item
element.all(by.repeater('list in listData.myLists')).count()
.then(function (secondAmount) {
expect(secondAmount).toEqual(amount + 1);
})
})
});
});
Upvotes: 1