How to wait for a page to load or element to be present when using Protractor for a non-Angular page

前端 未结 4 1556
耶瑟儿~
耶瑟儿~ 2021-02-09 16:32

I am new to Protractor. I think I have this down when dealing with an Angular page, but can\'t figure it out for a non-Angular page. Any help would be appreciated.



        
相关标签:
4条回答
  • 2021-02-09 17:06

    Another Neat approach is to use "Expected Conditions" inside browser.wait - something like this:

    var EC = protractor.ExpectedConditions;
    var search = element(by.id('search'))
    browser.wait(EC.visibilityOf(search), 2000).then(function(){
     search.click()
    })
    

    You can get more details here: https://angular.github.io/protractor/#/api?view=ExpectedConditions

    0 讨论(0)
  • 2021-02-09 17:19

    Testing non-angular pages with Protractor can be tricky regarding waiting for stuff.

    I suggest you upgrade Protractor to latest (1.5.0 as of now), use a custom function waitReady() that browser.wait for elements ready and rewrite your test like below. Note you can put everything within 1 spec if you like so.

    // TODO: use page objects
    var searchBtnElm = $('#search'); // use element(by.id('search')) if you prefer
    
    it('waits for the elements present and visible (non-angular)', function() {
        expect(searchBtnElm.waitReady()).toBeTruthy();
    });
    
    it('should click Search button', function() {
        searchBtnElm.click();
    });
    
    it('wait for more results', function() {
        // keep using waitReady() before interacting with the elements
        // and before performing expectations on them
    });
    

    More details of why waitReady here.

    Note: remember to set ignore synchronization for testing a non-angular page:

        browser.ignoreSynchronization = true;
    

    You can set it before browser.get the non-angular page.

    I've suggested setting a high implicit wait in the past, e.g.

    browser.manage().timeouts().implicitlyWait(5000);
    

    That hack allows to you avoid waitReady and keep using the standard

    expect(searchBtnElm.isPresent()).toBeTruthy();
    

    But has an ugly disadvantage when testing for elements NOT present, i.e. when testing for absent or non visible elements in which case it will wait 5 seconds (5000ms) in vane, e.g. when doing

    expect(someNonExistingElm.isPresent()).toBeFalsy();
    
    0 讨论(0)
  • 2021-02-09 17:22

    In protractor there are two types terms for on the page. isPresent ask if the element is exists on the page. isDisplayed asks if the element is visible. If you are waiting for a page to load you need to wait for isDisplayed, but that will error if it is not present, so wait for isPresent first. I use a function to wait for an element.

    function waitForElement(el, waitTimeoutMilliseconds){
        return browser.wait(function() { return el.isPresent(); }, waitTimeoutMilliseconds)
            .then(function(){
               return browser.wait(function() { return el.isDisplayed(); }, waitTimeoutMilliseconds);
            });
    }
    

    Then just call that function in your test.

    describe('Search', function() {
        it('should click Search button and wait for results', function() {
            var el = element(by.id('search'));
            waitForElement(el, 5000);
            el.click();
        });
    });
    
    0 讨论(0)
  • 2021-02-09 17:24

    Figured this out. I simply added the code below, after the click method:

    describe('Search', function() {
       it('should click Search button and wait for results', function() {
            browser.driver.findElement(by.id('search')).click();
            dvr.wait(function() {
                return dvr.isElementPresent(by.xpath(
                    '/html/body/div/div[4]/div/div[2]/div/div/div/span'));
            }, 20000);
        });
    });
    
    0 讨论(0)
提交回复
热议问题