WWW-Mechanize-1.96/000755 000765 000024 00000000000 13623637465 015334 5ustar00olafaldersstaff000000 000000 WWW-Mechanize-1.96/perltidyrc000644 000765 000024 00000000330 13623637465 017434 0ustar00olafaldersstaff000000 000000 --blank-lines-before-packages=0 --iterations=2 --no-outdent-long-comments -b -bar -boc -ci=4 -i=4 -l=78 -nolq -se -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" WWW-Mechanize-1.96/perlcriticrc000644 000765 000024 00000001277 13623637465 017753 0ustar00olafaldersstaff000000 000000 [-CodeLayout::ProhibitParensWithBuiltins] [CodeLayout::ProhibitHardTabs] allow_leading_tabs = 0 [-CodeLayout::RequireTidyCode] [-ControlStructures::ProhibitPostfixControls] [-Documentation::RequirePodAtEnd] [-Documentation::RequirePodSections] [-Editor::RequireEmacsFileVariables] [-ErrorHandling::RequireCarping] [-InputOutput::ProhibitInteractiveTest] [-InputOutput::ProhibitBacktickOperators] [-Miscellanea::RequireRcsKeywords] [-Modules::RequireVersionVar] [-RegularExpressions::RequireExtendedFormatting] [-RegularExpressions::RequireLineBoundaryMatching] [-ValuesAndExpressions::ProhibitConstantPragma] [-ValuesAndExpressions::ProhibitEmptyQuotes] [-Variables::ProhibitPunctuationVars] WWW-Mechanize-1.96/cpanfile000644 000765 000024 00000005014 13623637465 017040 0ustar00olafaldersstaff000000 000000 requires "Carp" => "0"; requires "Getopt::Long" => "0"; requires "HTML::Form" => "1.00"; requires "HTML::HeadParser" => "0"; requires "HTML::TokeParser" => "0"; requires "HTML::TreeBuilder" => "5"; requires "HTTP::Cookies" => "0"; requires "HTTP::Request" => "1.30"; requires "HTTP::Request::Common" => "0"; requires "LWP::UserAgent" => "5.827"; requires "Pod::Usage" => "0"; requires "Scalar::Util" => "1.14"; requires "Tie::RefHash" => "0"; requires "URI::URL" => "0"; requires "URI::file" => "0"; requires "base" => "0"; requires "perl" => "5.006"; requires "strict" => "0"; requires "warnings" => "0"; on 'test' => sub { requires "CGI" => "4.32"; requires "Exporter" => "0"; requires "ExtUtils::MakeMaker" => "0"; requires "File::Spec" => "0"; requires "File::Temp" => "0"; requires "FindBin" => "0"; requires "HTTP::Daemon" => "6.05"; requires "HTTP::Response" => "0"; requires "HTTP::Server::Simple::CGI" => "0"; requires "LWP" => "0"; requires "LWP::Simple" => "0"; requires "Test::Deep" => "0"; requires "Test::Fatal" => "0"; requires "Test::More" => "0.96"; requires "Test::Output" => "0"; requires "Test::Warnings" => "0"; requires "URI" => "0"; requires "URI::Escape" => "0"; requires "bytes" => "0"; requires "lib" => "0"; requires "vars" => "0"; }; on 'test' => sub { recommends "CPAN::Meta" => "2.120900"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "0"; }; on 'configure' => sub { suggests "JSON::PP" => "2.27300"; }; on 'develop' => sub { requires "Code::TidyAll" => "0.71"; requires "Code::TidyAll::Plugin::SortLines::Naturally" => "0.000003"; requires "Code::TidyAll::Plugin::Test::Vars" => "0.04"; requires "Code::TidyAll::Plugin::UniqueLines" => "0.000003"; requires "Encode" => "0"; requires "Parallel::ForkManager" => "1.19"; requires "Perl::Critic" => "1.132"; requires "Perl::Tidy" => "20180220"; requires "Pod::Coverage::TrustPod" => "0"; requires "Test::Code::TidyAll" => "0.50"; requires "Test::EOL" => "0"; requires "Test::Memory::Cycle" => "1.06"; requires "Test::Mojibake" => "0"; requires "Test::More" => "0.88"; requires "Test::Needs" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Portability::Files" => "0"; requires "Test::RequiresInternet" => "0"; requires "Test::Vars" => "0.014"; requires "Test::Version" => "1"; requires "constant" => "0"; requires "lib" => "0"; }; on 'develop' => sub { recommends "Dist::Zilla::PluginBundle::Git::VersionManager" => "0.007"; }; WWW-Mechanize-1.96/Changes000644 000765 000024 00000157563 13623637465 016650 0ustar00olafaldersstaff000000 000000 Revision history for WWW::Mechanize 1.96 2020-02-21 02:23:40Z [FIXED] - HTML::Form::find_input() has a 1-based index (GH#293) (Olaf Alders) - Fix invocation of dump_forms in mech-dump (GH#288) (積丹尼 Dan Jacobson) - make xt/author/eol.t pass (GH#291) (Shoichi Kaji) [DOCUMENTATION] - Fix documentation of use of undef in form_with() and all_forms_with() (GH#289) (積丹尼 Dan Jacobson) 1.95 2019-10-28 13:07:45Z [FIXED] - die if submit_form() called with invalid form_id (GH#287) (Olaf Alders) 1.94 2019-10-10 13:12:28Z [FIXED] - Issue #182: Don't autocheck for mech-dump so basic auth works (GH#285) (Julien Fiegehenn) [DOCUMENTATION] - Fix pod error reported by CPANTS. (GH#284) (Mohammad S Anwar) 1.93 2019-10-04 21:06:49Z [FIXED] - Allow images to not have a src attribute (GH#282) (Julien Fiegehenn) [DOCUMENTATION] - Pod fixes. (GH#283) (Mohammad S Anwar) 1.92 2019-08-24 01:00:35Z [FIXED] - Test requires HTTP::Daemon 6.05+ and uses 127.0.0.1 or [::1] according to server's sockdomain (GH#280) (Shoichi Kaji) - Install LWP::Protocol::https and fix xt/author/live/encoding.t (GH#277) (Shoichi Kaji) - Set dist trusty for old Perls on Travis (GH#279) (Shoichi Kaji) - Fixed pod errors as reported by CPANTS. (GH#273) (Mohammad S Anwar) [DOCUMENTATION] - Document that follow_link will die on failure with autocheck enabled (GH#271) (Olaf Alders) [TESTS] - Add a test for finding a link in a meta refresh tag (GH#275) (Olaf Alders) 1.91 2019-01-10 18:44:33Z [ENHANCEMENTS] - Don't install Perl::Critic and Perl::Tidy to run user tests (GH#268) (Julien Fiegehenn) - Remove redundant PodSyntaxTests (GH#265) (Andrew Grangaard) - Add test dependency for Perl::Tidy (GH#263) (Julien Fiegehenn) 1.90 2018-11-12 18:02:03Z [DOCUMENTATION] - Pod fixes (GH#261) (Julien Fiegehenn) - Fixed pod error as reported by CPANTS. (GH#264) (Mohammad S Anwar) [ENHANCEMENTS] - Upgrade to HTML::TreeBuilder version 5 to get support for weak references in HTML::Element (GH#251) (Julien Fiegehenn) 1.89 2018-10-18 19:13:34Z [ENHANCEMENTS] - Add support to find_image() and find_all_images() via 'id' and 'class' (GH#242) (Julien Fiegehenn) - Pass strict/verbose constructor args to HTML::Form (GH#256) (Julien Fiegehenn) - Add ability to clear history and tests for history (GH#259) (mschae94) 1.88 2018-03-23 15:37:25Z ======================================== [FIXED] - tick() now dies if checkbox is not found (GH#248) (Olaf Alders) [DOCUMENTATION] - Clarify behaviour of submit_form when with_fields is supplied as an arg (GH#247) (Olaf Alders) - Document some "Best Practices" (GH#246) (Olaf Alders) - Update links in Pod. Suggest LWP::ConsoleLogger rather than LWP::Debug (GH#244) (Olaf Alders) 1.87 2018-02-07 22:04:16Z ======================================== [FIXED] - Fix typo in contributor name (GH#241) (Philippe Bruhat (BooK)) - Fix link to Michael Schilli's article in Linux magazine (GH#240) (Bernhard Wagner) - Fix some section links (GH#238) (Evan Zacks) - Override _agent() method. (GH#236) (Сергей Романов) - Link to appropriate section of HTML::Form (GH#237) (Evan Zacks) - Make version consistent in .pm files (GH#231) (Olaf Alders) [ENHANCEMENTS] - Return form number in list context. (GH#235) (Сергей Романов) - Overload 'post' in order to set 'base'. (GH#111) (Stuart A Johnston) - Allow multiple file paths/uris in mech-dump; fixes issue 72 (GH#113) (Nik LaBelle) - Add docs for the output of dump_forms (GH#112) (John Beppu) 1.86 2017-07-04 15:48:46Z ======================================== [FIXED] - use 127.0.0.1 instead of 'localhost' in a test script to avoid the test hanging due to ipv6 issues (GH#31, see also changes in 1.85) 1.85 2017-06-28 22:06:00Z ======================================== [FIXED] - use 127.0.0.1 instead of 'localhost' in a test to avoid the test hanging due to ipv6 issues (GH#31) - Remove private logic for taint checking (Dave Doyle) - Fix Pod (simbabque) - Bump Test::More prereq to get working subtest support (Karen Etheridge) - Fix intermittent failures of taint.t (GH#108) (Kivanc Yazan) - Fix kwalitee issues (GH#107) (Kivanc Yazan) [ENHANCEMENTS] - Print section titles if mech-dump --all is invoked (GH#81) (Сергей Романов) - Add cookbook docs on dumping a req without sending it (#115) (Grigor Karavardanyan) - Document that submit only submits current form (GH#114) (nawglan) - Add Travis testing on Perl 5.26 (Karen Etheridge) - Remove obsolete and unincremented $VERSIONs in test modules (Karen Etheridge) 1.84 2017-03-07 13:34:57-05:00 America/Toronto ======================================== [ENHANCEMENTS] - Parse url (href attribute) for js window.open GH#11 [FIXED] - Set STDOUT to be utf8 in mech-dump. Fixes issue GH#36 - Added --version option to mech-dump - Don't die on uri() when there has been no request. Fixes issue GH#60 - Remove old information from the cookbook. Fixes issue GH#28 - Documentation correction. Fixes issue GH#65 and GH#59 - Work around Test::More prior to 1.001004. Fixes GH#74 - Fix hostname in test. Fixes GH#73 1.83 2016-10-14 16:45:30-04:00 America/Toronto ======================================== [FIXED] - Moved live tests to be author tests. Run using dzil test --author. (Steve Scaffidi) 1.82 2016-10-06 23:00:30-04:00 America/Toronto ======================================== [ENHANCEMENTS] - Added strict_forms flag to submit_form() which sets the HTML::Form strict flag (Gareth Tunley) [FIXED] - Fixed tests which tried to access HTTPS urls when LWP::Protocol::https wasn't installed (Olaf Alders). Reported by Slaven Rezić. See https://github.com/libwww-perl/WWW-Mechanize/issues/54 1.81 2016-10-06 08:52:44-04:00 America/Toronto ======================================== [FIXED] - Work around bug in HTTP::Cookies that is triggered on reload(). See https://rt.cpan.org/Public/Bug/Display.html?id=75897 (Gianni Ceccarelli) 1.80 2016-09-24 22:38:27-04:00 America/Toronto ======================================== [FIXED] - Fixes behaviour of submit_form() when multiple filters have been supplied (Ed Avis) 1.79 2016-09-16 23:53:48-04:00 America/Toronto ======================================== [ENHANCEMENTS] - Added form_with() method. (Martin Sluka) 1.78 2016-08-08 09:18:59-04:00 America/Toronto ======================================== [OTHER CHANGES] - No changes specific to this version. First non-develepment release in about a year. 1.77 2016-08-05 12:50:12-04:00 America/Toronto (TRIAL RELEASE) ======================================== [TESTS] - Skip Wikipedia tests if LWP::Protocol::https is not installed. 1.76 2016-07-29 12:17:25-04:00 America/Toronto (TRIAL RELEASE) ======================================== [ENHANCEMENTS] - Added history() and history_count() methods. (Ricardo Signes) - click_button() now accepts ids. (Olaf Alders) - Add a more descriptive error message when ->request is called without a parameter. (Max Maischein) [DOCUMENTATION] - Document that form_id warns in addition to returning undef when a form cannot be found. (Olaf Alders) - Document use of a proxy with bin/mech-dump. (Florian Schlichting) [OTHER CHANGES] - New releases for this distribution are now generated by Dist::Zilla 1.75 2015-06-03 ======================================== [OTHER CHANGES] - WWW::Mechanize::Image and WWW::Mechanize::Link now have a defined $VERSION - fixed warning about the use of the encoding pragma (new in 5.22) (RT#91971) - fixed warning about the use of CGI::param in list context (RT#103096) 1.74 2015-01-23 ======================================== [OTHER CHANGES] - updated repository link in metadata 1.73 2013-08-24 ======================================== [TESTS] - Update t/local/back.t to use LocalServer for 404 checking to avoid fails on win32. Fix by Matt S Trout, patient diagnostics and testing provided by jayefuu of freenode #perl - Blow away more proxy env vars in LocalServer, and do it on load so that the LWP env checking doesn't happen before we've done it. [OTHER CHANGES] - Better error when passing only one parameter to follow_link 1.72 Thu Feb 2 18:37:28 EST 2012 ======================================== [DEPENDENCIES] Bumped the HTML::Form dependency to fix failures on CentOS 5 1.71 Tue Nov 14 13:50:41 EDT 2011 ======================================== [ENHANCEMENTS] Recognise application/xhtml+xml as HTML. [DOCUMENTATION] Improved docs about support of JavaScript Typo fixes. [TESTS] Updated tests as oops-music.com is in utf-8 now 1.70 Fri Aug 26 13:46:30 EDT 2011 ======================================== [ENHANCEMENTS] Mech now defaults to _not_ running live tests by default. You can still enable them by running "perl Makefile.PL --live" Thanks to RJBS for the suggestion 1.69_01 ======================================== [INTERNALS] The test suite for the local tests was updated 1.68 Fri Apr 22 01:10:40 EST 2011 ======================================== No changes from 1.67_01 1.67_01 ======================================== [ANNOUNCE] As of this release, Jesse Vincent has taken over maintenance of WWW-Mechanize. The project's repository can be found at: https://github.com/bestpractical/www-mechanize [FIXED] Added prereq for HTML::TreeBuilder. 1.66 Fri Sep 10 16:25:44 CDT 2010 ======================================== [FIXED] Fixed prerequisites on HTTP::Server::Simple on Windows. DNS checks in t/autocheck.t and t/local/failure.t improved. Thanks, Schwern. [ENHANCEMENTS] New $mech->text method returns the text from your HTML page. The exact rendering of this text is simply removing all the HTML tags, but this will change. It's pretty ugly. If anyone wants to work on a better-looking text dump, I'd love to see it. Added mech-dump --text. [DOCUMENTATION] Improvements to the docs explaining explicitly about the subclassed methods we inherit from LWP::UserAgent. Thanks, Lyle Hopkins! 1.64 Thu Jul 1 10:41:00 CDT 2010 ======================================== [THINGS THAT MAY BREAK YOUR CODE] If you've been accessing $mech->{forms} or $mech->{form} values directly, instead of going through the $mech->forms or $mech->current_form accessors, respectively, then this version of Mech will break your code. [ENHANCEMENTS] Parsing of forms has been delayed until they're actually needed. If don't use forms on a page, you'll no longer waste time and memory parsing them. $mech->title now caches the title of the page after parsing the page to find it. mech-dump now takes a --cookie-file parameter for keeping cookies between calls. Thanks, Damien Clark. [DOCUMENTATION] Typo fixes. 1.62 Sat Apr 10 23:10:07 CDT 2010 ======================================== [FIXED] Fixed a declaration in the Movable Type example in WWW::Mechanize::Examples. Quiet warnings if %ENV has undef values. $mech->follow_link() no longer dies with an inappropriate error if the link is not found. $mech->click_button() now checks to see if a form is selected. [INCOMPATIBILITIES] $mech->form_name() and $mech->form_number() no longer throw warnings if they can't find the form specified. They still return undef, though. [DOCUMENTATION] More additions to the FAQ. 1.60 Mon Aug 17 00:41:39 CDT 2009 ======================================== No new features. Exists only to skip tests that always fail on Windows. Fixed up some minor documentation problems. 1.58 Mon Jul 13 22:32:23 CDT 2009 ======================================== No new features. If you have 1.56 installed OK, you do NOT need to install 1.58. [FIXES] Removed prereq of HTTP::Response::Encoding, even though it was never used. Thanks for the catch, Gisle. 1.56 Thu Jul 9 00:36:54 CDT 2009 ======================================== [THINGS THAT MAY BREAK YOUR CODE] For a while, Mech used HTTP::Response::Encoding to try to suss out the proper encoding of the page it receives. Now, it lets LWP::UserAgent do the work, and no longer requires HTTP::Response::Encoding. [ENHANCEMENTS] Added a new dump_headers() method to dump the HTTP response headers. Added --headers flag to mech-dump to dump the HTTP response headers. [FIXES] Now requires LWP version 5.829 because HTTP::Response has memory cycle bugs. [DOCUMENTATION] Added a few notes to the FAQ, and fixed some incorrect docs. 1.55_01 Mon Jul 6 12:17:10 CDT 2009 ======================================== This is mostly a bug fix release. There will be a number of other bug fix releases in the next few days. [FIXED] New test server now randomizes the port it runs on. t/cookies.t should not hang on Windows any more. META.yml has been updated so the search.cpan.org links should be correct. Passing no_proxy would make LWP::UserAgent barf. Thanks to Mike Schilli for the fix. Cookies test would fail under Windows. Fixed, thanks to many people reporting it. [ENHANCEMENTS] $mech->submit_form() now can specify the form by ID using the form_id parameter. [DOCUMENTATION] The docs used to say that ->stack_depth(0) was an infinite stack size. This is wrong. Zero will tell Mech not to keep any history. 1.54 Mon Jan 12 00:36:08 CST 2009 ======================================== [FIXED] Removed the computers4sure test that was failing. 1.52 Tue Nov 25 09:52:30 CST 2008 ======================================== [FIXED] Improved some error messages in $mech->submit_form(). Thanks to Norbert Buchmuller. 1.51_03 Thu Nov 20 11:05:49 CST 2008 ======================================== [FIXED] The $mech->clone() method was not passing the cookie jar to its clone properly. Thanks to David Sainty. The $mech->back() can fail if there's nothing on the stack to go back to. Thanks to Dave Page. $mech->follow_link() did not complain if a link could not be found, even with autocheck on. Now it does. Thanks, Flavio Poletti. [ENHANCEMENTS] Added a $mech->form_id() method so you can look up forms by ID. Added $mech->content_type(), because $mech->ct() is too cryptic. 1.51_02 Tue Nov 18 01:30:54 CST 2008 ======================================== [STILL BROKEN] t/local/click_button.t is still failing its tests for calling ->click on an HTML::Form object. I suspect this is an LWP change, but I haven't dug into it enough yet. [FIXES] Fixed the bad credentials API that stomped on LWP::UserAgent's credentials() method. Thanks to Max Maschien and Matt Lawrence. The $mech->links method now finds links. Thanks to H.Merijn Brand. Makefile.PL explicitly requires Perl 5.8.0. URI.pm has to be version 1.36 or else URIs don't get encoded correctly. LWP has to be 5.819 or we have encoding problems. 1.51_01 Thu Nov 6 15:13:03 CST 2008 ======================================== [FIXES] Page history is now working much better. The $mech->back() method should behave more like a browser now. Most notably, it no longer restores the cookie state, just like your browser doesn't restore cookie state when you page back. It also should use much less memory. 1.50 Sun Sun Oct 26 22:42:46 CDT 2008 ======================================== [THINGS THAT MAY BREAK YOUR CODE] WWW::Mechanize now requires version 5.815 of LWP. This in itself may cause problems for you because of changes in how LWP does authentication. 1.49_01 Sat Sep 27 23:50:04 CDT 2008 ======================================== [THINGS THAT MAY BREAK YOUR CODE] The autocheck argument to the constructor is now ON by default, unless WWW::Mechanize is being subclassed. There are so many new programmers whose ->get() calls fail unchecked that I'm now putting on the seat belts for them. [FIXES] I do believe we are on the way to having all the encoding problems ironed out. This version incorporates a patch from here: http://code.google.com/p/www-mechanize/issues/detail?id=61 and tests from Miyagawa's WWW::Mechanize::DecodedContent http://search.cpan.org/dist/WWW-Mechanize-DecodedContent/ to finally fix this. [ENHANCEMENTS] You can now specify not to set up the proxy, if there is one. The proxy causes problems for Crypt::SSLeay. For details see: http://code.google.com/p/www-mechanize/issues/detail?id=39 [DOCUMENTATION] Fixed internal links. [INTERNALS] Lots of refactoring based on Schwern's "Skimmable Code" talk. http://use.perl.org/~schwern/journal/36704 http://schwern.org/~schwern/talks/Skimmable%20Code%20-%20YAPC-NA-2008.pdf 1.34 Mon Dec 10 00:30:39 CST 2007 ======================================== [FIXES] Many fixes to make the test suite more portable. 1.32 Tue Oct 30 12:02:17 CDT 2007 ======================================== [ENHANCEMENTS] Added dump methods to mirror mech-dump: * $mech->dump_images() * $mech->dump_links() * $mech->dump_forms() * $mech->dump_all() Sanity checks in the WWW::Mechanize::Image constructor. Every Image must have a "url" and "tag" field passed in to it. 1.31_02 Thu Oct 25 11:48:29 CDT 2007 ======================================== [ENHANCEMENTS] Added class, class_regex, id and id_regex limiters to find_link() and find_all_links(). Thanks to Adriano Ferreira. 1.31_01 Mon Sep 17 23:38:03 CDT 2007 ======================================== [FIXES] Mech tests now pass even if your DNS server gives A records for anything (like OpenDNS). Thanks, Miyagawa! Searching for the is now case-inensitive. A better solution would be to actually parse the HTML. [ENHANCEMENTS] mech-dump now handles --user and --password arguments for sites that require authentication. 1.30 Thu May 24 21:31:10 CDT 2007 ======================================== [DOCUMENTATION] Minor doc fixes. Thanks David Steinbrunner. 1.29_01 Tue May 22 14:02:55 CDT 2007 ======================================== Kevin Falcone and I ask for your assistance in figuring out how to handle the warnings thrown by the tests, other than hiding them. [FIXES] Overhauled how tainting was done. Stole code directly from Test::Taint. Have LWP only handle decoding of Content-Encoding, not charset. [DOCUMENTATION] Fixed the docs for $mech->submit_form()'s with_fields arg. Thanks, Peteris Krumins. 1.26 Wed May 16 14:21:29 CDT 2007 ======================================== [FIXES] Re-reversed the content decoding. This is critical for reading from sites with gzip on the fly, like Wikipedia. Content is now properly tainted. [ENHANCEMENTS] mech-dump can now pass --agent and --agent-alias flags so you can fetch from sites like Wikipedia that block LWP user agents. [INSTALLATION] The mech-dump program is now always installed. It no longer is presented as an option. 1.24 Fri May 11 15:57:56 CDT 2007 ======================================== NOTE: Version 1.24 will NOT automatically decode gzipped content for you any more. Consider it a "do not use" release. [FIXES] * Fixed failures in "make test" with some versions of HTTP::Server::Simple * RT #26593: Improved handling of charsets. Thanks Kevin Falcone. * RT #24354: find_link now handles http-equivs with quoted URLs. * Reverses the change in 1.21_01 where it decodes the content. [ENHANCEMENTS] * Added find_all_inputs() and find_all_submits() methods. Thanks, Mike O'Regan. * Test::LongString is no longer needed, so has been removed as a requirement. [TESTS] * Added a test for save_content() 1.22 Fri Mar 2 00:05:57 CST 2007 ======================================== [INTERNALS] Added new tests. Added Perl::Critic changes and a perlcriticrc file. 1.21_04 Sat Oct 7 21:35:42 CDT 2006 ======================================== [FIXES] * $mech->content( type => 'text' ) was not freeing memory. Thanks to Cat Okita for finding it. [INTERNALS] * Made the order of parms to $mech->content() not relevant. 1.21_03 Sat Oct 7 01:21:46 CDT 2006 ======================================== [THINGS THAT MAY BREAK YOUR CODE] * The methods $mech->form() and $mech->follow() have been removed. They've been deprecated since 1.10, which was released in Feb 2005. [ENHANCEMENTS] * I'm trying to nail down what seems to be a memory leak on long-running Mech programs. I'm stringifying URI::URL objects wherever I can. [INTERNALS] * No longer uses UNIVERSAL. 1.21_02 Wed Oct 4 13:14:30 CDT 2006 ======================================== [ENHANCEMENTS THAT MAY BREAK YOUR CODE] * The $mech->stack_depth() setting had no way to say "don't cache any pages at all". How silly! Now, if you set $mech->stack_depth(0), no history of pages will be kept. In the past, it would mean "Keep all pages." This means that if you want to set it to keep all pages, set it to some ridiculously large number. [DOCUMENTATION] * The docs previously refered to Compress::Gzip instead of Compress::Zlib. 1.21_01 Mon Sep 18 17:18:43 CDT 2006 ======================================== [ENHANCEMENTS] * If Compress::Zlib is installed, gzipped content is now accepted and transparently decoded. No additional syntax needed! This should save time and bandwidth in a number of cases. (Mark Stosberg) * Added a put() method. It also calls a subfunction called _SUPER_put that will be removed once LWP::UserAgent supports put(). 1.20 Sat Aug 19 09:09:08 EDT 2006 [ENHANCEMENTS] * Added new two-argument form of credentials() method. $mech->credentials($username, $password); That provides simpler visiting of password-protected resources in the vast majority of cases and still allows the other cases to be supported. (Peter Scott) [BUG FIXES] * autocheck no longer is triggered when informational responses are returned. (Mark Stosberg) [INTERNALS] * test suite no longer fails when Test::Warn is missing. (CPAN testers, Mark Stosberg) * Removed all the testing against live sites. The networking code is not actually in Mech anway, and they were prone to breaking, as the live sites changed. (Mark Stosberg) 1.19_02 Mon Aug 7 23:57:56 CDT 2006 [ENHANCEMENTS] * Add new Do-What-I-Mean submit_form() option. $mech->submit_form( with_fields => \%data ); That expresses that you want to select the first form contains all fields in \%data, and then submit the data to that form. See the docs for form_with_fields() and submit_form() for details. (Mark Stosberg, inspired by RT#6100) [BUG FIXES] * The behavior of clone() now copies over the cookie jar, which is probably what you expected it did in the first place. This fixes bug RT#13541 filed against Test::WWW::Mechanize, which was using clone() internally. (Mark Stosberg) * The correct URL is returned after redirecting. This a regression from 1.04 and was reported as RT#9059, RT#12882, and RT#12786. The documentation about this has also been clarified that we return a URI object, but that it stringifies to the URI itself. [DOCUMENTATION] * Fixed a misleading parm in the constructor. * Document the return value of set_visible (RT#6071, MJD, Mark Stosberg) * Document that form_name and form_number return an HTML::Form object (Mark Stosberg) [INTERNALS] * Made lots of little cleanups based on Perl::Critic * Fix Taint-mode warnings with Perl 5.6.1 (RT#16945) 1.18 Thu Feb 2 00:11:26 CST 2006 [TESTS] * Makefile.PL now takes four new parms: * --live/nolive turns on/off the live tests * --local/nolocal turns on/off the local tests * --mech-dump/nomech-dump installs/doesn't the mech-dump program * --all turns on all tests and installs mech-dump * Fixed some failures in tests. Non-existent URLs now have a "." postpended to them, so if someone's got a search domain with a wildcard (i.e. ignore.us) it'll ignore that. Also, Google's second link is now a https:// link, which some Mechs can't handle. Added a 'url_regex' which now makes it look at the second non-https link. Thanks to Pete Krawczyk. 1.16 Fri Oct 28 17:34:20 CDT 2005 [ENHANCEMENTS] * Sped up Mech significantly (~20% in some cases). Images and links are extracted from the HTML, and objects are created, only when they're actually needed. This will be a speedup for pages where you're only following links, or vice versa. [THINGS THAT MAY BREAK YOUR CODE] * If you've been relying on the $mech->{images} and $mech->{links} fields being populated so that you can bypass the $mech->images() and $mech->links() accessors, your code will break. That's OK, because you should have been using the accessors all along. 1.14 Tue Aug 30 17:17:40 CDT 2005 [DOCUMENTATION] * Added lots of new FAQs. Thanks to Peter Stevens. [INTERNALS] * Now requires Test::LongString. That's not too odious. [FIXES] * Tests now pass with the shuffling around that Google did. 1.13_01 Tue Apr 12 14:11:18 CDT 2005 [ENHANCEMENTS] * Now dies if you call submit_form() with a non-existing form_number or form_name. Before, it would just warn. [DOCUMENTATION] * Added an example of using credentials() in the cookbook. 1.12 Thu Feb 24 23:38:44 CST 2005 [FIXES] * Fixed RT #9026: hang in t/local/back.t under Windows XP. Thanks Andrew Savige. It also should no longer complain about being unable to clean up a temp file. 1.11_01 Mon Feb 14 00:12:48 CST 2005 [THINGS THAT MAY BREAK YOUR CODE] * Removed deprecated _parse_html() method. [FIXES] * Was incorrectly looking for INPUT tags TYPE="SUBMIT" as images. Thanks to Abe Timmerman. [ENHANCEMENTS] * Calling $mech->set_fields() with no current form now dies. Thanks to Julien Beasley. 1.10 Tue Jan 31 11:30pm-ish [FIXES] * Fixed bug where images inside of links would not be found. * Fixed test failures because of Google changes. Thanks to Offer Kaye and others who sent in patches. [DOCUMENTATION] * More samples in the FAQ. Thanks to Joshua Gatcomb. [INTERNALS] * Added explanation of running live tests against Google in Makefile.PL. 1.08 Fri Dec 24 01:01:06 CST 2004 [ENHANCEMENTS] * Added find_image() and find_all_images(). 1.06 Wed Dec 8 14:58:39 CST 2004 [INTERNALS] * Now uses the base pragma instead of setting @ISA. 1.05_04 Fri Nov 5 23:35:38 CST 2004 [ENHANCEMENTS] * Added WWW::Mechanize::Image object for representing images. * Improved the regex on the URL for META tags. * Added --images flag to mech-dump. [FIXES] * When parsing urls out of meta refresh tags, "url" may now be uppercase (RT#8230) * Behavior of back() fixed in a number of cases (RT#8109 reported by Josh Purinton, patched by Dominique Quatravaux) [INTERNALS] * Mark figured out to how to prevent his text editor from putting tabs into the code. Andy's blood pressure dropped slightly. 1.05_03 Sun Oct 31 20:54:33 CST 2004 [ENHANCEMENTS] * click_button() has a new input option for HTML::Form::SubmitInput objects (DOMQ) * content() has new options to return the page formatted as text, with a added. (RT#8087, patch by Dominique Quatravaux) * update_html() method has been added, which can be used to modify the HTML that Mech parses. It should be sub-classed instead of _parse_html(), which has been deprecated. (RT#8087, patch by Dominique Quatravaux) * select() has new option to select an option by number (RT#5789, Scott Lanning) * WWW::Mechanize::Link now has support providing all the attributes of the link through a new attrs() method, which returns them as a hashref. This is a replacement for the alt() method, added in 1.05_01. It's not backwards compatible with that, but, hey, that's what developer releases are for. (RT#8092, Rob Casey and Mark Stosberg) [FIXES] * Upload does not use the default value to prevent attacks, patch by Jan Pazdziora (RT #7843). [INTERNALS] * Improved tests and documentation for select() (RT#5789, Scott Lanning) * Improve taint-safeness on Perl 5.6.1 (RT#8042, patch by Dominique Quatravaux) * Added tests for click_button() (RT#8061, by Dominique Quatravaux) * Require URI 1.25, fixing bug which exposed itself in WWW::Mechanize (RT#3048) * Move select() to better location in docs. Document and test the return values. The return value is now "1" on success instead of the undocumented behavior of returning a form value. (RT#6138, spotted by MJD, patched by Mark Stosberg) * Possible matching tags for the find_link() 'tag_regex' attribute are now documented. (RT#2989, by Mark Stosberg) * refactored find_link() to avoid use of eval(). This should improve performance a bit and avoid potential security issues. (Mark Stosberg) 1.05_02 Sat Oct 2 16:55:59 CDT 2004 [ENHANCEMENTS] * Added the $mech->save_content( $filename ) function, so you can dump stuff to files easily. 1.05_01 Thu Sep 30 21:04:44 CDT 2004 [FIXES] * set_visible() doesn't stop setting values when it finds a zero. [ENHANCEMENTS] * WWW::Mechanize::Link has a new, easier to remember constructor interface. The old one is still supported. Support for including an 'alt' attribute was added, which is useful for links. (RT #3317). Thanks to Mark Stosberg. * When links are extracted from tags, the ALT attribute will be captured and become part of the WWW::Mechanize::Link object. (RT #3317). Patch by Mark Stosberg. [INTERNALS] * t/mech-dump.t is now more portable (RT #7690) * t/local/follow.t has new tests to confirm that 'follow*' functions work with characters like o-umlaut, even when the o-umlaut is encoded in the HTML, but not in the call to follow(). (RT #2416) By Mark Stosberg. 1.04 Wed Sep 15 23:27:53 CDT 2004 [ENHANCEMENTS] * $mech->get() now accepts a WWW::Mechanize::Link object. * $mech->stack_depth(n) lets you set the depth of the mech object's page stack. This way, if you have a Mech that does lots of stuff and never/rarely goes back(), you won't be eating up memory. Thanks to BooK and Chi-Fung. (RT #5362) [FIXES] * Fixed tests that fail under LWP >= 5.800. * Added a workaround for LWP::UserAgent->clone() when ->{proxy} is undef. (RT #6443) * The Referer was getting passed as a URI object sometimes, and that caused sadness. Eugene Haimov supplied a workaround. (RT #6372) [DOCUMENTATION] * Added Ian Langworth's listmod and John Beppu's photobucket uploader programs to WWW::Mechanize::Examples. * Minor doc tweak for find_link() * Finally added a value() func. Thanks to Spoon, who even now, months after his passing, is still contributing to Mechanize. 1.02 Tue Apr 13 22:45:10 CDT 2004 No reason to install if you have 1.00. Fixes are only in tests. [FIXES] * t/referer.t didn't cope with spaces in $FindBin::Bin. Plus, it now forces its URL to localhost. 1.00 Sat Apr 10 00:35:51 CDT 2004 I figure it's about time we hit 1.00, and this version seems like a good place to do it, because of the potential breakage described below... [THINGS THAT WILL BREAK YOUR CODE] * Header handling has changed. There is no more package variable %headers that holds all the headers to be added. They are now added on a per-object basis. If you were adding a header with add_header(), and the code relied on that header still being set later on in a later instance of the class, that code will now break, because the later instance won't have the header set. [ENHANCEMENTS] * You can now prevent a header from being sent by adding it with an undef value, as in: $mech->add_header( Referer => undef ); [FIXES] * Now correctly adds Accept-Encoding to all requests that need it. [INTERNALS] * Added new $mech->_modify_request($req) method to do all the HTTP header modification before the actual request gets sent off. Subclasses are able to override it if they want. * Removed the unused Compress::Zlib stuff. 0.76 Wed Apr 7 22:01:43 CDT 2004 [ENHANCEMENTS] * Added update_html() to let you update the HTML for the page you're on. [FIXES] * Test files account for new Google layout. [INTERNALS] * Rearranged the local tests into their own t/local/ directory. * Made the standalone tests show what server they're hitting. * Checked that it runs under LWP 5.78. 0.74 Mon Mar 22 23:36:46 CST 2004 [ENHANCEMENTS] * WWW::Mechanize now sends an Accept-Encoding header of "identity" to always enforce plaintext responses. Preliminary support for Compress::Zlib is also there, but is disabled by default. * Added click_button() and select() methods. The field() method can now take an arrayref of values, if appropriate. Thanks, Linda Lee Julien. * Added url_abs and url_abs_regex parms to find_all_links(). * URLs in META REFRESH tags are now treated as links. * t/taint.t makes sure that things that should be tainted are. [FIXES] * Still more fixes if the machine you're on doesn't have DNS pointing to it. * The local changes use localhost as the local host name, instead of whatever host name that might be on the box, but not in DNS. Thanks to David Wheeler for letting me play on his box. * The http_proxy and HTTP_PROXY environment variables get deleted during the tests that access the dummy local server. This should let your tests pass, and clear up a lot of RT tickets. 0.72 Mon Jan 26 21:07:20 CST 2004 [ENHANCEMENTS] * Added the set_visible() method, thanks to Peter Scott. [DOCUMENTATION] * Started the Cookbook at WWW::Mechanize::Cookbook.pod. [INTERNALS] * Made the globbing in Makefile.PL a little less command-line intensive. Also fixed the missing files in MANIFEST. * Added t/pod-coverage.t for testing POD coverage. 0.71_02 Mon Dec 22 14:29:13 CST 2003 [THINGS THAT MAY BREAK YOUR CODE] * Added a 5th, optional parameter to WWW::Mechanize::Link's constructor. In 0.71_01, it was at the beginning of the argument list and was required. Now it's at the end and is optional. If, in the 15 hours since 0.71_01 came out, you went and changed all your WWW::Mechanize::Link constructors, you'll have to change them around again. Otherwise, you can just ignore this change. 0.71_01 Sun Dec 21 23:48:12 CST 2003 [THINGS THAT MAY BREAK YOUR CODE] * WWW::Mechanize::Link's constructor has a new argument that needs to be passed in, at the start of the argument list. [ENHANCEMENTS] * WWW::Mechanize::Link object now takes a $base URL, and will return absolute URLs with the url_abs() method. Thanks to Ashley Pond. * Added another script to WWW::Mechanize::Examples. It's a script that didn't make it into Spidering Hacks. [INSTALL & TESTS] * Heavy use of the new Test::Memory::Cycle module. * Fixed Makefile.PL so that the tests are selected under Win32. * Changed t/mech-dump.t so that the test succeeds under Win32. * Updated t/referer.t and t/mech-dump.t so they run under VMS. Thanks to Peter Prymmer. 0.70 Sun Nov 30 23:45:27 CST 2003 [THINGS THAT MAY BREAK YOUR CODE] * Redirects are now handled better by LWP, so the code that changes POSTs to GETs on redirects has been removed. [FIXES] * Fixed redirect_ok(), which had its API changed out from under it in LWP 5.76. [ENHANCEMENTS] * New warnings in find_link() for strings that are space padded, and for text matches that are passed a regex. Thanks to Jim Cromie. [DOCUMENTATION] * Patches from Mark Stosberg and Jim Cromie. [INTERNALS] * Removed all the checking for Carp. I don't know why I was thinking that Carp wasn't core. RT #4523. Also, a big bump in requirements on LWP: We need 5.76. 0.66 Thu Nov 13 14:35:31 CST 2003 No new functionality. Fixed up some install bugs and made a few documentation tweaks, mostly to plug Spidering Hacks. 0.65 Mon Nov 10 00:11:06 CST 2003 [ENHANCEMENTS] * Made a _parse_html() method that you can override or call manually, per request from Gavin Estey. [FIXES] * Made some path naming use File::Spec->catfile so that they work correctly under Windows. * "make clean" cleans up temp flag files. [INTERNALS] * Uses the new Test::Pod 1.00 for simplicity. 0.64 October 23, 2003 11:15pm [ENHANCEMENTS] * Many new tests, based on the excellent coverage reporting created by Paul Johnson's Devel::Cover module. * The start of JavaScript support, sort of! If you have an tag that does an onClick that opens a window, Mech will find the URL from that and make that be the link for the tag. This is for things like Movable Type that pop little windows to rebuild indexes. This is subject to change in the future. I don't know if it will, but I'm not making promises. It might be so buggy I just yank the whole thing. * Big jump in requirements, since we'll soon be using Gisle's new HTML::Form stuff. Also, older versions of HTML::Form don't give output I'm expecting. [FIXES] * Fixed the t/mech-dump.t failure. 0.63 October 13, 2003 2:56pm [ENHANCEMENTS] * mech-dump defaults to dumping forms. * Added name, name_regex, tag and tag_regex options to find_link() and follow_link(). * Added tests from Jim Brandt. 0.62 October 7, 2003 8:46pm [THINGS THAT MIGHT BREAK YOUR CODE] * The parms for find_link()'s url_regex and text_regex must now be actual regex objects, as in qr// objects. They can't just be little text strings. If this is a big bummer, let me know. [ENHANCEMENTS] * Added autocheck parm, to tell your Mech object to die on any error. This saves you from having to check yourself. This closes RT #3056. * Renamed the internal _carp() method as warn(). * Added a die() method. * Can now override the warn() and die() handlers in the constructor. * find_link() now complains if it gets a *_regex parm that isn't actually a regex. See RT #3032. [FIXES] * mech-dump.t no longer runs if you're not installing mech-dump. See RT #3724. [DOCUMENTATION] * More FAQs. Thanks to Gavin Estey. 0.61 October 6, 2003 6:30pm No new functionality here. It's mostly to get the new tests into the pipeline so the CPAN testers can run 'em. [FIXES] * Missing dependency on File::Temp. Thanks, Ask. [ENHANCEMENTS] * Added the test case for the form processing problem as a .t file, since I spent so long getting it down to a simple case. * Internal code uses accessors instead of direct hash entries. Prepare for deprecation of existing hash entries! [DOCUMENTATION] * The FAQ is now its own document at WWW::Mechanize::FAQ. 0.60 September 22, 2003 10:00pm [FIXES] * Changed how t/failure.t tries to fail. It used to hit a bogus hostname in .com, but with Verisign doing its SiteFinder crap, even bogus addresses in .com succeed. [ENHANCEMENTS] * Added _make_request() to let WWW::Mechanize::Cached easily hook into the request chain. 0.59 September 3, 2003 11:56pm [FIXES] * Squelched a warning in follow() where it tries to do a regex match against an undef value. * The page stack functionality, including the back() button, was entirely broken. Now it works. Thanks to the mighty Iain Truskett for help. [ENHANCEMENTS] * Added the mech-dump script, which replaces mech-forms. It will dump forms and lists of links. Eventually it will do lists of images, too, but not yet. 0.58 August 14, 2003 11:30pm [THINGS THAT MIGHT BREAK YOUR CODE] * $mech->uri() now returns a plain string, not a URI object. The automatic stringification of the URI object was causing problems on Win32 and/or threaded Perls, and I didn't feel like figuring out why. If the non-objectness of the uri() method is a problem, let me know. * form(), form_name() and form_number() now return the HTML::Form object of the form that was chosen. They used to return a 1 or 0. This means that if you're explicitly checking for 1 or 0, instead of evaluating the return code in a boolean context, your code will break. [FIXES] * The -handling in extract_links() was incorrectly building the text. * uri() now returns a string, not a URI object. * form(), form_name() and form_number() now return the HTML::Form object of the form that was chosen. [INTERNALS] * Determination of live vs. local tests is now done in Makefile.PL, and we don't have to set those silly semaphore files any more. * Made other cleanups in Makefile.PL, like using ExtUtils::Command instead of rolling my own touch(). * Moved all the *-live.t tests into t/live/*.t, and renamed the *-local.t files to not be -local. * Added more tests for tags. 0.57 July 31, 2003 11:21pm [ENHANCEMENTS] * Added tags to those that are links per find_links(). 0.56 July 24, 2003 12:15pm [THINGS THAT MIGHT BREAK YOUR CODE] * Created agent_alias() method to do the browser string translation. Passing "Windows IE 6" to agent() will get you back exactly that string as the agent. You have to call $a->agent_alias( "Windows IE 6" ) to get the translation. Fortunately, unless you used the new functionality of agent() in the past two days since I released 0.55, it won't be a problem. [ENHANCEMENTS] * Removed the dependencies on Carp and Test::Builder. There still is a dependency on Test::Builder for Test::More, but it's no longer explicit in the Makefile.PL. Mech will use Carp if possible, but it's no longer a requirement. [INTERNALS] * Added _carp method for handling conditional warnings, rather than checking quiet() all the time. 0.55 July 22, 2003 12:10pm [ENHANCEMENTS] * Added WWW::Mechanize::Link object to encapsulate what used to be an array reference of stuff from find_link(). This replaces having to know that $link->[0] was URL and so on. However, since WWW::Mechanize::Link is a blessed arrayref, it's backwards compatible with existing code. * The WWW::Mechanize::Link object now tracks what tag the link came from (, or
Fake Signature Signature Fake Signature WWW-Mechanize-1.96/t/TestServer.pm000644 000765 000024 00000004456 13623637465 020254 0ustar00olafaldersstaff000000 000000 package TestServer; use warnings; use strict; use Test::More; use HTTP::Server::Simple::CGI; use base qw( HTTP::Server::Simple::CGI ); my $dispatch_table = {}; =head1 OVERLOADED METHODS =cut our $pid; sub new { die 'An instance of TestServer has already been started.' if $pid; my $class = shift; my $port = shift; if ( !$port ) { $port = int(rand(20000)) + 20000; } my $self = $class->SUPER::new( $port ); my $root = $self->root; return $self; } sub run { my $self = shift; $pid = $self->SUPER::run(@_); $SIG{__DIE__} = \&stop; return $pid; } sub handle_request { my $self = shift; my $cgi = shift; my $path = $cgi->path_info(); my $handler = $dispatch_table->{$path}; if (ref($handler) eq "CODE") { print "HTTP/1.0 200 OK\r\n"; $handler->($cgi); } else { my $file = $path; if ( $file =~ m{/$} ) { $file .= 'index.html'; } $file =~ s/\s+//g; my $filename = "t/html/$file"; if ( -r $filename ) { if (my $response=do { local (@ARGV, $/) = $filename; <> }) { print "HTTP/1.0 200 OK\r\n"; print "Content-Type: text/html\r\nContent-Length: ", length($response), "\r\n\r\n", $response; return; } } else { print "HTTP/1.0 404 Not found\r\n"; print $cgi->header, $cgi->start_html('Not found'), $cgi->h1('Not found'), $cgi->end_html; } } } =head1 METHODS UNIQUE TO TestServer =cut sub set_dispatch { my $self = shift; $dispatch_table = shift; return; } sub background { my $self = shift; $pid = $self->SUPER::background() or Carp::confess( q{Can't start the test server} ); sleep 1; # background() may come back prematurely, so give it a second to fire up my $root = $self->root; diag( "Test server $root as PID $pid" ); return $pid; } sub hostname { my $self = shift; return '127.0.0.1'; } sub root { my $self = shift; my $port = $self->port; my $hostname = $self->hostname; return "http://$hostname:$port"; } sub stop { if ( $pid ) { kill( 9, $pid ) unless $^S; undef $pid; } return; } 1; WWW-Mechanize-1.96/t/find_link.t000644 000765 000024 00000014012 13623637465 017717 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More; use URI::file; BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/find_link.html' )->as_string; $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die q{Can't get test page}; my $x; $x = $mech->find_link(); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://www.drphil.com/', 'First link on the page' ); is( $x->url, 'http://www.drphil.com/', 'First link on the page' ); $x = $mech->find_link( n => 3 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'styles.css', 'Third link should be the CSS' ); is( $x->url, 'styles.css', 'Third link should be the CSS' ); $x = $mech->find_link( url_regex => qr/upcase/i ); isa_ok( $x, 'WWW::Mechanize::Link' ); like( $x->url, qr/\Qupcase.com/i, 'found link in uppercase meta tag' ); $x = $mech->find_link( text => 'CPAN A' ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://a.cpan.org/', 'First CPAN link' ); is( $x->url, 'http://a.cpan.org/', 'First CPAN link' ); $x = $mech->find_link( url => 'CPAN' ); ok( !defined $x, 'No url matching CPAN' ); $x = $mech->find_link( text_regex => qr/CPAN/, n=>3 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://c.cpan.org/', '3rd CPAN text' ); is( $x->url, 'http://c.cpan.org/', '3rd CPAN text' ); $x = $mech->find_link( text => 'CPAN', n=>34 ); ok( !defined $x, 'No 34th CPAN text' ); $x = $mech->find_link( text_regex => qr/(?i:cpan)/ ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://a.cpan.org/', 'Got 1st cpan via regex' ); is( $x->url, 'http://a.cpan.org/', 'Got 1st cpan via regex' ); $x = $mech->find_link( text_regex => qr/cpan/i ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://a.cpan.org/', 'Got 1st cpan via regex' ); is( $x->url, 'http://a.cpan.org/', 'Got 1st cpan via regex' ); $x = $mech->find_link( text_regex => qr/cpan/i, n=>153 ); ok( !defined $x, 'No 153rd cpan link' ); $x = $mech->find_link( url => 'http://b.cpan.org/' ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://b.cpan.org/', 'Got b.cpan.org' ); is( $x->url, 'http://b.cpan.org/', 'Got b.cpan.org' ); $x = $mech->find_link( url => 'http://b.cpan.org', n=>2 ); ok( !defined $x, 'Not a second b.cpan.org' ); $x = $mech->find_link( url_regex => qr/[b-d]\.cpan\.org/, n=>2 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://c.cpan.org/', 'Got c.cpan.org' ); is( $x->url, 'http://c.cpan.org/', 'Got c.cpan.org' ); my @wanted_links= ( [ 'http://a.cpan.org/', 'CPAN A', undef, 'a' ], [ 'http://b.cpan.org/', 'CPAN B', undef, 'a' ], [ 'http://c.cpan.org/', 'CPAN C', 'bongo', 'a' ], [ 'http://d.cpan.org/', 'CPAN D', undef, 'a' ], ); my @links = $mech->find_all_links( text_regex => qr/CPAN/ ); @{$_} = @{$_}[0..3] for @links; is_deeply( \@links, \@wanted_links, 'Correct links came back' ); my $linkref = $mech->find_all_links( text_regex => qr/CPAN/ ); is_deeply( $linkref, \@wanted_links, 'Correct links came back' ); # Check combinations of links $x = $mech->find_link( text => 'News' ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://www.msnbc.com/', 'First News is MSNBC' ); is( $x->url, 'http://www.msnbc.com/', 'First News is MSNBC' ); $x = $mech->find_link( text => 'News', url_regex => qr/bbc/ ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://www.bbc.co.uk/', 'First BBC news link' ); is( $x->url, 'http://www.bbc.co.uk/', 'First BBC news link' ); is( $x->[1], 'News', 'First BBC news text' ); is( $x->text, 'News', 'First BBC news text' ); $x = $mech->find_link( text => 'News', url_regex => qr/cnn/ ); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://www.cnn.com/', 'First CNN news link' ); is( $x->url, 'http://www.cnn.com/', 'First CNN news link' ); is( $x->[1], 'News', 'First CNN news text' ); is( $x->text, 'News', 'First CNN news text' ); AREA_CHECKS: { my @wanted_links = ( [ 'http://www.cnn.com/', 'CNN', undef, 'a' ], [ 'http://www.cnn.com/', 'News', 'Fred', 'a' ], # Can someone confirm that I just fixed a bug here, and # area tags /should/ have names? -mls [ 'http://www.cnn.com/area', undef, 'Marty', 'area' ], ); my @links = $mech->find_all_links( url_regex => qr/cnn\.com/ ); @{$_} = @{$_}[0..3] for @links; is_deeply( \@links, \@wanted_links, 'Correct links came back' ); } $x = $mech->find_link( name => 'bongo' ); isa_ok( $x, 'WWW::Mechanize::Link' ); is_deeply( $x, [ 'http://c.cpan.org/', 'CPAN C', 'bongo', 'a' ], 'Got the CPAN C link' ); $x = $mech->find_link( name_regex => qr/^[A-Z]/, n => 2 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is_deeply( $x, [ 'http://www.cnn.com/', 'News', 'Fred', 'a' ], 'Got 2nd link that begins with a capital' ); $x = $mech->find_link( tag => 'a', n => 3 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is_deeply( $x, [ 'http://b.cpan.org/', 'CPAN B', undef, 'a' ], 'Got 3rd tag' ); $x = $mech->find_link( tag_regex => qr/^(a|frame)$/, n => 7 ); isa_ok( $x, 'WWW::Mechanize::Link' ); is_deeply( $x, [ 'http://d.cpan.org/', 'CPAN D', undef, 'a' ], 'Got 7th or tag' ); $x = $mech->find_link( text => 'Rebuild Index' ); isa_ok( $x, 'WWW::Mechanize::Link' ); is_deeply( [@{$x}[0..3]], [ '/cgi-bin/MT/mt.cgi', 'Rebuild Index', undef, 'a' ], 'Got the JavaScript link' ); $x = $mech->find_link( url => 'blongo.html' ); isa_ok( $x, 'WWW::Mechanize::Link' ); $x = $mech->find_link( url_abs => 'blongo.html' ); ok( !defined $x, 'No match' ); $x = $mech->find_link( url_abs_regex => qr[t/blongo\.html$] ); isa_ok( $x, 'WWW::Mechanize::Link' ); $x = $mech->find_link( text_regex => qr/click/i); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->[0], 'http://www.yahoo.com/', 'Got js url link' ); is( $x->url, 'http://www.yahoo.com/', 'Got js url link' ); $mech->get( URI::file->new_abs('t/refresh.html') ); my $link = $mech->find_link( tag => 'meta' ); is( $link->url, 'http://www.mysite.com/', 'got link from meta tag via tag search' ); done_testing(); WWW-Mechanize-1.96/t/area_link.t000644 000765 000024 00000003754 13623637465 017722 0ustar00olafaldersstaff000000 000000 #!perl -T # WWW::Mechanize tests for tags use warnings; use strict; use Test::More tests => 9; use lib 't'; BEGIN { use Tools; } BEGIN { use_ok( 'WWW::Mechanize' ); } use URI::file; my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/area_link.html' ); $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die q{Can't get test page}; AREA_CHECKS: { my @wanted_links = ( [ 'http://www.msnbc.com/area', undef, undef, 'area', { coords => '1,2,3,4', href => 'http://www.msnbc.com/area' } ], [ 'http://www.cnn.com/area', undef, undef, 'area', { coords => '5,6,7,8', href => 'http://www.cnn.com/area' } ], [ 'http://www.cpan.org/area', undef, undef, 'area', { '/' => '/', coords => '10,11,12,13', href => 'http://www.cpan.org/area' } ], [ 'http://www.slashdot.org', undef, undef, 'area', { href => 'http://www.slashdot.org' } ], [ 'http://mark.stosberg.com', undef, undef, 'area', { alt => q{Mark Stosberg's homepage}, href => 'http://mark.stosberg.com' } ], ); my @links = $mech->find_all_links(); # Skip the 'base' field for now for (@links) { my $attrs = $_->[5]; @{$_} = @{$_}[0..3]; push @{$_}, $attrs; } is_deeply( \@links, \@wanted_links, 'Correct links came back' ); my $linkref = $mech->find_all_links(); is_deeply( $linkref, \@wanted_links, 'Correct links came back' ); SKIP: { skip 'Test::Memory::Cycle not installed', 2 unless $canTMC; memory_cycle_ok( \@links, 'Link list: no cycles' ); memory_cycle_ok( $linkref, 'Single link: no cycles' ); } } SKIP: { skip 'Test::Memory::Cycle not installed', 2 unless $canTMC; memory_cycle_ok( $uri, 'URI: no cycles' ); memory_cycle_ok( $mech, 'Mech: no cycles' ); } WWW-Mechanize-1.96/t/cookies.t000644 000765 000024 00000005751 13623637465 017430 0ustar00olafaldersstaff000000 000000 # XXX add cookie reading on the server side to the test BEGIN { delete @ENV{ qw( http_proxy HTTP_PROXY ) }; } use warnings; use strict; use Test::More; if ( $^O =~ /Win32/ ) { plan skip_all => 'HTTP::Server::Simple does not support Windows yet.'; } else { plan tests => 14; } use WWW::Mechanize; use URI::Escape qw( uri_unescape ); use lib 't/'; use TestServer; my $ncookies = 0; sub send_cookies { my $cgi = shift; return if !ref $cgi; ++$ncookies; print $cgi->header( -cookie => $cgi->cookie( -name => 'my_cookie', -value => "Cookie #$ncookies", -domain => '127.0.0.1', -path => '/', -expires => '+1h', -secure => 0, ) ), $cgi->start_html( -title => "Home of Cookie #$ncookies" ), $cgi->h1( "Here is Cookie #$ncookies" ), $cgi->end_html; } sub nosend_cookies { my $cgi = shift; return if !ref $cgi; print $cgi->header(), $cgi->start_html( -title => 'No cookies sent' ), $cgi->h1( 'No cookies sent' ), $cgi->end_html; } my $server = TestServer->new(); $server->set_dispatch( { '/feedme' => \&send_cookies, '/nocookie' => \&nosend_cookies, } ); my $pid = $server->background(); my $root = $server->root; my $cookiepage_url = "$root/feedme"; my $nocookiepage_url = "$root/nocookie"; my $mech = WWW::Mechanize->new( autocheck => 0 ); isa_ok( $mech, 'WWW::Mechanize' ); FIRST_COOKIE: { $mech->get( $cookiepage_url ); is( $mech->status, 200, 'First fetch works' ); my $cookieval = cookieval( $mech ); is( $cookieval, 'Cookie #1', 'First cookie matches' ); is( $mech->title, 'Home of Cookie #1', 'Right title' ); } SECOND_COOKIE: { $mech->get( $cookiepage_url ); is( $mech->status, 200, 'Second fetch works' ); my $cookieval = cookieval( $mech ); is( $cookieval, 'Cookie #2', 'Second cookie matches' ); is( $mech->title, 'Home of Cookie #2', 'Right title' ); } BACK_TO_FIRST_PAGE: { $mech->back(); my $cookieval = cookieval( $mech ); is( $cookieval, 'Cookie #2', 'Cookie did not change...' ); is( $mech->title, 'Home of Cookie #1', '... but back to the first page title' ); } FORWARD_TO_NONCOOKIE_PAGE: { $mech->get( $nocookiepage_url ); my $cookieval = cookieval( $mech ); is( $cookieval, 'Cookie #2', 'Cookie did not change...' ); is( $mech->title, 'No cookies sent', 'On the proper 3rd page' ); } GET_A_THIRD_COOKIE: { $mech->get( $cookiepage_url ); my $cookieval = cookieval( $mech ); is( $cookieval, 'Cookie #3', 'Got the third cookie' ); is( $mech->title, 'Home of Cookie #3', 'Title is correct' ); } my $signal = ($^O eq 'MSWin32') ? 9 : 15; my $nprocesses = kill $signal, $pid; is( $nprocesses, 1, 'Signaled the child process' ); sub cookieval { my $mech = shift; return uri_unescape( $mech->cookie_jar->{COOKIES}{'127.0.0.1'}{'/'}{'my_cookie'}[1] ); } WWW-Mechanize-1.96/t/form-parsing.t000644 000765 000024 00000000733 13623637465 020373 0ustar00olafaldersstaff000000 000000 #!perl -T use strict; use warnings; use Test::More tests=>1; use HTML::Form; my $base = 'http://localhost/'; my $content = do { local $/ = undef; }; my $forms = [ HTML::Form->parse( $content, $base ) ]; is( scalar @{$forms}, 1, 'Find one form, please' ); __DATA__ WWW::Mechanize::Shell test page
WWW-Mechanize-1.96/t/history_3.html000644 000765 000024 00000000235 13623637465 020410 0ustar00olafaldersstaff000000 000000 Testing the history_3
To first page WWW-Mechanize-1.96/t/field.html000644 000765 000024 00000000543 13623637465 017552 0ustar00olafaldersstaff000000 000000 Like a hole
WWW-Mechanize-1.96/t/link.t000644 000765 000024 00000003553 13623637465 016727 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More tests=>23; BEGIN { use_ok( 'WWW::Mechanize::Link' ); } OLD_API: { my $link = WWW::Mechanize::Link->new( 'url.html', 'text', 'name', 'frame', 'http://base.example.com/', { alt => 'alt text' } ); isa_ok( $link, 'WWW::Mechanize::Link' ); is( scalar @$link, 6, 'Should have five elements' ); # Test the new-style accessors is( $link->url, 'url.html', 'url() works' ); is( $link->text, 'text', 'text() works' ); is( $link->name, 'name', 'name() works' ); is( $link->tag, 'frame', 'tag() works' ); is( $link->base, 'http://base.example.com/', 'base() works' ); is( $link->attrs->{alt}, 'alt text', 'attrs() works' ); # Order of the parms in the blessed array is important for backwards compatibility. is( $link->[0], 'url.html', 'parm 0 is url' ); is( $link->[1], 'text', 'parm 1 is text' ); is( $link->[2], 'name', 'parm 2 is name' ); is( $link->[3], 'frame', 'parm 3 is tag' ); is( $link->[4], 'http://base.example.com/', 'parm 4 is base' ); my $URI = $link->URI; isa_ok( $URI, 'URI::URL', 'URI is proper type' ); is( $URI->rel, 'url.html', 'Short form of the url' ); is( $link->url_abs, 'http://base.example.com/url.html', 'url_abs works' ); } NEW_API: { # test new style API my $link = WWW::Mechanize::Link->new( { url => 'url.html', text => 'text', name => 'name', tag => 'frame', base => 'http://base.example.com/', attrs => { alt => 'alt text' }, } ); is( $link->url, 'url.html', 'url() works' ); is( $link->text, 'text', 'text() works' ); is( $link->name, 'name', 'name() works' ); is( $link->tag, 'frame', 'tag() works' ); is( $link->base, 'http://base.example.com/', 'base() works' ); is( $link->attrs->{alt}, 'alt text', 'attrs() works' ); } WWW-Mechanize-1.96/t/00-report-prereqs.dd000644 000765 000024 00000011517 13623637465 021324 0ustar00olafaldersstaff000000 000000 do { my $x = { 'configure' => { 'requires' => { 'ExtUtils::MakeMaker' => '0' }, 'suggests' => { 'JSON::PP' => '2.27300' } }, 'develop' => { 'recommends' => { 'Dist::Zilla::PluginBundle::Git::VersionManager' => '0.007' }, 'requires' => { 'Code::TidyAll' => '0.71', 'Code::TidyAll::Plugin::SortLines::Naturally' => '0.000003', 'Code::TidyAll::Plugin::Test::Vars' => '0.04', 'Code::TidyAll::Plugin::UniqueLines' => '0.000003', 'Encode' => '0', 'Parallel::ForkManager' => '1.19', 'Perl::Critic' => '1.132', 'Perl::Tidy' => '20180220', 'Pod::Coverage::TrustPod' => '0', 'Test::Code::TidyAll' => '0.50', 'Test::EOL' => '0', 'Test::Memory::Cycle' => '1.06', 'Test::Mojibake' => '0', 'Test::More' => '0.88', 'Test::Needs' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Portability::Files' => '0', 'Test::RequiresInternet' => '0', 'Test::Vars' => '0.014', 'Test::Version' => '1', 'constant' => '0', 'lib' => '0' } }, 'runtime' => { 'requires' => { 'Carp' => '0', 'Getopt::Long' => '0', 'HTML::Form' => '1.00', 'HTML::HeadParser' => '0', 'HTML::TokeParser' => '0', 'HTML::TreeBuilder' => '5', 'HTTP::Cookies' => '0', 'HTTP::Request' => '1.30', 'HTTP::Request::Common' => '0', 'LWP::UserAgent' => '5.827', 'Pod::Usage' => '0', 'Scalar::Util' => '1.14', 'Tie::RefHash' => '0', 'URI::URL' => '0', 'URI::file' => '0', 'base' => '0', 'perl' => '5.006', 'strict' => '0', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'CGI' => '4.32', 'Exporter' => '0', 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'File::Temp' => '0', 'FindBin' => '0', 'HTTP::Daemon' => '6.05', 'HTTP::Response' => '0', 'HTTP::Server::Simple::CGI' => '0', 'LWP' => '0', 'LWP::Simple' => '0', 'Test::Deep' => '0', 'Test::Fatal' => '0', 'Test::More' => '0.96', 'Test::Output' => '0', 'Test::Warnings' => '0', 'URI' => '0', 'URI::Escape' => '0', 'bytes' => '0', 'lib' => '0', 'vars' => '0' } } }; $x; }WWW-Mechanize-1.96/t/image-parse.t000644 000765 000024 00000004124 13623637465 020157 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More tests => 33; use URI::file; BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/image-parse.html' )->as_string; $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die 'Can\'t get test page'; my @images = $mech->images; is( scalar @images, 8, 'Only eight images' ); my $first = $images[0]; is( $first->tag, 'img', 'img tag' ); is( $first->url, 'wango.jpg', 'URL matches' ); is( $first->alt, 'The world of the wango', 'alt matches' ); my $second = $images[1]; is( $second->tag, 'input', 'input tag' ); is( $second->url, 'bongo.gif', 'URL matches' ); is( $second->alt, undef, 'alt matches' ); is( $second->height, 142, 'height' ); is( $second->width, 43, 'width' ); my $third = $images[2]; is( $third->url, 'linked.gif', 'Got the third image' ); is( $third->tag, 'img', 'input tag' ); is( $third->alt, undef, 'alt' ); my $fourth = $images[3]; is( $fourth->url, 'hacktober.jpg', 'Got the fourth image' ); is( $fourth->tag, 'img', 'input tag' ); is( $fourth->alt, undef, 'alt' ); is( $fourth->attrs->{id}, 'first-hacktober-image', 'id' ); is( $fourth->attrs->{class}, 'my-class-1', 'class' ); my $fifth = $images[4]; is( $fifth->url, 'hacktober.jpg', 'Got the fifth image' ); is( $fifth->tag, 'img', 'input tag' ); is( $fifth->alt, undef, 'alt' ); is( $fifth->attrs->{id}, undef, 'id' ); is( $fifth->attrs->{class}, 'my-class-2 foo', 'class' ); my $sixth = $images[5]; is( $sixth->url, 'hacktober.jpg', 'Got the sixth image' ); is( $sixth->tag, 'img', 'input tag' ); is( $sixth->alt, undef, 'alt' ); is( $sixth->attrs->{id}, undef, 'id' ); is( $sixth->attrs->{class}, 'my-class-3 foo bar', 'class' ); # regression github #269 my $seventh = $images[7]; is( $seventh->attrs->{id}, 'no-src-regression-269', 'Got the sevenths image'); is( $seventh->url, undef, 'it has no URL'); is( $seventh->attrs->{'data-image'}, 'hacktober.jpg', 'it has an extra attribute');WWW-Mechanize-1.96/t/taint.t000644 000765 000024 00000001166 13623637465 017107 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More; BEGIN { eval 'use Test::Taint'; plan skip_all => 'Test::Taint required for checking taintedness' if $@; plan tests=>6; } BEGIN { use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( autocheck => 1 ); isa_ok( $mech, 'WWW::Mechanize', 'Created object' ); $mech->get( 'file:t/google.html' ); # Make sure taint checking is on correctly tainted_ok( $^X, 'Interpreter Variable taints OK' ); is( $mech->title, 'Google', 'Correct title' ); untainted_ok( $mech->title, 'Title should not be tainted' ); tainted_ok( $mech->content, 'But content should' ); WWW-Mechanize-1.96/t/find_link.html000644 000765 000024 00000004021 13623637465 020417 0ustar00olafaldersstaff000000 000000 Testing the links blargle CPAN A CPAN B CPAN C CPAN D MSNBC CNN BBC News News News Rebuild Index NoWhere NoWhere Blongo! Click Here WWW-Mechanize-1.96/t/upload.t000644 000765 000024 00000001664 13623637465 017257 0ustar00olafaldersstaff000000 000000 #!perl -T use strict; use warnings; use Test::More tests => 5; use URI::file; BEGIN { delete @ENV{ qw( http_proxy HTTP_PROXY PATH IFS CDPATH ENV BASH_ENV) }; } use_ok( 'WWW::Mechanize' ); my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/upload.html' )->as_string; $mech->get( $uri ); ok( $mech->success, $uri ); my $form = $mech->form_number(1); my $reqstring = $form->click->as_string; $reqstring =~ s/\r//g; # trim off possible extra newline $reqstring =~ s/^\Z\n//m; my $wanted = <<'EOT'; POST http://localhost/ Content-Length: 77 Content-Type: multipart/form-data; boundary=xYzZY --xYzZY Content-Disposition: form-data; name="submit" Submit --xYzZY-- EOT is( $reqstring, $wanted, 'Proper posting' ); $mech->field('upload', 'dist.ini'); $reqstring = $form->click->as_string; like( $reqstring, qr/WWW-Mechanize/, 'The uploaded file should be in the request'); WWW-Mechanize-1.96/t/autocheck.t000644 000765 000024 00000001021 13623637465 017724 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::Fatal qw( exception ); use Test::More; use WWW::Mechanize (); my $bad_url = "file:///foo.foo.xx.random"; AUTOCHECK_OFF: { my $mech = WWW::Mechanize->new( autocheck => 0 ); $mech->get( $bad_url ); ok( !$mech->success, qq{Didn't fetch $bad_url, but didn't die, either} ); } AUTOCHECK_ON: { like( exception { WWW::Mechanize->new->get($bad_url) }, qr/Error GETing/, qq{Couldn't fetch $bad_url, and died as a result} ); } done_testing(); WWW-Mechanize-1.96/t/frames.t000644 000765 000024 00000001447 13623637465 017247 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More tests => 7; use URI::file; BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/frames.html' )->as_string; $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die q{Can't get test page}; my $link = $mech->find_link(); isa_ok( $link, 'WWW::Mechanize::Link' ); my @links = $mech->find_all_links(); is( scalar @links, 2, 'Only two links' ); is_deeply( [@{$links[0]}[0..3]], [ 'find_link.html', undef, 'top', 'frame' ], 'First frame OK' ); is_deeply( [@{$links[1]}[0..3]], [ 'google.html', undef, 'bottom', 'frame' ], 'Second frame OK' ); WWW-Mechanize-1.96/t/upload.html000644 000765 000024 00000000350 13623637465 017747 0ustar00olafaldersstaff000000 000000
WWW-Mechanize-1.96/t/find_frame.t000644 000765 000024 00000001113 13623637465 020052 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More tests => 5; use URI::file; BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/find_frame.html' )->as_string; $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die q{Can't get test page}; my $x; $x = $mech->find_link(); isa_ok( $x, 'WWW::Mechanize::Link' ); is( $x->url, 'bastro.html', 'First link sequentially' ); WWW-Mechanize-1.96/t/form_with_fields.t000644 000765 000024 00000011234 13623637465 021311 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More 'no_plan'; use Test::Fatal; use Test::Warnings ':all'; use Test::Deep; use URI::file (); BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef, autocheck => 0 ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/form_with_fields.html' )->as_string; $mech->get( $uri ); ok( $mech->success, "Fetched $uri" ) or die q{Can't get test page}; { my $test = 'dies with no input'; like( exception { my $form = $mech->form_with_fields(); }, qr/no fields provided/, $test, ); } { my $form; cmp_deeply( [ warnings { $form = $mech->form_with_fields(qw/1b/) } ], [ re(qr/There are 2 forms with the named fields. The first one was used./) ], 'warning on ambiguous match (1)', ); isa_ok( $form, 'HTML::Form' ); is($form->attr('name'), '1st_form', 'first form matches'); } { my $form = $mech->form_with_fields('1b', 'opt[2]'); isa_ok( $form, 'HTML::Form' ); is($form->attr('name'), '2nd_form', 'second form matches'); } { my $form; cmp_deeply( [ warnings { $form = $mech->form_with_fields('4a', '4b') } ], [ re(qr/There are 2 forms with the named fields. The first one was used./) ], 'warning on ambiguous match (2)', ); isa_ok( $form, 'HTML::Form' ); is($form->attr('name'), '4th_form_1', 'fourth form matches'); } { my @forms = $mech->all_forms_with( name => '3rd_form_ambiguous' ); is( scalar @forms, 2 ); isa_ok( $forms[0], 'HTML::Form' ); isa_ok( $forms[1], 'HTML::Form' ); is($forms[0]->attr('name'), '3rd_form_ambiguous', 'first result of 3rd_form_ambiguous'); is($forms[1]->attr('name'), '3rd_form_ambiguous', 'second result of 3rd_form_ambiguous'); } { $mech->get($uri); like( exception { $mech->submit_form( with_fields => { 'xx' => '' }, ); }, qr/There is no form with the requested fields/, 'submit_form with no match (1)', ); } { $mech->get($uri); like( exception { $mech->submit_form( with_fields => { '1a' => '' }, form_number => 2, ); }, qr/There is no form that satisfies all the criteria/, 'submit_form with no match (2)', ); } { $mech->get($uri); like( exception { $mech->submit_form( form_number => 2, form_name => '3rd_form_ambiguous', ); }, qr/There is no form that satisfies all the criteria/, 'submit_form with no match (3)', ); } { $mech->get($uri); like( exception { $mech->submit_form( form_name => '3rd_form_ambiguous', ); }, qr/More than one form satisfies all the criteria/, 'submit_form with more than one match', ); } { $mech->get($uri); is( exception { $mech->submit_form( with_fields => { 'x' => '' }, form_name => '3rd_form_ambiguous', ); }, undef, 'submit_form with intersection of two criteria', ); } { $mech->get($uri); is( exception { $mech->submit_form( with_fields => { '1b' => '', 'opt[2]' => '' }, ); }, undef, ' submit_form( with_fields => %data ) ', ); } { $mech->get($uri); is( exception { $mech->submit_form( form_name => '1st_form', fields => { '1c' => 'madeup_field', }, ); }, undef, 'submit_form with invalid field and without strict_forms option succeeds', ); } { $mech->get($uri); like( exception { $mech->submit_form( form_name => '1st_form', fields => { '1c' => 'madeup_field', }, strict_forms => 1, ); }, qr/^No such field '1c'/, 'submit_form with invalid field and strict_forms option fails', ); } { $mech->get($uri); is( exception { $mech->submit_form( form_name => '1st_form', fields => { '1a' => 'value1', '1b' => 'value2', }, strict_forms => 1, ); }, undef, 'submit_form with valid fields and strict_forms option succeeds', ); }WWW-Mechanize-1.96/t/history_2.html000644 000765 000024 00000000555 13623637465 020414 0ustar00olafaldersstaff000000 000000 Testing the history_2
WWW-Mechanize-1.96/t/select.t000644 000765 000024 00000005005 13623637465 017243 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More tests => 14; use URI::file; BEGIN { delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}; # Placates taint-unsafe Cwd.pm in 5.6.1 use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new( cookie_jar => undef ); isa_ok( $mech, 'WWW::Mechanize' ); my $uri = URI::file->new_abs( 't/select.html' )->as_string; my $response = $mech->get( $uri ); ok( $response->is_success, "Fetched $uri" ); my ($sendsingle, @sendmulti, %sendsingle, %sendmulti, $rv, $return, @return, @singlereturn, $form); # possible values are: aaa, bbb, ccc, ddd $sendsingle = 'aaa'; @sendmulti = qw(bbb ccc); @singlereturn = ($sendmulti[0]); %sendsingle = (n => 1); %sendmulti = (n => [2, 3]); ok($mech->form_number(1), 'set form to number 1'); $form = $mech->current_form(); # Multi-select # pass multiple values to a multi select $mech->select('multilist', \@sendmulti); @return = $form->param('multilist'); is_deeply(\@return, \@sendmulti, 'multi->multi value is ' . join(' ', @return)); $mech->select('multilist', \%sendmulti); @return = $form->param('multilist'); is_deeply(\@return, \@sendmulti, 'multi->multi value is ' . join(' ', @return)); # pass a single value to a multi select $mech->select('multilist', $sendsingle); $return = $form->param('multilist'); is($return, $sendsingle, "single->multi value is '$return'"); $mech->select('multilist', \%sendsingle); $return = $form->param('multilist'); is($return, $sendsingle, "single->multi value is '$return'"); # Single select # pass multiple values to a single select (only the _first_ should be set) $mech->select('singlelist', \@sendmulti); @return = $form->param('singlelist'); is_deeply(\@return, \@singlereturn, 'multi->single value is ' . join(' ', @return)); $mech->select('singlelist', \%sendmulti); @return = $form->param('singlelist'); is_deeply(\@return, \@singlereturn, 'multi->single value is ' . join(' ', @return)); # pass a single value to a single select $rv = $mech->select('singlelist', $sendsingle); $return = $form->param('singlelist'); is($return, $sendsingle, "single->single value is '$return'"); $rv = $mech->select('singlelist', \%sendsingle); $return = $form->param('singlelist'); is($return, $sendsingle, "single->single value is '$return'"); # test return value from $mech->select is($rv, 1, 'return 1 after successful select'); EAT_THE_WARNING: { # Mech complains about the non-existent field local $SIG{__WARN__} = sub {}; $rv = $mech->select('missing_list', 1); } is($rv, undef, 'return undef after failed select'); WWW-Mechanize-1.96/t/find_inputs.html000644 000765 000024 00000001614 13623637465 021011 0ustar00olafaldersstaff000000 000000
Like in PHP!
WWW-Mechanize-1.96/t/local/content.t000644 000765 000024 00000002002 13623637465 020522 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use lib 't/local'; use LocalServer; use Test::More tests => 10; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize', 'Created the object' ); my $server = LocalServer->spawn(); isa_ok( $server, 'LocalServer' ); diag('Running tests against ' . $server->url . '?xml=1'); my $response = $mech->get( $server->url . '?xml=1' ); isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, 'Got URL' ) or die q{Can't even fetch local url}; is( $response->content_type, 'application/xhtml+xml', 'Content type is application/xhtml+xml' ); ok( $mech->is_html, 'Local page is HTML' ); $mech->field(query => 'foo'); # Filled the 'q' field $response = $mech->click('submit'); isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, q{Can click 'Go' ('Google Search' button)} ); is( $mech->field('query'),'foo', 'Filled field correctly'); WWW-Mechanize-1.96/t/local/log-server000644 000765 000024 00000014515 13623637465 020707 0ustar00olafaldersstaff000000 000000 # Thanks to merlyn for nudging me and giving me this snippet! use strict; use HTTP::Daemon 6.05; use CGI 4.08; use Getopt::Long; use Socket (); $|++; GetOptions( 'e=s' => \my $expression, ); my $d = HTTP::Daemon->new or die; my $url = URI->new($d->url); if ($d->sockdomain == Socket::AF_INET) { $url->host( '127.0.0.1' ); } elsif ($d->sockdomain == Socket::AF_INET6) { $url->host( '[::1]' ); } else { die "unexpected sockdomain: " . $d->sockdomain; } print "$url\n"; my ($filename,$logfile) = @ARGV[0,1]; if ($filename) { open DATA, "< $filename" or die "Couldn't read page '$filename' : $!\n"; }; #open LOG, ">", $logfile # or die "Couldn't create logfile '$logfile' : $!\n"; my $log; my $body = join "", ; $body =~ s//chr(hex($1))/eg; utf8::encode($body); utf8::upgrade($body); sub debug($) { my $message = $_[0]; $message =~ s!\n!\n#SERVER:!g; warn "#SERVER: $message" if $ENV{TEST_HTTP_VERBOSE}; }; SERVERLOOP: { my $quitserver; while (my $c = $d->accept) { debug "New connection"; while (my $r = $c->get_request) { debug "Request:\n" . $r->as_string; my $location = ($r->uri->path || "/"); my ($link1,$link2) = ('',''); if ($location =~ m!^/link/([^/]+)/(.*)$!) { ($link1,$link2) = ($1,$2); }; my $res; if ($location eq '/get_server_log') { $res = HTTP::Response->new(200, "OK", undef, $log); $log = ''; } elsif ( $location eq '/quit_server') { debug "Quitting"; $res = HTTP::Response->new(200, "OK", [Connection => 'close'], "quit"); $quitserver = 1; } else { eval $expression if $expression; warn "eval: $@" if $@; $log .= "Request:\n" . $r->as_string . "\n"; if ($location =~ m!^/redirect/(.*)$!) { $res = HTTP::Response->new(302); $res->header('location', $d->url . $1); } elsif ($location =~ m!^/error/notfound/(.*)$!) { $res = HTTP::Response->new(404, "Not found", [Connection => 'close']); } elsif ($location =~ m!^/error/timeout/(\d+)$!) { sleep $1; $res = HTTP::Response->new(599, "Timeout reached", [Connection => 'close']); } elsif ($location =~ m!^/error/close/(\d+)$!) { sleep $1; $res = undef; } elsif ( $location =~ m!^/chunks!) { my $count = 5; $res = HTTP::Response->new(200, "OK", undef, sub { sleep 1; my $buf = 'x' x 16; return $buf if $count-- > 0; return undef; # done }); } elsif ($location =~ m!^/error/after_headers$!) { my $count = 2; $res = HTTP::Response->new(200, "OK", undef, sub { sleep 1; my $buf = 'x' x 16; return $buf if $count-- > 0; die "Planned error after headers"; }); } elsif ($location =~ m!^/encoding/(.*)!) { my $encoding = $1; $res = HTTP::Response->new( 200, "OK", [ 'Content-Type' => "text/html; charset=$encoding" ], "encoding $encoding" ); } else { my $q = CGI->new($r->uri->query); # Make sticky form fields my ($query,$session,%cat); $query = defined $q->param('query') ? $q->param('query') : "(empty)"; $session = defined $q->param('session') ? $q->param('session') : 1; %cat = map { $_ => 1 } (defined $q->param('cat') ? $q->multi_param('cat') : qw( cat_foo cat_bar )); my @categories = map { $cat{$_} ? "checked" : "" } qw( cat_foo cat_bar cat_baz ); (my $h = $r->headers->{host}) =~ s/:\d+//; my $rbody = sprintf $body,$location,$session,$query,@categories; $res = HTTP::Response->new(200, "OK", [ "Set-Cookie" => $q->cookie(-name => 'log-server',-value=>'shazam2', -discard=>1,), 'Cache-Control' => 'no-cache', 'Pragma' => 'no-cache', 'Max-Age' => 0, 'Connection' => 'close', 'Content-Length' => length($rbody), ], $rbody); $res->content_type( $q->param('xml') ? 'application/xhtml+xml' : 'text/html' ); debug "Request " . ($r->uri->path || "/"); }; }; debug "Response:\n" . $res->as_string if $res; eval { $c->send_response($res) if $res; }; if (my $err = $@) { debug "Server raised error: $err"; if ($err !~ /^Planned error\b/) { warn $err; }; $c->close; }; if (! $res) { $c->close; }; last if $quitserver; } sleep 1; undef($c); last SERVERLOOP if $quitserver; } }; END { debug "Server stopped" }; __DATA__ WWW::Mechanize test page

Location: %s

Link /test Link /foo Link / /Link /Link in slashes/ Link foo1.save_log_server_test.tmp Link foo2.save_log_server_test.tmp Link foo3.save_log_server_test.tmp Lschen -- testing for o-umlaut. Stösberg -- testing for encoded o-umlaut.
Col1Col2Col3
A1A2A3
B1B2B3
C1C2C3

WWW-Mechanize-1.96/t/local/post.t000644 000765 000024 00000001061 13623637465 020041 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 5; use lib qw( t t/local ); use LocalServer; BEGIN { use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $agent = WWW::Mechanize->new; isa_ok( $agent, 'WWW::Mechanize', 'Created object' ); # GET with full URL to set the base $agent->get($server->url); ok( $agent->success, "Get webpage" ); # POST with relative URL $agent->post('/post'); ok( $agent->success, "Post webpage" ); WWW-Mechanize-1.96/t/local/referer.t000644 000765 000024 00000004123 13623637465 020510 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use FindBin; use Test::More tests => 13; BEGIN { use lib 't'; use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } our $server; my $agent = WWW::Mechanize->new(); isa_ok( $agent, 'WWW::Mechanize' ); SKIP: { eval { require HTTP::Daemon; HTTP::Daemon->VERSION(6.05); }; skip 'HTTP::Daemon required to test the referrer header',10 if $@; # We want to be safe from non-resolving local host names delete $ENV{HTTP_PROXY}; # Now start a fake webserver, fork, and connect to ourselves my $command = qq'"$^X" "$FindBin::Bin/referer-server"'; if ($^O eq 'VMS') { $command = qq'mcr $^X t/referer-server'; } open $server, "$command |" or die "Couldn't spawn fake server: $!"; sleep 1; # give the child some time my $url = <$server>; chomp $url; $agent->get( $url ); is($agent->status, 200, 'Got first page') or diag $agent->res->message; is($agent->content, q{Referer: ''}, 'First page gets sent with empty referrer'); $agent->get( $url ); is($agent->status, 200, 'Got second page') or diag $agent->res->message; is($agent->content, "Referer: '$url'", 'Referer got sent for absolute url'); $agent->get( '.' ); is($agent->status, 200, 'Got third page') or diag $agent->res->message; is($agent->content, "Referer: '$url'", 'Referer got sent for relative url'); $agent->add_header( Referer => 'x' ); $agent->get( $url ); is($agent->status, 200, 'Got fourth page') or diag $agent->res->message; is($agent->content, q{Referer: 'x'}, 'Referer can be set to empty again'); my $ref = 'This is not the referer you are looking for *jedi gesture*'; $agent->add_header( Referer => $ref ); $agent->get( $url ); is($agent->status, 200, 'Got fourth page') or diag $agent->res->message; is($agent->content, "Referer: '$ref'", 'Custom referer can be set'); }; SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $agent, 'No memory cycles found' ); } END { close $server if $server; } WWW-Mechanize-1.96/t/local/submit.t000644 000765 000024 00000002233 13623637465 020361 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use lib qw( t t/local ); use Test::More tests => 13; use LocalServer; BEGIN { use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize', 'Created the object' ) or die; my $response = $mech->get( $server->url ); isa_ok( $response, 'HTTP::Response', 'Got back a response' ) or die; is( $mech->uri, $server->url, 'Got the correct page' ); ok( $response->is_success, 'Got local page' ) or die 'cannot even fetch local page'; ok( $mech->is_html, 'is HTML' ); is( $mech->value('upload'), '', 'Hopefully no upload happens'); $mech->field(query => 'foo'); # Filled the 'q' field $response = $mech->submit; isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, 'Can click "submit" ("submit" button)'); like($mech->content, qr/\bfoo\b/i, 'Found "Foo"'); is( $mech->value('upload'), '', 'No upload happens' ); SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $mech, 'Mech: no cycles' ); } WWW-Mechanize-1.96/t/local/form.t000644 000765 000024 00000003747 13623637465 020034 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 21; use lib 't/local'; use LocalServer; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my @warnings; my $mech = WWW::Mechanize->new( onwarn => sub { push @warnings, @_ } ); isa_ok( $mech, 'WWW::Mechanize' ) or die; $mech->quiet(1); $mech->get($server->url); ok( $mech->success, 'Got a page' ) or die; is( $mech->uri, $server->url, 'Got page' ); my ($form, $number) = $mech->form_number(1); isa_ok( $form, 'HTML::Form', 'Can select the first form in list context call'); is( $number, 1, 'Form number is correct' ); my $form_number_1 = $mech->form_number(1); isa_ok( $form_number_1, 'HTML::Form', 'Can select the first form'); is( $mech->current_form(), $mech->{forms}->[0], 'Set the form attribute' ); ok( !$mech->form_number(99), 'cannot select the 99th form'); is( $mech->current_form(), $mech->{forms}->[0], 'Form is still set to 1' ); my $form_name_f = $mech->form_name('f'); isa_ok( $form_name_f, 'HTML::Form', 'Can select the form' ); ok( !$mech->form_name('bargle-snark'), 'cannot select non-existent form' ); my $form_id_pounder = $mech->form_id('pounder'); isa_ok( $form_id_pounder, 'HTML::Form', 'Can select the form' ); ok( !$mech->form_id('bargle-snark'), 'cannot select non-existent form' ); my $form_with = $mech->form_with( class => 'test', id => undef ); isa_ok( $form_with, 'HTML::Form', 'Can select the form without id' ); is( $mech->current_form, $form_number_1, 'Form without id is now the current form' ); is( scalar @warnings, 0, 'no warnings so far' ); $mech->quiet(0); $form_with = $mech->form_with( class => 'test', foo => '', bar => undef ); is( $form_with, $form_number_1, 'Can select form with ambiguous criteria' ); is( scalar @warnings, 1, 'Got one warning' ); is( "@warnings", 'There are 2 forms with no bar and class "test"' . ' and empty foo. The first one was used.', 'Got expected warning' ); WWW-Mechanize-1.96/t/local/page_stack.t000644 000765 000024 00000004452 13623637465 021164 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More; use lib 't/local'; use LocalServer; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); STANDARD_STACK: { my $history; my $mech = WWW::Mechanize->new; isa_ok( $mech, 'WWW::Mechanize', 'Created object' ); is( scalar @{$mech->{page_stack}}, 0, 'Page stack starts empty' ); is( $mech->history_count, 0, 'No history count to start' ); is( $mech->history(0), undef, 'No 0th history item yet' ); ok( $mech->get($server->url)->is_success, 'Got start page' ); is( scalar @{$mech->{page_stack}}, 0, 'Page stack empty after first get' ); $history = $mech->history(0); is( $history->{req}->url, $server->url, "0th history is last request"); is( $mech->history(1), undef, 'No 1th history item yet' ); is( $mech->history_count, 1, 'One history count after first get' ); $mech->_push_page_stack(); is( scalar @{$mech->{page_stack}}, 1, 'Pushed item onto page stack' ); is( $mech->history_count, 2, 'Two history count after push' ); $mech->_push_page_stack(); is( scalar @{$mech->{page_stack}}, 2, 'Pushed item onto page stack' ); is( $mech->history_count, 3, 'Three history count after push' ); $mech->back(); is( scalar @{$mech->{page_stack}}, 1, 'Popped item from page stack' ); is( $mech->history_count, 2, 'History count back to 2 post pop' ); $mech->back(); is( scalar @{$mech->{page_stack}}, 0, 'Popped item from page stack' ); is( $mech->history_count, 1, 'History count back to 1 post pop' ); $mech->back(); is( scalar @{$mech->{page_stack}}, 0, 'Cannot pop beyond end of page stack' ); is( $mech->history_count, 1, 'History count stable at 1' ); } NO_STACK: { my $mech = WWW::Mechanize->new; isa_ok( $mech, 'WWW::Mechanize', 'Created object' ); $mech->stack_depth(0); is( scalar @{$mech->{page_stack}}, 0, 'Page stack starts empty' ); ok( $mech->get($server->url)->is_success, 'Got start page' ); is( scalar @{$mech->{page_stack}}, 0, 'Page stack starts empty' ); $mech->_push_page_stack(); is( scalar @{$mech->{page_stack}}, 0, 'Pushing has no effect' ); } done_testing; WWW-Mechanize-1.96/t/local/LocalServer.pm000644 000765 000024 00000014410 13623637465 021450 0ustar00olafaldersstaff000000 000000 package LocalServer; # start a fake webserver, fork, and connect to ourselves use warnings; use strict; # this has to happen here because LWP::Simple creates a $ua # on load so any time after this is too late. BEGIN { delete @ENV{qw( HTTP_PROXY http_proxy CGI_HTTP_PROXY HTTPS_PROXY https_proxy HTTP_PROXY_ALL http_proxy_all )}; } use LWP::Simple; use FindBin; use File::Spec; use File::Temp; use URI::URL qw(); use Carp qw(carp croak); =head1 SYNOPSIS use LWP::Simple qw(get); my $server = Test::HTTP::LocalServer->spawn; ok get $server->url, "Retrieve " . $server->url; $server->stop; =head1 METHODS =head2 Cspawn %ARGS> This spawns a new HTTP server. The server will stay running until C<< $server->stop >> is called. Valid arguments are: =over 4 =item * C<< html => >> scalar containing the page to be served =item * C<< file => >> filename containing the page to be served =item * C<< debug => 1 >> to make the spawned server output debug information =item * C<< eval => >> string that will get evaluated per request in the server Try to avoid characters that are special to the shell, especially quotes. A good idea for a slow server would be eval => sleep+10 =back All served HTML will have the first %s replaced by the current location. The following entries will be removed from C<%ENV>: HTTP_PROXY http_proxy CGI_HTTP_PROXY HTTPS_PROXY https_proxy HTTP_PROXY_ALL http_proxy_all =cut sub spawn { my ($class,%args) = @_; my $self = { %args }; bless $self,$class; local $ENV{TEST_HTTP_VERBOSE}; $ENV{TEST_HTTP_VERBOSE} = 1 if (delete $args{debug}); $self->{delete} = []; if (my $html = delete $args{html}) { # write the html to a temp file my ($fh,$tempfile) = File::Temp::tempfile(); binmode $fh; print $fh $html or die "Couldn't write tempfile $tempfile : $!"; close $fh; push @{$self->{delete}},$tempfile; $args{file} = $tempfile; }; my ($fh,$logfile) = File::Temp::tempfile(); close $fh; push @{$self->{delete}},$logfile; $self->{logfile} = $logfile; my $web_page = delete $args{file} || ""; my $server_file = File::Spec->catfile( $FindBin::Bin,'log-server' ); my @opts; push @opts, "-e" => qq{"} . delete($args{ eval }) . qq{"} if $args{ eval }; my $pid = open my $server, qq'$^X "$server_file" "$web_page" "$logfile" @opts|' or croak "Couldn't spawn local server $server_file : $!"; my $url = <$server>; chomp $url; die "Couldn't read back local server url" unless $url; $self->{_server_url} = URI::URL->new($url); $self->{_fh} = $server; $self->{_pid} = $pid; $self; }; =head2 C<< $server->port >> This returns the port of the current server. As new instances will most likely run under a different port, this is convenient if you need to compare results from two runs. =cut sub port { carp __PACKAGE__ . '::port called without a server' unless $_[0]->{_server_url}; $_[0]->{_server_url}->port }; =head2 C<< $server->url >> This returns the url where you can contact the server. This url is valid until the C<$server> goes out of scope or you call C<< $server->stop >> or C<< $server->get_log >>. =cut sub url { $_[0]->{_server_url}->abs->as_string }; =head2 C<< $server->stop >> This stops the server process by requesting a special url. =cut sub stop { my ($self) = @_; get( $self->quit_server ); undef $self->{_server_url}; if ( $self->{_fh} ) { close $self->{_fh}; delete $self->{_fh}; } }; =head2 C<< $server->kill >> This kills the server process via C. The log cannot be retrieved then. =cut sub kill { CORE::kill( 9 => $_[0]->{ _pid } ); undef $_[0]->{_server_url}; undef $_[0]->{_pid}; }; =head2 C<< $server->get_log >> This stops the server by calling C and then returns the output of the server process. This output will be a list of all requests made to the server concatenated together as a string. =cut sub get_log { my ($self) = @_; my $log = get( $self->get_server_log ); $self->stop; return $log; }; sub DESTROY { $_[0]->stop if $_[0]->{_server_url}; for my $file (@{$_[0]->{delete}}) { unlink $file or warn "Couldn't remove tempfile $file : $!\n"; }; }; =head1 URLs implemented by the server =head2 302 redirect C<< $server->redirect($target) >> This URL will issue a redirect to C<$target>. No special care is taken towards URL-decoding C<$target> as not to complicate the server code. You need to be wary about issuing requests with escaped URL parameters. =head2 404 error C<< $server->error_notfound($target) >> This URL will response with status code 404. =head2 Timeout C<< $server->error_timeout($seconds) >> This URL will send a 599 error after C<$seconds> seconds. =head2 Timeout+close C<< $server->error_close($seconds) >> This URL will send nothing and close the connection after C<$seconds> seconds. =head2 Error in response content C<< $server->error_after_headers >> This URL will send headers for a successfull response but will close the socket with an error after 2 blocks of 16 spaces have been sent. =head2 Chunked response C<< $server->chunked >> This URL will return 5 blocks of 16 spaces at a rate of one block per second in a chunked response. =head2 Other URLs All other URLs will echo back the cookies and query parameters. =cut use vars qw(%urls); %urls = ( 'quit_server' => 'quit_server', 'get_server_log' => 'get_server_log', 'redirect' => 'redirect/%s', 'error_notfound' => 'error/notfound/%s', 'error_timeout' => 'error/timeout/%s', 'error_close' => 'error/close/%s', 'error_after_headers' => 'error/after_headers', 'chunked' => 'chunks', ); for (keys %urls) { no strict 'refs'; my $name = $_; *{ $name } = sub { my $self = shift; $self->url . sprintf $urls{ $name }, @_; }; }; =head1 EXPORT None by default. =head1 COPYRIGHT AND LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Copyright (C) 2003-2011 Max Maischein =head1 AUTHOR Max Maischein, Ecorion@cpan.orgE Please contact me if you find bugs or otherwise improve the module. More tests are also very welcome ! =head1 SEE ALSO L,L,L =cut 1; WWW-Mechanize-1.96/t/local/overload.t000644 000765 000024 00000004545 13623637465 020701 0ustar00olafaldersstaff000000 000000 use Test::More skip_all => "Mysteriously stopped passing, and I don't know why."; use warnings; use strict; use lib 't/local'; use LocalServer; use Test::More tests => 11; =head1 NAME overload.t =head1 SYNOPSIS This tests for various ways, advertised in L, to create a subclass of the mech to alter it's behavior in a useful manner. (Of course free-style overloading is discouraged, as it breaks encapsulation big time.) This test first feeds some bad HTML to Mech to make sure that it throws an error. Then, it overloads update_html() to fix the HTML before processing it, and then we should not have an error. =head2 Overloading update_html() This is the recommended way to tidy up the received HTML in a generic way, and/or to install supplemental "surface tests" on the HTML (e.g. link checker). =cut BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn(html => <<'BROKEN_HTML'); Broken document</head> <form> <table> <tr><select name="foo"> <option value="bar">Bar</option></td></tr> </form> </html> BROKEN_HTML isa_ok( $server, 'LocalServer' ); do { package MyMech; use base 'WWW::Mechanize'; sub update_html { my $self = shift; my $html = shift; $html =~ s[Broken][Fixed]isg or die "Couldn't fix the HTML for the test (#1)"; $html =~ s[</option>.{0,3}</td>][</option></select></td>]isg or die "Couldn't fix the HTML for the test (#2)"; $self->WWW::Mechanize::update_html( $html ); } }; my $carpmsg; local $^W = 1; no warnings 'redefine'; local *Carp::carp = sub {$carpmsg = shift}; my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize' ); $mech->get( $server->url ); like($carpmsg, qr{bad.*select}i, 'Standard mech chokes on bogus HTML'); # If at first you don't succeed, try with a shorter bungee... undef $carpmsg; $mech = MyMech->new(); isa_ok( $mech, 'WWW::Mechanize', 'Derived object' ); my $response = $mech->get( $server->url ); isa_ok( $response, 'HTTP::Response', 'Response I got back' ); ok( $response->is_success, 'Got URL' ) or die 'Can\'t even fetch local url'; ok( $mech->is_html, 'Local page is HTML' ); ok( !$carpmsg, 'No warnings this time' ); my @forms = $mech->forms; is( scalar @forms, 1, 'One form' ); like($mech->content(), qr{/select}, 'alteration visible in ->content() too'); �����������������������������������������������������������������������������������������������������������������������������������������������������������WWW-Mechanize-1.96/t/local/encoding.t���������������������������������������������������������������000644 �000765 �000024 �00000000753 13623637465 020651� 0����������������������������������������������������������������������������������������������������ustar�00olafalders����������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������use warnings; use strict; use Test::More tests => 5; use lib qw( t/local ); use LocalServer; BEGIN { delete @ENV{qw( IFS CDPATH ENV BASH_ENV )}; use_ok('WWW::Mechanize'); } my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize' ); my $server = LocalServer->spawn(); isa_ok( $server, 'LocalServer' ); my $response = $mech->get( $server->url . 'encoding/euc-jp' ); ok( $mech->success, 'Fetched OK' ); is( $response->content_charset(), 'EUC-JP', 'got encoding enc-jp' ); ���������������������WWW-Mechanize-1.96/t/local/back.t�������������������������������������������������������������������000644 �000765 �000024 �00000010155 13623637465 017760� 0����������������������������������������������������������������������������������������������������ustar�00olafalders����������������������staff���������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������use warnings; use strict; use Test::More tests => 47; use lib qw( t t/local ); use LocalServer; use HTTP::Daemon 6.05; use HTTP::Response; =head1 NAME =head1 SYNOPSIS This tests Mech's Back "button". Tests were converted from t/live/back.t, and subsequently enriched to deal with RT ticket #8109. =cut BEGIN { use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new(cookie_jar => {}); isa_ok( $mech, 'WWW::Mechanize' ); isa_ok( $mech->cookie_jar(), 'HTTP::Cookies', 'this $mech starts with a cookie jar' ); my $html = <<'HTML'; <html> <head><title>%s Whatever. Images Scripts Ports Modules
HTML my $server = LocalServer->spawn( html => $html ); isa_ok( $server, 'LocalServer' ); ok( !$mech->back(), 'With no stack, no going back' ); $mech->get($server->url); ok( $mech->success, 'Fetched OK' ); my $first_base = $mech->base; my $title = $mech->title; $mech->follow_link( n=>2 ); ok( $mech->success, 'Followed OK' ); ok( $mech->back(), 'Back should succeed' ); is( $mech->base, $first_base, 'Did the base get set back?' ); is( $mech->title, $title, 'Title set back?' ); $mech->follow_link( text => 'Images' ); ok( $mech->success, 'Followed OK' ); ok( $mech->back(), 'Back should succeed' ); is( $mech->base, $first_base, 'Did the base get set back?' ); is( $mech->title, $title, 'Title set back?' ); is( scalar @{$mech->{page_stack}}, 0, 'Pre-search check' ); $mech->submit_form( fields => { 'q' => 'perl' }, ); ok( $mech->success, 'Searched for Perl' ); like( $mech->title, qr/search.cgi/, 'Right page title' ); is( scalar @{$mech->{page_stack}}, 1, 'POST is in the stack' ); $mech->head( $server->url ); ok( $mech->success, 'HEAD succeeded' ); is( scalar @{$mech->{page_stack}}, 1, 'HEAD is not in the stack' ); ok( $mech->back(), 'Back should succeed' ); ok( $mech->success, 'Back' ); is( $mech->base, $first_base, 'Did the base get set back?' ); is( $mech->title, $title, 'Title set back?' ); is( scalar @{$mech->{page_stack}}, 0, 'Post-search check' ); =head2 Back and misc. internal fields RT ticket #8109 reported that back() is broken after reload(), and that the cookie_jar was also damaged by back(). We test for that: reload() should not alter the back() stack, and the cookie jar should not be versioned (once a cookie is set, hitting the back button in a browser does not cause it to go away). =cut $mech->follow_link( text => 'Images' ); $mech->reload(); ok( $mech->back(), 'Back should succeed' ); is($mech->title, $title, 'reload() does not push page to stack' ); ok(defined($mech->cookie_jar()), '$mech still has a cookie jar after a number of back()'); # Now some other weird stuff. Start with a fresh history by recreating # $mech. SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $mech, 'No memory cycles found' ); } $mech = WWW::Mechanize->new( autocheck => 0 ); isa_ok( $mech, 'WWW::Mechanize' ); $mech->get( $server->url ); ok( $mech->success, 'Got root URL' ); my @links = qw( /scripts /ports/ modules/ ); is( scalar @{$mech->{page_stack}}, 0, 'Pre-404 check' ); my $server404url = $server->error_notfound('404check'); $mech->get($server404url); is( $mech->status, 404 , '404 check') or diag( qq{\$server404url=$server404url\n\$mech->content="}, $mech->content, qq{"\n} ); is( scalar @{$mech->{page_stack}}, 1, 'Even 404s get on the stack' ); ok( $mech->back(), 'Back should succeed' ); is( $mech->uri, $server->url, 'Back from the 404' ); is( scalar @{$mech->{page_stack}}, 0, 'Post-404 check' ); for my $link ( @links ) { $mech->get( $link ); warn $mech->status() if (! $mech->success()); is( $mech->status, 200, "Get $link" ); ok( $mech->back(), 'Back should succeed' ); is( $mech->uri, $server->url, "Back from $link" ); } SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $mech, 'No memory cycles found' ); } WWW-Mechanize-1.96/t/local/click_button.t000644 000765 000024 00000003743 13623637465 021545 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use lib 't/local'; use LocalServer; use Test::More 0.96; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize', 'Created the object' ); my $server = LocalServer->spawn(); isa_ok( $server, 'LocalServer' ); my $response = $mech->get( $server->url ); isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, 'Got URL' ) or die q{Can't even fetch local url}; ok( $mech->is_html, 'Local page is HTML' ); my @forms = $mech->forms; my $form = $forms[0]; subtest 'click by id' => sub { $mech->click_button(id => 0); test_click( $mech ); ok( !eval { $mech->click_button( id => 'i-do-not-exist' ); 1 }, 'Button id not found' ); }; subtest 'click by number' => sub { $mech->click_button(number => 1); test_click( $mech ); ok(! eval { $mech->click_button(number => 2); 1 }, 'Button number out of range'); }; subtest 'click by name' => sub { $mech->click_button(name => 'submit'); test_click( $mech ); ok(! eval { $mech->click_button(name => 'bogus'); 1 }, 'Button name unknown'); }; CLICK_BY_OBJECT_REFERENCE: { subtest 'click by object reference' => sub { my $clicky_button = $form->find_input( undef, 'submit' ); isa_ok( $clicky_button, 'HTML::Form::Input', 'Found the submit button' ); is( $clicky_button->value, 'Go', 'Named the right thing, too' ); my $res = $mech->click_button(input => $clicky_button); local $TODO = q{Calling ->click() on an object doesn't seem to use the submit button.}; test_click( $mech ); diag $res->request->uri; }; } sub test_click { my $mech = shift; like( $mech->uri, qr/formsubmit/, 'Clicking on button' ); like( $mech->uri, qr/submit=Go/, 'Correct button was pressed' ); like( $mech->uri, qr/cat_foo/, 'Parameters got transmitted OK' ); $mech->back; } done_testing(); WWW-Mechanize-1.96/t/local/follow.t000644 000765 000024 00000004341 13623637465 020362 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 28; use lib 't/local'; use LocalServer; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $agent = WWW::Mechanize->new( autocheck => 0 ); isa_ok( $agent, 'WWW::Mechanize', 'Created object' ); $agent->quiet(1); my $response; $agent->get( $server->url ); ok( $agent->success, 'Got some page' ); is( $agent->uri, $server->url, 'Got local server page' ); $response = $agent->follow_link( n => 99999 ); ok( !$response, q{Can't follow too-high-numbered link}); $response = $agent->follow_link( n => 1 ); isa_ok( $response, 'HTTP::Response', 'Gives a response' ); isnt( $agent->uri, $server->url, 'Need to be on a separate page' ); ok($agent->back(), 'Can go back'); is( $agent->uri, $server->url, 'Back at the first page' ); ok(! $agent->follow_link( text_regex => qr/asdfghjksdfghj/ ), "Can't follow unlikely named link"); ok($agent->follow_link( text => 'Link /foo' ), 'Can follow obvious named link'); isnt( $agent->uri, $server->url, 'Need to be on a separate page' ); ok($agent->back(), 'Can still go back'); ok($agent->follow_link( text_regex=>qr/L\x{f6}schen/ ), 'Can follow link with o-umlaut'); isnt( $agent->uri, $server->url, 'Need to be on a separate page' ); ok($agent->back(), 'Can still go back'); ok($agent->follow_link( text_regex=>qr/St\x{f6}sberg/ ), q{Can follow link with o-umlaut, when it's encoded in the HTML, but not in "follow"}); isnt( $agent->uri, $server->url, 'Need to be on a separate page' ); ok($agent->back(), 'Can still go back'); is( $agent->uri, $server->url, 'Back at the start page again' ); $response = $agent->follow_link( text_regex => qr/Snargle/ ); ok( !$response, q{Couldn't find it} ); ok($agent->follow_link( url => '/foo' ), 'can follow url'); isnt( $agent->uri, $server->url, 'Need to be on a separate page' ); ok($agent->back(), 'Can still go back'); ok(!$agent->follow_link( url => '/notfoo' ), "can't follow wrong url"); is( $agent->uri, $server->url, 'Needs to be on the same page' ); eval {$agent->follow_link( '/foo' )}; like($@, qr/Needs to get key-value pairs of parameters.*follow\.t/, "Invalid parameter passing gets better error message"); WWW-Mechanize-1.96/t/local/referer-server000644 000765 000024 00000001301 13623637465 021545 0ustar00olafaldersstaff000000 000000 # Thanks to merlyn for nudging me and giving me this snippet! use HTTP::Daemon 6.05; use URI::URL; use Socket (); $|++; my $d = HTTP::Daemon->new or die; my $lhurl = URI::URL->new( $d->url ); if ($d->sockdomain == Socket::AF_INET) { $lhurl->host( '127.0.0.1' ); } elsif ($d->sockdomain == Socket::AF_INET6) { $lhurl->host( '[::1]' ); } else { die "unexpected sockdomain: " . $d->sockdomain; } print $lhurl->as_string, "\n"; $counter = 5; while ($counter-- and my $c = $d->accept) { while (my $r = $c->get_request) { my $ref = $r->headers->referer || ""; $c->send_response(HTTP::Response->new(200, "OK", undef, "Referer: '$ref'")); } $c->close; undef($c); } WWW-Mechanize-1.96/t/local/click.t000644 000765 000024 00000001533 13623637465 020145 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use lib 't/local'; use LocalServer; use Test::More tests => 9; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $mech = WWW::Mechanize->new(); isa_ok( $mech, 'WWW::Mechanize', 'Created the object' ); my $server = LocalServer->spawn(); isa_ok( $server, 'LocalServer' ); my $response = $mech->get( $server->url ); isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, 'Got URL' ) or die q{Can't even fetch local url}; ok( $mech->is_html, 'Local page is HTML' ); $mech->field(query => 'foo'); # Filled the 'q' field $response = $mech->click('submit'); isa_ok( $response, 'HTTP::Response', 'Got back a response' ); ok( $response->is_success, q{Can click 'Go' ('Google Search' button)} ); is( $mech->field('query'),'foo', 'Filled field correctly'); WWW-Mechanize-1.96/t/local/failure.t000644 000765 000024 00000003044 13623637465 020506 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More; use lib 't/local'; use LocalServer; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; } my $NONEXISTENT = 'blahblahblah.xx-only-testing.foo.'; my @results = gethostbyname( $NONEXISTENT ); if ( @results ) { my ($name,$aliases,$addrtype,$length,@addrs) = @results; my $ip = join( '.', unpack('C4',$addrs[0]) ); plan skip_all => "Your ISP is overly helpful and returns $ip for non-existent domain $NONEXISTENT. This test cannot be run."; } my $bad_url = "http://$NONEXISTENT/"; plan tests => 15; require_ok( 'WWW::Mechanize' ); my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $mech = WWW::Mechanize->new( autocheck => 0 ); isa_ok( $mech, 'WWW::Mechanize', 'Created object' ); GOOD_PAGE: { my $response = $mech->get($server->url); isa_ok( $response, 'HTTP::Response' ); ok( $response->is_success, 'Success' ); ok( $mech->success, 'Get webpage' ); ok( $mech->is_html, 'It\'s HTML' ); is( $mech->title, 'WWW::Mechanize test page', 'Correct title' ); my @links = $mech->links; is( scalar @links, 10, '10 links, please' ); my @forms = $mech->forms; is( scalar @forms, 2, 'Two form' ); } BAD_PAGE: { my $bad_url = "http://$NONEXISTENT/"; $mech->get( $bad_url ); ok( !$mech->success, 'Failed the fetch' ); ok( !$mech->is_html, "Isn't HTML" ); ok( !defined $mech->title, "No title" ); my @links = $mech->links; is( scalar @links, 0, "No links" ); my @forms = $mech->forms; is( scalar @forms, 0, "No forms" ); } WWW-Mechanize-1.96/t/local/reload.t000644 000765 000024 00000002555 13623637465 020333 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 15; use lib qw( t t/local ); use LocalServer; BEGIN { use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $agent = WWW::Mechanize->new; isa_ok( $agent, 'WWW::Mechanize', 'Created object' ); NO_GET: { my $r = $agent->reload; ok( !defined($r), 'Initial reload should fail' ); } FIRST_GET: { my $r = $agent->get($server->url); isa_ok( $r, 'HTTP::Response' ); ok( $r->is_success, 'Get google webpage'); ok( $agent->is_html, 'Valid HTML' ); is( $agent->title, 'WWW::Mechanize test page' ); } INVALIDATE: { undef $agent->{content}; undef $agent->{ct}; isnt( $agent->title, 'WWW::Mechanize test page' ); ok( !$agent->is_html, 'Not HTML' ); } RELOAD: { my $r = $agent->reload; isa_ok( $r, 'HTTP::Response' ); ok( $agent->is_html, 'Valid HTML' ); ok( $agent->title, 'WWW::Mechanize test page' ); my $cookie_before = $agent->history(0)->{req}->header('Cookie'); $agent->reload; my $cookie_after = $agent->history(0)->{req}->header('Cookie'); is( $cookie_after, $cookie_before, 'cookies are not multiplied' ); } SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $agent, 'Mech: no cycles' ); } WWW-Mechanize-1.96/t/local/nonascii.t000644 000765 000024 00000001143 13623637465 020660 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 5; use lib 't/local'; use LocalServer; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn( file => 't/local/nonascii.html' ); isa_ok( $server, 'LocalServer' ); my $agent = WWW::Mechanize->new; isa_ok( $agent, 'WWW::Mechanize', 'Created object' ); $agent->quiet(0); $agent->get( $server->url ); ok( $agent->success, 'Got some page' ); # \321\202 is \x{442} $agent->field("ValueOf'CF.{\321\202}'", "\321\201"); is($agent->value("ValueOf'CF.{\321\202}'"), "\321\201", 'set utf value'); WWW-Mechanize-1.96/t/local/get.t000644 000765 000024 00000004543 13623637465 017643 0ustar00olafaldersstaff000000 000000 use warnings; use strict; use Test::More tests => 32; use lib qw( t t/local ); use LocalServer; BEGIN { use Tools; } BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) }; use_ok( 'WWW::Mechanize' ); } my $server = LocalServer->spawn; isa_ok( $server, 'LocalServer' ); my $agent = WWW::Mechanize->new; isa_ok( $agent, 'WWW::Mechanize', 'Created object' ); my $response = $agent->get($server->url); isa_ok( $response, 'HTTP::Response' ); isa_ok( $agent->response, 'HTTP::Response' ); ok( $response->is_success, 'Page read OK' ); ok( $agent->success, "Get webpage" ); is( $agent->ct, "text/html", "Got the content-type..." ); ok( $agent->is_html, "... and the is_html wrapper" ); is( $agent->title, 'WWW::Mechanize test page', 'Titles match' ); $agent->get( '/foo/' ); ok( $agent->success, 'Got the /foo' ); is( $agent->uri, sprintf('%sfoo/',$server->url), 'Got relative OK' ); ok( $agent->is_html,'Got HTML back' ); is( $agent->title, 'WWW::Mechanize test page', 'Got the right page' ); $agent->get( '../bar/' ); ok( $agent->success, 'Got the /bar page' ); is( $agent->uri, sprintf('%sbar/',$server->url), 'Got relative OK' ); ok( $agent->is_html, 'is HTML' ); is( $agent->title, 'WWW::Mechanize test page', 'Got the right page' ); $agent->get( 'basics.html' ); ok( $agent->success, 'Got the basics page' ); is( $agent->uri, sprintf('%sbar/basics.html',$server->url), 'Got relative OK' ); ok( $agent->is_html, 'is HTML' ); is( $agent->title, 'WWW::Mechanize test page', 'Title matches' ); like( $agent->content, qr/WWW::Mechanize test page/, 'Got the right page' ); $agent->get( './refinesearch.html' ); ok( $agent->success, 'Got the "refine search" page' ); is( $agent->uri, sprintf('%sbar/refinesearch.html',$server->url), 'Got relative OK' ); ok( $agent->is_html, 'is HTML' ); is( $agent->title, 'WWW::Mechanize test page', 'Title matches' ); like( $agent->content, qr/WWW::Mechanize test page/, 'Got the right page' ); my $rslength = do {use bytes; length $agent->content}; my $tempfile = './temp'; unlink $tempfile; ok( !-e $tempfile, 'tempfile not there right now' ); $agent->get( './refinesearch.html', ':content_file'=>$tempfile ); ok( -e $tempfile, 'File exists' ); is( -s $tempfile, $rslength, 'Did all the bytes get saved?' ); unlink $tempfile; SKIP: { skip 'Test::Memory::Cycle not installed', 1 unless $canTMC; memory_cycle_ok( $agent, 'Mech: no cycles' ); } WWW-Mechanize-1.96/t/local/nonascii.html000644 000765 000024 00000000622 13623637465 021362 0ustar00olafaldersstaff000000 000000 Query Builder
WWW-Mechanize-1.96/t/mech-dump/mech-dump.t000644 000765 000024 00000005544 13623637465 021532 0ustar00olafaldersstaff000000 000000 #!perl -T use warnings; use strict; use Test::More; use File::Spec; use LWP; BEGIN { delete @ENV{ qw( IFS CDPATH ENV BASH_ENV PATH ) }; } plan skip_all => 'Not installing mech-dump' if -e File::Spec->catfile( qw( t SKIP-MECH-DUMP ) ); plan tests => 4; my $exe = File::Spec->catfile( qw( script mech-dump ) ); if ( $^O eq 'VMS' ) { $exe = qq[mcr $^X -Ilib $exe]; } # Simply use a file: uri instead of the filename to make this test # more independent of what URI::* thinks. my $source = 'file:t/google.html t/find_inputs.html'; my $perl; $perl = $1 if $^X =~ /^(.+)$/; my $command = "$perl -Ilib $exe --forms $source"; my $actual = `$command`; my $expected; if ( $LWP::VERSION < 5.800 ) { $expected = <<'EOF'; GET file:/target-page [bob-the-form] hl=en (hidden) ie=ISO-8859-1 (hidden) q= btnG=Google Search (submit) btnI=I'm Feeling Lucky (submit) POST http://localhost/ (multipart/form-data) [1st_form] 1a= (text) submit1=Submit (image) submit2=Submit (submit) POST http://localhost/ [2nd_form] YourMom= (text) opt[2]= (text) 1b= (text) submit=Submit (submit) POST http://localhost/ [3rd_form] YourMom= (text) YourDad= (text) YourSister= (text) YourSister= (text) submit=Submit (submit) EOF } else { $expected = <<'EOF'; GET file:/target-page [bob-the-form] hl=en (hidden readonly) ie=ISO-8859-1 (hidden readonly) q= (text) btnG=Google Search (submit) btnI=I'm Feeling Lucky (submit) POST http://localhost/ (multipart/form-data) [1st_form] 1a= (text) submit1=Submit (image) submit2=Submit (submit) POST http://localhost/ [2nd_form] YourMom= (text) opt[2]= (text) 1b= (text) submit=Submit (submit) POST http://localhost/ [3rd_form] YourMom= (text) YourDad= (text) YourSister= (text) YourSister= (text) submit=Submit (submit) EOF } my @actual = split /\s*\n/, $actual; my @expected = split /\s*\n/, $expected; # First line is platform-dependent, so handle it accordingly. shift @expected; my $first = shift @actual; like( $first, qr/^GET file:.*\/target-page \[bob-the-form\]/, 'First line matches' ); cmp_ok( @expected, '>', 0, 'Still some expected' ); cmp_ok( @actual, '>', 0, 'Still some actual' ); is_deeply( \@actual, \@expected, 'Rest of the lines match' ); WWW-Mechanize-1.96/etc/www-mechanize-logo.png000644 000765 000024 00000114117 13623637465 022345 0ustar00olafaldersstaff000000 000000 PNG  IHDRaQgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxbk#vψG=#A[Fi?'\jH1~` ?X F3)22T T .TTIG+Q0 F_80#}Ύ:h4i*.\kJ:7L/i,xiXgcn u/Mddce~jrjZxʧz02?^PUM3Lfg3_8 @$'@k%mơg ?B;>9'!6|[dG4"$ ߪ-vźB H_  L39 p/8Hd g)@@_w Z r6MSPts)c0)b B)$/rGӫ}qdb4%3mqM#h7 qc@GMSA) Di0*εj ܻy@32>q;@1D'ϻŷs}ff&7~g`,$?a.#j1_!c-zoTsz}Ep?#\=RVpM Hr`>$ `1!nX k=x)E > eZ 09|R@u¿AHB f= ݳ&< XLJZ!b 9"_#cQ Li@4 + Hk%)!2Rq$b ZIl]1 Cըa#uqmT{I(GQf}z̙pb"e@-DFZĠ+=$i?b )ߠ:p"C //!P⪘Bӊ U̔T(lX~?ޠʘM23Bff`bffp|u00FE$#LQ'Tt"FLIM z.(ZUr a=Xʜ?%{H2f6 zXE ˳^_ Ue~_[x*DRA@F2Bf`0]7c&+ ?;;sq0pp+bP `eHon,P62#Bp0?,\U0ÐcUhϨ71ẀOрZ]L˅h.2T0 VrLh8~;c;';B JX9+cf5|8B-S<\=P'Yt|{6bP*X.R?J?}csYdԴ. bz4ӺXk:#r4[f cd H+hP nWgA+D01 l31Vnl5C;`vv6n+fVȬdHo2f9LXjh$[*Vl!#,r%2>R#A~ n.I:&ew_Fg5/ e3B=hH/47r 2B  XIx";B+`Bn4 XLLo.2rqs1q3ppa3=ePe =eQ\1b)) ZH&׈׊V/ZIWh9ROU#9D_0# :31h+"҇adK>P+!!2 ?@*_/p47_+?D {02b@x +Cb[[)~=׿rrq p*e0D-+enN<3+ 3rf]y11b/Ph 91bIz)T22 ;t.+U -=b_i P{Ì Hu3feA6\GOiy5 Flk2"z0ߠ ~昑*hp?=s-o2|<~ZAUzT)*`3@&A3i x)z&ȥ Ҙiq1l 4 |WQގhjUl_6zilY-Rrdg_}bRce874Y$+ŀ~CHCtv?[KACI_Q/U-HBQ~Ḽr@V3PrYY@eLZ!E}ͩn- $@15D ^G%겈W3y5OX!+e z̐lP`a=e&FFzSfZF2)#EYJbF-B_T}jO?J mS0hT!A gz( 76nĥѕ#o7T6lg#lTQz[1Gca6V 2 Y A;x0+NvhJFaҿHlP [h!; I2Rf23-\C+d`/O4 -bbP{ː!lfX)L>D?QV@#oaRo<%}VӰX h(fb fE+h&Fؚ&f6]F ׷fEa2#R=ÒȪ޲h&fh^`E' ^ VҠ!m6dRfa2|{#Z^)chfBM8\|MOre6wX.baو<ȳ=ZWM ž Nv ŚqBv |} kU?*HG?8g06+3 4o lZO2C1RMQ ^i_L3`C >h^T)9A{!eИ? Rf,b_;ƆlD&'m3`~&y=/q"x*i41 و\A PWu-,!_EkH3St#9tb'z3ghp j> ۹<%H~A?? 4m 1C*eQ-gB?*flۈ"9fB_~/^17 A[882h>ΌW t/d4lܔԻ#&Qǐ0$3ֽȕ+#8*$68FRI(A(1 7I8GoT`6%LH= /h?(h匣,]7+fXڅ^Y;} ^@a;| 3A0F$f|3l_4Og0K K%̀V93!U$U;{A :bSR.>qtLq@bK!յ2nwٹd^06i \ rMnFA\-Hk_x}w8qio6~,P;;!i:TJ!kQj߬_1Y`ja/+c8f+gSg!uAv0 ftDZ+ν4YAyc=V~֜0w-9@C,01ny31t쟡T(?Iu1 .5/SjZZ*B. Gv* t'z/HZR_?@: Xh t<.>6TΡ!lX Yuw^Y۱:g{;Z2f~C1OyX,MR[+ $|/'[-݂5g.ˀ/ĥ+, mCKꡟvxf[婩Ry(_pw- 0 P e S/[t B2@sH*3kVCɆaO|1}Xgx], 3c'2' qiGy`HE+F#j*0b (EIy7iu:oar=(Pkͤ;hV $ZTY˳@>6oQL,8@3]JWK a_*z&.YrPPVA%z,}N0!J5? w/`KMX1MI;ڃIϓZk7EB#_EUSkm=cϩOV o&ro6 LS1asӬt\jbq4mڤe t8p<o' ^ fLi)PԡS nX+i>֫<}b;n׉v!ke[ #&` f =Go>a$:~_AtNEvGLsf4m%z\9|G0Rp 0[.ip zཷVU1D.z^;-ygx]M2^춅Fe4l'黮Ͽ ]Qf~*q1W^}݅Hۗx0K63A%.Se4{,<甭ִ ׵TC$`9mvZ:%WjpZ!z\4KW\?bٓ?+uGX8Dw>祮nJڰ/qgF#T{X^cب%9'Zȸ V@%j@C./P-S|e#WuU\!P@\)E;cg$2`*LaXb n^@ٲ0{!9a~#xu2GP}+hm"l"4((iEmzЊPEP% = ""D/ zVD$(YJ&&E*FuN3%dwg͛p2;Fo>|世12s@@n7, ahZH$D"@FJ_O8}~klC6;L&$d28ԋI b1i\jr9;|>PV$ЅaDwFe$+ݟ@uޖ5uYdsPm sq2›$kmnFc_pNH1SĽDҮ̫ѳwbJcaݔCKQ*"nj{B-[ݗJps6^}Y <7\PqŁ&`<t0P`ϡ%pV h C/%6xCWW7 ђ?zQk1?r yn{V1#7{HH22Kօ5)y.7~&x JXeL)0=4cfvonsOrlvvvs0XI1Ӯ O gW aqd%aމ<JuAW. z>3\Bdy@hk_c- "eʝzyqY!!d_Z)yhgF}1Iu Ie\P}GLNAemnsfmn^/[sP4-C#wK PXiIVW`>>$vm!Ki{n0EwG|>#YJ䴡N9ps}I)sLJ 䭭MϪn65mFA09Y\'FF4p1c6~^;l8ߠCFTsk9Fӿ~Z]P]QҠzb@ 1sOqC!#ŧ99u B4WAgv[2j"2^^0/gKDQ2(Kz?0d gr>l(+|{(yZY5l׎wuZ' o~z[OKpkD 辠@SpEzhI/ XJ^cPJ!4V܊53zl pfӍ|Uܺ1&͖&n3+o5;[r*wJ>+gDO ҆")EA4(`|O㓉Hb>ᣏ&MLErPK;춐 MeI33;sΙ߬lı]Ͽ|f}!O/d״AmCqYR6 (~8 GU['Tu˨DGLJQULKw̏{PǐžvT"{h!QّGY!kJr9gP܄[JKP~=׌X* pRu&*E6\39|4yK/͓02y)c' 2}p p+[Ze~ޜ~zP.c-s3.,X_-yȏ/o%M qru⅊@x-}ߝ3,o5,c|c}i-e~*K6lw,zV.o+Ng0J ޭe+h']˥p!gMg&m~#5ɦ_,\;Gθ8NZ:Zp&\Qc;6?.m+aC?(&0!jJAbXO/`L#&c$&'z4"@) `l! -elrhٙfnQV6Koݝ9ʬrKsLg2i钔Q_Yx-D|2TAijnXYUňnv!G)ZjOYUl_+iG2Nי 4-*#YInO{Wַqf9<Ԧƌg644pY-9]XijL.%dv3R+_!|_LS[n^e-\$ԭ877 ttkR9ua@];iٶIPPgsn_ZW12CC>,֤H'jrr  3hW'٣4B$9ȶ>0={d0>nrj$l?@](*Y]pW(x|`BOh.=.] E{t9I*X\,Ct]jB-;|?D{uZֺF|d#奺Β8(??=y.+P5u}N&TaǍ>Jss[fi=~U$b(6600p+?O8Gbi跰QaD0eD|>3?INel({o['؞b' 0띙h&K+ 'W'kxĨ/@یޞH»Av{a6׺ԍ}OX餍^ Px/w9dPI: [t^|Lmx?: Lv?/`Æ b$HҼl5'%]z χ!M3ntCNY%JZcW!&.ӛLyl=_K}OBfϢ"yEMCQTmF=U F06 0"x,)&A+B#Bط~k>S!Zҁ`I ԡ3*#O\;VB/FU 25:/h37P=5bbB=_ N/ذҦo6ZP<,Vb6rXՃ2÷?<"I\akܺ[6m| $AxWW[?eg8~#d(TUܺ[*ls{3;1wxsq#<@ }b5)`{R YXofQwEe>YӮ9[̞Iplm<Ϻ4,j<]8k9E4(ka!R 2ŌKIuZ/p\3f\LM~]ɦYC]BT~ڬiO*E̜|*}G{o9!h#qt\i^b0bq!1."L:YզZ'%Ydp '2.xp~UdW._?(]23g!qY i[<:v3]qɁ SQJKAF1{"R)jU_(玻[usHt (Ð.;|:BR[:fhO($(|(".\ԖqYOĦq禚ş1]v]PZSH Vw܁$ ̽^wwtXl&<(eaejGPؔw.kDp]uF $ئ~\- oeWfQm៱y'[{BE(iG]j>qodw,Uro.mem϶gQm}]g7EVf5cz1/Fs\Y#4ߢYFF*F#x^w s7 4w8XDz^W/.Ⱥg,M,[M->xLvPV4a:1{R˸u,[@z*u<@T!r׋)>{=?S\J|B![|Πg3| EcےUP 㽽7豙_څÅ]7zdž_E %FК#zV^XVȍ('c.JRd7K@.*g4z;?_Gۻ"3b~J-l4mٯg.1g.t <A`C}(*;QPB@K={BWD};L54=Џ>e gYhkU;fU'~sD鳝=:`-P< †O[㻤F>j0v}MAKL+b-҆PAUE(K_ G>ZPI]rkٽ\penvvwٽxŇx^ޤt] D1 '\Q!n+Ou!dXA͑fRNa Jf;ǔtQ<=l좼P)SOdxV~Eʊyj|T~(28(;Zrݶ"!Ukj.G޳j>?RCh+QZ]Q `oVҧH:,2/^ΓgD{u> gwTAśL^3声ffw鞰6 `&e Ttf:` ۹=gWiKpPdcCtK!|+Hf _ckr,Herq15%tأf^8FN󗯤Sz ">QjOOُziUjثwȠB߾{_+&Wv2:o8a#l39}R:TA{ury?>=פNS1mO XGv4,MLvyd>%d@͹b3풆/ee vfI{zw,%kO:6d@uX.Qw`cZvtF~r!iE^4(O=oCmLg(' 8c@qn6E- +- qZą q!qx VU[v4Nώlꏜؙfe1UXS=lD| mc)O?{Nֿo2L'l4?Bͦyjx4)1>ah ˢj">b[ZKx]mkEBKϒNзTzGS"2: ٖtPP4f޳ׯ^,x?j=e9?D隓Ӝ’܉HTH#1I-@FB h\{A3.*:UF `g:"i/5M:<~:\4z-ww Max̷ccۀE8^x K?tT Ճd/횉 =qԘsb P%\woAA4'@*ybw]Ŭjs}\MVms/e4iS7IcM[BqS/} ހާx-\Uq*FV7:/vNEU|f>ϮZ@9Z!+.۳ Y>sP_Oq`(=*f}d &7NpDhcTh,1EQT-Lp\aDk'h4lå_֘^6`G>tB޿yd e`YdžRsVzk_FW=Km^PLorqF>=mhE5_.:_ރVojeyM=d̀}Lv" zl>̱I&=[VSpӊ~Ԅ`4v8֥Ҝ%򽬲Z) 4?w rJ# 2d@bV78*KkWI)'cL.v&f/24-0z9S l^<a10Z>v 2!c{?1^<h@ėůj<͟UA溛WE_iȍ5$O oMkϢ_ WOөe1ƷQE0N uط v,E6DW4H#j A@$:*%" Nvy>'3KVd)ݛ7lc֥3 z@/U)r;4*N<̎<3_49&Bk}t&!g*;'xOM31fVD5kS1'&pէ*YeZMb5c!juNC"ĭ%VDuc=`t#BPQ['؎: KGW/^p\;=_>M2eNOl֢ݗbsK}o-<|Do>Zw](U ]}J^ UĊzQCQCzg#O}#7{5ΈRjQ Ni3oX40lJ($p"^JbDYώ9/ "Mr)c)O9Y?tuĖI)b,м"NnMKFj>幧"qB9lE6~qy-&3F ލ}~cvH&iWIסYoBOt6skRi#02VmlD0MH 3 .6''ƣ4⏽z7c#ΓgcEnmx.Ѳy%=ۼ".q}Gpsj&˓}ό ?lu_(#ΚRg <B >sc{ ,qH#ͨMDz̃\J=K눃ڲR"D2o{woRբ8e ٕR,0CMmִ7 JG9Ճ O0$/ftu#Yy Z̋}܁-Y9r#lg^k''pTR:׊Z CeUs_ nCPsg|􍮬g4*%l.k>RI$ETk٦@ |z$D Ua~pTUA9_ 7\»7/N8`o˘*`jZdڴŴڃ Jڛq,?P^R$q$xP?4*)Imv3&dh Ͳwvgw&B(ۤ2~6]m2 73(r f"O PyHt˖ #1ɽ 0j[I>xUj4ˠ k *pi+==)EIzWA&`}0m(hфǭQxnXK+~ ^N=2EKwp8wo%JwUutΒ`I`OR'*| T;l_(姏zgfDmfnN+M4hw_#l g7^C!0x^Cvb `f{v[@vxt3Uұ1A*3;4k*&r9,\\UAC%N_QPz\,TDvJe|A^ֆ8O׆_?RCbC(#T#CCcCTv[@ǮMN:t/RD6o;698DUW3.8uȶr$obT62nWO' +tvݾ3!qU(lvnݼ/B zsdI-0#i8߷ _\V l5"`VEbf֠ m/UE c7AyX]kSQ&6%`$ɐ .]$".v7 :iU,JF&ĘyϹ&6yWSL};;(bSi$[W wPy@/ Yզ)vJ-&NjӦ":7=UEM˦6Mך2DM]B>gYBv\"ORtf~RQAu5* jr^ x9OΠ.ZtN93hz+l<6;֩'I>tsWŀ7 bgq6*.O^D|jk7a'`ܛÏKr ΰ*QRhE #+Ɨgx(](ĩ7씶`5h~&d2)bo[7(he0ED1p\-"^tܟ,ԙՇ[]T;DAж p`=_h|?gp?9k43%"\pa<| /Ž*+6RHb&m?Yz'~GTI&"$`ukn"}52Ƚ\)3eI\5{,[Yʅ,-V7|-m Rٶ)R{NtC 20y0Vs)lR)oNeK-!KkC@eghGN 9`M  նiwזu~기wI+/Ucxvkdרf㗧j-k4ωMĈ%* C"H1 ufbdg`ae`gfd@ bA$D[q:vwދ"K;]c{EQFG5PcH&zs\ qp$14WKULvY}ˤ;{}X/) ,TʦRS|dVUc]cІUy;%XkEfpn~&`w9 2߳u2¯mOi7d}%EQ 7yO8ن# "_C[l(-^נgC#.=ʛ7P|z, z t>C0T6K'cigЧLf# wWo,q|{ K!:E\WvA46FD0suaqŠ/stxob2c"t(ƏD 'nXH㕹]&B=0 9 t]Y4N@kۡn9zsUcF hm\;WwZP,> c)@P96Qj>?.a5Z:: e`^Xw=T: TRkJ`[À@'Ohqqz,f)M&.fqx\,Tj ST1fe]KkQ>4Ʊ6Jl((ڵą_Wn\J6 n7څVF*1apwi;m@3w{wZ[^ IOELP7Y;_ {RUA۠!UdW(, /ζ)+)xMQubF-kQq 1TCaOV&yA(Ej|8~Zk3MLΫhr74bŽ` r:0<:q 507D1VL%f:"*J  ;LF vᓚ3fϦs6Aa~6ƞըs<,f$E*A~AϜ/capb?|@SZ%T7׶(Qz>ke:8G @?'uQ:I.]oǶy*fX<*-Cf8m_9NMIVt꭫EfgH]ryuC1ջ}ԍJ♕j]*è,HH7 UdϝYy>/!ug ao%gnO7rG޳#j{sb:7GYjFiS=&T5Q'E\h1?%KZz3v%il;BⒺe&@xe Fvj?0cTZC.bvMK8:߶mjR(]T`ϥR`=,RؔJoseԲ 8BLDDgOVS~"I}Q[@lp11< SsDSZ١nV-gkXSǗ2y%tl̺Ŝm٦?Q3`K;8 KԱJ{B_gvMʟJ)lilSjٷ2b//v͚٪pB,S\PٵYH]p썂-O[kV#d (+0 6D5im,Z`h{PP(ӣWfsP z" &VLԒf4$;q73M;mByo{o}/Fe:MCp5b  'hIlO+ց.̧bKzI'޼]r97"J#zFӵ"W7b+&(9]T/tCXn|eV1޺?RlZ/Z_6Be?K8b#JJ4j#ꖷߧ]!\ }D[)SozT;]~V ,e:r`&Hi/['_5n3{.mC}GyąY S6›T6&i7֞ Y*Z%"f ",q"P%7Tv+UC@vZ2isg{WπAh` xsxǷ<+0;/!^}Ƃ7 jK|~'lM A)eL)]ᄎV\ץ TKC SRB"WGr %/Dˋ6o.yܯ9J%^_ @ciK_'tA/ш)Eb2&>i/ P,J(ΕK ,8c|]1m"o} )hT H P*@DGPABJI$31oݱ3w ,kmff߼2p4cV'rpW ϙ'Bk+rLYjYs1K^kfR/$5>E0Ӣ"Hm-&ɨ|N b 麎r K[4RQV)1?nSzS3[1s,"F~z,i.D: c TR^8ԥ}ծ;$ea`)/{QsV  ߁])Z־ҳZ@,-k R,ݬCo lV`Dɪd-a׀ Μ"_D}(C*cko`מt=h__pX-6]b+hCLFTcq,6tֹgRq_QHQ~oy80/J"@A I{{8wރ;TR>U3y߭gk#2,90MR3u;**V6@S8+OL8M p뵊v ñ26/IZ+ѹ ȱ<_bwgZ 0JTSMhmq6)&C5p"u&ϴZ EΓeo>}kgivKg xvKҋ=J&&s#բ3 9ga?eq\]iԹ]_kArIZ|Q >AD_b`TBFy6IvCȑ͟(O/y=nu;A!Ga@x u$tpsQF(u7t[zH@%[R{b+I-6N?r${Җ/c߽l [v:o=ml !P>(Ɨ{Cqg Q~syO+ yg 씔r~ L69č5n{ BՆ/cLbބ3&a&l[kί=nJ֐EXP:@$dH.%OZFzI [Cm1qBAkU.d}7RLMT չ&|Oc0qfx5< RՆGXsLfTA*pz3{:yllmm4+$=xb{UG"ql1=v=Ͷؚ^:QŃU|6«CxTg^t`ՠqlf}8n$bRxW+ʎvŞR)#,mш|İfު/c 5BR*fc=9_gj-O7_cT(f݁|>qa G:/I3Sfu),4Pmh#߇O4Eɪj (zh"Ы3ss+ιsf7C.&."ۡqdΞHM::UC13\9B4Qk5<.AB \nKv #@F[Ӆc97  3FK("kqGL_MiR٠.7[NQ4:$z/;v%h>P-? ZKXlV` ]n۷/w"ӁYb *ݸ ,|{z)xMpñ/i%=)J2 KQ9x7qA€. 22#C =h~*.d&=?Z”~2 IX pXdNH'MA.Gl)rd2x-]c,J:ݝkm3p >>*"BZ-#A1೴GB $iF뤲9)d2 _0Xmt8s9 dkM1? ΀Z>3(Jpe5JaҌqSn:s$A  ^>[Lڟ̌mD,a`3 8s"NTQ@eՋ-i {m: _ߪ eO,EK08VUz " Ńtw٣ED},ˑkdM/2T{zH͢fG{#mWDv-Q)4Fڒh"VH$GϞx\*|-Τ) %TmV3A nuzd; ]u؉?=p~z/21As0R[w*px 98g C~ wrJGCPdn#av3k^iI޹ @ \.77=;OeܝVPb N;#SfXA/`8]ɼaAPv'ᠵ Νh*ǴvCa'ghubE wcA8s!ۑ?^$&=/ud9Upޫ$ó39f—Ϊv|>}NeY)Nq]bsXAv)[( QrN1k y>3W )f1C&[ʮ0 ?&T*Z6҂ZCXlANBC3h: -hD#CLip$9K!$>>=OzhZIo$w/t)Xfd@e *-$Җ)ŊPNQS jye /y8-/#_|^/:S}5b!P C?y\[8_^6L=$""^.GFYן|/Zd`*Ǻ{Me pfU]̔_;A[jϣPS6.8v]A˧8~,K7[OıADչ2{D⭰A-bh"غ1i}G6nYc'avwPt"E=}'IҘdq9/7K8\iZ̩p*]pd8eAw51Z=^{iu_FjK3.nԯAo慽G& ֍pEN/DؼnlB0Ө2 ʃ?wx!Icfl]ɘXW ֗g"`0Hvw [:|4+~I@g֜$n3yLQ$Bǣ@̓j%X\\Ph al'LE,tuLRY;D`nmm--f"k #N$]NiJt5~o'Ȉ\VR}O,dƲ_z+)հdoH9 x=:uTW(Tʰƺ&<9&*}) hƮKY?F,&&o&+ *5b'B@&!*gݵHoD}7Ea\/x G{v T*/p`_={Kt*A95(u+d-X'7Re IC; fظUas+hT)C w#Qz@AkM V,d3`J &3D͔y-GT3d;{ !ÃV*(=PBla I0} o JCo?|'/7'^Vo18 m㯐#5x #`0d虳\9V27aɆ#`@tcL^'R&6`ًw8{eB^]]  4x.~~?DP% bZ511{x >1~貅T \UΠzQ ,lD%  yzhGX*]{qV8&(6 *ERAQ<b*KOѓ` xRJ!'Aг-ѐnllK M[SCw&i45vyoޛMlj'~ϊdSd EEwsKrkfڣbXY0z证 +T`B0qf-㙭?M/Ӈkl(.2m8=ypkCQ[Ru]kYR(Nّs]2> *6aY6S9gp{.gyȻ7RҵL\+Lz-6oٰ픈^=OO:bcd$gS?gq?%ԧbcLOʋ`:[AG!-8W telccu;uGo )B!;\uul8#o^$KV%1z~"L١ @W0ˆrCذOQi>GfegӔPYBfx8ש*ex< > 8/e()^bR󎞣p(,,ݛpe< +G_xDK]SCÔeeJWInq I_ӡ9*n|Lz/<\ԄYpQ"rxLTC }}\ h~z,f  wz?K燝7ޫ3 92By8Gy@6eєQG0KleCrzHݎ ٵ4FGEZnfTHF^R2`"XѠ_aATB/QAgBd)^j./mڦt=m^c۷=yys3+C=A:>v|W 2Sk5pXmpF`VB.;S.P!#ddHh{wSش-PfҒ NHH( pމS|AE,~0]LM0£5;PoЪUISF&$&+=?/^{m=| `WOr}!H@-":A73u* Ez =g/sSaAkTHNA۷z|풜 }#wmFxL4'PfUN(Ks*1q+d\qolE3?356:2Ab4ۘ*&P̕WjJD+݋ae(0n0;W*{lw=E&& 瞱'0{D (+Ӄ)nۼ2B@<=;Pv-MDQL&%"v碠VՅOJʵ7BEDtF҇Pi5H*mXҴ3gr&m:003{EBA쵈;}T1Qg#DlHƢeѰ,jeMZD;PiQ>|'\=T!r@NȐ _o~Dv:Rz\3zG9֖wc[U3]" ARp׬S e]x2 ^MA'w|hpAO^/|X#s9#kFD:793yn]σFu=$ᱼA](AhVJOgr9YE+p8fX/{ƲxPM3.rCLsz28INk.9,rzZ1b`y&H [AecukɰQm`2 SEÈkGogI,R?IJSW-pMv ~?ZZ8flψ]kA~m (x((bUxOAT<A(񤅖^ *VCP,9x0 ZERj[&&yogvgvv}{} J(/+Bn-L^Vª5J((h\en$pPHBMb 1~W0K;9 ]DFSg" -0pl:A_%D~:BW4طfR{pipcM!yHY'\c_}!<59HoדӔ@P@[T1<~T}K8q> mg~PgBl ̎swV*KuÞu@7m=g/aǪ;}yX>C% gtL,]'JFFш0I &4C2q՞9μSE&fCO8i`)mV r ~{.ȍd`Uj-d]Zd&ą|{qd&62hEZ10,o`DŽPZ9{Nub= $yQ s|SK5Nj ~ -xFbĉ+4$dz{#,nU"Vya/MC;iaMR.+>7[xA*,aXCD;vH"(E$eV)O!<2 #{KhV~@f&GfT!6,3 %YZ# Gkdw<:%PnCu#wb{&i`c(CJ?ow=. #ggA IQAF@FTQl| B_l @+ Qbc7f&d^2L23™f^?<O~&?PI[ z $Hlv;/ j0lY_lné1]=Ök'ހz%Z0 GӳtMKw=Y^݉hmsH_#}X+tA_ozc=C-aK&9 AA=TvujwڎdU# ( F#pvVg+X ) Ј](DLS>KgҨG?͗@(wCS33+C9/s> u9m)R"!`,S,,H,< HH6Q;bG%͐Ċc?wɬl/szm{j2i6PG/O΍TSKRiQb眱Ki%cnxS-ccg=&PH~rBH'k2(?di7i{ԆOK#c ˬ-ћhIbU޲TQ뗅m `Ow]V$eqȺ&aQ/qpnW֮d7 *".G\NmRS@DBThQ zC(RfɌͯ.l޺ؒw'O_ku;մe۶xtt;wiҺJsb (0BP(Cڕ.K ޗU ڻb@Ȟ@}6o1=4P)əE83)s:D}qf#1L0 rpKYB-w:p-]DcE\|wAۃ{XIY 盲4C2Dșj 0taW@b_V+rh11 ٮ7?r&9R)Č^I k {J0thl܂g=ĭE4|*9 S@?7ame0[IaQ{Ƨe!i[|̣?hva(۴ ;|o Y*Hy_Ư؍J>sboÖ:~m̕?Dnvi?as>jpC&`"i ɋ`ݳf MV{QA_бhY҉DATxv\'gY0*wO=-0K*mGZX'1ޓ)؅D;'ٝ iQcxWS{$f'ۧ58[b o8zfi4O6:Z=>4Ppywo8Y29ܩP:EHNc<&#. Jj2EV=@ ) ΞkT8_ s@rAtӤPi:|k ^×J\!0NAY.0OڮA 2lgba'YYXc&h xb޼z9Ϸ(|,`Q\|} -/ڹAc * i = ET%HvГ9m,9/1qk@G[*F8ЍԪ(C@'@dҪ)=␎V^'<֠B`~}4:ip 0LF; ^UIHU4dj찆SۿU+6u=Y&絼' 0.2K0K RpJ=-\utʃ|`qa`@EE L x +[h5N'- [U5|^2'ZŌ\9< ػza(B م?cq&,N$W(oi.$wy{~V6|͊dYdUuVfы;!.2M)D{(YS$[2~A6eG#j…i3ntR}Z#NT7A~DW"1/Nd=Cj|a[ijʕCW!,hnW{ub4DŽSM5NՇ#K7K:[CO h_nbNqq!p6# g Tegg_X$Yw"ܕ3CL` PFj=FRHC۰mUCbVo7ßWȰŀ У3!U9 s"ɑzUȍs5_=ۖ{(spOx` -|ڶ ؇!a"?zf􊙨S)sH@qyOls\#CL$  dK "E("k^T8޽R΄tʝoKmWÙV[`8ԁr/;pUa6o\Kʖ`m~(OsKTJOH5(j'P~ z5=Q3K3b/ma0 E`=c~o޿7?~߿Ͽb̪85QW2&L]̃CQ RFۤiV2TEy}U6JV!WQ"[( _SE$/T2xi?Ȉ}/j?G{ɣ` S:< w)C+`  ľ1 +OkV !lF&&ƿ?9mV@Y>_e, Ll¨{{+Ƚgm4!1,#aH(H  @^e;% ћ^!3[e?$ hCӈ,|6†Pp1X^G,a퐌Jya~u3>/ћ?*gdu2z bz^/1kaVl~V~j\Xq;of/F&vA|g^3rNjy,NЌo{J~SEa8!#WQN¬1!Dg@o, ]DpQ&&&k/߼ϟ3~ 23331r|Ϗ ~pcfdb{F3f`DG,BVqjN?JА6jBSOH ۖѫf}vj#"F(=3|ʰ5+a]J;F}Y[@ XUf^6|~?^3R2ro5#e]&޽X HhgFP+E5gMoU܃WʈRy"*d7и{\n~l(`H.iWZŌ<\9G%c[[Poիd???ӷo?C,9@^0.VԠyhFT9{Y]s*.cVhR#ƽhR][S^rY?IXSNtZ7k()G {-堀\Sbk5v#z 0AxKC?^,-U4{21,>Xx'etY{:u!FxfTOg8gA8Bk2.g#ָ0B"QMw7/Tel6_6~o5?n)5C>S(> ϳ΃~=hbWϯN_Ot:(,?ru`V8 {d ί6PSCo .'vΑ1;֌w> Ff\ !R[YWg5lʖ*NjzW>]u{C͏-sV\tWSKdǂ10۽71'7C9)8DtʲRoJ<=Nxw.+@U?V̱2{@QAtu$?C5 gd? y wOfdaW֘/QVJ z Yy~;u됶V×Չ>F: ܵQ;A6W QPQm&RA&] 61xcNX(4 |9ezWʶAEDmh 6NrÏ lhP6jBn6J+ɚK#~!SҴ>@yy/vEc2)RVXlm^sVdҫy3~fIE"U= S|̻UTAW^xv{؃{>WƠEc̠JZ93Ah`"nyݣi^5hn3 wR`[9CKW4[l6E2r =;XL_î!m WgG%9+wzy3ڐ%5S\@kBFzʦ5%S69hޏۂ҂5R؍xTTVȣ`R+gl.!>M+d V̠^?0}z1ŕF++iXE-&&fMS7|uW>T/_?>}=Z)Q0 H+e\5+d pV  P%׮mj\Q*iXE +kdGꡍi ^@R|MkF+Q0 F921hrͣj @X+f\f`% }cضj!J[*$%Er'?C} ~`$`G(Ԩn3@᭘{o~N_@ZA⪤qUڣƍGXbB` 6]*fY1#Wί^}\zv /^k]UGNY%IlE=X G(õ"U1Q3\t/7o>O09Q@5~&F|oLd? @L&Q0 :]xh!`)51IENDB`