File Coverage

blib/lib/WWW/Webrobot/TestplanRunner.pm
Criterion Covered Total %
statement 30 117 25.6
branch 7 44 15.9
condition 0 6 0.0
subroutine 7 15 46.6
pod 2 6 33.3
total 46 188 24.4


line stmt bran cond sub pod time code
1             package WWW::Webrobot::TestplanRunner;
2 1     1   21216 use strict;
  1         2  
  1         40  
3 1     1   6 use warnings;
  1         1  
  1         205  
4              
5             # Author: Stefan Trcek
6             # Copyright(c) 2004-2006 ABAS Software AG
7              
8              
9 1     1   565 use WWW::Webrobot::UserAgentConnection;
  1         4  
  1         43  
10 1     1   1951 use WWW::Webrobot::Print::Null;
  1         3  
  1         32  
11 1     1   5 use WWW::Webrobot::AssertConstant;
  1         2  
  1         27  
12 1     1   6 use WWW::Webrobot::Attributes qw(sym_tbl failed_assertions);
  1         2  
  1         8  
13              
14             my $ASSERT_TRUE = WWW::Webrobot::AssertConstant->new(0, ["0 always true"]);
15              
16              
17             =head1 NAME
18              
19             WWW::Webrobot::TestplanRunner - runs a testplan
20              
21             =head1 SYNOPSIS
22              
23             WWW::Webrobot::TestplanRunner -> new() -> run($test_plan, $cfg);
24              
25             =head1 DESCRIPTION
26              
27             This module configures Webrobot with $cfg,
28             reads a testplan and executes this plan.
29              
30              
31             =head1 METHODS
32              
33             =over
34              
35             =item $wr = WWW::Webrobot::TestplanRunner -> new();
36              
37             Construct an object.
38              
39             =cut
40              
41             sub new {
42 0     0 1 0 my $class = shift;
43 0   0     0 my $self = bless({}, ref($class) || $class);
44 0         0 return $self;
45             }
46              
47              
48             =item WWW::Webrobot::TestplanRunner -> run($testplan, $cfg);
49              
50             =over
51              
52             =item $testplan
53              
54             Read in the testplan (reference to list).
55              
56             =item $cfg
57              
58             [optional] Read the configuration (reference to list).
59              
60             =back
61              
62             =cut
63              
64             sub run {
65 0     0 1 0 my ($self, $testplan, $cfg, $sym_tbl) = @_;
66              
67 0         0 $self -> {cfg} = $cfg;
68 0         0 $self -> {_sym_tbl} = $sym_tbl;
69 0         0 $self -> {_ua_list} = {};
70 0         0 $self -> {_defined} = [];
71 0         0 $self -> {_failed_assertions} = 0;
72             my $max_errors = $cfg->{max_errors} ? sub {
73 0     0   0 my ($fail) = @_;
74 0 0       0 $self->{_failed_assertions}++ if $fail;
75 0         0 $self->{_failed_assertions} >= $cfg->{max_errors};
76 0 0   0   0 } : sub {0};
  0         0  
77              
78             # treat testplan
79 0   0     0 my $out = $cfg -> {output} || WWW::Webrobot::Print::Null -> new();
80 0         0 $_ -> global_start() foreach (@$out);
81 0         0 my $exit_status = 0;
82 0         0 my @global_assert_xml = ();
83             ENTRY:
84 0         0 foreach my $entry (@$testplan) {
85             # assertion
86 0         0 my @a_xml = ();
87 0 0       0 if (defined $entry->{global_assert_xml}) { # defining a global assertion
88 0 0       0 @global_assert_xml = () if $entry->{mode} eq "new";
89 0         0 push @global_assert_xml, clone_me($entry->{global_assert_xml});
90             }
91             else {
92 0 0       0 push @a_xml, clone_me($entry->{assert_xml}) if defined $entry->{assert_xml};
93 0         0 push @a_xml, clone_me($_) foreach (@global_assert_xml);
94             }
95 0         0 $entry->{assert_xml} = \@a_xml;
96 0         0 $sym_tbl -> evaluate($entry); # substitute variables
97              
98 0         0 my @a = ();
99 0 0       0 if (defined $entry->{global_assert_xml}) {
100 0         0 push @a, $ASSERT_TRUE;
101             }
102             else {
103 0         0 foreach (@{$entry->{assert_xml}}) {
  0         0  
104 0         0 push @a, parse_assertion($_);
105             }
106             }
107 0         0 $entry->{assert} = \@a;
108              
109             # recursion
110 0 0       0 if (defined (my $xml = $entry->{recurse_xml})) {
111 0         0 $entry->{recurse} = get_plugin($xml->[0], $xml->[1]);
112             }
113              
114 0         0 my $user = $self -> _get_ua_connection($cfg, $entry -> {useragent});
115              
116             # get url in testplan
117 0         0 $_ -> item_pre($entry) foreach (@$out);
118 0         0 my ($r_plan, $fail_plan, $fail_plan_str) = $user -> treat_single_url($entry, $sym_tbl);
119 0         0 $entry->{fail} = $fail_plan;
120 0         0 $entry->{fail_str} = $fail_plan_str;
121 0         0 $_ -> item_post($r_plan, $entry, $fail_plan) foreach (@$out);
122 0 0       0 last ENTRY if $max_errors->($fail_plan);
123              
124             # do recursion
125 0         0 my $fail_all = $fail_plan;
126 0 0       0 if (defined(my $recurse = $entry -> {recurse})) {
127 0         0 $user -> ua() -> set_redirect_ok($recurse);
128 0         0 my ($newurl, $caller_pages) = $recurse -> next($r_plan);
129 0         0 while ($newurl) {
130 0         0 my $entry_recurse = {
131             method => "GET",
132             url => $newurl,
133             description => $entry->{description},
134             assert => $entry->{assert},
135             global_assert => $entry->{global_assert},
136             http_header => $entry->{http_header},
137             caller_pages => $caller_pages,
138             is_recursive => 1,
139             };
140              
141 0         0 $_ -> item_pre($entry_recurse) foreach (@$out);
142 0         0 my ($r, $fail, $fail_str) = $user -> treat_single_url($entry_recurse, $sym_tbl);
143 0         0 $entry_recurse->{fail} = $fail;
144 0         0 $entry_recurse->{fail_str} = $fail_str;
145 0         0 $_ -> item_post($r, $entry_recurse, $fail) foreach (@$out);
146 0 0       0 last ENTRY if $max_errors->($fail);
147              
148 0 0       0 $fail_all = 1 if $fail;
149 0         0 ($newurl, $caller_pages) = $recurse -> next($r);
150 0 0       0 save_memory($r) if WWW::Webrobot::Global->save_memory();
151             }
152 0         0 $user -> ua() -> set_redirect_ok(undef);
153             }
154 0         0 $entry -> {result} = $r_plan;
155 0         0 $entry -> {fail} = $fail_all;
156 0         0 $entry -> {fail_str} = $fail_plan_str;
157 0 0       0 $exit_status = 1 if $fail_all;
158 0 0       0 save_memory($r_plan) if WWW::Webrobot::Global->save_memory();
159             }
160 0         0 $_ -> global_end() foreach (@$out);
161 0         0 return $exit_status;
162             }
163              
164              
165             sub clone_me {
166 12     12 0 4057 my ($tree) = @_;
167 12         36 SWITCH: foreach (ref $tree) {
168 12 100       47 /^ARRAY$/ and do {
169 9         22 my @array = ( @$tree );
170 9         14 foreach my $elem (@array) {
171 26 100       73 $elem = clone_me($elem) if ref $elem;
172             }
173 9         47 return \@array;
174             };
175 3 50       16 /^HASH$/ and do {
176 3         5 my %hash = ();
177 3         16 while (my ($key,$value) = each %$tree) {
178 8 100       60 $hash{$key} = ref $value ? clone_me($value) : $value;
179             }
180 3         20 return \%hash;
181             };
182 0           return undef;
183             };
184             }
185              
186              
187             sub parse_assertion {
188 0     0 0   my ($assert_xml) = @_;
189 0 0         return undef if ! defined $assert_xml;
190 0           my $name = $assert_xml->[0];
191 0 0         if ($name =~ /^[A-Z][^.]*\./) {
192 0           return get_plugin($assert_xml->[0], $assert_xml->[1]);
193             }
194             else {
195 0           return get_plugin('WWW.Webrobot.Assert', [{}, @$assert_xml]);
196             }
197             }
198              
199              
200             # SAVE MEMORY: delete _content and _content_xhtml of response
201             sub save_memory {
202 0     0 0   my ($req) = @_;
203 0           while (defined $req) { # for all subrequests
204 0           undef $req->{_content};
205 0           undef $req->{_content_xhtml};
206 0           $req = $req -> {_previous};
207             }
208             }
209              
210              
211             sub get_plugin {
212 0     0 0   my ($tag, $content) = @_;
213 0           $tag =~ s/\./::/g;
214             # ??? delete ', 0' in following line
215 0           my $ret = eval "require $tag; $tag -> new(\$content, 0);";
216 0 0         die "Can't use lib $tag: $@" if $@;
217 0           return $ret;
218             }
219              
220              
221             # get useragent - create one if nonexistent
222             sub _get_ua_connection {
223 0     0     my ($self, $cfg, $user) = @_;
224 0 0         if (!exists $self->{_ua_list}->{$user}) {
225 0           $self->{_ua_list}->{$user} =
226             WWW::Webrobot::UserAgentConnection -> new($cfg, user => $user);
227             }
228 0           return $self->{_ua_list}->{$user};
229             }
230              
231            
232             =item $conn -> sym_tbl
233              
234             Get the symbol table, see L.
235             Symbols are defined within a config file or within a test plan.
236              
237             =back
238              
239              
240             =head1 SEE ALSO
241              
242             =over
243              
244             =item L
245              
246             is a frontend for this class
247              
248             =back
249              
250             =cut
251              
252             1;