1

I've been playing around with protractor and promises, and I'm puzzled by the different results I'm getting. I have three tests that basically load www.angularjs.org and wait for the "Home" link.

describe('Sample tests', function() {

  it("test1", function(){
    browser.get("angularjs.org");
    browser.wait(protractor.ExpectedConditions.visibilityOf(element(by.linkText('Home'))))
      .then(function() {
        console.log("element visible");
      })
  })

  it("test2", function() {
    browser.get("angularjs.org");
    fn1().then(function(){
      return browser.wait(protractor.ExpectedConditions.visibilityOf(element(by.linkText('Home'))))
      .then(function() {
        console.log("element visible");
      })
    });

    function fn1() {
      return new Promise(function (fulfill, reject){
        fulfill();
      });
    }

  })

  it("test3", function() {
    browser.get("angularjs.org");
    fn1().then(function(){
       browser.wait(protractor.ExpectedConditions.visibilityOf(element(by.linkText('Home'))))
      .then(function() {
        console.log("element visible");
      }, function(err) {
        console.log("error: " + err);
      })
    });

    function fn1() {
      return new Promise(function (fulfill, reject){
        browser.manage().addCookie("abc", "123")
          .then(function() {
            console.log("set cookie");
            fulfill();
          }, function(err){
            console.log("error in fn1: " + err);
          })
      });
    }
  })
})

test1 passes and outputs element visible.

test2 fails with exception Error while waiting for Protractor to sync with the page: "[ng:test] http://errors.angularjs.org/1.5.8/ng/test" or Error: Error while waiting for Protractor to sync with the page: "window.angular is undefined.

test3 does not print element visible, and intermittently outputs error: WebDriverError: no such session (Driver info: chromedriver=2.22.397929 (fb72fb249a903a0b1041ea71eb4c8b3fa0d9be5a),platform=Mac OS X 10.10.5 x86_64)

Funny thing is if I move browser.get("angularjs.org"); to a beforeEach block, test2 does not throw an error and outputs element visible, while test1 and test3 behaves the same regardless of the location of browser.get("angularjs.org");.

So my questions are

  1. Why does placing browser.get("angularjs.org"); in a beforeEach block make test2 work, and why doesn't the location of browser.get("angularjs.org"); affect test1 and test3?
  2. Why doesn't test3 output element visible?

UPDATE I fixed test3 by

  1. returning the browser-promise from fn1
  2. returning the browser-promise in fn1().then( ... )
  3. chained an additional then clause to the end (fn1().then().then()) and called done().


  it("test3", function(done) {
    browser.get('https://www.angularjs.org')
    fn1()
      .then(function(){
          return browser.wait(protractor.ExpectedConditions.visibilityOf(element(by.linkText('Home'))))
        .then(function() {
          console.log("element visible");
        }, function(err) {
          console.log("error: " + err);
        })
      })
      .then(function(){
        done();
      });

    function fn1() {
      return new Promise(function (fulfill, reject){
        return browser.manage().addCookie("abc", "123")
          .then(function() {
            console.log("set cookie");
            fulfill();
          }, function(err){
            console.log("error in fn1: " + err);
          })
      });
    }
  })
mws
  • 61
  • 1
  • 1
  • 3
  • What exactly is `//do stuff`? – Bergi Sep 18 '16 at 20:00
  • Did you try adding `.catch()` handlers to your promises? – Bergi Sep 18 '16 at 20:01
  • @Bergi I edited the question and added error handling to test3, which now outputs `WebDriverError: no such session`. Removed `//do stuff`, as it's just a comment. – mws Sep 19 '16 at 02:03
  • In test2, you should replace `fn1()` by `Promise.resolve`, and in test3 you should avoid the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572) in `fn1`. Also in test3 you forgot the `return` in the `then` callback that you had in test2. Though neither of these really explain the errors. – Bergi Sep 19 '16 at 07:17

1 Answers1

0

Firstly if you pass browser.get('angularjs.org') you should get an webdriver exception Failed: Target URL angularjs.org is not well-formed. You didn't get this exception. I think you are using an older version of Protractor.

When I changed the url to browser.get('https://www.angularjs.org') and ran your spec(Firefox browser) all the 3 tests passed and got the following output:

element visible  // 1st test output
..element visible  // 2nd test output
set cookie          
.element visible   // 3rd test output

3 specs, 0 failures
Finished in 8.661 seconds

As you can see from above output all the three tests have executed as expected and promises are returned accordingly.There is nothing wrong in your implementation.

Protractor's API is entirely asynchronous and return promises, each task is queued up in a ControlFlow. In order to understand how the tasks are queued up and how the control flow works please check out the webdriverJS control flow API doc

Ram Pasala
  • 4,931
  • 3
  • 16
  • 26
  • Thanks, I was using v4.0.0. Updated to v4.0.8 and got the URL error. However, I still get the same errors as in my original question. I noticed in your output, all three tests finished in 8.6 seconds. For me, just running test3 takes 10 seconds. I think due to my slow connection, protractor isn't waiting. – mws Sep 21 '16 at 00:22
  • I fixed test3 by calling `done()` and returning the promises. Using the same technique for test2 doesn't seem to work though. – mws Sep 21 '16 at 00:31