【问题标题】:Angular Protractor end-2-end test fails after clicking a button单击按钮后,Angular Protractor end-2-end 测试失败
【发布时间】:2015-11-03 19:36:50
【问题描述】:

所以今天我一直致力于使用 Protractor 为 Angular JS 应用程序设置端到端测试。为了编写更简洁的测试,我使用了 Protractor 网站上描述的 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 能够填写用户凭据并单击登录按钮。但是,不会发生到验证页面的相应重定向,导致预期失败,因为 Protractor 无法定位页面对象,因为这些对象位于另一个页面上。 Here 是 Protractor 产生的错误消息的一部分。以防万一,here 你能看到正在使用的 Protractor 配置文件吗?

我尝试在按钮点击周围放置明确的等待(browser.wait(<condition>),但这似乎具有相同的效果。有人能指出我做错了什么以及为什么没有发生重定向吗?我在这里遗漏了一些明显的东西吗? ? 提前致谢!

【问题讨论】:

  • 您是否手动运行规范,全部由您自己完成?那它成功了吗?
  • 运行应用程序时(使用 end-2-end 配置),一切正常。我只需登录、验证并进入登录页面。
  • 发生了什么而不是重定向到验证页面?浏览器控制台上的任何错误?谢谢。
  • 另外,如果在单击登录按钮后,您会等到验证文本输入变得可见怎么办:browser.wait(protractor.ExpectedConditions.visibilityOf(validationPage.validationCode), 5000)?..
  • 当您点击登录按钮时,您的应用程序中是否发送了任何 XHR 请求?此请求是否在测试中成功?

标签: angularjs protractor pageobjects e2e-testing


【解决方案1】:

如果您的登录页面不是 Angular,请仔细检查您是否需要在 Protractor 中将 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 方法实际上返回验证点击的承诺。 (我通常让我的所有页面对象方法返回承诺)。

还与您的页面对象相关,而不是仅使用元素查找器作为字段的登录页面对象,为什么不为该页面对象提供现在在 util 类中的更抽象的登录方法?

此外,我倾向于给每个页面对象一个“自检”方法,它允许检查浏览器是否确实在预期的页面上。在登录页面上单击登录后,我希望在验证页面上。因此,我要做的第一件事是检查(断言)我确实在验证页面上。只有这样我才真正按下验证按钮。如果您的应用程序的路由被破坏,这往往会提供更清晰的错误消息。

我在my blog 上写了更多关于状态导航和页面对象的内容。

【讨论】:

    【解决方案2】:

    我发现有助于工作的是强制量角器通过等待标题是特定标题来等待页面加载。

    例如:标题可能是在您的登录页面登录,但在您点击登录后,下一页标题是验证。所以你可以强制量角器等到验证页面加载。

    注意我不知道您的标题的实际名称,所以我只是使用占位符。

    '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();
        });
    
      }
    };
    

    【讨论】:

      【解决方案3】:

      我在代码中遇到了一些问题,其中一部分比您预期的更早中断。例如,一旦它加载了一个具有正确路径的页面对象,但页面本身的声明可能有错误,整个测试就会崩溃。

      首先,我会在单击登录按钮后将所有内容注释掉。然后可能会增加 10 秒的睡眠时间。运行测试并观察它。它是否单击按钮?它会通过登录屏幕吗?

      如果这样可行,请一次取消注释一行,然后查看崩溃的位置。试着在那里保持睡眠,看看它是否有所作为。如果睡眠确实有所作为,这意味着您使用的任何等待都不适用于这种情况。

      当然,如果您遇到的线路每次都让您崩溃,那么您可以进一步挖掘!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-17
        • 2015-02-23
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多