Frage

I'd like to have a CasperJS script that launches a page, and then stays open indefinitely so I can send commands to it via HTTP whenever I want. The problem is that the entire CasperJS process shuts down as soon as the casper.run call finishes. I've tried getting around this by using a long wait call in a step, but then the web server can't do anything with Casper because Casper is busy waiting for the wait call to finish.

var port = 6100;

var casper = require("casper").create();
casper.start("http://google.com");
casper.then(function() {
  // If I include this wait, then the server works, but the
  // `this.capture` call inside it never executes, presumably
  // because casper is executing the `then` calls in serial.
  // But if I don't include this wait, the entire process finishes
  // instantly and I can't use the server anyway.
  this.wait(100000000, function() {
    console.log("i have waited");
  });
});
casper.run(function() {
  console.log("finished");
});

var pictureNum = 0;
require("webserver").create().listen(port, function(request, response) {
  var src = "my_picture_" + (pictureNum++) + ".png";
  response.writeHead(200, { 'Content-Type': 'text/html' });
  response.write("written " + src);
  response.close();

  casper.then(function() {
    // How can I do this whenever I want?
    this.capture(src);
  });
  casper.run(); // Maybe?
});
console.log("listening on port", port);

Is there any way I can just keep Casper open and send commands to it like this?

EDIT: turns out I can quite easily do this with raw PhantomJS, just by not calling exit. This works perfectly as a PhantomJS script:

var port = 6100;

var page = require("webpage").create();
page.open("http://google.com", function() { });

var pictureNum = 0;
require("webserver").create().listen(port, function(request, response) {
  var src = "my_picture_" + (pictureNum++) + ".png";
  response.writeHead(200, { 'Content-Type': 'text/html' });
  response.write("written " + src);
  response.close();
  page.render(src);
});
console.log("listening on port", port);

But my question remains as to how to do the same thing while also taking advantage of CasperJS's niceness.

War es hilfreich?

Lösung

Finally got something reasonable!

There is an onRunComplete setting that by default calls this.exit. If you override it with a function that does nothing, then the process won't terminate when run finishes. Then you can call then and run again and the tasks will just work. Complete example:

var port = 6100;

var casper = require("casper").create({
  onRunComplete: function() {
    // Don't exit on complete.
  }
});
casper.start("http://google.com");
casper.run(function() {
  console.log("finished");
});

var pictureNum = 0;
require("webserver").create().listen(port, function(request, response) {
  var src = "my_picture_" + (pictureNum++) + ".png";
  response.writeHead(200, { 'Content-Type': 'text/html' });
  response.write("written " + src);
  response.close();

  // HACK: without this, the `run()` call will re-execute all
  // the previous steps too!
  casper.steps = [];
  casper.step = 0;

  casper.then(function() {
    this.capture(src);
  });
  casper.run();
});
console.log("listening on port", port);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top