I am trying to write an e2e test for my angular application, and in particular a form that has 3 select inputs on. The test will need to involve picking random options from these selects. The first select is already populated with data, but the other 2 selects asynchronously populate when the one before has been selected, so they are dependant on each other.
The select inputs also use ng-disabled and only enable when there are options available as per their ng-repeat expressions.
I am using the page object approach with my tests, and so am trying to make some utility functions to achieve the random selection behaviour I need in my tests:
Page Object:
this.selectRandomCustomer = function() {
var option,
randomIndex;
this.customerSelect.click();
this.customerSelectOptions.count().then(function(count) {
randomIndex = Math.floor(Math.random() * count);
option = element(by.repeater('customer in vm.customers').row(randomIndex));
option.click();
});
};
this.selectRandomOrder = function() {
if(this.orderSelect.isEnabled()===true) {
var option,
randomIndex;
this.orderSelect.click();
this.orderSelectOptions.count().then(function(count) {
randomIndex = Math.floor(Math.random() * count);
option = element(by.repeater('order in vm.orders').row(randomIndex));
option.click();
});
}
};
Given that the orderSelect can only be selected once populated with options after choosing an option from the customerSelect, I wondered about hooking into the promise returned when calling this.customerSelectOptions.count(), so calling this.selectRandomOrder, but it seems this is undefined as I get an error from protractor saying it cannot find the selectRandomOrder function.
Right now I can only get the first select to pick an option since it's always populated on the initial page load.
Also, I'm unsure whether using isEnabled() is actually working for me, as I am certain this should be returning true for my second input, but if I console log this out, I see false. Does this not work with ng-disabled?
What are the best practices for dealing with inputs on a form that wont initially be populated with data and waiting for angular to fetch and populate any available options?
Thanks
UPDATE:
I have got this to working using a call to getAttribute() checking for the presence of the disabled property instead.
So from my spec file in an it block I can call
page.customerSelect.getAttribute('disabled').then(function(result){
if(!result) {
page.selectRandomCustomer();
}
});
page.orderSelect.getAttribute('disabled').then(function(result){
if(!result) {
page.selectRandomOrder();
}
});
Ideally what I'd like to be able to do is to call the selectRandomOrder after clicking the option in the selectRandomCustomer:
this.selectRandomCustomer = function() {
var option,
randomIndex;
this.customerSelect.click();
this.customerSelectOptions.count().then(function(count) {
randomIndex = Math.floor(Math.random() * count);
option = element(by.repeater('customer in vm.customer').row(randomIndex));
option.click();
//Like to be able to call selectRandomOrder but only after angular has finished performing AJAX request for data and received response
});
};
this.selectRandomOrder = function() {
var option,
randomIndex;
this.orderSelect.click();
this.orderSelectOptions.count().then(function(count) {
randomIndex = Math.floor(Math.random() * count);
option = element(by.repeater('order in vm.orders').row(randomIndex));
option.click();
});
};
I did try calling this.selectRandomOrder immediately after the option.click() but I get an error saying no such function, it seems this is not accessible from inside the returned promise function callback.
There is at least one major problem in the posted code:
if(this.orderSelect.isEnabled()===true) {
Here isEnabled() returns a promise. You have to resolve it to check it's value:
var self = this; // saving the page object reference
this.orderSelect.isEnabled().then(function (isEnabled) {
if (isEnabled) {
var option,
randomIndex;
self.orderSelect.click();
self.orderSelectOptions.count().then(function(count) {
randomIndex = Math.floor(Math.random() * count);
option = element(by.repeater('order in vm.orders').row(randomIndex));
option.click();
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With