How can I call jQuery or Angular functions via WWW::Mechanize::Firefox?

282 views Asked by At

I'm trying to execute jQuery/Angular calls via WWW::Mechanize::Firefox's eval_in_page. I'm guessing there is some sort of scope issue, because I'm getting errors.

If I try to execute this code:

angular.element(document.getElementsByClassName("input")[0]).triggerHandler(('change');

I get this response:

MozRepl::RemoteObject: ReferenceError: angular is not defined at ...

If I try to execute this code:

$(".input").val("Foo")

I get this response:

MozRepl::RemoteObject: ReferenceError: $ is not defined ...

It seems I don't have access to either framework. The page does appear to have both loaded, however. If I execute the code in the browser console it works fine.

2

There are 2 answers

0
Todd G. On

Thanks for the ideas all. I wasn't able to solve the original question, but I was able to come up with this alternate solution. Using this javascript I was able to fill in the field and trigger the appropriate change and blur events. Doing this allowed angular to do the processing it needed to do.

$js = qq(
  var myElement = document.getElementsByClassName("input")[0];
  myElement.value = "$value";

  function fireEvent(element, event) {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent(event, true, true); // event type,bubbling,cancelable
    return !element.dispatchEvent(evt);
  }

  fireEvent(myElement, 'change');
  fireEvent(myElement, 'blur');
);
$mech->eval_in_page($js);

Note the function I used was a trimmed down solution found here. I trimmed it down to just the Firefox code. If you're using a different browser, you'd want to use their more robust code. If anyone comes up with a solution to the original question I'd be happy to accept it.

3
user3606329 On

You could click inside the field with $mech->click(), it accepts x, y coordinates, insert the text and remove the focus again. I used PhantomJS for similar work before. It should work for WWW::Mechanize::Firefox too.

use WWW::Mechanize::PhantomJS;
use strict;
use warnings;

my $mech = WWW::Mechanize::PhantomJS->new(log => 1);
$mech->get('http://example.com');

if($mech->success) { 
   # accepts x, y coordinates
   $mech->click(.. field[2]);

   # set a text for example in input-field number 2
   $mech->eval('document.getElementsByTagName("input")[2].value = "Your value";');   

   # Click somewhere else to trigger blur event
   $mech->click(.. outside the field[2]);

  # Read the converted textual input from span
}