Protractor wait for isElementPresent and click on

2020-03-18 07:26发布

问题:

I have a issue with my end2end tests. Sometimes they pass without any problem but two thirds of the time they fail. I use protractor with following code:

 describe('Admin dashboard delete Exports', function () {
        it('create export', function () {
            browser.get(e2GUrl + '/admin/studies');
            ptor.wait(function() {
                return ptor.isElementPresent(by.id('export'));
            }, 5000, 'wait for study list page to be loaded.');
            element(by.id('export')).click();
         });

HTML (note that this element is visible and not hidden by ng-if or ng-show):

 <ul>
    <li data-ng-repeat="study in studies">
       <div data-ng-controller="ExportController" class="btn-group">
          <a id="export" class="btn btn-small dropdown-toggle" data-toggle="dropdown" href="#">
             <i class="fw-icon fw-icon-cloud-download"></i>Export
                <span class="caret"></span>
           </a>
           <ul class="dropdown-menu export-list">
                <li class="excel"><a data-ng-click="excel(study.Code)">Export to Excel</a>
                </li>
           </ul>
       </div>
    </li>
</ul>

Error I receive:

E2E: Admin dashboard delete Exports create export Message: NoSuchElementError: No element found using locator: By.id("export")

回答1:

I found out there the issue is in the difference between: element isPresent() and isDisplayed()

so if you wait for only isPresent() it could be found in html but not yet displayed.

tricky if you just want to use elm.isDisplayed() only, it will crash if the element doesn’t exist yet. So you have to check first is isPresent() before isDisplayed()

I made a function that waits blocking for the 2 properties:

this.waitUntilReady = function (elm) {
        browser.wait(function () {
            return elm.isPresent();
        },10000);
        browser.wait(function () {
            return elm.isDisplayed();
        },10000);
    };

describe('Admin dashboard delete Exports', function () {
        it('create export', function () {
            browser.get(e2GUrl + '/admin/studies');
            waitUntilReady(element(by.id('export')));
            element(by.id('export')).click();
         });