2

The site I'm testing on is a single page application with angular.

Because of this a lot of the DOM is loaded ahead of time and are hidden. Depending on what the user does, the hidden DOM will be displayed. Regardless of if the DOM is displayed or hidden, protractor sees this as part of the entire DOM tree. When I locate an element by id:

this.usernameTextbox = element(by.id('username'));

It detects that there are multiple elements with that same id, one element being visible (ng-show) and the other being hidden (ng-hide).

Is there a way for protractor to only locate elements that are not hidden?

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
awaken
  • 789
  • 1
  • 11
  • 22
  • I used this solution to interact with visible elements only: http://stackoverflow.com/questions/27905584/select-first-visible-element-in-protractor – awaken May 20 '15 at 01:14

2 Answers2

1

Have you tried the following:

browser.wait(function(){
    return element(by.id('username')).isDisplayed();
}, 1000).then(function(){
    //Your code here
});
Tom Nijs
  • 3,835
  • 3
  • 22
  • 40
1

You cannot reliably tell the webdriver to locate visible elements only, you need to get all of the elements matching a locator and filter them out checking the "displayedness".

In other words, use element.all() to find all elements by id, and use filter() to filter out the one that is visible, example code:

var username = element.all(by.id("username")).filter(function (elm) {
    return elm.isDisplayed().then(function (value) {
        return value;
    });
}).first();

By "reliably" here I mean that theoretically you may check the presence of display: none or visibility: hidden (reference), but don't ever do it, since the "displayedness" itself is a quite complicated thing that webdriver exposes/implements through that isDisplayed() method.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195