0

I think I'm misunderstanding how elements works..

HTML code:

<div id="div-item">
    <a href="#">A link</a>
    <form>
        <div>
            <select>
                <option>1</option>
                <option>2</option>
            </select>
        </div>
    </form>
</div>

When I do this:

element(by.tagName('select')).all(by.tagName('option')).count();

This gives me 2, which is correct

When I do this:

element(by.id('div-item')).element(by.tagName('select')).all(by.tagName('option')).count();

This gives me 0. I thought chaining elements finds sub-elements. Is this not correct? How do I restrict the .all(by.tagName('option')) only within this div, rather than the whole page?

This is the xeditable library. My HTML code is:

<div id="div-item" class="col-xs-3">
    <a id="xeditable-link" href="#" ng-if="canEdit"
       editable-select="user_id"
       e-ng-options="user.id as user.name for user in users"
       onbeforesave="updateProfile({user_id: $data})">
       {{ showNameFromID(user_id) || 'none'}}
    </a>
</div>

But this generates a lot of HTML code. It's something like:

<div id="div-item" class="col-xs-3">
    <a id="xeditable-link" href="#" ng-if="canEdit"
       editable-select="user_id"
       e-ng-options="user.id as user.name for user in users"
       onbeforesave="updateProfile({user_id: $data})">
       {{ showNameFromID(user_id) || 'none'}}
    </a>
    <form ...>
        <div class="xeditable-controle..." ...blah blah>
            <select ...ng-options="..." blah blah>
                <option>1</option>
                <option>2</option>
            </select>
            <span> ...the buttons... </span>
        </div>
    </form>
</div>

My test spec:

it('should pass ...', function() {
    element(by.id('xeditable-link')).click(); // Click the link to bring up xeditable
    element(by.tagName('select')).click();    // Click the select to bring up the popup
    var allOptions = element(by.id('div-item')).element(by.tagName('select')).all(by.tagName('option'));
    expect(allOptions.count()).toBe(2);
    for (var i = 0; i < 2; ++i) {
        expect(allOptions.get(i).getText()).toBe(testText[i]);
    }
});

Both of the expect statements fail. count is 0, instead of 2 and "NoSuchElementError: No element found using locator: By.tagName("select")"

Jason
  • 1,787
  • 4
  • 29
  • 46
  • The latter works for me, something else is wrong. Could you show the complete test/spec you have? Which protractor version are you using? – alecxe Jan 07 '15 at 15:06
  • Updated with some more code. This is trying to test the xeditable library, which generates a lot of code. Not sure what I'm missing here. – Jason Jan 07 '15 at 15:21
  • I found it. id 'div-item' is used in another page. Since angular is single page, it's picking up the element in another .html file. – Jason Jan 07 '15 at 15:31
  • Gotcha :) Please post it as an answer so others would see it is resolved. – alecxe Jan 07 '15 at 15:31

2 Answers2

1

Try a single css locator

$$('#div-item select [option]').count()
// The same as
element.all(by.css('#div-item select [option]')).count()
Andres D
  • 8,910
  • 2
  • 26
  • 31
0

Turns out i had a 'div-item' in another .html file. Since AngularJS is a single page application, it was picking up that one instead of the one I wanted.

Jason
  • 1,787
  • 4
  • 29
  • 46