Javascript 如何使PageObject方法像量角器方法一样工作

Javascript 如何使PageObject方法像量角器方法一样工作,javascript,angularjs,selenium,protractor,pageobjects,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

使用量角器,我们可以做到:

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 GET/POST所需的会话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);
});
失败,因为这将导致beforeach函数退出,并且第一个it()将运行,并在设置会话ID之前尝试执行homePage.get()

我一直在玩弄:

browser.driver.controlFlow().execute(function() {...});
以某种方式使代码同步并并行执行,但我已经完全掌握了诀窍

有人知道我要做什么吗

我试图避免在文档的“控制流”部分中出现大量then()链接:


量角器试图隐藏这样一个事实,即大多数有趣的方法实际上并没有做到它们所说的,而只是将一个承诺列在队列中,让它按照您的要求去做。因此,虽然代码看起来像是连续运行的,但它不是

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

loginPage.loginAs('testuser@example.com', 'mypassword').then(function(sessionId) {
  homePage = new HomePage(sessionId);
});
但是,您需要使后续
中的代码等待
完成。由于这个原因,
then
方法返回一个承诺()

所以,从那时起,把承诺保留下来。您也可以使用这个承诺来传递结果,因此我将把这个承诺称为“主页承诺”
homePage
(但请阅读它,就像大多数量角器结果一样,将其称为“主页承诺”)

然后在你的测试中把这个承诺连锁反应:

homePage.then(function(page) {
   page.get();

   expect(browser.getCurrentUrl()).toMatch(page.homePageRegex);
});
在最后一部分之前,我对我的答案很有信心(在这里,您还希望在expect中使用页面的“homePageRegex”)。我想你可以把它包含在
中,然后
,但是如果它不起作用,我想我不会太惊讶


此外,我认为在每个
块之前,在
it
/
之间共享承诺没有任何特别的警告。但我可能遗漏了什么…

您是否让loginAs回复了承诺?那你就可以了

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