量角器:单击按钮后如何等待页面完成?
Posted
技术标签:
【中文标题】量角器:单击按钮后如何等待页面完成?【英文标题】:Protractor : How to wait for page complete after click a button? 【发布时间】:2014-03-11 23:44:22 【问题描述】:在测试规范中,我需要单击网页上的按钮,然后等待新页面完全加载。
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');
【问题讨论】:
您能否在您等待的页面上更具体一些?您只是在等待页面更改或一些异步加载吗? 【参考方案1】:根据你想做什么,你可以尝试:
browser.waitForAngular();
或
btnLoginEl.click().then(function()
// do some stuff
);
解决承诺。如果你能在beforeEach
中做到这一点会更好。
注意:我注意到,expect() 会等待内部的 promise(即 getCurrentUrl)在比较之前得到解决。
【讨论】:
感谢分享,帮助发现了一些奇怪的间歇性问题。 我仍然有问题:等待异步脚本结果超时 这并没有解决我在点击按钮后等待javascript完成修改页面的问题。按照建议的below 添加browser.driver.sleep(1000)
就可以了。
waitForAngular()
should not be used。关于click().then()
,它对我不起作用。我只能依靠browser.wait(//use of protractor.ExpectedConditions)
。【参考方案2】:
我刚刚查看了源代码 - Protractor 仅在少数情况下等待 Angular(例如在调用 element.all
或设置/获取位置时)。
所以 Protractor 不会在每次命令后等待 Angular 稳定下来。
另外,在我的测试中,有时我会在 Angular 摘要循环和点击事件之间进行竞争,所以有时我必须这样做:
elm.click();
browser.driver.sleep(1000);
browser.waitForAngular();
使用睡眠等待执行进入AngularJS上下文(由click
事件触发)。
【讨论】:
量角器不同步.click(),它同步了下一个涉及ElementFinder/ElementArrayFinder的操作。 我从经验中知道,在使用expect
评估期望值时,量角器会等待角度。在其他情况下,我明确使用waitForAngular
。
虽然你的帖子已经快两年了,但我发现你还是对的。我目前需要在量角器 element(by.css('my-css')).click()
之后添加一个 '.sleep(1000)' 。 .click 似乎没有等待,尽管返回了一个承诺。
我总是使用承诺。例如:return elm.click().then(function () return nextAction();
我不建议使用显式睡眠,因为即使您的应用程序加载速度比配置的睡眠快,您也会进入睡眠状态。【参考方案3】:
您无需等待。 Protractor 会自动等待 angular 准备好,然后执行控制流中的下一步。
【讨论】:
理论上是的,因为waitForAngular()
是在内部调用的,但我也必须为某些规格调用它。
它会自动等待吗?看着像browser.get
这样的东西,它明确表示它的存在是为了覆盖它包装的东西。如果ElementFinder
没有click
方法,那么它似乎只是委托给webDriver.WebElement
。 angular.github.io/protractor/#/api?view=ElementFinder
@Snekse Protractor 同步了 ElementFinder 和 ElementArrayFinder 上的所有操作。因此,每当您的测试尝试查找任何元素时,查找本身都会等待 angular 完成消化周期,然后将调用委托给 webdriver。在 expect() 调用中也会发生同样的情况。
如果我们不需要等待,那么这个帖子不会被浏览 100,000 次。【参考方案4】:
使用 Protractor,您可以使用以下方法
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 可用于测试。
参考:Protractor ExpectedConditions
【讨论】:
【参考方案5】:在这种情况下,您可以使用:
页面对象:
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);
【讨论】:
【参考方案6】:我通常只是在控制流中添加一些东西,即:
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();
【讨论】:
【参考方案7】:用这个我觉得更好
*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;
;
【讨论】:
【参考方案8】:要等到点击本身完成(即解决 Promise),请使用 await
关键字
it('test case 1', async () =>
await login.submit.click();
)
这将停止命令队列,直到点击(sendKeys、sleep 或任何其他命令)完成
如果您很幸运,并且您在构建良好且没有待处理的微观和宏观任务的角度页面上,那么 Protractor 应该自行等待,直到页面准备好。但有时您需要自己处理等待,例如通过非 Angular 页面登录时(阅读how to find out if page has pending tasks and how to work with non angular pages)
如果您手动处理等待,browser.wait
是您的最佳选择。只需将一个函数传递给它,该函数将具有等待的条件。例如等到页面上没有加载动画
let $animation = $$('.loading');
await browser.wait(
async () => (await animation.count()) === 0, // function; if returns true it stops waiting; can wait for anything in the world if you get creative with it
5000, // timeout
`message on timeout`
);
请务必使用await
【讨论】:
【参考方案9】:你可以这样做
emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');
btnLoginEl.click().then(function()
browser.wait(5000);
);
【讨论】:
browser.wait(5000) 将返回“不可分配给类型函数”,因为 browser.wait 接受 >1 个参数,第一个是条件,第二个是时间...跨度> 【参考方案10】:browser.waitForAngular();
btnLoginEl.click().then(function() Do Something );
兑现承诺。
【讨论】:
以上是关于量角器:单击按钮后如何等待页面完成?的主要内容,如果未能解决你的问题,请参考以下文章