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
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
Share Improve this question asked Mar 15, 2015 at 16:02 MarcMarc 131 silver badge4 bronze badges2 Answers
Reset to default 10Yep! 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 e 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 e 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!
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);
})
})
});
});