1

I'm running protractor e2e tests on an angular page and I wan't to check some dropdown boxes for their selected options. I got the following html code generated from angular:

<select class="ng-pristine ng-valid ng-touched" id="idxyz" ng-model="model" ng-options="xxx">
    <option selected="selected" value="object:null"></option>
    <option label="Steuerung 1" value="number:1">Steuerung 1</option>
    <option selected="selected" label="Programme" value="number:2">Programme</option>
    <option label="Steuerung 2" value="number:3">Steuerung 2</option>
</select>

And this is the protractor code that I use to get the selected option.

expect(element(by.css("select[ng-model='model'] option[selected='selected']")).getAttribute("value")).toBe("Programme");

As you might have noticed - there are two options with selected='selected'.

This is only the case when running the tests with protractor. When doing the same things by hand, only the truly selected option has the attribute selected='selected'.

Can anyone explain why this happens? The css selector should only return one option element because only one can be selected. But since there are two with the selected attribute - protractor gives me the following warning:

WARNING - more than one element found for locator By.cssSelector("select[ng-model='model'] option[selected='selected']") - the first result will be used

The first result is the empty option which is actually not selected.

Setup to run the tests:

  • angular: 1.4.4
  • grunt: 0.4.5
  • protractor: 2.5.1
  • grunt-protractor-runner: 2.1.0
Dominik Mohr
  • 827
  • 9
  • 19
  • I have never worked with protractor but CSS will return more than element because as you yourself has indicated there are two elements which match it. You may have to check the part of your code which is wrongly(?) updating two elements with `selected='selected'`. I am pretty sure this is not because of CSS. – Harry Nov 30 '15 at 16:13
  • What if you click the `select` element and then get the selected option in your test? – alecxe Nov 30 '15 at 16:17
  • Where is your code that selects the option? I would assume there is something odd going on in there to end up with two selected options. – codemonkey Nov 30 '15 at 16:25
  • 1
    May be this can give you a clue why is this happening: http://stackoverflow.com/questions/23643712/angularjs-select-creates-option-with-value-objectnull-and-doesnt-use-emp – alecxe Nov 30 '15 at 16:25
  • I'll check on the null/default binding @alecxe. But the problem seems to be within protractor since I cannot reproduce this without it. – Dominik Mohr Dec 01 '15 at 08:29
  • @DominikMohr thanks, another shot in the dark - what if you would add an artificial delay with `browser.sleep()` before searching for the select option?..does it make any difference?.. – alecxe Dec 01 '15 at 14:31

1 Answers1

1

To workaround the problem, you my additionally check the value to start with number:

select[ng-model=model] option[selected=selected][value^=number]

Or, we may check the value not equal to object:null:

select[ng-model=model] option:not([value="object:null"])[selected=selected]

Note that to make dealing with select-option easier, consider using a custom wrapper, see:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • The problem is that the additional attribute check `[value^=number]` will not work if the empty option is selected. At the moment I'm working around the issue with the following element selection: `element.all(by.css("select[ng-model='model'] option[selected='selected']")).last()` but I guess there is a reason why this happens?? – Dominik Mohr Nov 30 '15 at 16:20
  • Thanks for the info-link about the wrapper! – Dominik Mohr Nov 30 '15 at 16:21
  • @DominikMohr okay, updated the answer, we can also check for the value not to equal `object:null` - updated. This is to workaround the symptoms, I understand. Thanks. – alecxe Nov 30 '15 at 16:24