Nightwatch: Angular.js support?

Created on 24 Sep 2015  路  13Comments  路  Source: nightwatchjs/nightwatch

Hello,

As you can know angular.js is getting more and more popular, what about giving it some support from Nightwatch.js side? Would it be useful? Do you need it?

I would love to see waitForAngular feature because it's really useful when testing Angular. And it's the most desired one I think, because when you want to access angular selectors easly you can write your own custom commands.

Nice example is wd.io plugin:
http://webdriver.io/guide/plugins/webdriverjs-angular.html

Maybe it could be ported somehow? What do you think about this idea?

Best regards,
drptbl.

Most helpful comment

I've improved on this design a bit, and now have an approach that tests my angular apps 'flawlessly':

exports.command = function(callback) {
  var self = this;
  this.timeoutsAsyncScript(10000, function() {
    this.executeAsync(function(done) {
        if(angular && angular.getTestability) {
          angular.getTestability(document.body).whenStable(done);
        }
        else {
          done();
        }
      },
      [], 
      function(result) {
        if(typeof(callback) === "function") {
          callback.call(self, result);
        }
      });
  });
  return this;
};

All 13 comments

I'm afraid this is not something we're going to focus on anytime soon. Maybe you can create some custom commands for this?

@beatfactor I'm already working on custom commands and I would love to share them with you when I'm finished. Just not able to port waitForAngular thing from Protractor which is the most useful feature they got (it waits for angular to finish animations and requests so you don't have to use any waits). I know it's portable because already saw Python and Ruby ports of this Protractor feature. Also webdriver.io has this feature ported as additional plugin. Thanks for answer :+1:!

Just in case anyone cares, I wrote this custom command and it seemed to help me a bunch:

exports.command = function(callback) {
  var self = this;
  this.executeAsync(function(done) {
      angular.getTestability(document.body).whenStable(done);
    },
    [], 
    function(result) {
      if(typeof(callback) === "function") {
        callback.call(self, result);
      }
    });
  return this;
};

Seems there's a small issue in nightwatch that means to call this I have to pass an empty string to the command (command-wrapper.makeWrappedCommand doesn't appear to handle no arguments)

I've improved on this design a bit, and now have an approach that tests my angular apps 'flawlessly':

exports.command = function(callback) {
  var self = this;
  this.timeoutsAsyncScript(10000, function() {
    this.executeAsync(function(done) {
        if(angular && angular.getTestability) {
          angular.getTestability(document.body).whenStable(done);
        }
        else {
          done();
        }
      },
      [], 
      function(result) {
        if(typeof(callback) === "function") {
          callback.call(self, result);
        }
      });
  });
  return this;
};

If it's wired up correctly then in your tests you should be able to do things like
browser.page.pageobjects().navigate('http://mysite').waitForAngular("")

I am attempting to use an angular.element statement to retrieve a value from my app but when I run the test, I receive the error: ReferenceError: angular is not defined

Did anyone else run into this and/or know what the fix might be?

I am new to nightwatchjs. I am trying to use nightwatchjs for angularjs application.
I copied the above code in command.js and when I am trying to call as browser.page.pageobjects().navigate('http://mysite').waitForAngular(""), I am getting the following error:-

TypeError: Cannot read property 'waitForAngular' of undefined

@ciaranj

I have been struggling with Angular (1) testing because of timing issues.
You command seems very interesting.

Could you give a more elaborate example?

For example how would you implement it in this sample?

module.exports = {
  'LOGIN': function (browser) {
    browser
      .url( '/#/login')
      .vicLogin(data_login_email, data_login_password)
      .waitForElementVisible('#email', 1000)
      .setValue('#email', username)
      .click('button.btn.btn-success.btn-block')
      .assert.containsText('.main_container', 'Projects', 'CHECK - Logged in successful');
     .end();
  }
};

@ciaranj this is great and saved me so much time!

Awesome, glad it helped!

@ciaranj Thanks that really helped! Also it looks like we no longer need to pass an empty string argument.
Tested with nightwatch v0.9.21.
browser.waitForAngular();

To maintainers, maybe a good addition to the FAQ:
When testing AngularJS apps, Nightwatch does not offer the same synchronization as Protractor out of the box but <that little custom command above> helps a lot.

Hi,
anyone able to run this command in headless mode successfully in chrome ?

Ain't working for me, I tried

module.exports = class waitForAngular {
    command(callback){
        return new Promise((resolve) => {
            var self = this;
            const pageTimeout = 60000; // ms
            this.api.timeoutsAsyncScript(pageTimeout, function() {
            this.executeAsync(function(done) {
                if(angular && angular.getTestability) {
                    angular.getTestability(document.body).whenStable(done);
                }
                else {
                    done();
                }
                }, [], function(result) {
                if(typeof(callback) === "function") {
                    callback.call(self, result);
                }
                });
            });
            resolve(this);
        });
    }
};

but angular is not defined, no idea what author had installed additionaly

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aking1012 picture aking1012  路  4Comments

antogyn picture antogyn  路  4Comments

davidlinse picture davidlinse  路  4Comments

chaseconey picture chaseconey  路  4Comments

sgleonardoopitz picture sgleonardoopitz  路  3Comments