所以今天我一直在为使用Protractor的Angular JS应用程序设置end-2-end测试。为了编写更清晰的测试,我使用了量角器网站上描述的Page Object模式。
测试场景:当用户进入网站时,他/她需要先登录。通过填写凭证并单击按钮,用户将被重定向到验证页面。他们需要输入通过电子邮件发送给他们的代码。在这种情况下,运行end-2-end测试(123456
)时验证代码始终相同。当用户输入他/她的代码时,需要单击验证按钮才能进入登录页面(organisations
)。有一个组织列表呈现给用户。
量角器测试:
'use strict';
describe('when selecting organisation', function () {
var page;
var util = require('../../util');
browser.get('/#/login');
// login before each test case
beforeEach(function () {
page = require('./organisations.po');
util.login('username', 'password');
});
// logout after each one
afterEach(function () {
page.logoutButton.click();
});
it('should have a list of organisations', function () {
expect(browser.getCurrentUrl()).toEqual('http://localhost:9111/#/organisations');
expect(page.organisationList.isPresent()).toBe(true);
});
});
organisations.po.js (the page object)
'use strict';
var MainPage = function () {
// organisations
this.organisationList = element(by.css('.select-list'));
this.logoutButton = element(by.css('.logout-button'));
};
module.exports = new MainPage();
util.js (code for login process)
'use strict';
var Util = function () {
this.login = function login(username, password) {
browser.get('/#/login');
var loginPage = require('./spec/login/login.po');
var validationPage = require('./spec/login/validate.po');
// fill in login form
loginPage.username.sendKeys(username);
loginPage.password.sendKeys(password);
// submit login form and navigate to validation page
loginPage.loginButton.click();
// fill in validation form
validationPage.validationCode.sendKeys('123456');
// submit validation form and navigate to landing page
validationPage.submitValidateBtn.click();
}
};
module.exports = new Util();
运行测试时会发生什么:量角器可以填写用户凭据并单击登录按钮。但是,不会发生相应的重定向到验证页面,导致期望失败,因为Protractor无法找到页面对象,因为它们位于另一页面上。 Here是Protractor生成的错误消息的一部分。以防万一,here可以看到正在使用的Protractor配置文件。
我尝试在按钮点击周围进行显式等待(browser.wait(<condition>)
,但这似乎有相同的效果。有人可以指出我做错了什么以及为什么没有发生重定向?我错过了什么这里很明显?提前谢谢!
答案 0 :(得分:1)
如果您的登录页面是非Angular,请仔细检查您是否需要在量角器中将browser.ignoreSynchronization
设置为false。
如果他们是Angular,我认为您需要等待click
承诺在登录后完成?以下是否有效?
loginPage.loginButton.click().then(function () {
validationPage.validationCode.sendKeys('123456');
...
}
通过这种方式,如果登录/验证页面确实在Angular中完成,Protractor会自己执行wait
(在其他答案中建议)。
作为相关评论,在您的beforeEach
和afterEach
中,您可能还希望使用可选的done
回调,以便实际测试仅在登录成功后启动:
beforeEach(function (done) {
...
util.login(user, pw).then(done);
}
但这确实需要您的login
方法实际上返回验证点击的承诺。 (我通常让所有的页面对象方法都返回promises)。
还与您的页面对象相关,而不是只有元素查找器作为字段的登录页面对象,为什么不给那个页面对象提供现在在util类中的更抽象的登录方法?
此外,我倾向于为每个页面对象提供一个“自检”方法,该方法允许检查浏览器确实在预期的页面上。在登录页面上单击登录后,我希望在验证页面上。因此,我做的第一件事是检查(断言)我确实在验证页面上。只有这样我才真正按下验证按钮。如果应用程序的路由被破坏,这往往会提供更清晰的错误消息。
我在my blog上写了更多关于状态导航和页面对象的内容。
答案 1 :(得分:0)
我在某个部分的代码中遇到了一些问题,这些问题比你预期的更早地在一个地方打断。例如,只要它加载一个具有正确路径的页面对象,但可能是页面本身声明的错误,整个测试就会崩溃。
首先,我会在点击登录按钮后对所有内容进行评论。然后可能加10秒睡眠。运行测试并观察它。它是否单击按钮?它是否超过登录屏幕?
如果有效,请一次取消注释一行,看看它崩溃的位置。尽量保持睡眠,看看它是否有所作为。如果睡眠确实有所作为,那就意味着你所使用的等待不是那种在那种情况下起作用的。
当然,如果你每次碰到一条让你崩溃的线路,那么你可以进一步挖掘!
答案 2 :(得分:0)
我发现帮助工作的是强制量角器等到页面加载,等待标题是特定标题。
例如:标题可以在您的登录页面登录,但是在您登录后,下一页标题就是验证。所以你可以强制量角器等到验证页面加载。
注意:我不知道您的标题的实际名称,所以我只是使用占位符。
'use strict';
var Util = function () {
this.login = function login(username, password) {
browser.get('/#/login');
var loginPage = require('./spec/login/login.po');
var validationPage = require('./spec/login/validate.po');
// fill in login form
loginPage.username.sendKeys(username);
loginPage.password.sendKeys(password);
// submit login form and navigate to validation page
loginPage.loginButton.click();
// wait till our validation page loads then do our validation
browser.wait(protractor.until.titleIs("Validation"), 5000, "✗ Failed to wait for the validation page to load").then(function(){
// fill in validation form
validationPage.validationCode.sendKeys('123456');
// submit validation form and navigate to landing page
validationPage.submitValidateBtn.click();
});
}
};