Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

WWW::Mechanize::Chrome: Click on button not part of a form

by stevieb (Canon)
on Dec 01, 2019 at 14:43 UTC ( #11109505=perlquestion: print w/replies, xml ) Need Help??

stevieb has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow Monks,

I've created a small one-page web application and am attempting to use Corion's WWW::Mechanize::Chrome to do some testing. I'm not a web developer, and this is my first attempt at automating anything related to the web.

My problem is that I can't seem to figure out how to click on something (ie. a button) that isn't part of a form. I'm sure I just haven't read through enough of the massive amounts of documentation, but my searching is failing me as well.

I reduced the problem scope to the following:

<!doctype html> <html lang="en"> <head> <title>Testing</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script +> <script> $(document).ready(function() { $("#test-button").click(function() { alert("Tada!"); }); }); </script> </head> <body> <button type="button" id="test-button">Test</button> <input type="file" name="fileupload" value="fileupload" id="fileup +load"> </body> </html>

Both the test-button and the fileupload operations Do The Right Thing in the browser, but fail with mechanize:

use warnings; use strict; use Log::Log4perl qw(:easy); use WWW::Mechanize::Chrome; Log::Log4perl->easy_init($ERROR); my $server = 'http://devvps.ddns.net:3000'; my $url = "$server/test.html"; my $m = WWW::Mechanize::Chrome->new( autoclose => 0, ); $m->get($url); $m->click('test-button');

Here's just a few things I've tried along with the resulting output:

$m->click('test-button'); # No elements found for Button with name 'test\-button' at t/20-mech.t +.pl line 21. $m->click('test-button', 28, 20); # No elements found for Button with name 'test\-button' at t/20-mech.t +.pl line 22. $m->click_button(id => 'test-button'); # No elements found for form number 1 at t/20-mech.t.pl line 23.

Can someone please let me know what I'm missing?

On a side note, it would be nice if I could be informed of a way to click on the fileupload input as well, but that one's not even a button so I'm at a further loss :)

Thanks!

-stevieb

PS: It's a crying shame that Mozilla broke things so that WWW::Mechanize::Firefox no longer works. I don't use Chrome normally.

Replies are listed 'Best First'.
Re: WWW::Mechanize::Chrome: Click on button not part of a form
by Corion (Pope) on Dec 01, 2019 at 16:00 UTC

    The method ->click only works with elements contained within <form> elements, unless you directly hand it elements to click on.

    The easiest way is likely to get the element you want, and then hand it to the click method (or, as shown below, do it all in one call):

    use warnings; use strict; use Log::Log4perl qw(:easy); use WWW::Mechanize::Chrome; Log::Log4perl->easy_init($ERROR); my $html = <<'HTML'; <!doctype html> <html lang="en"> <head> <title>Testing</title> </head> <body> <button type="button" id="test-button" onclick="alert('Ta-daa')">T +est</button> <input type="file" name="fileupload" value="fileupload" id="fileup +load"> </body> </html> HTML my $m = WWW::Mechanize::Chrome->new( autoclose => 0, ); $m->update_html($html); my $button = $m->selector('#test-button', single => 1); print "Clicking on button with content:" . $button->get_attribute('inn +erHTML'); print "\n"; $m->sleep(1); $m->click({ dom => $button }); # Or, all in one go $m->sleep(1); $m->click({ selector => '#test-button' }); $m->sleep(10);

    I have removed the external reference to jquery and other stuff that needed external files.

      $mech->click({ selector => '#element-id' }); works wonderfully! Thanks a lot Corion!

Re: WWW::Mechanize::Chrome: Click on button not part of a form
by karlgoethebier (Monsignor) on Dec 01, 2019 at 16:06 UTC

    You need the form tag. As far as i remember. You may also wish to validate your HTML to avoid pain in the ass. Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

      As per Corion's reply, you can use $mech->click({ selector => '#element-id' }); and that works great.

      Since I'm using pure JS/jQuery functions, I don't need or want a form in this case, as there's nothing to submit it to. I do all the logic in client-side code, then dump it off to a route on the server without ever leaving the page.

      Thanks for the validator link though, that's quite handy.

        He! May be it works. HTML is always good for a surprise. But the markup you supplied is not valid. You may try it yourself ibidem. I hope I don’t miss the point. Good luck and have some fun 😎

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: WWW::Mechanize::Chrome: Click on button not part of a form
by 1nickt (Abbot) on Dec 01, 2019 at 14:49 UTC

    Hi Steve, going by your error output, maybe you want <button type="button" name="test-button">Test</button> (name rather than id)?

    Update: per the doc: Has the effect of clicking a button (or other element) on the current form. The first argument is the name of the button to be clicked.

    Hope this helps!


    The way forward always starts with a minimal test.

      Thanks Nick, but no dice.

      No change after adding the name attribute (I even went as far to test it after removing id). Thanks though!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11109505]
Approved by 1nickt
Front-paged by Discipulus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2019-12-05 23:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (154 votes). Check out past polls.

    Notices?