I have a list of checkboxes and at the top a all
checkbox. When toggling the all checkbox, all checkboxes will get deselected or selected.
By default/initially, all
checkbox is enabled with all checkboxes checked. So, I will deselect the all checkbox and all the checkboxes will uncheck. This passes no with no issues in protractor:
it('all checkbox is deselected', function() {
modelsAllCheckbox.click();
expect(modelsAllCheckbox.isSelected()).to.eventually.be.false;
});
it('all models should be deselected', function() {
ppvPercentages.modelChoices().then(function(modelChoices) {
modelChoices.forEach(function(modelChoice) {
expect(modelChoice.isSelected()).to.eventually.be.false;
});
});
});
this.modelChoices = function(rowNumber) {
return element.all(by.repeater('model in vehicleCheckboxes.models'));
}
Then I re-enable the all
checkbox. I visually can see, in the browser, the all checkbox being checked in all the checkboxes successfully being checked/selected. Hoewever, in the test to assert they are all selected fails:
it('all button is re-enabled', function() {
modelsAllCheckbox.click();
expect(modelsAllCheckbox.isSelected()).to.eventually.be.true;
// give time for all models to set
browser.sleep(3000)
});
it('all models are selected', function() {
ppvPercentages.modelChoices().then(function(modelChoices) {
modelChoices.forEach(function(modelChoice) {
expect(modelChoice.isSelected()).to.eventually.be.true;
});
});
})
<div class="overflow-container">
<!-- all checkbox -->
<input type="checkbox"
ng-model="vehicleAllCheckbox.models"
ng-change="toggleAllModels(vehicleAllCheckbox, vehicleCheckboxes.models, vehicleCheckboxes.year)">All
<div ng-repeat="model in vehicleCheckboxes.models | orderBy: 'description' track by model.description">
<!-- the rest of the checkboxes -->
<input type="checkbox"
ng-change="modelCheckboxToggle()"
ng-model="model.checked" >
{{model.description}}
</div>
</div>
I see all the checkboxes are checked in the browser viusally. Why is modelChoice.isSelected()
giving false instead of true up re-enabling the all checkbox?
The problem is in the way you are locating the checkboxes. Currently, you are targeting the parent div
elements since you are using the by.repeater()
locator:
<div ng-repeat="model in vehicleCheckboxes.models | orderBy: 'description' track by model.description">
Instead, point modelChoices
to input
elements (your checkboxes):
this.modelChoices = function(rowNumber) {
return element.all(by.repeater('model in vehicleCheckboxes.models')).all(by.model('model.checked'));
}
As a side note, I think you can improve the way you are expecting the checkboxes to be selected, by either using .each()
:
ppvPercentages.modelChoices().each(function (modelChoice) {
expect(modelChoice.isSelected()).to.eventually.be.true;
});
Or, by using .reduce()
:
var allSelected = ppvPercentages.modelChoices().reduce(function (acc, modelChoice) {
return modelChoice.isSelected().then(function (isSelected) {
return acc && isSelected;
});
}, true);
expect(allSelected).to.eventually.be.true;
Or, there are other ways as well.