Want to remove Browser.sleep()

2019-02-27 20:35发布

问题:

Hi all I am working on a protractor to test a nonangular website. Initially while testing I had browser.sleep() so that page gets load completely. I know that adding browser.sleep is not a good way of testing and hence want to remove it from the code.

I tried browser.wait but I get an error and when I add broswer.manage.timeouts.implicitwait() the wait doesn't happen. I'm stuck on this issue for a long time please help me out :(

  var co = require('co');
    var path = require('path');

    describe("Portal: Partner Admin ", function () {
        beforeEach(function () {
            browser.ignoreSynchronization = true;

        });

        it("test", co.wrap(function* () {

            yield browser.get(browser.params.baseUrl);

            var elmOK = browser.driver.findElement(by.css('a[href="#login"]'));
            yield elmOK.click();
            expect(browser.getCurrentUrl()).toContain("login");
            yield browser.switchTo().frame('here-account-sdk').then(function () {
                browser.driver.findElement(by.id('sign-in-email')).sendKeys("Userid");
                browser.driver.findElement(by.id('sign-in-password-encrypted')).sendKeys("password");
                browser.driver.findElement(by.xpath(' //*[@id="sign-in-form"]/div[2]/div[6]/form/fieldset[3]/button')).click();

            });
            browser.sleep(5000);
            var elmOK = browser.driver.findElement(by.xpath('//*[@id="lnav"]/li[3]/a'));
            yield elmOK.click();
            browser.sleep(1500);
            browser.driver.findElement(by.xpath('//*[@id="administration"]/div/div[1]/select/option[2]')).click();
            browser.sleep(5000);

            browser.driver.findElement(by.xpath('//*[@id="administration"]/div/div[2]/table/tbody/tr[1]/td[10]/span')).click();
            browser.sleep(5000);

            browser.driver.findElement(by.xpath('//*[@id="content"]/div/div[2]/div/div/div/div[3]/button[1]')).click();//Delete the file
            browser.sleep(5000);
        }));

回答1:

Rather than waiting for the page itself wait for an element on the page.

The trick is to wait first for the element to be present, then wait for it to be displayed. Just calling "isDisplayed" causes errors if you do not wait for "isPresent" first. Here is a good function to use.

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

Instead of

browser.sleep(5000);
var elmOK = browser.driver.findElement(by.xpath('//*[@id="lnav"]/li[3]/a'));
yield elmOK.click();

do

var elmOk = element(by.xpath('//*[@id="lnav"]/li[3]/a'));
waitForElement(elmOk, 5000);
elmOk.click();


回答2:

You can use protractor expected conditions.

var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be clickable.
browser.wait(EC.elementToBeClickable($('#abc')), 5000);

like

var webElement = browser.driver.findElement(by.xpath('//*[@id="administration"]/div/div[1]/select/option[2]'));
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be clickable.
browser.wait(EC.elementToBeClickable(webElement )), 5000, 'element is not clickable with 5 seconds');

so that you don't need to put explicit waits. If element is clickable then browser immediately clicks on it, otherwise it waits for 5 seconds before it timeouts. you can increase that wait time as well.