在量角器中单击按钮后如何等待 URL 加载?
How to wait for URL to load after button click in protractor?
我正在 angular 2 项目上使用量角器进行端到端测试,我需要测试登录操作。这里的问题是,当单击登录按钮时,expect 语句仍然会获得登录页面的 URL 作为主页。如果我等待,则测试成功。我在文档中的某个地方读到量角器等待进程自动完成,所以,
- 导致此错误的原因是什么?
- 如何在不显式使用
wait()
方法的情况下正确执行操作?
- 量角器是否有类似于
fakeAsync
、async
或至少 whenStable
的单位
测试?
这是我的测试用例
it("User successfully login",()=>{
browser.get(browser.baseUrl + '/account/login').then(() => {
return expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/account/login")
}).then(()=>{
element(by.tagName('input[type=text]')).sendKeys('username');
element(by.tagName('input[type=password]')).sendKeys('password');
element(by.css('button[type=submit]')).click().then(()=>{
return expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
});
});
});
注:
- 我有避免使用
browser.wait()
方法的说明。
- 登录按钮通过API向后端发送http请求。
解决方案[基于 Ernst 的解决方案]:
我解决了这个问题。我不知道它是否适用于其他场景,或者它是否是正确的方法。我添加了
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 10000);
browser.waitForAngularEnabled(false);
browser.wait(EC.urlContains(browser.baseUrl + "/home");
就在 click() 事件之后,它现在似乎可以正常工作。
错误原因:
click()
returns 一个promise,量角器等待解决。当登录请求被发送到服务器而不是主页加载时,它可能已经解决了。因此下一步的执行在页面加载之前开始。
为什么不wait()
:
我不确定,您根据什么得到不使用 browser.wait()
的指示。很可能你不应该使用 browser.sleep()
(因为该命令总是过时的),但如果你不想使用 browser.wait()
,你的开发人员可能不会离开最初打开的 Angular 页面.
fakeAsync
、whenStable
等等:
Protractor 在 browser.waitForAngular()
中默认使用 whenStable
,它总是在承诺之后调用,只要你没有关闭 browser.waitForAngularEnabled(false)
... 你只需要关闭非 angular 页面,或者如果您的开发人员使用即持久的 Macrotasks,这将导致超时。
此外,由于 Selenium 控制流可能会在 2018 年 11 月被弃用 (read about here),因此 async/await
可用。
Read this important guide here and also some further infos from protractor about it here
现在你的情况是:
您不需要在您的案例中使用 then()
,因为您不需要立即解决承诺。 expect()
会自动解决你的承诺,所以那里不需要 then()
。
事实上 Protractor 逐行执行所有命令,就好像它们都包含在 then()
s 中一样,因此它会自动保持您的执行同步(只要您不通过使用 then()
在代码中。
所以这是我对你的代码的建议:
it("User successfully login",()=>{
var EC = protractor.ExpectedConditions; //or within onPrepare() of conf.js put global.EC = protractor.ExpectedConditions ... to make it everywhere available.
browser.get(browser.baseUrl + '/account/login');
//next line lets protractor wait max 5 seconds for your url to become, what you want.
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 5000);
//additionally after the URL appeared, use this command to wait until the page is fully loaded.
browser.waitForAngular();
expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/account/login");
element(by.tagName('input[type=text]')).sendKeys('username');
element(by.tagName('input[type=password]')).sendKeys('password');
element(by.css('button[type=submit]')).click();
//next line lets protractor wait max 5 seconds for your url to become, what you want.
//as here a new page is loaded and the click()-promise is resolved before, use this:
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 5000);
//additionally after the URL appeared, use this command to wait until the page is fully loaded.
browser.waitForAngular();
expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
});
如果您现在超时,那么这是一个需要调试的单独问题。
检查 this Protractor site for infos about timeouts and check 如何调试超时。
我正在 angular 2 项目上使用量角器进行端到端测试,我需要测试登录操作。这里的问题是,当单击登录按钮时,expect 语句仍然会获得登录页面的 URL 作为主页。如果我等待,则测试成功。我在文档中的某个地方读到量角器等待进程自动完成,所以,
- 导致此错误的原因是什么?
- 如何在不显式使用
wait()
方法的情况下正确执行操作? - 量角器是否有类似于
fakeAsync
、async
或至少whenStable
的单位 测试?
这是我的测试用例
it("User successfully login",()=>{
browser.get(browser.baseUrl + '/account/login').then(() => {
return expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/account/login")
}).then(()=>{
element(by.tagName('input[type=text]')).sendKeys('username');
element(by.tagName('input[type=password]')).sendKeys('password');
element(by.css('button[type=submit]')).click().then(()=>{
return expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
});
});
});
注:
- 我有避免使用
browser.wait()
方法的说明。 - 登录按钮通过API向后端发送http请求。
解决方案[基于 Ernst 的解决方案]:
我解决了这个问题。我不知道它是否适用于其他场景,或者它是否是正确的方法。我添加了
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 10000);
browser.waitForAngularEnabled(false);
browser.wait(EC.urlContains(browser.baseUrl + "/home");
就在 click() 事件之后,它现在似乎可以正常工作。
错误原因:
click()
returns 一个promise,量角器等待解决。当登录请求被发送到服务器而不是主页加载时,它可能已经解决了。因此下一步的执行在页面加载之前开始。
为什么不wait()
:
我不确定,您根据什么得到不使用 browser.wait()
的指示。很可能你不应该使用 browser.sleep()
(因为该命令总是过时的),但如果你不想使用 browser.wait()
,你的开发人员可能不会离开最初打开的 Angular 页面.
fakeAsync
、whenStable
等等:
Protractor 在 browser.waitForAngular()
中默认使用 whenStable
,它总是在承诺之后调用,只要你没有关闭 browser.waitForAngularEnabled(false)
... 你只需要关闭非 angular 页面,或者如果您的开发人员使用即持久的 Macrotasks,这将导致超时。
此外,由于 Selenium 控制流可能会在 2018 年 11 月被弃用 (read about here),因此 async/await
可用。
Read this important guide here and also some further infos from protractor about it here
现在你的情况是:
您不需要在您的案例中使用 then()
,因为您不需要立即解决承诺。 expect()
会自动解决你的承诺,所以那里不需要 then()
。
事实上 Protractor 逐行执行所有命令,就好像它们都包含在 then()
s 中一样,因此它会自动保持您的执行同步(只要您不通过使用 then()
在代码中。
所以这是我对你的代码的建议:
it("User successfully login",()=>{
var EC = protractor.ExpectedConditions; //or within onPrepare() of conf.js put global.EC = protractor.ExpectedConditions ... to make it everywhere available.
browser.get(browser.baseUrl + '/account/login');
//next line lets protractor wait max 5 seconds for your url to become, what you want.
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 5000);
//additionally after the URL appeared, use this command to wait until the page is fully loaded.
browser.waitForAngular();
expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/account/login");
element(by.tagName('input[type=text]')).sendKeys('username');
element(by.tagName('input[type=password]')).sendKeys('password');
element(by.css('button[type=submit]')).click();
//next line lets protractor wait max 5 seconds for your url to become, what you want.
//as here a new page is loaded and the click()-promise is resolved before, use this:
browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 5000);
//additionally after the URL appeared, use this command to wait until the page is fully loaded.
browser.waitForAngular();
expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
});
如果您现在超时,那么这是一个需要调试的单独问题。
检查 this Protractor site for infos about timeouts and check