1
package Test::WWW::Mechanize;
8
Test::WWW::Mechanize - Testing-specific WWW::Mechanize subclass
16
our $VERSION = '1.26';
20
Test::WWW::Mechanize is a subclass of L<WWW::Mechanize> that incorporates
21
features for web application testing. For example:
23
use Test::More tests => 5;
24
use Test::WWW::Mechanize;
26
my $mech = Test::WWW::Mechanize->new;
27
$mech->get_ok( $page );
28
$mech->base_is( 'http://petdance.com/', 'Proper <BASE HREF>' );
29
$mech->title_is( "Invoice Status", "Make sure we're on the invoice page" );
30
$mech->content_contains( "Andy Lester", "My name somewhere" );
31
$mech->content_like( qr/(cpan|perl)\.org/, "Link to perl.org or CPAN" );
33
This is equivalent to:
35
use Test::More tests => 5;
38
my $mech = WWW::Mechanize->new;
41
is( $mech->base, 'http://petdance.com', 'Proper <BASE HREF>' );
42
is( $mech->title, "Invoice Status", "Make sure we're on the invoice page" );
43
ok( index( $mech->content, "Andy Lester" ) >= 0, "My name somewhere" );
44
like( $mech->content, qr/(cpan|perl)\.org/, "Link to perl.org or CPAN" );
46
but has nicer diagnostics if they fail.
48
Default descriptions will be supplied for most methods if you omit them. e.g.
50
my $mech = Test::WWW::Mechanize->new;
51
$mech->get_ok( 'http://petdance.com/' );
52
$mech->base_is( 'http://petdance.com/' );
53
$mech->title_is( "Invoice Status" );
54
$mech->content_contains( "Andy Lester" );
55
$mech->content_like( qr/(cpan|perl)\.org/ );
59
ok - Got 'http://petdance.com/' ok
60
ok - Base is 'http://petdance.com/'
61
ok - Title is 'Invoice Status'
62
ok - Content contains 'Andy Lester'
63
ok - Content is like '(?-xism:(cpan|perl)\.org)'
67
use WWW::Mechanize ();
71
use Carp::Assert::More;
73
use base 'WWW::Mechanize';
75
my $Test = Test::Builder->new();
82
Behaves like, and calls, L<WWW::Mechanize>'s C<new> method. Any parms
83
passed in get passed to WWW::Mechanize's constructor.
85
You can pass in C<< autolint => 1 >> to make Test::WWW::Mechanize
86
automatically run HTML::Lint after any of the following methods are
95
and will eventually do the same after any of the following:
103
=item * submit_form_ok()
105
=item * follow_link_ok()
111
This means you no longerhave to do the following:
113
my $mech = Test::WWW::Mechanize->new();
114
$mech->get_ok( $url, 'Fetch the intro page' );
115
$mech->html_lint_ok( 'Intro page looks OK' );
119
my $mech = Test::WWW::Mechanize->new( autolint => 1 );
120
$mech->get_ok( $url, 'Fetch the intro page' );
122
The C<< $mech->get_ok() >> only counts as one test in the test count. Both the
123
main IO operation and the linting must pass for the entire test to pass.
131
agent => "Test-WWW-Mechanize/$VERSION",
135
my $autolint = delete $args{autolint};
137
my $self = $class->SUPER::new( %args );
139
$self->{autolint} = $autolint;
144
=head1 METHODS: HTTP VERBS
146
=head2 $mech->get_ok($url, [ \%LWP_options ,] $desc)
148
A wrapper around WWW::Mechanize's get(), with similar options, except
149
the second argument needs to be a hash reference, not a hash. Like
150
well-behaved C<*_ok()> functions, it returns true if the test passed,
153
A default description of "GET $url" is used if none if provided.
160
my ($url,$desc,%opts) = $self->_unpack_args( 'GET', @_ );
162
$self->get( $url, %opts );
163
my $ok = $self->success;
165
$ok = $self->_maybe_lint( $ok, $desc );
175
local $Test::Builder::Level = $Test::Builder::Level + 1;
178
if ( $self->is_html && $self->{autolint} ) {
179
$ok = $self->_lint_content_ok( $desc );
182
$Test->ok( $ok, $desc );
186
$Test->ok( $ok, $desc );
187
$Test->diag( $self->status );
188
$Test->diag( $self->response->message ) if $self->response;
194
=head2 $mech->head_ok($url, [ \%LWP_options ,] $desc)
196
A wrapper around WWW::Mechanize's head(), with similar options, except
197
the second argument needs to be a hash reference, not a hash. Like
198
well-behaved C<*_ok()> functions, it returns true if the test passed,
201
A default description of "HEAD $url" is used if none if provided.
208
my ($url,$desc,%opts) = $self->_unpack_args( 'HEAD', @_ );
210
$self->head( $url, %opts );
211
my $ok = $self->success;
213
$Test->ok( $ok, $desc );
215
$Test->diag( $self->status );
216
$Test->diag( $self->response->message ) if $self->response;
223
=head2 $mech->post_ok( $url, [ \%LWP_options ,] $desc )
225
A wrapper around WWW::Mechanize's post(), with similar options, except
226
the second argument needs to be a hash reference, not a hash. Like
227
well-behaved C<*_ok()> functions, it returns true if the test passed,
230
A default description of "POST to $url" is used if none if provided.
237
my ($url,$desc,%opts) = $self->_unpack_args( 'POST', @_ );
239
$self->post( $url, \%opts );
240
my $ok = $self->success;
241
$Test->ok( $ok, $desc );
243
$Test->diag( $self->status );
244
$Test->diag( $self->response->message ) if $self->response;
250
=head2 $mech->put_ok( $url, [ \%LWP_options ,] $desc )
252
A wrapper around WWW::Mechanize's put(), with similar options, except
253
the second argument needs to be a hash reference, not a hash. Like
254
well-behaved C<*_ok()> functions, it returns true if the test passed,
257
A default description of "PUT to $url" is used if none if provided.
264
my ($url,$desc,%opts) = $self->_unpack_args( 'PUT', @_ );
265
$self->put( $url, \%opts );
267
my $ok = $self->success;
268
$Test->ok( $ok, $desc );
270
$Test->diag( $self->status );
271
$Test->diag( $self->response->message ) if $self->response;
277
=head2 $mech->submit_form_ok( \%parms [, $desc] )
279
Makes a C<submit_form()> call and executes tests on the results.
280
The form must be found, and then submitted successfully. Otherwise,
283
I<%parms> is a hashref containing the parms to pass to C<submit_form()>.
284
Note that the parms to C<submit_form()> are a hash whereas the parms to
285
this function are a hashref. You have to call this function like:
287
$agent->submit_form_ok( {n=>3}, "looking for 3rd link" );
289
As with other test functions, C<$desc> is optional. If it is supplied
290
then it will display when running the test harness in verbose mode.
292
Returns true value if the specified link was found and followed
293
successfully. The L<HTTP::Response> object returned by submit_form()
300
my $parms = shift || {};
303
if ( ref $parms ne 'HASH' ) {
304
Carp::croak 'FATAL: parameters must be given as a hashref';
307
# return from submit_form() is an HTTP::Response or undef
308
my $response = $self->submit_form( %{$parms} );
313
$error = 'No matching form found';
316
if ( $response->is_success ) {
320
$error = $response->as_string;
324
$Test->ok( $ok, $desc );
325
$Test->diag( $error ) if $error;
331
=head2 $mech->follow_link_ok( \%parms [, $desc] )
333
Makes a C<follow_link()> call and executes tests on the results.
334
The link must be found, and then followed successfully. Otherwise,
337
I<%parms> is a hashref containing the parms to pass to C<follow_link()>.
338
Note that the parms to C<follow_link()> are a hash whereas the parms to
339
this function are a hashref. You have to call this function like:
341
$mech->follow_link_ok( {n=>3}, "looking for 3rd link" );
343
As with other test functions, C<$desc> is optional. If it is supplied
344
then it will display when running the test harness in verbose mode.
346
Returns a true value if the specified link was found and followed
347
successfully. The L<HTTP::Response> object returned by follow_link()
354
my $parms = shift || {};
357
if (!defined($desc)) {
358
my $parms_str = join(', ', map { join('=', $_, $parms->{$_}) } keys(%{$parms}));
359
$desc = qq{Followed link with "$parms_str"} if !defined($desc);
362
if ( ref $parms ne 'HASH' ) {
363
Carp::croak 'FATAL: parameters must be given as a hashref';
366
# return from follow_link() is an HTTP::Response or undef
367
my $response = $self->follow_link( %{$parms} );
372
$error = 'No matching link found';
375
if ( $response->is_success ) {
379
$error = $response->as_string;
383
$Test->ok( $ok, $desc );
384
$Test->diag( $error ) if $error;
390
=head2 click_ok( $button[, $desc] )
392
Clicks the button named by C<$button>. An optional C<$desc> can
393
be given for the test.
402
my $response = $self->click( $button );
404
return $Test->ok( 0, $desc );
407
if ( !$response->is_success ) {
408
$Test->diag( "Failed test $desc:" );
409
$Test->diag( $response->as_string );
410
return $Test->ok( 0, $desc );
412
return $Test->ok( 1, $desc );
425
my $flex = shift; # The flexible argument
427
if ( !defined( $flex ) ) {
430
elsif ( ref $flex eq 'HASH' ) {
434
elsif ( ref $flex eq 'ARRAY' ) {
443
if ( not defined $desc ) {
444
$url = $url->url if ref($url) eq 'WWW::Mechanize::Link';
445
$desc = "$method $url";
448
return ($url, $desc, %opts);
453
=head1 METHODS: CONTENT CHECKING
455
=head2 $mech->html_lint_ok( [$desc] )
457
Checks the validity of the HTML on the current page. If the page is not
458
HTML, then it fails. The URI is automatically appended to the I<$desc>.
460
Note that HTML::Lint must be installed for this to work. Otherwise,
469
my $uri = $self->uri;
470
$desc = $desc ? "$desc ($uri)" : $uri;
474
if ( $self->is_html ) {
475
$ok = $self->_lint_content_ok( $desc );
478
$ok = $Test->ok( 0, $desc );
479
$Test->diag( q{This page doesn't appear to be HTML, or didn't get the proper text/html content type returned.} );
485
sub _lint_content_ok {
489
local $Test::Builder::Level = $Test::Builder::Level + 1;
491
if ( not ( eval 'require HTML::Lint' ) ) {
492
die "Test::WWW::Mechanize can't do linting without HTML::Lint: $@";
495
# XXX Combine with the cut'n'paste version in get_ok()
496
my $lint = HTML::Lint->new;
497
$lint->parse( $self->content );
499
my @errors = $lint->errors;
500
my $nerrors = @errors;
503
$ok = $Test->ok( 0, $desc );
504
$Test->diag( 'HTML::Lint errors for ' . $self->uri );
505
$Test->diag( $_->as_string ) for @errors;
506
my $s = $nerrors == 1 ? '' : 's';
507
$Test->diag( "$nerrors error$s on the page" );
510
$ok = $Test->ok( 1, $desc );
516
=head2 $mech->title_is( $str [, $desc ] )
518
Tells if the title of the page is the given string.
520
$mech->title_is( "Invoice Summary" );
528
$desc = qq{Title is "$str"} if !defined($desc);
530
local $Test::Builder::Level = $Test::Builder::Level + 1;
531
return is_string( $self->title, $str, $desc );
534
=head2 $mech->title_like( $regex [, $desc ] )
536
Tells if the title of the page matches the given regex.
538
$mech->title_like( qr/Invoices for (.+)/
546
$desc = qq{Title is like "$regex"} if !defined($desc);
548
local $Test::Builder::Level = $Test::Builder::Level + 1;
549
return like_string( $self->title, $regex, $desc );
552
=head2 $mech->title_unlike( $regex [, $desc ] )
554
Tells if the title of the page matches the given regex.
556
$mech->title_unlike( qr/Invoices for (.+)/
564
$desc = qq{Title is unlike "$regex"} if !defined($desc);
566
local $Test::Builder::Level = $Test::Builder::Level + 1;
567
return unlike_string( $self->title, $regex, $desc );
570
=head2 $mech->base_is( $str [, $desc ] )
572
Tells if the base of the page is the given string.
574
$mech->base_is( "http://example.com/" );
582
$desc = qq{Base is "$str"} if !defined($desc);
584
local $Test::Builder::Level = $Test::Builder::Level + 1;
585
return is_string( $self->base, $str, $desc );
588
=head2 $mech->base_like( $regex [, $desc ] )
590
Tells if the base of the page matches the given regex.
592
$mech->base_like( qr{http://example.com/index.php?PHPSESSID=(.+)});
600
$desc = qq{Base is like "$regex"} if !defined($desc);
602
local $Test::Builder::Level = $Test::Builder::Level + 1;
603
return like_string( $self->base, $regex, $desc );
606
=head2 $mech->base_unlike( $regex [, $desc ] )
608
Tells if the base of the page matches the given regex.
610
$mech->base_unlike( qr{http://example.com/index.php?PHPSESSID=(.+)});
618
$desc = qq{Base is unlike "$regex"} if !defined($desc);
620
local $Test::Builder::Level = $Test::Builder::Level + 1;
621
return unlike_string( $self->base, $regex, $desc );
624
=head2 $mech->content_is( $str [, $desc ] )
626
Tells if the content of the page matches the given string
635
local $Test::Builder::Level = $Test::Builder::Level + 1;
636
$desc = qq{Content is "$str"} if !defined($desc);
638
return is_string( $self->content, $str, $desc );
641
=head2 $mech->content_contains( $str [, $desc ] )
643
Tells if the content of the page contains I<$str>.
647
sub content_contains {
652
local $Test::Builder::Level = $Test::Builder::Level + 1;
653
if ( ref($str) eq 'REGEX' ) {
654
diag( 'content_contains takes a string, not a regex' );
656
$desc = qq{Content contains "$str"} if !defined($desc);
658
return contains_string( $self->content, $str, $desc );
661
=head2 $mech->content_lacks( $str [, $desc ] )
663
Tells if the content of the page lacks I<$str>.
672
local $Test::Builder::Level = $Test::Builder::Level + 1;
673
if ( ref($str) eq 'REGEX' ) {
674
diag( 'content_lacks takes a string, not a regex' );
676
$desc = qq{Content lacks "$str"} if !defined($desc);
678
return lacks_string( $self->content, $str, $desc );
681
=head2 $mech->content_like( $regex [, $desc ] )
683
Tells if the content of the page matches I<$regex>.
691
$desc = qq{Content is like "$regex"} if !defined($desc);
693
local $Test::Builder::Level = $Test::Builder::Level + 1;
694
return like_string( $self->content, $regex, $desc );
697
=head2 $mech->content_unlike( $regex [, $desc ] )
699
Tells if the content of the page does NOT match I<$regex>.
707
$desc = qq{Content is unlike "$regex"} if !defined($desc);
709
local $Test::Builder::Level = $Test::Builder::Level + 1;
710
return unlike_string( $self->content, $regex, $desc );
713
=head2 $mech->has_tag( $tag, $text [, $desc ] )
715
Tells if the page has a C<$tag> tag with the given content in its text.
724
$desc = qq{Page has $tag tag with "$text"} if !defined($desc);
726
my $found = $self->_tag_walk( $tag, sub { $text eq $_[0] } );
728
return $Test->ok( $found, $desc );
732
=head2 $mech->has_tag_like( $tag, $regex [, $desc ] )
734
Tells if the page has a C<$tag> tag with the given content in its text.
743
$desc = qq{Page has $tag tag like "$regex"} if !defined($desc);
745
my $found = $self->_tag_walk( $tag, sub { $_[0] =~ $regex } );
747
return $Test->ok( $found, $desc );
756
my $p = HTML::TokeParser->new( \($self->content) );
758
while ( my $token = $p->get_tag( $tag ) ) {
759
my $tagtext = $p->get_trimmed_text( "/$tag" );
760
return 1 if $match->( $tagtext );
765
=head2 $mech->followable_links()
767
Returns a list of links that Mech can follow. This is only http and
772
sub followable_links {
775
return $self->find_all_links( url_abs_regex => qr{^https?://} );
778
=head2 $mech->page_links_ok( [ $desc ] )
780
Follow all links on the current page and test for HTTP status 200
782
$mech->page_links_ok('Check all links');
790
$desc = 'All links ok' unless defined $desc;
792
my @links = $self->followable_links();
793
my @urls = _format_links(\@links);
795
my @failures = $self->_check_links_status( \@urls );
796
my $ok = (@failures==0);
798
$Test->ok( $ok, $desc );
799
$Test->diag( $_ ) for @failures;
804
=head2 $mech->page_links_content_like( $regex [, $desc ] )
806
Follow all links on the current page and test their contents for I<$regex>.
808
$mech->page_links_content_like( qr/foo/,
809
'Check all links contain "foo"' );
813
sub page_links_content_like {
818
$desc = qq{All links are like "$regex"} unless defined $desc;
820
my $usable_regex=$Test->maybe_regex( $regex );
821
unless(defined( $usable_regex )) {
822
my $ok = $Test->ok( 0, 'page_links_content_like' );
823
$Test->diag(qq{ "$regex" doesn't look much like a regex to me.});
827
my @links = $self->followable_links();
828
my @urls = _format_links(\@links);
830
my @failures = $self->_check_links_content( \@urls, $regex );
831
my $ok = (@failures==0);
833
$Test->ok( $ok, $desc );
834
$Test->diag( $_ ) for @failures;
839
=head2 $mech->page_links_content_unlike( $regex [, $desc ] )
841
Follow all links on the current page and test their contents do not
842
contain the specified regex.
844
$mech->page_links_content_unlike(qr/Restricted/,
845
'Check all links do not contain Restricted');
849
sub page_links_content_unlike {
853
$desc = "All links are unlike '$regex'" if !defined($desc);
855
my $usable_regex=$Test->maybe_regex( $regex );
856
unless(defined( $usable_regex )) {
857
my $ok = $Test->ok( 0, 'page_links_content_unlike' );
858
$Test->diag(qq{ "$regex" doesn't look much like a regex to me.});
862
my @links = $self->followable_links();
863
my @urls = _format_links(\@links);
865
my @failures = $self->_check_links_content( \@urls, $regex, 'unlike' );
866
my $ok = (@failures==0);
868
$Test->ok( $ok, $desc );
869
$Test->diag( $_ ) for @failures;
874
=head2 $mech->links_ok( $links [, $desc ] )
876
Follow specified links on the current page and test for HTTP status
877
200. The links may be specified as a reference to an array containing
878
L<WWW::Mechanize::Link> objects, an array of URLs, or a scalar URL
881
my @links = $mech->find_all_links( url_regex => qr/cnn\.com$/ );
882
$mech->links_ok( \@links, 'Check all links for cnn.com' );
884
my @links = qw( index.html search.html about.html );
885
$mech->links_ok( \@links, 'Check main links' );
887
$mech->links_ok( 'index.html', 'Check link to index' );
896
my @urls = _format_links( $links );
897
$desc = _default_links_desc(\@urls, 'are ok') unless defined $desc;
898
my @failures = $self->_check_links_status( \@urls );
899
my $ok = (@failures == 0);
901
$Test->ok( $ok, $desc );
902
$Test->diag( $_ ) for @failures;
907
=head2 $mech->link_status_is( $links, $status [, $desc ] )
909
Follow specified links on the current page and test for HTTP status
910
passed. The links may be specified as a reference to an array
911
containing L<WWW::Mechanize::Link> objects, an array of URLs, or a
914
my @links = $mech->followable_links();
915
$mech->link_status_is( \@links, 403,
916
'Check all links are restricted' );
926
my @urls = _format_links( $links );
927
$desc = _default_links_desc(\@urls, "have status $status") if !defined($desc);
928
my @failures = $self->_check_links_status( \@urls, $status );
929
my $ok = (@failures == 0);
931
$Test->ok( $ok, $desc );
932
$Test->diag( $_ ) for @failures;
937
=head2 $mech->link_status_isnt( $links, $status [, $desc ] )
939
Follow specified links on the current page and test for HTTP status
940
passed. The links may be specified as a reference to an array
941
containing L<WWW::Mechanize::Link> objects, an array of URLs, or a
944
my @links = $mech->followable_links();
945
$mech->link_status_isnt( \@links, 404,
946
'Check all links are not 404' );
950
sub link_status_isnt {
956
my @urls = _format_links( $links );
957
$desc = _default_links_desc(\@urls, "do not have status $status") if !defined($desc);
958
my @failures = $self->_check_links_status( \@urls, $status, 'isnt' );
959
my $ok = (@failures == 0);
961
$Test->ok( $ok, $desc );
962
$Test->diag( $_ ) for @failures;
968
=head2 $mech->link_content_like( $links, $regex [, $desc ] )
970
Follow specified links on the current page and test the resulting
971
content of each against I<$regex>. The links may be specified as a
972
reference to an array containing L<WWW::Mechanize::Link> objects, an
973
array of URLs, or a scalar URL name.
975
my @links = $mech->followable_links();
976
$mech->link_content_like( \@links, qr/Restricted/,
977
'Check all links are restricted' );
981
sub link_content_like {
987
my $usable_regex=$Test->maybe_regex( $regex );
988
unless(defined( $usable_regex )) {
989
my $ok = $Test->ok( 0, 'link_content_like' );
990
$Test->diag(qq{ "$regex" doesn't look much like a regex to me.});
994
my @urls = _format_links( $links );
995
$desc = _default_links_desc(\@urls, "are like '$regex'") if !defined($desc);
996
my @failures = $self->_check_links_content( \@urls, $regex );
997
my $ok = (@failures == 0);
999
$Test->ok( $ok, $desc );
1000
$Test->diag( $_ ) for @failures;
1005
=head2 $mech->link_content_unlike( $links, $regex [, $desc ] )
1007
Follow specified links on the current page and test that the resulting
1008
content of each does not match I<$regex>. The links may be specified as a
1009
reference to an array containing L<WWW::Mechanize::Link> objects, an array
1010
of URLs, or a scalar URL name.
1012
my @links = $mech->followable_links();
1013
$mech->link_content_unlike( \@links, qr/Restricted/,
1014
'No restricted links' );
1018
sub link_content_unlike {
1024
my $usable_regex=$Test->maybe_regex( $regex );
1025
unless(defined( $usable_regex )) {
1026
my $ok = $Test->ok( 0, 'link_content_unlike' );
1027
$Test->diag(qq{ "$regex" doesn't look much like a regex to me.});
1031
my @urls = _format_links( $links );
1032
$desc = _default_links_desc(\@urls, qq{are not like "$regex"}) if !defined($desc);
1033
my @failures = $self->_check_links_content( \@urls, $regex, 'unlike' );
1034
my $ok = (@failures == 0);
1036
$Test->ok( $ok, $desc );
1037
$Test->diag( $_ ) for @failures;
1042
# Create a default description for the link_* methods, including the link count.
1043
sub _default_links_desc {
1044
my ($urls, $desc_suffix) = @_;
1045
my $url_count = scalar(@{$urls});
1046
return sprintf( '%d link%s %s', $url_count, $url_count == 1 ? '' : 's', $desc_suffix );
1049
# This actually performs the status check of each url.
1050
sub _check_links_status {
1053
my $status = shift || 200;
1054
my $test = shift || 'is';
1056
# Create a clone of the $mech used during the test as to not disrupt
1058
my $mech = $self->clone();
1062
for my $url ( @{$urls} ) {
1063
if ( $mech->follow_link( url => $url ) ) {
1064
if ( $test eq 'is' ) {
1065
push( @failures, $url ) unless $mech->status() == $status;
1068
push( @failures, $url ) unless $mech->status() != $status;
1073
push( @failures, $url );
1080
# This actually performs the content check of each url.
1081
sub _check_links_content {
1084
my $regex = shift || qr/<html>/;
1085
my $test = shift || 'like';
1087
# Create a clone of the $mech used during the test as to not disrupt
1089
my $mech = $self->clone();
1092
for my $url ( @{$urls} ) {
1093
if ( $mech->follow_link( url => $url ) ) {
1094
my $content=$mech->content();
1095
if ( $test eq 'like' ) {
1096
push( @failures, $url ) unless $content=~/$regex/;
1099
push( @failures, $url ) unless $content!~/$regex/;
1104
push( @failures, $url );
1111
# Create an array of urls to match for mech to follow.
1116
if (ref($links) eq 'ARRAY') {
1117
if (defined($$links[0])) {
1118
if (ref($$links[0]) eq 'WWW::Mechanize::Link') {
1119
@urls = map { $_->url() } @{$links};
1132
=head2 $mech->stuff_inputs( [\%options] )
1134
Finds all free-text input fields (text, textarea, and password) in the
1135
current form and fills them to their maximum length in hopes of finding
1136
application code that can't handle it. Fields with no maximum length
1137
and all textarea fields are set to 66000 bytes, which will often be
1138
enough to overflow the data's eventual recepticle.
1140
There is no return value.
1142
If there is no current form then nothing is done.
1144
The hashref $options can contain the following keys:
1150
hash value is arrayref of field names to not touch, e.g.:
1152
$mech->stuff_inputs( {
1153
ignore => [qw( specialfield1 specialfield2 )],
1158
hash value is default string to use when stuffing fields. Copies
1159
of the string are repeated up to the max length of each field. E.g.:
1161
$mech->stuff_inputs( {
1162
fill => '@' # stuff all fields with something easy to recognize
1167
hash value is arrayref of hashrefs with which you can pass detailed
1168
instructions about how to stuff a given field. E.g.:
1170
$mech->stuff_inputs( {
1172
# Some fields are datatype-constrained. It's most common to
1173
# want the field stuffed with valid data.
1174
widget_quantity => { fill=>'9' },
1175
notes => { maxlength=>2000 },
1179
The specs allowed are I<fill> (use this fill for the field rather than
1180
the default) and I<maxlength> (use this as the field's maxlength instead
1181
of any maxlength specified in the HTML).
1190
my $options = shift || {};
1191
assert_isa( $options, 'HASH' );
1192
assert_in( $_, ['ignore', 'fill', 'specs'] ) foreach ( keys %{$options} );
1194
# set up the fill we'll use unless a field overrides it
1195
my $default_fill = '@';
1196
if ( exists $options->{fill} && defined $options->{fill} && length($options->{fill}) > 0 ) {
1197
$default_fill = $options->{fill};
1200
# fields in the form to not stuff
1202
if ( exists $options->{ignore} ) {
1203
assert_isa( $options->{ignore}, 'ARRAY' );
1204
$ignore = { map {($_, 1)} @{$options->{ignore}} };
1208
if ( exists $options->{specs} ) {
1209
assert_isa( $options->{specs}, 'HASH' );
1210
$specs = $options->{specs};
1211
foreach my $field_name ( keys %{$specs} ) {
1212
assert_isa( $specs->{$field_name}, 'HASH' );
1213
assert_in( $_, ['fill', 'maxlength'] ) foreach ( keys %{$specs->{$field_name}} );
1217
my @inputs = $self->find_all_inputs( type_regex => qr/^(text|textarea|password)$/ );
1219
foreach my $field ( @inputs ) {
1220
next if $field->readonly();
1221
next if $field->disabled(); # TODO: HTML::Form::TextInput allows setting disabled--allow it here?
1223
my $name = $field->name();
1225
# skip if it's one of the fields to ignore
1226
next if exists $ignore->{ $name };
1228
# fields with no maxlength will get this many characters
1229
my $maxlength = 66000;
1231
# maxlength from the HTML
1232
if ( $field->type ne 'textarea' ) {
1233
if ( exists $field->{maxlength} ) {
1234
$maxlength = $field->{maxlength};
1235
# TODO: what to do about maxlength==0 ? non-numeric? less than 0 ?
1239
my $fill = $default_fill;
1241
if ( exists $specs->{$name} ) {
1242
# process the per-field info
1244
if ( exists $specs->{$name}->{fill} && defined $specs->{$name}->{fill} && length($specs->{$name}->{fill}) > 0 ) {
1245
$fill = $specs->{$name}->{fill};
1248
# maxlength override from specs
1249
if ( exists $specs->{$name}->{maxlength} && defined $specs->{$name}->{maxlength} ) {
1250
$maxlength = $specs->{$name}->{maxlength};
1251
# TODO: what to do about maxlength==0 ? non-numeric? less than 0?
1256
if ( ($maxlength % length($fill)) == 0 ) {
1258
$field->value( $fill x ($maxlength/length($fill)) );
1261
# can be improved later
1262
$field->value( substr( $fill x int(($maxlength + length($fill) - 1)/length($fill)), 0, $maxlength ) );
1271
Add HTML::Tidy capabilities.
1273
Add a broken image check.
1277
Andy Lester, C<< <andy at petdance.com> >>
1281
Please report any bugs or feature requests to
1282
<http://code.google.com/p/www-mechanize/issues/list>. I will be
1283
notified, and then you'll automatically be notified of progress on
1284
your bug as I make changes.
1288
You can find documentation for this module with the perldoc command.
1290
perldoc Test::WWW::Mechanize
1292
You can also look for information at:
1296
=item * Google Code bug tracker
1298
L<http://code.google.com/p/www-mechanize/issues/list>
1300
Please B<do not use> the old queues for WWW::Mechanize and
1301
Test::WWW::Mechanize at
1302
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-WWW-Mechanize>
1304
=item * AnnoCPAN: Annotated CPAN documentation
1306
L<http://annocpan.org/dist/Test-WWW-Mechanize>
1308
=item * CPAN Ratings
1310
L<http://cpanratings.perl.org/d/Test-WWW-Mechanize>
1314
L<http://search.cpan.org/dist/Test-WWW-Mechanize>
1318
=head1 ACKNOWLEDGEMENTS
1329
and Pete Krawczyk for patches.
1331
=head1 COPYRIGHT & LICENSE
1333
Copyright 2004-2009 Andy Lester.
1335
This program is free software; you can redistribute it and/or
1336
modify it under the terms of either:
1340
=item * the GNU General Public License as published by the Free
1341
Software Foundation; either version 1, or (at your option) any
1344
=item * the Artistic License version 2.0.
1350
1; # End of Test::WWW::Mechanize