title: Angular JS- testing with Protractor: how to get an element when element doesn't have a tag-name?
body: <p>I am developing a test suite for my AngularJS app using <a href="http://www.protractortest.org" rel="nofollow noreferrer">Protractor</a> as my testing framework.</p>
  
  <p>The app's menu is displayed at a fixed location across all pages of the site- when the user hovers the cursor over any of the buttons on the menu, the cursor changes to a pointer, to indicate that that button can be clicked. Each button in the menu represents a particular page of the app- if there are sub-pages belonging to a page when the user hovers the cursor over the menu button for that page, a sub-menu is displayed, with text-buttons for each of the sub-pages.</p>
  
  <p>I am currently working on a test that will test the functionality of the menu- hovering the cursor over one of the buttons on the menu, checking that the sub-menu is displayed, and then hidden again when the cursor is no longer hovering over that menu button, checking that clicking any of the menu buttons/ sub-menu buttons take you to the right page, etc.</p>
  
  <p>The HTML for the menu is written as follows:</p>
  
  <pre><code>&lt;ul id="nav"
      class="nav"
      data-slim-scroll
      data-collapse-nav
      data-highlight-active&gt;
      &lt;li data-ng-mouseenter="setMenuTop($event)" ng-show="menu.pages.length &gt; 0 || menu.upages.length &gt; 0 || canCreatePage"&gt;
          &lt;a href="#/pages" id="pagesMenuBtn" target="_self"&gt;&lt;i class="ti-layers"&gt;&lt;/i&gt;&lt;span data-i18n="Pages"&gt;&lt;/span&gt;&lt;/a&gt;
          &lt;ul class="text-capitalize"&gt;
              &lt;li ng-repeat="page in menu.pages"&gt;&lt;a href="#/{{page.location}}" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="{{page.title}}"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li ng-repeat="upage in menu.upages"&gt;
                  &lt;div class="nav-menu-divider" data-ng-if="$index === 0"&gt;&lt;/div&gt;
                  &lt;a href="#/{{upage.location}}" target="_self"&gt;
                      &lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="{{upage.title}}"&gt;&lt;/span&gt;
                  &lt;/a&gt;
              &lt;/li&gt;
              &lt;li data-ng-show="canCreatePage"&gt;
                  &lt;div class="nav-menu-divider"&gt;&lt;/div&gt;
                  &lt;a href="#/pages/create" target="_self"&gt;
                      &lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="Create Page"&gt;&lt;/span&gt;
                  &lt;/a&gt;
              &lt;/li&gt;
          &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;...&lt;/li&gt;
      &lt;li&gt;...&lt;/li&gt;
      &lt;li&gt;...&lt;/li&gt;
      &lt;li&gt;...&lt;/li&gt;
      &lt;li data-ng-mouseenter="setMenuTop($event)"&gt;
          &lt;a href="#/config" target="_self"&gt;&lt;i class="ti-settings"&gt;&lt;/i&gt;&lt;span data-i18n="Config"&gt;&lt;/span&gt;&lt;/a&gt;
          &lt;ul&gt;
              &lt;li ng-repeat="page in menu.config"&gt;&lt;a href="#/{{page.location}}" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="{{page.title}}"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li ng-show="platform._id"&gt;&lt;a ng-href="#/config/platform/{{platform._id}}" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="Platform"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li ng-show="system._id"&gt;&lt;a ng-href="#/config/system/{{system._id}}" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="System"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href="#/config/user" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="Users"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li&gt;&lt;a href="#/config/backup" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="Backup / Restore"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
              &lt;li ng-show="systemActions.dateTime"&gt;&lt;a href="#/config/systemtime" target="_self"&gt;&lt;i class="ti-angle-right"&gt;&lt;/i&gt;&lt;span data-i18n="Date / Time"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li class="nav-footer"&gt;
          &lt;span&gt;{{currentTime.localTDZFormat}}&lt;/span&gt;
      &lt;/li&gt;
  &lt;/ul&gt;
  </code></pre>
  
  <p>As shown, there are two menu items which have 'sub-menus' associated with them.</p>
  
  <p>I want to test that when the user hovers their cursor over one of the menu-items that have an associated sub-menu, the sub-menu is displayed correctly, and when the cursor leaves the menu-item, the sub-menu is no longer displayed: I have tried to do this with the following test:</p>
  
  <pre><code>it('should display the Pages menu', function() {
      browser.waitForAngularEnabled(false);
      browser.actions().mouseMove(pagesMenuBtn).perform();
      expect(pageVarBrowserBtn.isDisplayed()).toBeTruthy();
      browser.actions().mouseMove(userCircle).perform();
      expect(pageVarBrowserBtn.isDisplayed()).toBeFalsy();
      browser.waitForAngularEnabled(true);
  });
  </code></pre>
  
  <p>The variables used in this test are defined with:</p>
  
  <pre><code>var pagesMenuBtn = element(by.id('pagesMenuBtn'));
  var pageVarBrowserBtn = element.all(by.id('menu.pages')).get(0);
  var userCircle = element(by.id('icon-user-circle'));
  </code></pre>
  
  <p>The <code>pageVarBrowserBtn</code> is the first menu-item in the sub-menu displayed when the user hovers their cursor over the <code>pagesMenuBtn</code>.</p>
  
  <p>Currently, when I run the test, the browser opens, navigates to the root page of my app, and hovers the cursor over the <code>pagesMenuBtn</code> element, so that the sub-menu is displayed (I can see it displayed in the browser window that was opened up by the test).</p>
  
  <p>But, I then get an error in the console that says:</p>
  
  <blockquote>
    <p>Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(CSS selector, *[id="menu.pages"]) </p>
  </blockquote>
  
  <p>I don't understand why I'm getting this error...? How can I get a single element from the sub-menu that's being displayed, in order to check that it is the correct item and that clicking it takes the user to the correct location? I can't specify the exact element's ID because it is being created by the <code>ng-repeat</code>, so that's why I'm trying to get it by its position/ array index - 0.</p>