量角器和执行顺序

时间:2016-06-09 17:41:00

标签: javascript asynchronous promise protractor

无法理解Protractor的执行顺序是如何运作的。

如果我有Unhandled Error Traceback (most recent call last): File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/internet/defer.py", line 388, in errback self._startRunCallbacks(fail) File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/internet/defer.py", line 455, in _startRunCallbacks self._runCallbacks() File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/internet/defer.py", line 542, in _runCallbacks current.result = callback(current.result, *args, **kw) File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/internet/defer.py", line 1076, in gotResult _inlineCallbacks(r, g, deferred) --- <exception caught here> --- File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/internet/defer.py", line 1018, in _inlineCallbacks result = result.throwExceptionIntoGenerator(g) File "/usr/share/opscenter/lib/py-redhat/2.6/shared/amd64/twisted/python/failure.py", line 349, in throwExceptionIntoGenerator return g.throw(self.type, self.value, self.tb) File "/usr/lib/python2.6/site-packages/opscenterd/WrappedDriver.py", line 102, in _defer_to_pool opscenterd.WrappedDriver.NoHostAvailable: Unable to complete the operation against any hosts

执行顺序定义如下:

PageObject:InvitePage

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

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

问题是protractor.promise.defer() 首先执行,而后面的方法不等待waitForEmail完成,我希望通过使用量角器方法创建承诺是真的......无论如何我发现它的解决方案看起来像这样:

waitForEmail

你觉得很难看吗?

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

getInvitationEmail

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

};

然后 waitForEmail

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;

};

3 个答案:

答案 0 :(得分:3)

在Protractor / WebDriverJS中,有一种称为Control Flow的特殊机制,它基本上是一个承诺队列。如果你有一个&#34; custom&#34;承诺,为了让它在队列中,你需要put it there

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

或者:

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

答案 1 :(得分:0)

一个问题和一个评论。

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

答案 2 :(得分:0)

waitForEmail中您已定义了一个承诺,但您需要将其插入到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承诺的一种方法,但上面的代码是你正在寻找的美丽。