量角器:单击按钮后如何等待页面完成?


78

在测试规范中,我需要单击网页上的按钮,然后等待新页面完全加载。

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

// ...Here need to wait for page complete... How?

ptor.waitForAngular();
expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

2
您能在正在等待的页面上更具体些吗?您是在等待页面更改还是在等待异步加载?
Furzel 2014年

Answers:


92

根据您要执行的操作,可以尝试:

browser.waitForAngular();

要么

btnLoginEl.click().then(function() {
  // do some stuff 
}); 

兑现诺言 如果您可以在Windows中这样做,那会更好beforeEach

注意:我注意到Expect()在比较之前会等待内部的Promise(即getCurrentUrl)得到解决。


感谢您的分享,帮助您确定了一些奇怪的间歇性问题。
哈坎·塞斯

1
我仍然有问题:等待异步脚本结果超时
Emna Ayadi '16

3
这并没有解决我单击按钮后等待javascript完成修改页面的问题。browser.driver.sleep(1000)按照下面的建议添加就可以了。
CGFoX'2

3
waitForAngular() 不应该使用。关于click().then()它对我不起作用。我只能依靠browser.wait(//use of protractor.ExpectedConditions)

30

我只是看了一下源代码-量角器仅在少数情况下等待Angular(例如何时element.all调用,或设置/获取位置)。

因此,量角器无需等待每条命令后Angular的稳定。

另外,有时在我的测试中,我似乎在Angular摘要循环和click事件之间进行了竞争,因此有时我必须这样做:

elm.click();
browser.driver.sleep(1000);
browser.waitForAngular();

使用sleep等待执行进入AngularJS上下文(由click事件触发)。


1
量角器不同步.click(),而是同步涉及ElementFinder / ElementArrayFinder的下一个操作。
最多

我从经验中知道,量角器在使用评估期望时会等待角度expect。在其他情况下,我明确使用waitForAngular
jrharshath

1
尽管您的职位将近两年,但我发现您仍然正确。我目前需要在量角器后添加'.sleep(1000)' element(by.css('my-css')).click()。似乎.click没有等待,尽管返回了承诺。
bob.mazzo

我总是用诺言。例如:return elm.click().then(function () { return nextAction(); }
Ed Greaves,2016年

3
我不建议您使用显式睡眠,因为即使您的应用程序加载的速度比配置的睡眠速度快,您也会睡眠。
timbru31

25

您无需等待。量角器自动等待角度准备就绪,然后执行控制流程中的下一步。


5
从理论上讲,是的,因为waitForAngular()在内部被调用,但是我也不得不为某些规格调用它。
glepretre 2014年

8
它会自动等待吗?看着类似的东西browser.get,它明确表示存在它要覆盖它包装的东西。如果没有click方法ElementFinder,则似乎只是将其委托给webDriver.WebElementangular.github.io/protractor/#/api?view=ElementFinder
Snekse 2014年

5
@Snekse量角器通过ElementFinder和ElementArrayFinder同步了所有操作。因此,每当您的测试尝试查找任何元素时,查找本身都会等待angular完成摘要循环,然后将调用委派给webdriver。在Expect()调用中也会发生同样的情况。
最多

8
如果我们不需要等待,那么该线程将不会被查看100,000次。
贾斯汀

7

通过量角器,可以使用以下方法

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain newPageName
browser.wait(EC.urlContains('newPageName'), 10000);

因此您的代码看起来像

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click();

var EC = protractor.ExpectedConditions;
// Wait for new page url to contain efg
ptor.wait(EC.urlContains('efg'), 10000);

expect(ptor.getCurrentUrl()).toEqual(url + 'abc#/efg');

注意:这可能并不意味着新页面已完成加载并且DOM已准备就绪。随后的'expect()'语句将确保Protractor等待DOM可用于测试。

参考:量角器的预期条件


3

在这种情况下,您可以使用:

页面对象:

    waitForURLContain(urlExpected: string, timeout: number) {
        try {
            const condition = browser.ExpectedConditions;
            browser.wait(condition.urlContains(urlExpected), timeout);
        } catch (e) {
            console.error('URL not contain text.', e);
        };
    }

页面测试:

page.waitForURLContain('abc#/efg', 30000);

2

我通常只在控制流中添加一些内容,即:

it('should navigate to the logfile page when attempting ' +
   'to access the user login page, after logging in', function() {
  userLoginPage.login(true);
  userLoginPage.get();
  logfilePage.expectLogfilePage();
});

日志文件页面:

function login() {
  element(by.buttonText('Login')).click();

  // Adding this to the control flow will ensure the resulting page is loaded before moving on
  browser.getLocationAbsUrl();
}

1

用这个我觉得比较好

   *isAngularSite(false);*
    browser.get(crmUrl);


    login.username.sendKeys(username);
    login.password.sendKeys(password);
    login.submit.click();

    *isAngularSite(true);*

为了使用isAngularSite的此设置,应将其放在此处的protractor.conf.js中:

        global.isAngularSite = function(flag) {
        browser.ignoreSynchronization = !flag;
        };

-1

你可以做这样的事情

emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');

btnLoginEl.click().then(function(){
browser.wait(5000);
});


browser.wait(5000)将返回“不可分配给类型函数”,因为browser.wait接受> 1个参数,第一个是条件,第二个是时间...
IWI

-2
browser.waitForAngular();

btnLoginEl.click().then(function() { Do Something });

兑现诺言

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.