質問

I'm writing a Selenium soda test. When I use method aliases to avoid args copyPasting...

var method = bool ? browser.clickAndWait : browser.click; 
method("css=button:first", function (err) {
    if (err) {
        console.log(err);
    }
});

... I get a TypeError:

/pathToMyProject/node_modules/soda/lib/soda/client.js:478
      return this.command(cmd, args, fn);
              ^
TypeError: Object #<Object> has no method 'command'

Full code:

var soda = require('soda'),
    assert = require('assert');


var browser = soda.createClient({
    host: 'localhost', port: 4444, url: 'http://google.com', browser: 'firefox'
});

browser.session(function (err) {
    browser.open('/', function (err, body, res) {
        if (!err) {
            bool = false;
            var method = bool ? browser.clickAndWait : browser.click;
            method("css=button:first", function (err) {
                if (err) {
                    console.log(err);
                }
            });
        }
    });
});

If I only use clickAndWait or click, everything works fine, however, I want to choose which method depending on the value of bool.

The arguments of both functions are the same, so why doesn't this work? When I use simple functions without soda, like below, things work fine:

var a = function(){};
var b = function(){};
var c = bool ? a : c;
c();

I get the same error using apply:

var args = ["css=button:first", function (err) {
    if (err) {
        console.log(err);
    }
}];
browser.click.apply(undefined, args);
役に立ちましたか?

解決

The reason that your example works is that there are no dependencies between a, b, and c; they are all simple functions. It is not always possible to to just make a reference to a method of an object. In your case, soda likely calls command from within the method reference you create, except that the scope is wrong.

If the function works with either (but not when making a reference to the function), why not just do something like this:

//...
var myFunction = function (err) {
    if (err) {
        console.log(err);
    }
}

if (bool) {
    browser.clickAndWait("css=button:first", myFunction);
} else {
    browser.click("css=button:first", myFunction);
}
// ...

Or a shorter variation:

// ...
(bool ? browser.clickAndWait : browser.click)("css=button:first", myFunction);
// ...

Alternatively, you may just need to set the scope when you call apply:

// ...
var method = bool ? browser.clickAndWait : browser.click;
method.apply(browser, ["css=button:first", function (err) {
    if (err) {
        console.log(err);
    }
}]);
// ...
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top