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');
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');
根据您想要做什么,您可以尝试:
browser.waitForAngular();
或者
btnLoginEl.click().then(function() {
// do some stuff
});
为了解决这个承诺,最好在beforeEach
中完成。
NB: 我注意到expect()
会等待内部的承诺(即getCurrentUrl
)被解决后再进行比较。
browser.driver.sleep(1000)
就解决了这个问题。 - CGFoXwaitForAngular()
不应该使用(参见https://dev59.com/vl0Z5IYBdhLWcg3w8kH3)。关于click().then()
,它对我无效。我只能依赖于browser.wait(//使用protractor.ExpectedConditions)
。 - ThCollignon我刚刚查看了源代码 - Protractor 只在少数情况下等待 Angular(例如在调用 element.all
或设置 / 获取位置时)。
因此,Protractor 不会在每个命令之后等待 Angular 稳定。
另外,在我的一些测试中,有时会出现 Angular digest 循环和点击事件之间的竞争,所以有时我必须执行以下操作:
elm.click();
browser.driver.sleep(1000);
browser.waitForAngular();
使用 sleep
来等待执行进入 AngularJS 上下文(由 click
事件触发)。
.click()
,它会同步涉及到ElementFinder/ElementArrayFinder的下一个操作。 - Maxexpect
评估期望时,Protractor会等待Angular。在其他情况下,我会明确地使用waitForAngular
。 - jrharshathelement(by.css('my-css')).click()
后添加一个 .sleep(1000)
。似乎 .click
不会等待,尽管返回了一个 promise。 - bob.mazzoreturn elm.click().then(function () { return nextAction(); }
- Ed Greaves您无需等待。Protractor会自动等待Angular准备就绪,然后在控制流中执行下一步。
waitForAngular()
会在内部调用,但我也必须为某些规格调用它。 - glepretrebrowser.get
这样的内容,它明确表示它存在是为了覆盖它所包装的东西。如果 ElementFinder
没有 click
方法,那么它似乎只是委托给 webDriver.WebElement
。
(注意:本文中的术语可能需要根据上下文进行调整翻译) - Sneksevar 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');
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);
通常我只是在控制流中添加一些内容,例如:
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();
}
*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;
};
要等到点击本身完成(即解决 Promise),请使用 await
关键字
it('test case 1', async () => {
await login.submit.click();
})
这将停止命令队列,直到点击(sendKeys、sleep或任何其他命令)完成
如果你很幸运,你在一个构建良好且没有微观和宏观任务待处理的Angular页面上,那么Protractor应该自己等待页面准备就绪。但有时候你需要自己处理等待,例如通过非Angular页面登录(阅读如何找出页面是否有待处理任务以及如何处理非Angular页面)
在你手动处理等待的情况下,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
你可以像这样做
emailEl.sendKeys('jack');
passwordEl.sendKeys('123pwd');
btnLoginEl.click().then(function(){
browser.wait(5000);
});
browser.waitForAngular();
btnLoginEl.click().then(function() { Do Something });
解决 Promise 的问题。