Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot click element with Phantomjs [duplicate]

From post: How to ng-click an A directive in a PhantomJS test I understand I need to create my own function to click an element, but how do I use it?

The following code gives me error TypeError: 'undefined' is not a function (evaluating 'click(obj)')

var page = require('webpage').create();
var url = 'http://somesite.com/document.html';

page.open(url, function(status) {
    page.evaluate(function() {
        var obj = document.querySelectorAll('button')[0];
        click(obj);
    });
    console.log(page.content);
    phantom.exit();
});


function click(el){
    var ev = document.createEvent('MouseEvent');
    ev.initMouseEvent(
        'click',
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null
    );
    el.dispatchEvent(ev);
}
like image 392
zoltar Avatar asked Oct 19 '15 15:10

zoltar


1 Answers

PhantomJS has two context. Only the page context, accessed through page.evaluate(), has access to the DOM and can trigger synthetic events. Since your click() function uses document, it needs to be run in the page context.

page.evaluate() is sandboxed, which is why you can't simply use variables that are defined outside. You either need to define them in the page context or you need to pass them in in a complicated manner (because only primitive objects can be pass into and out of the page context and functions are not primitive objects).

page.open(url, function(status) {
    page.evaluate(function() {
        if (typeof window.click !== "function") {
            window.click = function(el){
                var ev = document.createEvent('MouseEvent');
                ev.initMouseEvent(
                    'click',
                    true /* bubble */, true /* cancelable */,
                    window, null,
                    0, 0, 0, 0, /* coordinates */
                    false, false, false, false, /* modifier keys */
                    0 /*left*/, null
                );
                el.dispatchEvent(ev);
            }
        }
        var obj = document.querySelectorAll('button')[0];
        click(obj);
    });
    console.log(page.content);
    phantom.exit();
});

References:

  • Documentation of page.evaluate()
  • Ways to "click" in PhantomJS: Q: PhantomJS; click an element
like image 175
Artjom B. Avatar answered Sep 30 '22 04:09

Artjom B.