File Coverage

blib/lib/HTTP/WebTest/Plugin/TagAttTest.pm
Criterion Covered Total %
statement 12 74 16.2
branch 0 34 0.0
condition 0 15 0.0
subroutine 4 10 40.0
pod 0 6 0.0
total 16 139 11.5


line stmt bran cond sub pod time code
1            
2             package HTTP::WebTest::Plugin::TagAttTest;
3            
4 1     1   11399 use vars qw($VERSION);
  1         3  
  1         70  
5             $VERSION = '1.00';
6             =head1 NAME
7            
8             HTTP::WebTest::Plugin::TagAttTest - Test by tag and attribute existence
9            
10             =head1 SYNOPSIS
11            
12             Not Applicable
13            
14             =head1 DESCRIPTION
15            
16             This plugin allows to forbid or require tags and/or attributes in a web page.
17            
18             =cut
19            
20 1     1   6 use strict;
  1         2  
  1         35  
21 1     1   27 use base qw(HTTP::WebTest::Plugin);
  1         3  
  1         1608  
22            
23            
24             #use HTTP::Status;
25            
26             =head1 TEST PARAMETERS
27            
28             =for pod_merge copy params
29            
30             =head2 ignore_case
31            
32             Determines if case is important.
33            
34             =head3 Allowed values
35            
36             C,C
37            
38             =head3 Default value
39            
40             C
41            
42             =head2 tag_require
43            
44             A required tag. This is an array of hashs such as C<< require_tag => [{tag=>"script", tag_text=>"spam", attr=>"language",attr_text=>"javascript"}] >>
45            
46             See also the L for a more detailed explaination.
47            
48            
49             =head3 Allowed values
50            
51             list of hashes
52            
53             =head3 Default value
54            
55             None (will generate a failed test)
56            
57             =head2 forbid_tag
58            
59            
60             A forbidden tag. This is an array of hashs such as C<< forbid_tag => [{tag=>"script",attr=>"language",attr_text=>"javascript"}] >>
61            
62             See also the L for a more detailed explaination.
63            
64            
65             =head3 Allowed values
66            
67             list of hashes
68            
69             =head3 Default value
70            
71             None (will generate a failed test)
72            
73             =head1 TAG HASH
74            
75            
76             =head2 tag
77            
78             tag to forbid
79            
80             =head2 attr
81            
82             attribute to forbid
83            
84            
85             =head2 attr_text
86            
87             regular expression or text. If text, will do a substring search.
88            
89            
90             =head2 tag_text
91            
92             regular expression or text. If text, will do a substring search.
93            
94             Note that if an element is missing, it will not be considered. So something like
95             C [{tag=>"title"}]> will assure that a page has a title tag, but the
96             title tag could be blank.
97            
98            
99             =cut
100            
101            
102             sub param_types {
103 0     0 0   return q(use_case yesno
104             tag_forbid list
105             tag_require list);
106             }
107            
108             sub get_tag($ $)
109             {
110 0     0 0   my ($page, $tag_name) = @_;
111 0 0         if (!defined($tag_name))
112             {
113 0           return ($page->get_tag) ;
114             }
115             else
116             {
117 0           my $res = $page->get_tag($tag_name);
118 0           return ($res);
119             }
120             }
121             sub find_attributes
122             {
123            
124 0     0 0   my( $ok, @attrarr, $attr_search, %attrhash, $attr_text_search, $case_re) = @_;
125 0           for my $attribute (@attrarr)
126             {
127             #this isn't as simple as for tags, because we can't get just certain attributes.
128             #the code can be shortened by combining the two if's, but it was giving me a
129             #headache figuring out all of the possibilities, so I left it for readability.
130             #case 6
131 0 0         if (!defined($attr_search))
132             {
133 0           my $attr_content = $attrhash{$attribute};
134 0 0         $ok = 0 if ($attr_content =~ /$case_re\Q$attr_text_search\E/);
135             }
136            
137             #case 4
138 0 0 0       if (!(defined ($attr_text_search)) and ($attribute eq $attr_search))
139             {
140 0           $ok = 0;
141             }
142             #case 5
143             else
144             {
145 0           my $attr_content = $attrhash{$attribute};
146 0 0         $ok = 0 if ($attr_content =~ /$case_re\Q$attr_text_search\E/);
147             }
148             }
149             }
150            
151             sub search_tag
152             {
153 0     0 0   my $ok = 1;
154 0           my ($page,$case_re, %tag_search_struct) = @_;
155 0           chomp (%tag_search_struct);
156 0           my $tag_search = $tag_search_struct{"tag"};
157 0 0         undef $tag_search if ($tag_search eq ''); #an undefined tag causes it to loop through all tags.
158 0           my $tag_text_search = $tag_search_struct{"tag_text"};
159 0           my $attr_search = $tag_search_struct{"attr"};
160 0 0         undef $attr_search if ($attr_search eq '');
161 0           my $attr_text_search = $tag_search_struct{"attr_text"};
162 0           my @results=();
163            
164 0 0 0       return(0, "No values for tag searched") unless (defined ($tag_search) or defined ($attr_search));
165             #at this point we start looking for tags
166             #there are 6 main cases
167             #1, looking for a tag
168             #2, looking for a specific tag containing some specific text
169             #3, looking for any tag containing some specific text
170             #4, looking for an attribute
171             #5, looking for an attribute containing some specifice text
172             #6, looking for any attribute containing some specific text
173             # these can be combined
174 0           while ( my $tagstruct = get_tag($page,$tag_search) )
175             {
176 0           my $tag = $tagstruct->[0];
177 0 0         next if ($tag =~ m!/!);
178 0           my %attrhash= %{$tagstruct->[1]};
  0            
179 0           my @attrarr = @{$tagstruct->[2]};
  0            
180             #the tag exists so we want to see if the contents match
181             #case 1
182 0 0 0       $ok = 0 if (defined ($tag_search) and !defined ($tag_text_search)); #if we didn't search a tag, we should continue with the success assumption
183            
184             #case 2 or 3
185 0 0         if ( defined ($tag_text_search) )
186             {
187 0           my $tag_content = $page->get_text;
188 0 0         $ok = 0 if ($tag_content =~ /$case_re\Q$tag_text_search\E/);
189             }
190            
191             #this quits if we hit case 1, 2 or 3 and we aren't looking for cases 4, 5 or 6
192 0 0 0       last if ( (!defined ($attr_search) && !defined ($attr_text_search)) && !($ok));
      0        
193            
194             #look for cases 4, 5, 6
195 0           $ok = find_attributes( $ok, @attrarr, $attr_search, %attrhash, $attr_text_search, $case_re);
196            
197             #if $ok is 0, one of cases 4,5 or 6 must have failed.
198 0 0         last if ($ok == 0);
199             }
200 0           return ($ok, "tag: " . $tag_search . ", tag text: " . $tag_text_search . ", attribute: " . $attr_search . ", attribute text: " . $attr_text_search);
201             }
202            
203             sub test_tags
204             {
205 0     0 0   my ($self, $tag_type, $content, $case_re) = @_;
206 1     1   2054 use HTML::TokeParser;
  1         16232  
  1         405  
207 0           my $page = HTML::TokeParser->new(\$content);
208            
209 0           my @results;
210 0           for my $tag_struct (@{$self->test_param( $tag_type, [] )})
  0            
211             {
212 0           my ($ok, $result) = search_tag( $page, $case_re, %{ $tag_struct });
  0            
213 0           push @results, $self->test_result($ok, $result);
214             }
215            
216 0           return @results;
217             }
218            
219            
220             sub check_response {
221 0     0 0   my $self = shift;
222            
223             # response content
224 0           my $content = $self->webtest->current_response->content;
225 0           $self->validate_params(qw(ignore_case
226             tag_forbid tag_require));
227            
228             # ignore case or not?
229 0           my $ignore_case = $self->yesno_test_param('ignore_case');
230 0 0         my $case_re = $ignore_case ? '(?i)' : '';
231            
232             # clean test results
233 0           my @results = ();
234 0           my @ret = ();
235            
236             # check for forbidden tag and attribute
237            
238 0           my @forbid = test_tags($self, 'tag_forbid', $content, $case_re );
239 0 0         push @ret, ['Forbidden tag and attribute', @results] if @forbid;
240            
241 0           my @require = test_tags( $self,'tag_require', $content, $case_re );
242 0 0         push @ret, ['Required tag and attribute', @results] if @require;
243 0           return @ret;
244             }
245            
246            
247            
248            
249            
250             =head1 COPYRIGHT
251            
252             Copyright (c) 2003-2004 Edward Fancher. All rights reserved.
253            
254             This program is free software; you can redistribute it and/or modify
255             it under the same terms as Perl itself.
256            
257             =head1 SEE ALSO
258            
259             L
260            
261             L
262            
263             L
264            
265             L
266            
267            
268             L
269            
270             =cut
271            
272             1;