单击按钮

时间:2015-08-11 14:08:47

标签: angularjs protractor pageobjects e2e-testing

所以今天我一直在为使用Protractor的Angular JS应用程序设置end-2-end测试。为了编写更清晰的测试,我使用了量角器网站上描述的Page Object模式。

测试场景:当用户进入网站时,他/她需要先登录。通过填写凭证并单击按钮,用户将被重定向到验证页面。他们需要输入通过电子邮件发送给他们的代码。在这种情况下,运行end-2-end测试(123456)时验证代码始终相同。当用户输入他/她的代码时,需要单击验证按钮才能进入登录页面(organisations)。有一个组织列表呈现给用户。

量角器测试:

organisations.spec.js

'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>),但这似乎有相同的效果。有人可以指出我做错了什么以及为什么没有发生重定向?我错过了什么这里很明显?提前谢谢!

3 个答案:

答案 0 :(得分:1)

如果您的登录页面是非Angular,请仔细检查您是否需要在量角器中将browser.ignoreSynchronization设置为false。

如果他们是Angular,我认为您需要等待click承诺在登录后完成?以下是否有效?

loginPage.loginButton.click().then(function () {
  validationPage.validationCode.sendKeys('123456');
  ...
}

通过这种方式,如果登录/验证页面确实在Angular中完成,Protractor会自己执行wait(在其他答案中建议)。

作为相关评论,在您的beforeEachafterEach中,您可能还希望使用可选的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();
    });

  }
};