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

Hello,
I am trying to open two pages at the same time, in two different tabs, with WWW::Mechanize::Firefox.

I need to read information in these two pages, and don't want to open them one after the other, as i have to wait a bit of time, for the pages to load.

How could i do this?

Because i need to read information in both at the same time, i thought that i needed to open two www::Mechanize::Firefox objects/browsers at the same time. Is that wrong ?
Here is what i have tried, and the results i obtained :

1. create two different WWW::Mechanize::Firefox objects one after the other.
=> seems to work (at least for opening the two pages in two different tabs), but i get this warning when i create the second browser:
Subroutine MozRepl::__load_plugins redefined at C:/strawberry/perl/site/lib/Module/Pluggable/Fast.pm line 104, <DATA> line 1.
Shall i just ignore it?
Edit : i just tried it again and this time it works without warning... All good, then?

2. get the current browser's Firefox::Application, open a new tab and select it. finally, try to use the Application's browser with Firefox::Application::browser(), and get() a page with it.
=> it gives me this output :
Use of uninitialized value in concatenation (.) or string at C:/strawberry/perl/site/lib/MozRepl/RemoteObject.pm line 835, <> line 3. MozRepl::RemoteObject: : Object has no function get at test_tabs_application.pl line 72.
I suppose it was simply not the right thing to do.

What is the right way to do this?

Here is the code that i used for these two methods:
1. Opening two browsers, one after the other (it seems to work without warning now):

#!/usr/bin/perl use 5.012003; # Perl version requirement use strict; use warnings; #comment before releasing use autodie 2.10; use Carp 1.25; use Perl6::Say 0.16; use Readonly 1.03; # ##### use WWW::Mechanize::Firefox 0.59; # where is my Firefox executable ? Readonly my $FIREFOX_FOLDER => 'C:\Program Files\Mozilla Firefox\firefox.exe'; # ###### # URL address of the two pages that we want to open in two tabs Readonly my $URL_1 => 'http://www.perlmonks.org/?node_id=958952'; Readonly my $URL_2 => 'http://www.perlmonks.org/?node_id=907951'; # start browser 1 my $browser_1 = WWW::Mechanize::Firefox->new( # launch Firefox if it is not already running launch => $FIREFOX_FOLDER, ); croak 'Could not initialize the browser' if !$browser_1->success(); say '# Browser 1 is now ready to go'; # open page 1 $browser_1->get( $URL_1 ); croak 'Could not open page 1' if !$browser_1->success(); say '# Page 1 opened'; # start browser 2 say '# now creating a second WWW::MEchanize::Firefox browser'; my $browser_2 = WWW::Mechanize::Firefox->new( # launch Firefox if it is not already running launch => $FIREFOX_FOLDER, ); croak 'Could not initialize the browser' if !$browser_2->success(); say '# Browser 2 is now ready to go'; # open page 2 $browser_2->get( $URL_2 ); croak 'Could not open page 2' if !$browser_2->success(); say '# Page 2 opened'; # stop the program, so i can check which pages have been opened say '# done !'; my $stop = <ARGV>;

2. Trying to use Firefox::Aplication::browser() :
#!/usr/bin/perl use 5.012003; # Perl version requirement use strict; use warnings; #comment before releasing use autodie 2.10; use Carp 1.25; use Perl6::Say 0.16; use Readonly 1.03; # ##### use WWW::Mechanize::Firefox 0.59; # where is my Firefox executable ? Readonly my $FIREFOX_FOLDER => 'C:\Program Files\Mozilla Firefox\firefox.exe'; # ###### # URL address of the two pages that we want to open in two tabs Readonly my $URL_1 => 'http://www.perlmonks.org/?node_id=958952'; Readonly my $URL_2 => 'http://www.perlmonks.org/?node_id=907951'; # start the browser my $browser_1 = WWW::Mechanize::Firefox->new( # launch Firefox if it is not already running launch => $FIREFOX_FOLDER, ); croak 'Could not initialize the browser' if !$browser_1->success(); say '# A browser is now ready to go'; # open page 1 $browser_1->get( $URL_1 ); croak 'Could not open page 1' if !$browser_1->success(); say '# Page 1 opened'; # open a new tab my $Firefox_application = $browser_1->application(); my $old_tab = $Firefox_application->selectedTab(); say '# old tab recorded'; my $new_tab = $Firefox_application->addTab(); say '# new tab opened'; # get the new tab's browser my $browser_2 = $Firefox_application->browser(); say "# new tab's browser ready to go"; # bring the new tab in the foreground $Firefox_application->activateTab( $new_tab ); # bring to foreground say '# the new tab is now in the foreground'; # open page 2 say '# Now trying to open the page 2 with get($URL_2)'; $browser_2->get( $URL_2 ); say '# Page 2 opened in new tab'; # stop the program, so i can check which pages have been opened say '# done !'; my $stop = <ARGV>;

Replies are listed 'Best First'.
Re: How to control two tabs at the same time with WWW::Mechanize::Firefox
by Corion (Patriarch) on Mar 11, 2012 at 19:05 UTC
    1. create two different WWW::Mechanize::Firefox objects one after the other. => seems to work (at least for opening the two pages in two different tabs), but i get this warning when i create the second browser:
    Subroutine MozRepl::__load_plugins redefined at C:/strawberry/perl/sit +e/lib/Module/Pluggable/Fast.pm line 104, <DATA> line 1.

    That warning is an unfortunate side-effect of Module::Pluggable::Fast, the plug-in system used by MozRepl. It is otherwise harmless.

    2. get the current browser's Firefox::Application, open a new tab and select it. finally, try to use the Application's browser with Firefox::Application::browser(), and get() a page with it. => it gives me this output :
    Use of uninitialized value in concatenation (.) or string at C:/strawb +erry/perl/site/lib/MozRepl/RemoteObject.pm line 835, <> line 3. MozRe +pl::RemoteObject: : Object has no function get at test_tabs_applicati +on.pl line 72.
    I suppose it was simply not the right thing to do.

    Exactly - a Firefox tab has vastly different methods from WWW::Mechanize(::Firefox). There should be a way to construct another WWW::Mechanize::Firefox object by supplying a freshly connected tab, but that is no option yet. Maybe in a later version, but as you can simply create another WWW::Mechanize::Firefox object, it is no high priority.

      Thank you !

      I have one last small question (shall i ask it in another node ?) :
      When i load my pages, it takes some time. Most of the time, i don't need to wait for the images to be loaded in the page, just the HTML content, and sometimes the DOM.
      I found an imperfect solution, and am looking for the a better one.
      At the moment i use

      synchronize => 0,
      in the WWW::Mechanize::Firefox constructor, and then wait 1 second. But sometimes, it is not enough. Sometimes, 5 seconds doesn't seem to be enough either.

      I think i need to use the "events" parameter of the WWW:Mechanize::Firefox contructor. For example

      events => ['DOMContentLoaded'],
      (as 'DOMContentLoaded' doesn't wait for the images to be loaded, contrarely to 'load').
      It still seems to be slow.
      Is that the best solution ?

      I am sorry, i have read on this subject several time in the past, and have searched again today. I am making you repeat. The best solution i read seems to be

      events => ['DOMContentLoaded'],
      but it seems fairly slow, so i thought...i can try to ask again, maybe i missed something.

        I'm not aware of a faster method than waiting for the DOMContentLoaded event. You can speed things up if you only need to wait for certain elements of the page becoming available, but if you want the DOM to be complete, I know of no better event to wait for.