hash-bang / async-chainable-nighmare

Plugin for async-chainable that wraps Nightmare
MIT License
3 stars 1 forks source link

Question #1

Open fprivitera opened 8 years ago

fprivitera commented 8 years ago

I am testing nightmare capabilites, I am just starting to evaluate your work too, because I think it is useful.

But I have a question, how I can add an custom action to Nightmare ?

the following standard action is able to log all electron events:

Nightmare.action('init-done',
  function(name, options, parent, win, renderer, done) {
    function logAllEvents(eventEmitter,logname)
    {
        var emitLog = eventEmitter.emit;
        eventEmitter.emit = function () {
           console.log(logname,arguments);
           emitLog.apply(eventEmitter, arguments);
        }
    }
    logAllEvents(parent,'parent')
    done();
  },
  function(message, done) {
    this.child.call('init-done', done);
  });

I am not able to use it through your library.

thank you very much

hash-bang commented 8 years ago

If you are asking how can you inject custom callbacks within the async-chainable stack you could just use a .then() operation:

asyncChainable()
    .use(asyncChainableNightmare)
    .nightmare({show: true})
    .nightmareGoto('http://google.com')
    .then(function(next) {
        // Do some custom stuff
        next();
    })
    .nightmareType('input[name="q"]', 'github async-chainable-nightmare')
    .then(function(next) {
        // Do some more custom stuff
        next();
    })
    .nightmareClick('input[name="btnK"]')
    .nightmareWait('#resultStats')
    .nightmareEvaluate('result', function () {
        return document.querySelector('#resultStats').innerHTML;
    })
    .nightmareEnd()
    .end(function(err) {
        expect(err).to.be.not.ok;
        evalResult = this.result;
        finish();
    });

See the original async-chainable documentation for more ways you can run callbacks.

fprivitera commented 8 years ago

no the question is different, in your library you don't wrap this method action() of nightmare.

hash-bang commented 8 years ago

I'm not really sure its needed as a-c already does most of what you're after anyway.

I've added an example of code injection which might explain how to access Nightmares own methods in conjunction with a-c's callback style. The example injects, runs and returns (as a callback) native code into the browser via a-c's own .then() call.

hash-bang commented 8 years ago

Did the above answer your question? Can I close this?

fprivitera commented 8 years ago

actually I am sorry but you didn't answer properly. let me explain it better.

on nightmare you can use the method action() to interact with the electron layer, for example to access to the renderer object and so on. I think you haven't wrap that method yet.

another question that came up, not so much related to this issues, is the following:

Just imagine that nightmare goes to the url A, the page can contain a random integer number, if the number is odd nightmare should go to page B, if not, on page C. how can you implement this ? let me know if you want to open another issue for this topic.

hash-bang commented 8 years ago

Unless I'm missing something the action wrapper provided by Nightmare provides you with access to the renderer by passing in a callback to execute within its instance. The example I provided previously shows how to access this:

.then('title', function(next) {
    this.nightmare.evaluate_now(function() {
        return document.title;
    }, next);
})

In the above the function calls the evaluate_now function which Nightmare uses to inject code into its instance. As far as I can tell this is what the Nightmare action() function actually uses as a wrapper. Action isn't really needed in the case of this module as the parent project async-chainable does all this for you anyway.

The test case does work as intended as you can see if you run mocha test/codeInjection.js.

Regarding your second point - yes this is valid. What I could do is allow functions that normally accept strings such as nightmareGoto() to also accept a function which gets lazily evaluated at run time. Allowing the function to return a scope injected variable.

Something like:

.nightmareGoto(function(next) {
    // Search Google for the current timestamp
    return 'http://google.com?q=' + Date.now();
})