Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nightmare.js conditional browsing

I'm trying to understand how I should make a nightmare.js script using "if-then" logic. For example

var Nightmare = require('nightmare');
var nightmare = Nightmare({
    show: true,
    paths: {
        userData: '/dev/null'
    }
});

nightmare
    .goto('http://www.example.com/')
    .wait('h1')
    .evaluate(function() {
        return document.querySelector('title').innerText;
    })
    // here: go to url1 if title == '123' otherwise to url2
    .end()
    .then(function() {
        console.log('then', arguments);

    }).catch(function() {
        console.log('end', arguments);
    });

How do I make this script go to a different url depending on the result of evaluate?

like image 645
Fluffy Avatar asked Jun 16 '16 11:06

Fluffy


People also ask

Is Nightmare JS examples of headless Web browser?

Nightmare is a browser automation library. It's a solid choice for automating smoke tests to do all of the clicks, text inputs, and visual checking that a human can do. Under the hood, it uses Electron as a headless browser.

What is Nightmare js?

js is a high-level browser automation library, designed to automate browsing tasks for sites that don't have APIs. The library itself is a wrapper around Electron, which Nightmare. js uses as a browser to interact with web sites.


1 Answers

Since Nightmare is thenable, you can return it from a .then() to chain it like you would ordinary Promises.

var Nightmare = require('nightmare');
var nightmare = Nightmare({
  show: true,
  paths: {
    userData: '/dev/null'
  }
});

nightmare
  .goto('http://www.example.com/')
  .wait('h1')
  .evaluate(function() {
    return document.querySelector('title')
      .innerText;
  })
  .then(function(title) {
    if (title == 'someTitle') {
      return nightmare.goto('http://www.yahoo.com');
    } else {
      return nightmare.goto('http://w3c.org');
    }
  })
  .then(function() {
    //since nightmare is `then`able, this `.then()` will
    //execute the call chain described and returned in 
    //the previous `.then()`
    return nightmare
      //... other actions...
      .end();
  })
  .then(function() {
    console.log('done');
  })
  .catch(function() {
    console.log('caught', arguments);
  });

If you want a more synchronous-looking logic, you may want to consider using generators with vo or co. For example, the above rewritten with vo:

var Nightmare = require('nightmare');
var vo = require('vo');

vo(function * () {
  var nightmare = Nightmare({
    show: true,
    paths: {
      userData: '/dev/null'
    }
  });

  var title = yield nightmare
    .goto('http://www.example.com/')
    .wait('h1')
    .evaluate(function() {
      return document.querySelector('title')
        .innerText;
    });

  if (title == 'someTitle') {
    yield nightmare.goto('http://www.yahoo.com');
  } else {
    yield nightmare.goto('http://w3c.org');
  }

  //... other actions...

  yield nightmare.end();
})(function(err) {
  if (err) {
    console.log('caught', err);
  } else {
    console.log('done');
  }
});
like image 149
Ross Avatar answered Oct 05 '22 09:10

Ross