29

I am a PhantomJs newbie. Just checked a similar post on this site. My question is why 'foo' is not logged to console or printed?

var page = require('webpage').create()
var foo = 42;

function evaluate(page, func) {
    var args = [].slice.call(arguments, 2);
    var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}";
    return page.evaluate(fn);
}

page.open('http://google.com', function() {
  var foo = 42;
  evaluate(page, function(foo) {
  console.log(foo);
        },foo);

});
Sled
  • 18,541
  • 27
  • 119
  • 168

5 Answers5

51

The call page.evaluate() runs your evaluated code in a sandbox. The sandbox's console is not the same as PhantomJS's console.

The following lines added to your script will print your page's console to stderr.

var system = require('system');

page.onConsoleMessage = function(msg) {
    system.stderr.writeLine('console: ' + msg);
};

A more complete implementation would be:

var page = require('webpage').create()
var system = require('system');
var foo = 42;

page.onConsoleMessage = function(msg) {
  system.stderr.writeLine( 'console: ' + msg );
};

function evaluate(page, func) {
  var args = [].slice.call(arguments, 2);
  var fn = "function() { return (" + func.toString() + ").apply(this, " +     JSON.stringify(args) + ");}";
  return page.evaluate(fn);
}

page.open(
  'http://google.com',
  function() {
    var foo = 42;
    evaluate(
      page,
      function(foo) {
        console.log(foo);
      },
      foo
    );

    console.log( "Done" );

    phantom.exit( 0 ); // must exit somewhere in the script
  }
);

Outputs:

$ phantomjs /tmp/idiot.js 
console: 42
Done

By the way, you can call page.open using "about:blank" as your URL if you just want to sandbox test the evaluate function.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
PP.
  • 10,764
  • 7
  • 45
  • 59
  • i just added and nothing happened. it's hanging. not even exiting. that means its not knowing which function to eneter first. page.open or page.onConsoleMessage! and there is no main function! Is there any debugger? –  May 23 '13 at 13:21
  • i missed the angry bird 'foo' variable here : **`},foo);`** . thanks. where do i get page. functions? is there any ctags for them. real time waste without tools these javascripts. are there anything which i can import from python. if not how will i import these phantomjs javascripts into python apart from os.shell. i have tried pyphantomjs but not so convincing. –  May 23 '13 at 22:17
  • got this [link](http://stackoverflow.com/questions/13287490/is-there-a-way-to-use-phantomjs-in-python) . looks good. wonder if it waits till ajax loads values. let me try. –  May 24 '13 at 00:37
  • got error `TypeError: 'undefined' is not an object (evaluating 'system.stderr.writeLine')` (https://github.com/yegor256/phandom/issues/2) in 1.6. Upgrading to 1.9 fixed the issue. – Max Jun 05 '14 at 18:45
17

Output to standard error did not work for me

a work around is assigning :

window.console.log = function(msg) { alert(msg) }; 

inside the page.evaluate

Then use :

page.onAlert = function(msg) {
  console.log(msg);
};

to catch the alert

Brad
  • 311
  • 2
  • 7
10

There were some problems in the past with console logging, but with the current version on phantomjs (1.9.8), you can do:

page.onConsoleMessage = function (msg) {
  console.log(msg);
};

then fire away your console.logs in the evaluate's callback:

page.evaluate(function() {
  console.log("some logged message");
});
Bogdan D
  • 5,321
  • 2
  • 31
  • 32
0

I'm using phantomjs to automate some Google Closure tests and ran into an issue I needed to debug. I was able to dispatch custom events from my test page and receive them inside page.evaluate.

File to log messages:

function logger(msg) {
  var evt = document.createEvent('CustomEvent');  // MUST be 'CustomEvent'
  evt.initCustomEvent('logger', false, false, msg);
  document.dispatchEvent(evt);
}

logger('my debug message');

Phantomjs file. Here I'm using a saveMessage method to store the string, but you can make that something more appropriate to your needs.

var exec = page.evaluate(function () {
  window.phantomRunner = new window.goog.testing.TestRunner();
  window.phantomTest = new window.goog.testing.TestCase();

  // Listen for `logger` events. The message is stored inside the event's detail property.
  document.addEventListener('logger', function(e) {
    window.phantomTest.saveMessage(e.detail);
  });

  window.phantomTest.autoDiscoverTests();
  window.phantomRunner.initialize(window.phantomTest);
  window.phantomRunner.execute();
  return (window.phantomTest.result_.messages);
})
Vestride
  • 3,410
  • 1
  • 17
  • 18
0

Make sure your phantomjs setting does not disable executing javascript

page.settings.javascriptEnabled = true;
TroodoN-Mike
  • 15,687
  • 15
  • 55
  • 78