Friday, September 14, 2018

isDisplayed returns false for a visible element in Protractor

Leave a Comment

EDIT #4: Breakthrough!!

I started recursively going through the parent nodes and returning the same values as below. One of the parents--the inner mat-drawer-container--also returned false for isDisplayed (all the others returned true, which seems odd).

Looking at that node, it turns out that it's the only tag on the site to have the CSS of display: contents. Removing that causes the button in question--and everything else below it--to return true for isDisplayed. Heck, Protractor can even click the button and I can see the expected result in the browser.

Now I suppose the question remains: is this is expected behavior or a bug? It's not as straightforward as there being an ancestor with display: contents applied; I applied it directly to rb-container and Protractor was still able to find the button.


I'm working on end-to-end testing in Protractor for the first time, and I'm running into an issue when trying to test for a button being visible; despite the button element being in the DOM and visible, isDisplayed returns false and my assertion fails.

This is the initial assertion that's been failing:

expect(element(by.css("mat-drawer-content rb-container rb-fab-button[data-qaid='create-button'] > button")).isDisplayed()).toBe(true); 

(Yes, the selector is a mess, but I don't have control over the HTML.)

I've used a long browser.sleep() interval to essentially pause the browser in place so I could use the dev tools to inspect the humanly-visible element, and the CSS leads me to believe it should be detected as visible.

After searching for answers and/or bugs to no avail, I logged some information to the console which still leads me to believe that isDisplayed should return true:

[ EDITS #2, #3: Logged some more information on all the direct children of rb-container; only one node is "visible", according to Protractor. ]

  let selector = element.all(by.tagName("mat-drawer-content")).get(0).all(by.css("rb-container > *"));    selector.count().then(function(selCount) {      for (let match = 0; match < selCount; match ++) {        browser.sleep(1000).then(() => {         let elm = selector.get(match);          console.log("\n >> " + match + "]");          elm.getTagName().then(tag => { console.log("tag name:", tag); });         elm.getCssValue("visibility").then(vis => { console.log("visibility:", vis); });         elm.getCssValue("display").then(disp => { console.log("display:", disp); });         elm.getCssValue("opacity").then(opa => { console.log("opacity:", opa); });         elm.getCssValue("overflow").then(ov => { console.log("overflow:", ov); });         elm.getAttribute("hidden").then(hid => { console.log("hidden:", hid); });         elm.getAttribute("class").then(c => { console.log("class:", c)});         elm.getSize().then(size => { console.log("size:", size); });         elm.getCssValue("position").then(ov => { console.log("position:", ov); });         elm.getLocation().then(loc => { console.log("location:", loc); });         elm.isPresent().then(pres => { console.log("isPresent:", pres); });         elm.isDisplayed().then(disp => { console.log("isDisplayed:", disp); });       });      }    }); 

This is what I see logged:

 >> 0] tag name: div visibility: visible display: block opacity: 1 overflow: auto hidden: null class: title-tab dn db-m mediumGreyColor pl4 pv2 overflow-auto size: { ceil: {},   clone: {},   floor: {},   height: 62,   round: {},   scale: {},   toString: {},   width: 898 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 0,   y: 74.765625 } isPresent: true isDisplayed: false   >> 1] tag name: div visibility: visible display: block opacity: 1 overflow: auto hidden: null class: player-menu container overflow-auto dn db-m pv2 ng-star-inserted size: { ceil: {},   clone: {},   floor: {},   height: 64,   round: {},   scale: {},   toString: {},   width: 834 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 32,   y: 136.765625 } isPresent: true isDisplayed: false   >> 2] tag name: rb-fab-button visibility: visible display: block opacity: 1 overflow: visible hidden: null class: add-fab-button absolute dn db-m ng-star-inserted size: { ceil: {},   clone: {},   floor: {},   height: 56,   round: {},   scale: {},   toString: {},   width: 56 } position: absolute location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 762,   y: 154.765625 } isPresent: true isDisplayed: false   >> 3] tag name: div visibility: visible display: block opacity: 1 overflow: visible hidden: null class: mr4-l w-100-m size: { ceil: {},   clone: {},   floor: {},   height: 0,   round: {},   scale: {},   toString: {},   width: 834 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 32,   y: 200.765625 } isPresent: true isDisplayed: false   >> 4] tag name: rb-table-wrapper visibility: visible display: block opacity: 1 overflow: visible hidden: null class: dn db-m size: { ceil: {},   clone: {},   floor: {},   height: 672,   round: {},   scale: {},   toString: {},   width: 834 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 32,   y: 200.765625 } isPresent: true isDisplayed: true   >> 5] tag name: div visibility: visible display: block opacity: 1 overflow: visible hidden: null class: container size: { ceil: {},   clone: {},   floor: {},   height: 0,   round: {},   scale: {},   toString: {},   width: 834 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 32,   y: 872.5625 } isPresent: true isDisplayed: false   >> 6] tag name: rb-table-wrapper visibility: visible display: none opacity: 1 overflow: visible hidden: null class: db dn-m size: { ceil: {},   clone: {},   floor: {},   height: 0,   round: {},   scale: {},   toString: {},   width: 0 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 0,   y: 0 } isPresent: true isDisplayed: false   >> 7] tag name: div visibility: visible display: none opacity: 1 overflow: auto hidden: null class: player-menu container overflow-auto db dn-m ng-star-inserted size: { ceil: {},   clone: {},   floor: {},   height: 0,   round: {},   scale: {},   toString: {},   width: 0 } position: static location: { ceil: {},   clone: {},   floor: {},   round: {},   scale: {},   toString: {},   translate: {},   x: 0,   y: 0 } isPresent: true isDisplayed: false 

With no hidden attribute set, a display value that isn't "none", visibility set to "visible", and non-zero size dimensions, I would expect isDisplayed to return true.

It's interesting to look at node 4, the only child element for which isDisplayed returns true, and compare it with node 2, the rb-fab-button element I'm trying to access. The only noticeable difference I can see is that rb-fab-button is positioned absolutely; however, the other statically-positioned elements also return false for isDisplayed.

Am I missing something? I'd settle for checking for css visibility, but my next test is to click that button, which errors if the element is not visible.

[ EDIT #1: Added some HTML: ]

<mat-drawer-container _ngcontent-c0="" class="root-container w-100 mat-drawer-container mat-drawer-container-explicit-backdrop" hasbackdrop="true" ng-reflect-has-backdrop="true">      <div class="mat-drawer-backdrop ng-star-inserted"></div>      <div tabindex="-1" class="cdk-visually-hidden cdk-focus-trap-anchor"></div>      <mat-drawer _ngcontent-c0="" class="mobile-drawer dn-m w-80 mat-drawer ng-tns-c2-0 ng-trigger ng-trigger-transform mat-drawer-over ng-star-inserted" tabindex="-1" ng-reflect-mode="over" style="box-shadow: none; visibility: hidden;">        <!-- [... mobile nav ...] -->      </mat-drawer>      <div tabindex="-1" class="cdk-visually-hidden cdk-focus-trap-anchor"></div>      <mat-drawer-content _ngcontent-c0="" class="mat-drawer-content">          <rb-navbar _ngcontent-c0="" _nghost-c7="" class="ng-star-inserted">            <!-- [... nav bar ...] -->          </rb-navbar>          <div _ngcontent-c0="" class="main-body">              <div _ngcontent-c0="" class="container h-100">                  <router-outlet _ngcontent-c0=""></router-outlet>                  <rb-system-setup _nghost-c18="" class="ng-star-inserted">                      <router-outlet _ngcontent-c18=""></router-outlet>                      <rb-site-tab class="ng-star-inserted">                          <mat-drawer-container autosize="" class="mat-drawer-container" ng-reflect-autosize="">                              <div class="mat-drawer-backdrop ng-star-inserted"></div>                              <div tabindex="-1" class="cdk-visually-hidden cdk-focus-trap-anchor"></div>                              <mat-drawer class="mat-drawer ng-tns-c2-8 ng-trigger ng-trigger-transform mat-drawer-end mat-drawer-over ng-star-inserted" disableclose="true" mode="over" position="end" tabindex="-1" ng-reflect-position="end" ng-reflect-mode="over" ng-reflect-disable-close="true" style="box-shadow: none; visibility: hidden;">                                  <rb-create-site _nghost-c20="" ng-reflect-side-panel="[object Object]" ng-reflect-side-panel-container="[object Object]" ng-reflect-ng-grid="[object Object]" ng-reflect-is-editing="false" ng-reflect-timezones="[object Object],[object Object">                                      <rb-side-panel _ngcontent-c20="" _nghost-c24="" ng-reflect-title="Add Site" ng-reflect-close-button-label="Cancel" ng-reflect-submit-button-label="CREATE_SITE.SUBMIT" ng-reflect-show-submit-button="true" ng-reflect-modal-submitting="true" ng-reflect-side-panel-container="[object Object]">                                        <!-- [... side panel ...] -->                                      </rb-side-panel>                                  </rb-create-site>                              </mat-drawer>                              <div tabindex="-1" class="cdk-visually-hidden cdk-focus-trap-anchor"></div>                              <mat-drawer-content cdkscrollable="" class="mat-drawer-content ng-star-inserted">                                  <div class="ph4-m h-100">                                      <rb-card _nghost-c21="">                                          <div _ngcontent-c21="" class="card rb-min-width-1 h-100">                                              <div _ngcontent-c21="" class="relative h-100">                                                  <rb-container _nghost-c22="" ng-reflect-row-data="[object Object]" ng-reflect-show-player="true" ng-reflect-show-search-bar="true" ng-reflect-include-edit="true" ng-reflect-include-delete="true" ng-reflect-include-stop="false" ng-reflect-include-sync="false" ng-reflect-include-checkbox="true" ng-reflect-include-fab-button="true" ng-reflect-route-type="systemSetup" ng-reflect-header="Sites" ng-reflect-mobile-table="site" ng-reflect-show-site-selector="false" ng-reflect-mobile-navigation="true">                                                      <div _ngcontent-c22="" class="title-tab dn db-m mediumGreyColor pl4 pv2 overflow-auto">                                                          <h1 _ngcontent-c22="" class="header-text pa2 fl ng-star-inserted">Sites</h1></div>                                                      <div _ngcontent-c22="" class="player-menu container overflow-auto dn db-m pv2 ng-star-inserted">                                                        <!-- [... player menu ...] -->                                                      </div>                                                      <rb-fab-button _ngcontent-c22="" class="add-fab-button absolute dn db-m ng-star-inserted" data-qaid="create-button" _nghost-c28="">                                                          <button _ngcontent-c28="" class="w-10 z-1 mat-fab mat-accent" mat-fab="" type="button" ng-reflect-disabled="false"><span class="mat-button-wrapper"><mat-icon _ngcontent-c28="" aria-label="add" class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">add</mat-icon></span>                                                              <div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple="" ng-reflect-centered="false" ng-reflect-disabled="false" ng-reflect-trigger="[object HTMLButtonElement]"></div>                                                              <div class="mat-button-focus-overlay"></div>                                                          </button>                                                      </rb-fab-button>                                                      <div _ngcontent-c22="" class="mr4-l w-100-m"></div>                                                      <rb-table-wrapper _ngcontent-c22="" class="dn db-m" ng-reflect-row-data="[object Object]" ng-reflect-enable-sorting="true" ng-reflect-include-checkbox="true" ng-reflect-is-clickable="false" ng-reflect-row-selection="multiple" ng-reflect-dom-layout="" ng-reflect-columns="[object Object],[object Object" ng-reflect-un-select-all_="[object Object]" ng-reflect-mobile-table="site" ng-reflect-mobile-navigation="true" ng-reflect-row-drag="false" ng-reflect-row-drag-field-name="">                                                          <ag-grid-angular class="ag-theme-material" ng-reflect-grid-options="[object Object]" ng-reflect-row-data="[object Object]" ng-reflect-column-defs="[object Object],[object Object" ng-reflect-default-col-def="[object Object]" ng-reflect-row-selection="multiple" ng-reflect-suppress-row-click-selection="true" ng-reflect-enable-sorting="true" ng-reflect-enable-filter="true" ng-reflect-suppress-no-rows-overlay="true" ng-reflect-dom-layout="" ng-reflect-row-drag-managed="false">                                                            <!-- [... data grid ...] -->                                                          </ag-grid-angular>                                                          <div class="backgroundColor w-100 fixed bottom-0 left-0 dn db-m ng-star-inserted">                                                              <div class="item-selection fr w-20">0/ 1 Selected</div>                                                          </div>                                                      </rb-table-wrapper>                                                      <div _ngcontent-c22="" class="player-menu container overflow-auto db dn-m ng-star-inserted"></div>                                                  </rb-container>                                              </div>                                          </div>                                      </rb-card>                                  </div>                              </mat-drawer-content>                          </mat-drawer-container>                      </rb-site-tab>                  </rb-system-setup>              </div>              <div _ngcontent-c0="" class="snacks fixed mw6 rb-min-width-2">                  <rb-global-snack-bar _ngcontent-c0="" _nghost-c8="" class="ng-tns-c8-3">                      <div _ngcontent-c8="" class="snackBar">                          <ul _ngcontent-c8="" class="ma0 pa0 list"></ul>                      </div>                  </rb-global-snack-bar>              </div>          </div>      </mat-drawer-content>  </mat-drawer-container>

0 Answers

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment