Prevent Protractor from finishing before promise h

2020-01-31 07:41发布

问题:

I have some async WebDriverJS processing that is being skipped because the test is completing before they are are being resolve. How do I get protractor to wait ?

e.g.: (both of these tests should fail (potential ticket submitted)

  it('test promise ', function (done) {
      var d = protractor.promise.defer();
      d.fulfill(true)
      d.promise.then(function (item) {
          console.log("fulfill", item);
      });
      expect(d.promise)
          .toBe(false);
      console.log("test done");
  });

  it('test promise with timeout ', function (done) {
      var d = protractor.promise.defer();
      setTimeout(function () {
          console.log("fulfill");
          d.fulfill(true)
      }, 3000);

      d.promise.then(function (item) {
          console.log("fulfill", item);
      });
      expect(d.promise)
          .toBe(false);
      console.log("test done");
  });

Let me know if you need more information ... ?

This will return true.. if you remove the timeout and just set fulfill it will work...

回答1:

Protractor side

The fix for this has been merged 11 days ago

You can have it working with createFlow but solution will be much simpler, just call done() after fulfill like this:

it('test promise with setTimeout ', function(done) {
  var d = protractor.promise.defer();
  setTimeout(function() {
    console.log("fulfill");
    d.fulfill('ok');
    done();
  }, 3000);
  expect(d).toBe('ok');
});

Currently on master branch so expect this to be shipped in protractor >= 0.23.0

Web app side (informative)

Protractor doesn't know how to wait for setTimeout

But does know how to wait for $timeout



回答2:

I couldn't get Nix's example to work and so I took Kato's suggestion and did the following:

describe('Tests stuff', function () {

    function do_work() {
        var d = protractor.promise.defer();
        protractor.promise.controlFlow().execute(function () {
            setTimeout(function () {
                console.log("fulfill");
                d.fulfill(true)
            }, 3000);
        });
        return d;
    }

    it('test promise with timeout ', function () {
        protractor.promise.controlFlow().wait(do_work).then(function (done) {
            console.log("test done:" + done);
        });
    });
});

The out put is as expected and the method waits correctly, and then follows the next flow. My output:

Started
fulfill
test done:true

I'm sure there's many other ways to get this to work, however this worked for me.



回答3:

I need someone to validate this is the correct way to do it.. but I believe the issue was the promise was not being added to the current control flow.

Solution:

it('test promise with timeout ', function (done) {
  var wait = protractor.promise.createFlow(function(flow){
      var d = protractor.promise.defer();
      flow.execute(function(){
          setTimeout(function () {
            console.log("fulfill");
            d.fulfill(true)
           }, 3000);
      });
  });

  expect(wait).toBe(false);
  console.log("test done");
 });


标签: protractor