PhantomJS / CasperJS - keep session open indefinitely and interact with it via HTTP?

casperjs, javascript, phantomjs

Solution

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);

Problem

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.

Original source