如何使PageObject方法像Protractor方法一样

时间:2014-07-11 12:43:22

标签: javascript angularjs selenium protractor pageobjects

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

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模型方法像量角器方法一样工作,在'系列'中运行。

作为登录过程的一部分,返回后续HTTP获取/发布所需的会话ID。登录后,我想测试主页,所以我使用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() {...});

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

有没有人知道要完成我想要做的事情?

我试图避免按照文档的控制流部分进行大量的()链接:

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

2 个答案:

答案 0 :(得分:0)

量角器试图隐瞒这样一个事实,即大多数有趣的方法实际上并没有他们所说的话,而只是将你承诺去做你所要求的事情。因此,虽然代码看起来像串行运行,但不是。

在您的情况下,您希望使用then()方法初始化HomePage:

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

但是,您需要在后续it中使代码等待then完成。 then方法因此而返回承诺(see the WebDriverJS doc)。

所以,保存当时的承诺。您也可以使用此承诺传递结果,因此我将调用promise homePage(但读取它,就像大多数Protractor结果一样“主页承诺”)。

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块之间分享承诺有任何特别的警告。但我可能会遗漏一些东西......

答案 1 :(得分:0)

你是否已经登录了返回承诺?然后就可以了

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