【问题标题】:how to make a PageObject method act like Protractor methods如何使 PageObject 方法像 Protractor 方法一样工作
【发布时间】:2014-07-11 12:43:21
【问题描述】:

使用量角器我们可以做到这一点:

beforeEach(function() {
  browser.get(myLoginUrl);
  this.username = element(by.model('username'));
  this.password = element(by.model('password'));
  this.loginButton = element(by.css('[ng-click="login()"]'));

  this.username.sendKeys(...);
  this.password.sendKeys(...);
  this.loginButton.click();

  // i'm logged in
});

这一切都可以正常工作,因为上述每个方法,出于所有实际目的,都将串行运行,等待每个依次运行。

现在我已经构建了一个 PageObject 模型对象来为我的登录页面建模,该页面需要用于测试其他页面。我试图弄清楚如何让我的 PageObject 模型方法像量角器方法一样工作,以“系列”运行。

作为我登录过程的一部分,会返回一个会话 ID,这是后续 HTTP 获取/发布所需的。登录后,我想测试主页,所以我使用 Login PageObject 有这样的测试代码:

beforeEach(function() {
  // code from above has been refactored into a page object. here i can just
  // call loginPage.loginAs(...) and it will log the user in and return the
  // session id
  var sessionId = loginPage.loginAs('testuser@example.com', 'mypassword');

  // construct the home PageObject with a sessionId because homePage.get() will
  // need to put the sessionId in the url
  homePage = new HomePage(sessionId);
});

// test we can access the page
it('is accessible', function() {
  homePage.get();

  expect(browser.getCurrentUrl()).toMatch(homePage.homePageRegex);
});

我想要

homePage = new HomePage(sessionId)

等待,直到

var sessionId = loginPage.loginAs(...)

已完全成功并返回了有效的 sessionId。类似于量角器元素本身的工作方式。

使用类似的东西:

loginPage.loginAs('testuser@example.com', 'mypassword').then(function(sessionId) {
  homePage = new HomePage(sessionId);
});

失败,因为这将退出 beforeEach 函数,第一个 it() 将运行并尝试在 sessionId 设置之前执行 homePage.get()。

我一直在玩弄:

browser.driver.controlFlow().execute(function() {...});

以某种方式让代码同步并并行执行,但我已经完全掌握了配方。

有谁知道要完成我想做的事情吗?

根据文档的控制流部分,我试图避免大量 then() 链接:

https://code.google.com/p/selenium/wiki/WebDriverJs#Understanding_the_API

【问题讨论】:

    标签: javascript angularjs selenium protractor pageobjects


    【解决方案1】:

    Protractor 试图隐藏这样一个事实,即大多数有趣的方法实际上并没有执行他们所说的,而只是加入一个承诺去做你所要求的事情。因此,虽然代码看起来像是在串行运行,但实际上并非如此。

    在您的情况下,您想使用then() 方法来初始化主页:

    loginPage.loginAs('testuser@example.com', 'mypassword').then(function(sessionId) {
      homePage = new HomePage(sessionId);
    });
    

    但是,您需要让后续it 中的代码等待then 完成。由于这个原因,then 方法返回了一个承诺 (see the WebDriverJS doc)。

    所以,保存从那时起的承诺。你也可以使用这个 Promise 来传递结果,所以我将把这个 Promise 称为 homePage(但是请阅读它,就像大多数 Protractor 结果一样,称为“主页 Promise”)。

    var homePage;
    
    ...
    
    homePage = loginPage.loginAs('testuser@example.com', 'mypassword').then(function(sessionId) {
      return new HomePage(sessionId);  // return the page via the promise
    });
    

    然后在你的测试中链接这个承诺:

    homePage.then(function(page) {
       page.get();
    
       expect(browser.getCurrentUrl()).toMatch(page.homePageRegex);
    });
    

    直到最后一部分(您还想在期望中使用页面的“homePageRegex”)之前,我对我的回答非常有信心。我认为您可以将其包含在 then 中,但我想如果它不起作用我不会太惊讶...

    另外,我认为在 it/beforeEach 块之间共享承诺没有任何特别的警告。但我可能会遗漏一些东西......

    【讨论】:

      【解决方案2】:

      您是否让 loginAs 返回了一个承诺?然后就可以了

      beforeEach(function() {
        loginPage.loginAs('testuser@example.com', 'mypassword').
           then(function(sessionId) {
             homePage = new HomePage(sessionId);
           });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-04
        • 1970-01-01
        • 1970-01-01
        • 2021-06-30
        相关资源
        最近更新 更多