Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS closures with deep nesting

There is the following code of NPM module:

var actions = {};
var methods = ['POST', 'GET', 'PATCH', 'DELETE'];

methods.forEach(function(method) {
  actions['mock' + method] = function(browser, url, response) {
    browser.execute(function() {
      result[method][url] = response;
    });
  }
});

module.exports = actions;

I want to have 4 methods: mockPOST, mockGET, mockDELETE, mockPATCH. Each method should just execute browser.execute with callback function and put response in the appropriate result field - result['POST'] in the mockPOST and so on. But when I execute

utils.mockPOST(browser, 'auth', {"result": "OK"});

I get method is not defined error. What should I do? Thanks!

like image 265
malcoauri Avatar asked May 21 '26 19:05

malcoauri


1 Answers

As I see you are using selenium or webdriver for node.js. That makes things a littlebit tricky. You cannot use closures in the browser.execute function, and the reason is it does not run there at all. Webdriver will convert the function to a string, will transfer it to the browser, and will eval that string inside the browser. The nodejs closure is not transferred to the browser, only the function code as a string.

I assume the result object is defined globally inside the browser already.

So what can you do about it? I always recommend not to put function literals inside browser.execute and browser.executeAsync as they are confusing. You can put there a string instead, which will be evaluated. Try the following:

methods.forEach(function(method) {
  actions['mock' + method] = function(browser, url, response) {
    var browserAction = "result[" + JSON.stringify(method) + "]" +
        "[" + JSON.stringify(url) + "] = " +
        JSON.stringify(response) + ";";
    browser.execute(browserAction);
  };
});
like image 50
Tamas Hegedus Avatar answered May 24 '26 08:05

Tamas Hegedus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!