5

I use PhantomJS 1.9.7 on windows 8.1 and I am going to click on Login button after typing username and password. I can write username and password but, when I want PhantomJS to click on the button, It can find the element but is not able of clicking on that. I found in previous posts that I need to create event and use "dispatchEvent". I did that but I got an error as follows:

TypeError: 'undefined' is not a function (evaluating 'elm.dispatchEvent(event)')

I also tried to get help from EventListener but I got the same error for that.

How can I click on an element?

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

page.open('URL', function() {
    var submitButton = enterUserAndPassAndLogin();      
    click(submitButton);
    phantom.exit();
});

function enterUserAndPassAndLogin() {
    var element = page.evaluate(function()  {
        document.querySelector('input[name="username"]').value = "*******";
        document.querySelector('input[name="password"]').value = "*******";
        return document.getElementsByTagName("Button");
    });
    return element;
}

function click(elm) {
    var event = document.createEvent("MouseEvent");
    event.initMouseEvent("click", true, true, window,
        0, 0, 0, 0, 0, false, false, false, false, 0, null);
    elm.dispatchEvent(event);
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Can you write the code you are using to click the button? – Steven de Salas Jun 26 '14 at 06:28
  • @cracker: please don't use [inline code spans for highlighting words](http://meta.stackexchange.com/questions/135112/inline-code-spans-should-not-be-used-for-emphasis-right) -- it's often not necessary and if something really requires emphasis, please [use bold or italics](http://www.etf.europa.eu/authorssite.nsf/Pages/Use%20of%20bold%20and%20italics) instead. Inline code spans are (as the name implies) for code within sentences only: please keep this in mind when editing posts. – Qantas 94 Heavy Jun 27 '14 at 07:47
  • Sure, thanks i'll take care next time – cracker Jun 27 '14 at 08:52
  • I have added my code to the above post. is something wrong with it? – user3321210 Jun 27 '14 at 14:57

2 Answers2

1

There are two problems with the code. First DOM elements cannot be passed from the page context (page.evaluate) outside. Corresponding line from the docs:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

So the submitButton is [null]. Because an array is returned, the error message doesn't show the actual problem. Since the DOM element cannot be passed outside, the click must happen inside of page.evaluate.

Since page.evaluate is sandboxed the click function must be defined inside of the page context. Variables and functions from outside cannot be directly accessed.

A possible script is this:

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

page.open('URL', function() {
    enterUserAndPassAndLogin();
    setTimeout(function(){
        // wait a little to maybe see the click result
        phantom.exit();
    }, 1000);
});

function enterUserAndPassAndLogin() {
    page.evaluate(function()  {
        function click(elm) {
            var event = document.createEvent("MouseEvent");
            event.initMouseEvent("click", true, true, window,
                0, 0, 0, 0, 0, false, false, false, false, 0, null);
            elm.dispatchEvent(event);
        }
        document.querySelector('input[name="username"]').value = "*******";
        document.querySelector('input[name="password"]').value = "*******";
        click(document.getElementsByTagName("Button")[0]);
    });
}
Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
-1

Simply plug in Jquery and do

$(selector).trigger('click');

Note, that if the page uses an async post, the page load event does not trigger, however it "is loading" and you have to wait for the response.

maybe set a wait for a few secs and that will simply be enough for the async post to come back.

Sesertin
  • 462
  • 2
  • 11
  • Just suggesting "Do it with jQuery instead!" does nothing to solve the specific issue that the OP is having. – Sam Hanley Jun 23 '14 at 02:00
  • Dear @sphanley: Just to note: the poster says: dispatchEvent was undefined. Jquery has the method. For sure. – Sesertin Jun 23 '14 at 03:48
  • Yeah, but that's like telling someone who's asking for help with getting their car to start to just take the bus instead. Sure, jQuery can trigger a click on an element, but the OP is using PhantomJS, not jQuery. – Sam Hanley Jun 23 '14 at 12:43