awatson1978 / clinical-nightwatch

Ultra-easy acceptance testing for your Meteor app with Selenium and Nightwatch.
21 stars 3 forks source link

Is it possible to run a Meteor.call method from within a nightwatch command? #8

Closed AChusuei closed 9 years ago

AChusuei commented 9 years ago

I would like to try and run a Meteor call from a nightwatch command: something like this:

exports.command = function(taskId, callback) {
  var self = this;

  this.execute (
    function(data) { 
      Meteor.call('resolveThingForMe', data);
      return true;
    }, 

    [taskId],

    function(result) {
      if (typeof callback === "function") {
        callback.call(self, result);
      }
    }
  );

  return this;
};

Is this possible at all?

awatson1978 commented 9 years ago

That's exactly the right approach. Not entirely sure about the exact syntax, but you're definitely on the right track. Be sure to use clinical:nightwatch@2.0.0 in your .meteor/packages directory and use the latest version, and then create the appropriate directories for your commands.

/tests/nightwatch/globals.json
/tests/nightwatch/logs
/tests/nightwatch/commands
/tests/nightwatch/assertions
/tests/nightwatch/walkthroughs
AChusuei commented 9 years ago

Just tried something to this effect, but doesn't seem to work ... I even tried moving it outside the function, and I got this:

Error while running getTask command: Meteor is not defined

I'm guessing it's because I'm basically in a node module, trying to access Meteor framework type deal.

awatson1978 commented 9 years ago

Did you read these two email threads?

https://groups.google.com/forum/#!searchin/nightwatchjs/execute/nightwatchjs/ZdXtwMgliss/O14Duu_cZ7sJ https://groups.google.com/forum/#!searchin/nightwatchjs/run$20command$20line/nightwatchjs/SCwoiVOniWw/wObZ_DcLOUoJ

They're as far as I've gotten in researching how to do this. Massa Ferber seems to be getting Meteor.loginWithPassword to work, just without the callback. Maybe there's a clue there?

AChusuei commented 9 years ago

@awatson1978, I just decided to hook up a client api endpoint to a Meteor.publish call that would do the work for me. It feels a little hacky, but I don't see how Massa bootstrapped the Meteor object into his/her command, doesn't seem like it would work to me.

I was trying to figure out the semantics of how Meteor.call translates at the Node level, but that looks like native code to me ...

AChusuei commented 9 years ago

@awatson1978, I revisited this and here is a generalized MeteorApply.js command I wrote that allows someone to call a meteor method (using the Meteor.apply variant):

exports.command = function(methodName, arguments, timeout, callback) {

    var self = this;
    if (!timeout) {
        timeout = 5000;
    }
    this
        .timeoutsAsyncScript(timeout)
        .executeAsync(function (meteorMethodNameAndArguments, meteorCallback) {
            var meteorMethodName = meteorMethodNameAndArguments[0];
            var meteorArguments = meteorMethodNameAndArguments[1];
            Meteor.apply(meteorMethodName, meteorArguments, function (meteorError, meteorResult) {
                var response = (meteorError ? { error: meteorError } : { result: meteorResult });
                meteorCallback(response);   
            });
        }, [[methodName, arguments]], function (response) { // you need to pass an ARRAY of ONE argument, must be a bug
            if (response.value.error) {
                throw 'Meteor apply (call) returned an error: ' + response.value.error;
            } else if (typeof callback === 'function') {
                callback.call(self);
            }
        });

    return this;
};
awatson1978 commented 9 years ago

Aaaaw, you are awesome! Thank you for this! You rock!

AChusuei commented 9 years ago

@robincwillis, you get some credit for getting me a decent part of the way through this.