File Coverage

blib/lib/Win32/Watir.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Win32::Watir - Perl extension for automating Internet Explorer.
4              
5             =head1 SYNOPSIS
6              
7             use Win32::Watir;
8              
9             # Creating new instance of Internet Explorer
10             my $ie = Win32::Watir::new(
11             visible => 1,
12             maximize => 1,
13             );
14             # show google, search 'Perl Win32::Watir' keyword.
15             $ie->goto("http://www.google.co.jp/");
16             $ie->text_field('name:', "q")->setvalue("Perl Win32::Watir")
17              
18             =head1 DESCRIPTION
19              
20             Win32::Watir helps you to write tests that are easy to read and easy to
21             maintain.
22              
23             Watir drives browsers the same way people do.
24             It clicks links, fills in forms, presses buttons.
25             Watir also checks results, such as whether expected text appears on the page.
26              
27             Win32::Watir is inspired on Ruby/Watir, then fork Win32::IEAutomation.
28              
29             Win32::IEAutomation special nice interface at perl and windows, but
30             some method doesn't support IE7, IE8 for Window/Dialog name changes.
31             Win32::Watir are support IE7, IE8 and use more compatible/like Ruby/Watir
32             method names, ..etc.
33              
34             * Ruby/Watir :
35             http://wtr.rubyforge.org/
36              
37             * Win32::IEAutomation :
38             http://search.cpan.org/perldoc?Win32::IEAutomation
39              
40             you may require setup Multiple_IE when using this with IE6.0
41              
42             =cut
43              
44             package Win32::Watir;
45              
46 1     1   21133 use 5.010000;
  1         3  
  1         32  
47 1     1   5 use strict;
  1         1  
  1         48  
48 1     1   6 use warnings;
  1         7  
  1         31  
49 1     1   5 use vars qw($warn);
  1         2  
  1         72  
50              
51 1     1   484 use Win32;
  0            
  0            
52             use Win32::OLE qw(EVENTS);
53             use Win32::Watir::Element;
54             use Win32::Watir::Table;
55             use Config;
56              
57             our $VERSION = '0.06';
58              
59             # methods go here.
60              
61             =head2 new - construct.
62              
63             options are supported to this method in hash format.
64              
65             warnings => 0 or 1
66             0: output no warning.
67             1: output some warnings.
68              
69             maximize => 0 or 1
70             0: default window size.
71             1: maximize IE window when IE start.
72              
73             visible => 0 or 1
74             0: IE window invisible.
75             1: IE window visible.
76              
77             codepage => undef or 'utf8'
78             undef: use default codepage at your Windows.
79             utf8 : use Win32::OLE::CP_UTF8 codepage.
80              
81             ie (IE executable path) :
82             specify your multiple IE executable path.
83             ex) c:/path_to/multipleIE/iexplorer.exe
84              
85             find :
86             If "find" key exists, find IE window in
87             current workspace
88              
89             if no options specified, use those default.
90              
91             $ie = new Win32::Watir(
92             warnings => 0,
93             maximize => 0,
94             visible => 1,
95             codepage => undef,
96             );
97              
98             =cut
99              
100             sub new {
101             my $class = shift;
102             my %opts = @_;
103             $opts{visible} = 1 unless (exists $opts{visible});
104             $warn = $opts{warnings} if (exists $opts{warnings});
105             my $self = bless (\%opts, $class);
106             $self->_check_os_name();
107             if ( $opts{'ie'} or $opts{'find'} ){
108             return $self->_startCustomIE();
109             } else {
110             return $self->_startIE();
111             }
112             }
113              
114             sub _set_codepage {
115             my $self = shift;
116             if ($self->{codepage} and ($self->{codepage} =~ /UTF8/i || $self->{codepage} =~ /UTF-8/i)){
117             Win32::OLE->Option(CP => Win32::OLE::CP_UTF8);
118             binmode(STDOUT, ":utf8");
119             binmode(STDERR, ":utf8");
120             print STDERR "DEBUG: Win32::OLE::CP=".Win32::OLE->Option('CP')."\n" if ($self->{warnings});
121             }
122             }
123              
124             sub _startIE {
125             my $self = shift;
126             defined $self->{agent} and return;
127             $self->{agent} = Win32::OLE->new("InternetExplorer.Application") ||
128             die "Could not start Internet Explorer Application through OLE\n";
129             Win32::OLE->Option(Warn => 0);
130             Win32::OLE->WithEvents($self->{agent});
131             $self->_set_codepage();
132             $self->{agent}->{Visible} = $self->{visible};
133             $self->{IE_VERSION} = $self->_check_ie_version();
134             if ($self->{maximize}){
135             $self->maximize_ie();
136             }
137             return $self;
138             }
139              
140             sub _startCustomIE {
141             my $self = shift;
142             if ( defined($self->{agent}) ){
143             print STDERR "Notice: IE already initialized..\n";
144             return $self->{agent};
145             }
146             if ( exists($self->{ie}) ){
147             my $ie = $self->{ie};
148             die "Error: Coud not execute '$ie'\n" unless ( -x "$ie" );
149             if ( exists($ENV{OSTYPE}) && $ENV{OSTYPE} eq 'cygwin' ){
150             system("cygstart.exe '${ie}'");
151             } else {
152             system("start '${ie}'");
153             }
154             # find current windows opened.
155             } else {
156             $self->_log("DEBUG: find IE from current windows....\n");
157             }
158             my $shApp = Win32::OLE->new("Shell.Application") || die "Could not start Shell.Application\n";
159             my $_wait = time();
160             while ( ! defined($self->{agent}) ) {
161             my $windows = $shApp->Windows;
162             for (my $n = 0; $n <= $windows->count - 1; $n++){
163             my $window = $windows->Item($n);
164             my $name = $window->name;
165             if ($name =~ /(\w+) Internet Explorer$/i){
166             my $_ie_prefix = $1;
167             $self->{IE_VERSION} = 6 if ($_ie_prefix eq 'Microsoft');
168             $self->{agent} = $window;
169             $self->{agent}->WaitforDone;
170             }
171             }
172             if ( (time() - $_wait) > 10 ){
173             die "Could not start or detect Internet Explorer\n";
174             }
175             sleep 2;
176             }
177             die "Could not start or detect Internet Explorer\n" unless(defined($self->{agent}));
178             $self->_set_codepage();
179             $self->{IE_VERSION} = $self->_check_ie_version() unless ($self->{IE_VERSION});
180             $self->{agent}->{Visible} = $self->{visible};
181             if ($self->{maximize}){
182             $self->maximize_ie();
183             }
184             return $self;
185             }
186              
187             sub getAgent {
188             my $self = shift;
189             $self->{agent};
190             }
191              
192             sub getElement {
193             my $self = shift;
194             $self->{element};
195             }
196              
197             =head2 close()
198              
199             =head2 closeIE()
200              
201             close IE window.
202              
203             =cut
204              
205             sub closeIE {
206             my $self = shift;
207             my $agent = $self->{agent};
208             $agent->Quit;
209             }
210             sub close {
211             my $self = shift;
212             $self->closeIE(@_);
213             }
214              
215             =head2 goto(url)
216              
217             =head2 gotoURL(url)
218              
219             Site navigate to specified URL.
220              
221             ex). go cpan-site.
222             $ie->goto('http://search.cpan.org/');
223              
224             =cut
225              
226             sub gotoURL {
227             my ($self, $url, $nowait) = @_;
228             my $agent = $self->{agent};
229             $agent->Navigate($url);
230             $self->WaitforDone unless $nowait;
231             }
232             sub goto {
233             my $self = shift;
234             $self->gotoURL(@_);
235             }
236              
237             =head2 back()
238              
239             =head2 Back()
240              
241             IE window back. same as "back button" or type Backspace key.
242              
243             =cut
244              
245             sub Back {
246             my $self = shift;
247             my $agent = $self->{agent};
248             $agent->GoBack;
249             $self->WaitforDone;
250             }
251             sub back {
252             my $self = shift;
253             $self->Back(@_);
254             }
255              
256             =head2 reload()
257              
258             =head2 Reload()
259              
260             reload, refresh IE page.
261             same as type 'F5' key.
262              
263             =cut
264              
265             sub Reload {
266             my $self = shift;
267             my $agent = $self->{agent};
268             $agent->Refresh2;
269             $self->WaitforDone;
270             }
271             sub reload {
272             my $self = shift;
273             $self->Reload(@_);
274             }
275              
276             =head2 URL()
277              
278             return current page URL.
279              
280             =cut
281              
282             sub URL {
283             my $self = shift;
284             my $agent = $self->{agent};
285             $agent->LocationURL;
286             }
287              
288             =head2 title()
289              
290             =head2 Title()
291              
292             return current page title.
293              
294             =cut
295              
296             sub Title {
297             my $self = shift;
298             my $agent = $self->{agent};
299             $agent->document->title;
300             }
301             sub title {
302             my $self = shift;
303             return $self->Title(@_);
304             }
305              
306             =head2 html()
307              
308             =head2 Content()
309              
310             return current page html.
311              
312             notice: "CR" code (\r) removed from html.
313              
314             =cut
315              
316             sub Content {
317             my $self = shift;
318             my $agent = $self->{agent};
319             my $html = $agent->document->documentElement->{outerHTML};
320             $html =~ s/\r//g;
321             if (wantarray){
322             return split (/\n/, $html);
323             } else {
324             return $html;
325             }
326             }
327             sub html {
328             my $self = shift;
329             return $self->Content(@_);
330             }
331              
332             =head2 VerifyText(text, flag)
333              
334             verify current document include specified "text" .
335              
336             text : string
337             flag :
338             0 (default)
339             1 (?)
340            
341             [ToDO] check createTextRange()
342              
343             =cut
344              
345             sub VerifyText {
346             my ($self, $string, $flag) = @_;
347             $flag = 0 unless $flag;
348             my $textrange = $self->{agent}->document->body->createTextRange;
349             return $textrange->findText($string, 0 , $flag);
350             }
351              
352             =head2 PageText()
353              
354             =head2 text()
355              
356             return current page as Plain TEXT which removed HTML tags.
357              
358             =cut
359              
360             sub PageText {
361             my $self = shift;
362             my $text = $self->getAgent->document->documentElement->outerText;
363             $text =~ s/\r//g;
364             if (wantarray){
365             return split (/\n/, $text);
366             } else {
367             return $text;
368             }
369             }
370             sub text {
371             my $self = shift;
372             return $self->PageText(@_);
373             }
374              
375             =head2 link(how, value)
376              
377             =head2 getLink(how, value)
378              
379             Finding hyperlinks.
380              
381             ex).
382             Using 'linktext:' option (text of the link shown on web page)
383             $ie->getLink('linktext:', "About Google")->Click;
384              
385             Using 'linktext:' option with pattern matching
386             $ie->getLink('linktext:', qr/About Google/)->Click;
387              
388             Using 'id:' option ( )
389             $ie->getLink('id:', "1a")->Click;
390              
391             Using 'href:' option ( )
392             $ie->getLink('id:', qr/search.cpan.org/)->click;
393              
394             =cut
395              
396             sub getLink {
397             my ($self, $how, $what) = @_;
398             my $agent = $self->{agent};
399             my $links = $agent->Document->links;
400             my $target_link = __getObject($links, $how, $what) if ($links);
401             my $link_object;
402             if ($target_link){
403             $link_object = Win32::Watir::Element->new();
404             $link_object->{element} = $target_link;
405             $link_object->{parent} = $self;
406             } else {
407             $link_object = undef;
408             $self->_log("WARNING: No link is present in the document with your specified option $how $what");
409             }
410             return $link_object;
411             }
412             sub link {
413             my $self = shift;
414             return $self->getLink(@_);
415             }
416              
417             =head2 links()
418              
419             =head2 getAllLinks()
420              
421             return all array of link_object.
422              
423             ex). print pagename at google search result.
424             foreach my $ln ( $ie->getAllLinks ){
425             print $ln->text."\n" if ($ln->class eq 'l');
426             }
427              
428             =cut
429              
430             sub getAllLinks {
431             my $self = shift;
432             my $agent = $self->{agent};
433             my @links_array;
434             my $links = $agent->Document->links;
435             for (my $n = 0; $n <= $links->length - 1; $n++){
436             my $link_object = Win32::Watir::Element->new();
437             $link_object->{element} = $links->item($n);
438             $link_object->{parent} = $self;
439             push (@links_array, $link_object);
440             }
441             return @links_array;
442             }
443             sub links {
444             my $self = shift;
445             return $self->getAllLinks();
446             }
447              
448             =head2 button(how, what)
449              
450             =head2 getButton(how, what)
451              
452             finding input buttons.
453              
454             =cut
455              
456             sub getButton {
457             my ($self, $how, $what) = @_;
458             my $agent = $self->{agent};
459             my $buttons = $agent->Document->all->tags("input");
460             my $target_button = __getObject($buttons, $how, $what, 'button|img|submit|cancel') if ($buttons);
461             my $button_object;
462             if ($target_button){
463             $button_object = Win32::Watir::Element->new();
464             $button_object->{element} = $target_button;
465             $button_object->{parent} = $self;
466             } else {
467             $button_object = undef;
468             $self->_log("WARNING: No button is present in the document with your specified option $how $what");
469             }
470             return $button_object;
471             }
472             sub button {
473             my $self = shift;
474             return $self->getButton(@_);
475             }
476              
477             =head2 image(how, what)
478              
479             =head2 getImage(how, what)
480              
481             finding img.
482              
483             =cut
484              
485             sub getImage {
486             my ($self, $how, $what) = @_;
487             my $agent = $self->{agent};
488             my $images = $agent->Document->images;
489             my $target_image = __getObject($images, $how, $what) if ($images);
490             my $image_object;
491             if ($target_image){
492             $image_object = Win32::Watir::Element->new();
493             $image_object->{element} = $target_image;
494             $image_object->{parent} = $self;
495             } else {
496             $image_object = undef;
497             $self->_log("WARNING: No image is present in the document with your specified option $how $what\n");
498             }
499             return $image_object;
500             }
501             sub image {
502             my $self = shift;
503             return $self->getImage(@_);
504             }
505              
506             =head2 images()
507              
508             =head2 getAllImages()
509              
510             return array of all image tag.
511              
512             =cut
513              
514             sub getAllImages {
515             my $self = shift;
516             my $agent = $self->{agent};
517             my @image_array;
518             my $images = $agent->Document->images;
519             for (my $n = 0; $n <= $images->length - 1; $n++){
520             my $image_object = Win32::Watir::Element->new();
521             $image_object->{element} = $images->item($n);
522             $image_object->{parent} = $self;
523             push (@image_array, $image_object);
524             }
525             return @image_array;
526             }
527             sub images {
528             my $self = shift;
529             return $self->getAllImages(@_);
530             }
531              
532             =head2 radio(how, what)
533              
534             =head2 getRadio(how, what)
535              
536             return input radio object.
537              
538             =cut
539              
540             sub getRadio {
541             my ($self, $how, $what) = @_;
542             my $agent = $self->{agent};
543             my $inputs;
544             if ($how eq "beforetext:" || $how eq "aftertext:"){
545             $inputs = $agent->Document->all;
546             } else {
547             $inputs = $agent->Document->all->tags("input");
548             }
549             my $target_radio = __getObject($inputs, $how, $what, "radio") if ($inputs);
550             my $radio_object;
551             if ($target_radio){
552             $radio_object = Win32::Watir::Element->new();
553             $radio_object->{element} = $target_radio;
554             $radio_object->{parent} = $self;
555             } else {
556             $radio_object = undef;
557             $self->_log("WARNING: No radio button is present in the document with your specified option $how $what\n");
558             }
559             return $radio_object;
560             }
561             sub radio {
562             my $self = shift;
563             return $self->getRadio(@_);
564             }
565              
566             =head2 checkbox(how, what)
567              
568             =head2 getCheckbox(how, what)
569              
570             return input checkbox object.
571              
572             =cut
573              
574             sub getCheckbox {
575             my ($self, $how, $what) = @_;
576             my $agent = $self->{agent};
577             my $inputs;
578             if ($how eq "beforetext:" || $how eq "aftertext:"){
579             $inputs = $agent->Document->all;
580             } else {
581             $inputs = $agent->Document->all->tags("input");
582             }
583             my $target_checkbox = __getObject($inputs, $how, $what, "checkbox") if ($inputs);
584             my $checkbox_object;
585             if ($target_checkbox){
586             $checkbox_object = Win32::Watir::Element->new();
587             $checkbox_object->{element} = $target_checkbox;
588             $checkbox_object->{parent} = $self;
589             } else {
590             $checkbox_object = undef;
591             $self->_log("WARNING: No checkbox is present in the document with your specified option $how $what\n");
592             }
593             return $checkbox_object;
594             }
595             sub checkbox {
596             my $self = shift;
597             return $self->getCheckbox(@_);
598             }
599              
600             sub getSelectList {
601             my ($self, $how, $what) = @_;
602             my $agent = $self->{agent};
603             my $select_lists = $agent->Document->all->tags("select");
604             my $target_list = __getObject($select_lists, $how, $what, "select-one|select-multiple") if ($select_lists);
605             my $list_object;
606             if ($target_list){
607             $list_object = Win32::Watir::Element->new();
608             $list_object->{element} = $target_list;
609             $list_object->{parent} = $self;
610             } else {
611             $list_object = undef;
612             $self->_log("WARNING: No select list is present in the document with your specified option $how $what\n");
613             }
614             return $list_object;
615             }
616             sub select_list {
617             my $self = shift;
618             return $self->getSelectList(@_);
619             }
620              
621             =head2 getTextBox(how, what)
622              
623             return input (type=text) object.
624              
625             =cut
626              
627             sub getTextBox {
628             my ($self, $how, $what) = @_;
629             my $agent = $self->{agent};
630             my ($inputs, $target_field);
631             if ($how eq "beforetext:" || $how eq "aftertext:"){
632             $inputs = $agent->Document->all;
633             } else {
634             $inputs = $agent->Document->all->tags("input");
635             }
636             if ($inputs){
637             $target_field = __getObject($inputs, $how, $what, "text|password|file");
638             }
639             my $text_object;
640             if ($target_field){
641             $text_object = Win32::Watir::Element->new();
642             $text_object->{element} = $target_field;
643             $text_object->{parent} = $self;
644             } else {
645             $text_object = undef;
646             $self->_log("WARNING: No text box is present in the document with your specified option $how $what\n");
647             }
648             return $text_object;
649             }
650              
651             =head2 getTextArea(how, what)
652              
653             return textarea object.
654              
655             =cut
656              
657             sub getTextArea {
658             my ($self, $how, $what) = @_;
659             my $agent = $self->{agent};
660             my ($inputs, $target_field);
661             if ($how eq "beforetext:" || $how eq "aftertext:"){
662             $inputs = $agent->Document->all;
663             } else {
664             $inputs = $agent->Document->all->tags("textarea");
665             }
666             if ($inputs){
667             $target_field = __getObject($inputs, $how, $what, "textarea");
668             }
669             my $text_object;
670             if ($target_field){
671             $text_object = Win32::Watir::Element->new();
672             $text_object->{element} = $target_field;
673             $text_object->{parent} = $self;
674             } else {
675             $text_object = undef;
676             $self->_log("WARNING: No text area is present in the document with your specified option $how $what\n");
677             }
678             return $text_object;
679             }
680              
681             =head2 text_field(how, what)
682              
683             =cut
684              
685             sub text_field {
686             my ($self, $how, $what) = @_;
687             my $object = $self->getTextBox($how, $what);
688             if ($object){
689             return $object;
690             } else {
691             return $self->getTextArea($how, $what);
692             }
693             }
694              
695             sub getTable {
696             my ($self, $how, $what) = @_;
697             my $agent = $self->{agent};
698             my ($inputs, $target_table);
699             if ($how eq "beforetext:" || $how eq "aftertext:"){
700             $inputs = $agent->Document->all;
701             } else {
702             $inputs = $agent->Document->all->tags("table");
703             }
704             if ($inputs){
705             $target_table = __getObject($inputs, $how, $what);
706             }
707             my $table_object;
708             if ($target_table){
709             $table_object = Win32::Watir::Table->new();
710             $table_object->{table} = $target_table;
711             $table_object->{parent} = $self;
712             } else {
713             $table_object = undef;
714             $self->_log("WARNING: No table is present in the document with your specified option $how $what\n");
715             }
716             return $table_object;
717             }
718              
719             sub getAllTables {
720             my $self = shift;
721             my $agent = $self->{agent};
722             my @links_array;
723             my $links = $agent->Document->all->tags("table");
724             for (my $n = 0; $n < $links->length; $n++){
725             my $link_object = Win32::Watir::Element->new();
726             $link_object->{element} = $links->item($n);
727             $link_object->{parent} = $self;
728             push (@links_array, $link_object);
729             }
730             return @links_array;
731             }
732              
733              
734             =head2 getAllDivs()
735              
736             return all array of div tag.
737              
738             =cut
739              
740             sub getAllDivs {
741             my $self = shift;
742             my $agent = $self->{agent};
743             my @divs_array;
744             my $divs = $agent->Document->divs;
745             for (my $n = 0; $n <= $divs->length - 1; $n++){
746             my $link_object = Win32::Watir::Element->new();
747             $link_object->{element} = $divs->item($n);
748             $link_object->{parent} = $self;
749             push (@divs_array, $link_object);
750             }
751             return @divs_array;
752             }
753             sub divs {
754             my $self = shift;
755             return $self->getAllDivs();
756             }
757              
758             sub __getObject {
759             my ($coll, $how, $what, $type) = @_;
760             my ($aftertext_flag, $input, $index_counter, $regex_flag);
761             my @_re = ();
762             $index_counter = 0 unless (defined $index_counter);
763             $regex_flag = 1 if (ref($what) eq 'Regexp');
764             for (my $n = 0; $n <= $coll->length - 1; $n++){
765              
766             if ($how eq "linktext:" or $how eq 'text:') {
767             my $text = $coll->item($n)->outerText;
768             $text = trim_white_spaces($text);
769             if ($regex_flag){
770             return $coll->item($n) if ($text =~ $what);
771             } else {
772             return $coll->item($n) if ($text eq $what);
773             }
774             }
775              
776             elsif ($how eq "tabtext:") {
777             my $text = $coll->item($n)->outerText;
778             $text = trim_white_spaces($text);
779             if ($regex_flag){
780             return $coll->item($n) if ($text =~ $what);
781             } else {
782             return $coll->item($n) if ($text eq $what);
783             }
784             }
785              
786             elsif ($how eq "id:") {
787             my $id = $coll->item($n)->id;
788             return $coll->item($n) if ($id eq $what);
789             }
790              
791             elsif ($how eq "name:") {
792             my $name = $coll->item($n)->name;
793             if ($regex_flag){
794             return $coll->item($n) if ($name =~ $what);
795             } else {
796             return $coll->item($n) if ($name eq $what);
797             }
798             }
799              
800             elsif ($how eq "value:") {
801             my $value = $coll->item($n)->value;
802             if ($regex_flag){
803             return $coll->item($n) if ($value =~ $what);
804             } else {
805             return $coll->item($n) if ($value eq $what);
806             }
807             }
808              
809             elsif ($how eq "class:") {
810             my $class = $coll->item($n)->{className};
811             if ($regex_flag){
812             if ($class =~ $what){
813             if (wantarray){
814             push(@_re,$coll->item($n));
815             next;
816             } else {
817             return $coll->item($n);
818             }
819             }
820             } else {
821             return $coll->item($n) if ($class eq $what);
822             }
823             }
824              
825             elsif ($how eq "index:") {
826             $index_counter++ if ($coll->item($n)->type =~ m/^($type)$/);
827             return $coll->item($n) if ($index_counter == $what);
828             }
829              
830             elsif ($how eq "caption:") {
831             my $value = $coll->item($n)->value;
832             if ($regex_flag){
833             return $coll->item($n) if ($value =~ $what);
834             } else {
835             return $coll->item($n) if ($value eq $what);
836             }
837             }
838              
839             elsif ($how eq "linkurl:" or $how eq 'url:' or $how eq 'href') {
840             my $url = $coll->item($n)->href;
841             if ($regex_flag){
842             return $coll->item($n) if ($url =~ $what);
843             } else {
844             return $coll->item($n) if ($url eq $what);
845             }
846             }
847              
848             elsif ($how eq "imgurl:" or $how eq 'src:') {
849             my $imgurl = $coll->item($n)->src;
850             if ($regex_flag){
851             return $coll->item($n) if ($imgurl =~ $what);
852             } else {
853             return $coll->item($n) if ($imgurl eq $what);
854             }
855             }
856              
857             elsif ($how eq "alt:") {
858             my $imgurl = $coll->item($n)->alt;
859             if ($regex_flag){
860             return $coll->item($n) if ($imgurl =~ $what);
861             } else {
862             return $coll->item($n) if ($imgurl eq $what);
863             }
864             }
865              
866             elsif ($how eq "beforetext:") {
867             $input = $coll->item($n) if ($coll->item($n)->tagname eq "INPUT");
868             my $text = $coll->item($n)->getAdjacentText("beforeEnd");
869             $text = trim_white_spaces($text);
870             if ($regex_flag){
871             return $input if ($text =~ $what);
872             } else {
873             return $input if ($text eq $what);
874             }
875             $text = $coll->item($n)->getAdjacentText("afterEnd");
876             $text = trim_white_spaces($text);
877             if ($regex_flag){
878             return $input if ($text =~ $what);
879             } else {
880             return $input if ($text eq $what);
881             }
882             }
883              
884             elsif ($how eq "aftertext:") {
885             undef $input;
886             $input = $coll->item($n) if (($coll->item($n)->tagName =~ m/^(INPUT|TEXTAREA)$/) && $coll->item($n)->type =~ m/^($type)$/);
887             #print $coll->item($n)->{type}."\n" if ($aftertext_flag == 1 && $input);
888             return $input if ($aftertext_flag == 1 && $input);
889             unless ($aftertext_flag){
890             my $text = $coll->item($n)->getAdjacentText("beforeEnd");
891             $text = trim_white_spaces($text);
892             if ($regex_flag){
893             $aftertext_flag = 1 if ($text =~ $what);
894             } else {
895             $aftertext_flag = 1 if ($text eq $what);
896             }
897             $text = $coll->item($n)->getAdjacentText("afterEnd");
898             $text = trim_white_spaces($text);
899             if ($regex_flag){
900             $aftertext_flag = 1 if ($text =~ $what);
901             } else {
902             $aftertext_flag = 1 if ($text eq $what);
903             }
904             }
905             }
906              
907             else {
908             print "WARNING: \'$how\' is not supported to get the object\n";
909             }
910             }
911             return @_re;
912             }
913              
914             # * __getObject hasn't type?
915             sub getFrame {
916             my ($self, $how, $what) = @_;
917             my $target_frame;
918             my $agent = $self->{agent};
919             my $frames = $agent->Document->frames;
920             $target_frame = __getObject($frames, $how, $what) if ($frames);
921             if ($target_frame){
922             my %frame = %{$self};
923             my $frameref = \%frame;
924             $frameref->{agent} = $target_frame;
925             bless $frameref;
926             return $frameref;
927             } else {
928             $self->_log("WARNING: No frame is present in the document with your specified option $how $what\n");
929             }
930             }
931             sub frame {
932             my $self = shift;
933             return $self->getFrame(@_);
934             }
935              
936             sub getAllFrames {
937             my $self = shift;
938             my $agent = $self->{agent};
939             my @frames_array;
940             my $frames = $agent->Document->frames;
941              
942             for (my $n = 0; $n <= $frames->length - 1; $n++){
943             my %frame = %{$self};
944             my $frameref = \%frame;
945             $frameref->{agent} = $frames->item($n);
946             bless $frameref;
947             push(@frames_array, $frameref);
948             }
949             return @frames_array;
950             }
951             sub frames {
952             my $self = shift;
953             return $self->getAllFrames(@_);
954             }
955              
956             sub getPopupWindow {
957             my $self = shift;
958             my ($what, $wait) = @_;
959             my $counter = 0;
960             $wait = 2 unless $wait;
961             while($counter <= $wait ){
962             my $shApp = Win32::OLE->new("Shell.Application") || die "Could not start Shell.Application\n";
963             my $windows = $shApp->Windows;
964             for (my $n = 0; $n <= $windows->count - 1; $n++){
965             my $window = $windows->Item($n);
966             my $title = $window->document->title if ($window && defined $window->document);
967             if ($title eq $what){
968             my %popup = %{$self};
969             my $popupref = \%popup;
970             $popupref->{agent} = $window;
971             bless $popupref;
972             $popupref->WaitforDone;
973             return $popupref;
974             }
975             }
976             sleep 1;
977             $counter++
978             }
979             $self->_log("WARNING: No popup window is present with your specified title: $what");
980             }
981              
982             sub WaitforDone {
983             my $self = shift;
984             my $agent = $self->{agent};
985             while ($agent->Busy || $agent->document->readystate ne "complete"){
986             sleep 1;
987             }
988             }
989              
990             sub WaitforDocumentComplete {
991             my $self = shift;
992             my $agent = $self->{agent};
993             while ($agent->document->readystate ne "complete"){
994             sleep 1;
995             }
996             }
997              
998             =head2 autoit
999              
1000             return AutoItX3.Control
1001              
1002             =cut
1003              
1004             sub autoit {
1005             my $self = shift;
1006             unless ( defined $self->{autoit} ){
1007             $self->{autoit} = Win32::OLE->new("AutoItX3.Control");
1008             }
1009             unless ($self->{autoit}){
1010             my $autoitx_dll = $self->_find_autoitx_dll();
1011             if ($autoitx_dll){
1012             register_autoitx_dll($autoitx_dll);
1013             $self->{autoit} = Win32::OLE->new("AutoItX3.Control") ||
1014             die "Could not start AutoItX3.Control through OLE\n";
1015             } else {
1016             $self->_log("Error: AutoItX3.Control is not present in the module.");
1017             exit 1;
1018             }
1019             }
1020             return $self->{autoit};
1021             }
1022              
1023             =head2 bring_to_front()
1024              
1025             make IE window active.
1026              
1027             =cut
1028              
1029             sub bring_to_front {
1030             my $self = shift;
1031             my $title = shift;
1032             unless ($title){
1033             if ($self->ie_version == 6){
1034             $title = 'Microsoft Internet Explorer';
1035             } elsif ($self->ie_version >= 7){
1036             $title = 'Windows Internet Explorer';
1037             }
1038             }
1039             $self->autoit->AutoItSetOption("WinTitleMatchMode", 2);
1040             $self->autoit->WinActivate($title);
1041             $self->autoit->AutoItSetOption("WinTitleMatchMode", 1);
1042             }
1043              
1044             =head2 ie_version()
1045              
1046             return IE major version (6 or 7 or 8).
1047              
1048             =cut
1049              
1050             sub ie_version {
1051             my $self = shift;
1052             return $self->{IE_VERSION};
1053             }
1054             sub _check_ie_version {
1055             my $self = shift;
1056             ## HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer
1057             ## Version REG_SZ 8.0.6001.18813
1058             my $_cmd = 'reg query "HKLM\SOFTWARE\Microsoft\Internet Explorer" /v Version';
1059             my $_result = `$_cmd`;
1060             my $_ver;
1061             foreach my $line ( split(/[\n\r]+/,$_result) ){
1062             if ($line =~ /Version\s+REG_SZ\s+([\d\.]+)/){
1063             $_ver = $1;
1064             $self->_log("DEBUG: IE_VERSION=$_ver\n") if ($self->{warnings} or $warn);
1065             }
1066             }
1067             if ($_ver){
1068             my $_major_ver = $_ver;
1069             $_major_ver =~ s/\..*$//;
1070             if ($_major_ver >= 5.0 && $_major_ver <= 6.0){
1071             die "Could not use IE version 5.x\n";
1072             }
1073             elsif ($_major_ver >= 6.0 && $_major_ver < 7.0){
1074             return 6;
1075             }
1076             elsif ($_major_ver >= 7.0 && $_major_ver < 8.0){
1077             return 7;
1078             }
1079             elsif ($_major_ver >= 8.0 && $_major_ver < 9.0){
1080             return 8;
1081             }
1082             elsif ($_major_ver >= 9.0 && $_major_ver < 10.0){
1083             return 9;
1084             } else {
1085             die "Unknown Internet Explorer VERSION - '$_ver'\n";
1086             }
1087             } else {
1088             die "Can't get Internet Explorer VERSION.\n";
1089             }
1090             }
1091              
1092             sub _check_os_name {
1093             my $self = shift;
1094             unless ( exists($self->{OS_NAME}) ){
1095             $self->{OS_NAME} = Win32::GetOSName();
1096             }
1097             print STDERR "DEBUG: _check_os_name(): ".$self->{OS_NAME}."\n" if ($self->{warnings});
1098             return $self->{OS_NAME};
1099             }
1100              
1101             sub _find_autoitx_dll {
1102             my $self = shift;
1103             my $dllname = "AutoItX3.dll";
1104             $dllname = "AutoItX3_x64.dll" if ( $Config{'archname'} =~ /MSWin32-x64/ );
1105             foreach my $libdir (@INC)
1106             {
1107             if ( $libdir =~ /^\/cygdrive\/(\w+)\/(.*)$/i ){
1108             $libdir = "${1}:/${2}";
1109             }
1110             my $dllpath = "$libdir/Win32/Watir/$dllname";
1111             if ( -e "$dllpath" ){
1112             $self->_log("DEBUG: _find_autoitx_dll: $dllpath");
1113             return $dllpath;
1114             }
1115             }
1116             return "";
1117             }
1118              
1119             =head2 register_autoitx_dll(dll_path)
1120              
1121             Register specified dll to Server.
1122              
1123             arg[0] : dll path.
1124              
1125             =cut
1126              
1127             sub register_autoitx_dll {
1128             my $self = shift if (ref($_[0]) eq 'Win32::Watir');
1129             my $dll = shift;
1130             my $_tit = "Attension: Registering AutoItX.Control";
1131             my $_msg = "Win32::Watir require AutoItX.Control, register AutoItX now?\r\n".
1132             "You must be Administrator (or 'administrator mode').";
1133             my $_ret = msgbox("$_tit","$_msg",4);
1134             if ($_ret == 6){
1135             Win32::RegisterServer($dll);
1136             } else {
1137             msgbox("$_tit","registration canceled, script exit.",0);
1138             }
1139             }
1140              
1141             =head2 push_security_alert_yes(wait)
1142              
1143             push "Yes" button at "Security Alert" dialog window.
1144              
1145             wait: number of sec, for waiting.
1146              
1147             =cut
1148              
1149             sub push_security_alert_yes {
1150             my ($self, $wait) = @_;
1151             $wait = 5 unless $wait;
1152             my $title;
1153             if ( $self->ie_version == 6 ){
1154             $title = 'Security Alert';
1155             } else {
1156             $title = 'Security Alert'; # ToDO
1157             }
1158             my $window = $self->autoit->WinWait($title, "", $wait);
1159             if ($window){
1160             $self->autoit->WinActivate("$title");
1161             $self->autoit->Send('!y');
1162             } else {
1163             $self->_log("WARNING: No Security Alert dialog is present. Function push_security_alert_yes is timed out.");
1164             }
1165             }
1166              
1167             =head2 push_confirm_button_ok(title, wait)
1168              
1169             type enter key (OK) at JavaScript confirm dialog window.
1170              
1171             =cut
1172              
1173             sub push_confirm_button_ok {
1174             my ($self, $title, $wait) = @_;
1175             $title = 'Windows Internet Explorer' unless $title;
1176             $wait = 5 unless $wait;
1177             my $window = $self->autoit->WinWait($title, "", $wait);
1178             if ($window){
1179             $self->autoit->WinActivate($title);
1180             $self->autoit->Send('{ENTER}');
1181             }
1182             }
1183              
1184             =head2 push_button_yes()
1185              
1186             push "Yes" button at JavaScript confirm dialog window.
1187              
1188             =cut
1189              
1190             sub push_button_yes {
1191             my ($self, $title, $wait) = @_;
1192             $title = 'Windows Internet Explorer' unless $title;
1193             $wait = 5 unless $wait;
1194             my $window = $self->autoit->WinWait($title, "", $wait);
1195             if ($window){
1196             $self->autoit->WinActivate($title);
1197             $self->autoit->Send('!y');
1198             } else {
1199             $self->_log("WARNING: No dialog is present with title: $title. Function push_button_yes is timed out.");
1200             }
1201             }
1202              
1203             =head2 push_confirm_button_cancel(title, wait)
1204              
1205             type escape key (cancel) at JavaScript confirm dialog window.
1206              
1207             =cut
1208              
1209             sub push_confirm_button_cancel {
1210             my ($self, $title, $wait) = @_;
1211             $title = 'Windows Internet Explorer' unless $title;
1212             $wait = 5 unless $wait;
1213             my $window = $self->autoit->WinWait($title, "", $wait);
1214             if ($window){
1215             $self->autoit->WinActivate($title);
1216             $self->autoit->Send('{ESCAPE}');
1217             }
1218             }
1219              
1220             =head2 logon(options)
1221              
1222             Enter username, password at Basic Auth dialog window.
1223              
1224             options : hash
1225              
1226             title : dialog window title.
1227             user : username.
1228             password : username.
1229              
1230             ex)
1231             $ie->goto('https://pause.perl.org/pause/authenquery', 1); ## no wait
1232             $ie->logon(
1233             title => "pause.perl.org へ接続",
1234             user => "myname",
1235             password => "mypassword",
1236             );
1237              
1238             =cut
1239              
1240             sub logon {
1241             my $self = shift;
1242             my %opt = @_;
1243             $opt{wait} = 5 unless ( $opt{wait} );
1244             my $window = $self->autoit->WinWait($opt{title}, "", $opt{wait});
1245             if ($window){
1246             $self->autoit->WinActivate($opt{title});
1247             $self->autoit->Send($opt{user});
1248             $self->autoit->Send('{TAB}');
1249             $self->autoit->Send($opt{password});
1250             $self->autoit->Send('{ENTER}');
1251             } else {
1252             $self->_log("WARNING: No logon dialog is present with title \'$opt{title}\'. Function logon is timed out.\n");
1253             }
1254             }
1255              
1256             =head2 maximize_ie(title)
1257              
1258             maximize specified title window.
1259              
1260             arg[0] : window Title name (optional)
1261              
1262             =cut
1263              
1264             sub maximize_ie {
1265             my $self = shift;
1266             my $title = shift;
1267             unless ($title){
1268             if ($self->ie_version == 6){
1269             $title = 'Microsoft Internet Explorer';
1270             } elsif ($self->ie_version >= 7){
1271             $title = 'Windows Internet Explorer';
1272             }
1273             }
1274             $self->autoit->AutoItSetOption("WinTitleMatchMode", 2);
1275             $self->autoit->WinSetState("$title", "", $self->autoit->SW_MAXIMIZE);
1276             $self->autoit->AutoItSetOption("WinTitleMatchMode", 1);
1277             return 1;
1278             }
1279              
1280             =head2 delete_cookie()
1281              
1282             delete IE cookies.
1283              
1284             =cut
1285              
1286             sub delete_cookie {
1287             my $self = shift;
1288             my $folder = Win32::GetFolderPath(Win32::CSIDL_COOKIES, undef);
1289             opendir(my $_dh,"$folder") or die $@;
1290             my @files = grep { /^\w+/ && -w "$folder\\$_" } readdir($_dh);
1291             my $deleted = 0;
1292             foreach my $_f (@files){
1293             next if ($_f =~ /desktop\.ini$/i);
1294             if ( unlink("$folder\\$_f") ){
1295             $deleted++;
1296             print STDERR "DEBUG: delete_cookie(): $folder\\$_f\n" if ($self->{warnings});
1297             }
1298             }
1299             closedir($_dh);
1300             return $deleted;
1301             }
1302              
1303             =head2 delete_cache()
1304              
1305             delete IE caches.
1306              
1307             =cut
1308              
1309             sub delete_cache {
1310             my $self = shift;
1311             my $folder = Win32::GetFolderPath(Win32::CSIDL_INTERNET_CACHE, undef);
1312             opendir(my $_dh,"$folder") or die $@;
1313             my @files = grep { /^\w+/ && -w "$folder\\$_" } readdir($_dh);
1314             my $deleted = 0;
1315             foreach my $i (@files){
1316             next if (-d "$folder\\$i" or $i =~ /desktop\.ini$/i);
1317             if ( -f "$folder\\$i" ){
1318             if ( unlink("$folder\\$i") ){
1319             $deleted++;
1320             print STDERR "DEBUG: delete_cache(): $folder\\$i\n" if ($self->{warnings});
1321             } else {
1322             print STDERR "DEBUG: delete_cache(): can't delete $folder\\$i\n" if ($self->{warnings});
1323             }
1324             } elsif ( -d "$folder\\$i" ){
1325             if ( rmdir("$folder\\$i") ){
1326             $deleted++;
1327             } else {
1328             print STDERR "DEBUG: delete_cache(): can't delete $folder\\$i\n" if ($self->{warnings});
1329             }
1330             } else {
1331             print STDERR "DEBUG: delete_cache(): skipped - $folder\\$i\n";
1332             }
1333             }
1334             closedir($_dh);
1335             return $deleted;
1336             }
1337              
1338              
1339             =head2 msgbox(title, message, mode)
1340              
1341             show PopUp dialog window.
1342              
1343             title : dialog window title.
1344             message: messages.
1345             mode : mode of buttons:
1346             . 0 = OK
1347             . 1 = OK and Cancel
1348             . 2 = Abort, Retry, and Ignore
1349             . 3 = Yes, No and Cancel
1350             . 4 = Yes and No
1351             . 5 = Retry and Cancel
1352             return values:
1353             . 0 Error
1354             . 1 OK
1355             . 2 Cancel
1356             . 3 Abort
1357             . 4 Retry
1358             . 5 Ignore
1359             . 6 Yes
1360             . 7 No
1361              
1362             see more detail: http://search.cpan.org/perldoc?Win32
1363              
1364             =cut
1365              
1366             sub msgbox {
1367             my $title = shift;
1368             my $message = shift;
1369             my $mode = shift || 0;
1370             my $_ret = Win32::MSgBox($message,$mode,$title);
1371             return $_ret;
1372             }
1373              
1374              
1375             =head2 trim_white_spacs()
1376              
1377             return string - trim \s+
1378              
1379             =cut
1380              
1381             sub trim_white_spaces {
1382             my $string = shift;
1383             $string =~ s/^\s+//;
1384             $string =~ s/\s+$//;
1385             return $string;
1386             }
1387              
1388             =head2 _log(string)
1389              
1390             private method for testing.
1391             use only with t/*.t test.
1392              
1393             =cut
1394              
1395             sub _log {
1396             my $self = shift;
1397             return 1 if ($warn or $self->{warnings});
1398             my $str = shift;
1399             chomp($str);
1400             unless ($str){ return 1; }
1401             select STDERR; $| = 1;
1402             select STDOUT; $| = 1;
1403             foreach my $line (split(/\n/,$str)){
1404             chomp($line);
1405             print STDERR "[$$]: $line\n";
1406             }
1407             }
1408              
1409             1;
1410             __END__