【问题标题】:protractor and order of execution量角器和执行顺序
【发布时间】:2016-06-09 17:40:59
【问题描述】:

很难理解 Protractor 的执行顺序是如何工作的。

如果我有PageObject:InvitePage

并且执行顺序是这样定义的:

InvitePage.EnterUsername()
InvitePage.EnterPassword()
InvitePage.EnterEmail()
InvitePage.Invite();
InviteHelper.waitForEmail()
browser.go(invitationUrl)
...
expect(somecondition)

所有页面方法都返回量角器承诺(例如 browser.sendKeys 用于输入密码) waitForEmail 还返回我创建的承诺:

protractor.promise.defer()

问题是waitForEmail 首先执行,之后的方法不等待waitForEmail 完成,我希望通过使用量角器方法创建承诺来实现这一点......无论如何我找到了解决方案并且它看起来像这样:

lastMethodBeforeWaitForEmail.then(function(){
    browser.driver.wait(InvitationHelper.waitForEmail(userEmail))
       .then(function(recievedUrl){
         ...
         //methods that I want after
        expect(someCondition)
    });
  });

你不觉得很丑吗?

有没有办法更好地做到这一点,有什么建议吗? 我没有得到关于量角器异步性质的哪一部分?我错过了什么吗?

getInvitationEmail

var getInvitationEmail = function (emailAddress){
var deferred = protractor.promise.defer();
mailbox.getEmailsByRecipient(emailAddress, function(err, emails) {
  if (err) {
    console.log('>Fetch email - call rejected');
    deferred.reject(err);
  }else{
    console.log('>Email service fetched.')
    deferred.fulfill(emails);
  }
});

return deferred.promise;

};

然后waitForEmail

this.waitForEmail = function(email){
var deferred = protractor.promise.defer();
var timeout;
var interval = 3000;
var timePassed = 0;

var recursive = function () {
  var message = '>Checking for invitational email';
  if(timePassed>0) {
    message = message + ":" + timePassed/1000 + "s";
  }
  console.log(message);
  timePassed += interval;

  getInvitationEmail(email).then(function(data){
    if(data.length>0){
      var loginUrl = data[0].html.links[0].href;
      if(interval) clearTimeout(timeout);
      console.log(">Email retrieved.Fetching stopped.")
      deferred.fulfill(loginUrl);
    }else{
      console.log(">Still no email.");
    }
  });

  timeout = setTimeout(recursive,interval);
};

recursive();

return deferred.promise;

};

【问题讨论】:

    标签: javascript asynchronous promise protractor


    【解决方案1】:

    在 Protractor/WebDriverJS 中,有一种称为Control Flow 的特殊机制,它基本上是一个承诺队列。如果你有一个“自定义”承诺,为了让它在队列中,你需要put it there

    flow = protractor.promise.controlFlow();
    flow.await(InviteHelper.waitForEmail());
    

    或者:

    browser.controlFlow().wait(InviteHelper.waitForEmail());
    

    【讨论】:

    • @Marko 好的,你能说明一下函数里面的内容吗?
    • 我已经编辑了问题,添加了waitForEmail方法
    • @Marko 很有趣,我在其中一个项目中有一个类似的用例。我们有this getLastEmail function 并通过browser.controlFlow().wait(helpers.getLastEmail("topic")).then(function (email) { ... });..为我们使用它。你能检查一下可能是setTimeout() 是什么导致了这里的问题吗?谢谢!
    【解决方案2】:

    一问一言。

    • 如果要控制执行流程,不应该把其他方法放在ControlFlow中吗?
    • JavaScript 引擎在需要时会在命令末尾添加 ;,但最好自己添加。

    【讨论】:

    • 1) 他们已经在流程中,他们每个人都返回 protractor.promise,例如 browser.sendKeys 或 element(by.model(...)) 2) 我禁用了 atom 插件当我跳过时警告我; :D
    【解决方案3】:

    waitForEmail 中你已经定义了一个promise,但是你需要将它插入到controlFlow 中。您可能知道,所有正常的 webdriver 操作 click(), getText(), etc 已经知道如何以正确的顺序执行,因此您不必每次都将所有承诺与 .then 链接起来。

    ... the bottom of your function should look like this
    recursive();
    return browser.controlFlow().execute(function() {
        return deferred.promise;
    });
    

    你丑陋的解决方案 lastMethodBeforeWaitForEmail.then(function() ... 有效,因为它是确保waitForEmail 承诺以正确顺序执行的一种方法,但上面的代码是你正在寻找的漂亮。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 2022-01-08
      • 2022-01-25
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多