jIETest : an updated version of SAMIE in Perl. Uses OO extensively and unit tested thoroughly.

Download jietest.zip

Synopsis:

jIETest.pm
GatedThread.pm
jIELogger.pm
jIESelfTest.pm
jIETestNode.pm
LeakTest.pm
gendoc.pl
testjietest.html
testjietest.pl
testjietest_embbededword.doc
testjietest_frame1.html
testjietest_frame2.html
testjietest_frames.html
testjietest_ie5.html
testjietest_ie7.html
testjietest_img1src.jpg
testjietest_link.html
testjietest_popup1.html
testjitest.cfg


jIETest.pm

Synopsis
#!perl -w

package jIETest;
#use LeakTest; #uncomment to run leak test

#=title jIETest - Perl module for automating Internet Explorer
#=head1 jIETest
#= A Perl module for automating Internet Explorer.
#=head2 Description
#= jIETest runs the Internet Explorer COM object model. From there you
#= can manipulate IE to click, navigate, tec.
#=
#= The original version of jIETest came from samie
#= <a href='http://samie.sourceforge.net/'>http://samie.sourceforge.net</a>
#= I took it and:
#= <ul>
#= <li>refactored extensively
#= <li>rewrote some parts
#= <li>added embedded documentation
#= <li>added a lot of tracing/debug code
#= <li>added result log
#= <li>removed procedural style interface and replaced it with object-oriented style
#= <li>implemented a naming convention for the functions
#= <li>added file/line information to the result log
#= <li>wrote self tests which translates into 2300 or so asserts.
#= These can be invoked randomly (see testjietest.pl), it takes about
#= 30 minutes to run 2000 tests (22,500 asserts).
#= </ul>
#=
#= Check here for a Ruby version:
#= <a href='http://rubyforge.org/projects/wtr/'>http://rubyforge.org/projects/wtr</a>
#= and
#= <a href='http://pamie.sourceforge.net/'>http://pamie.sourceforge.net</a>
#= for a Python version.
#=
#=head2 Author
#= John Arrizza (+ the samie authors + the watir authors)
#=end
#=
#=head2 Configuration
#=
#= These are the versions I use to test as reported by Module::Versions::Report
#= <table>
#= <tr><td>ActiveState Perl<td>v5.8.8 build 822 (or later)
#= <tr><td>AutoLoader<td>v5.63
#= <tr><td>Exporter<td>v5.60;
#= <tr><td>Thread::Semaphore<td>v2.06;
#= <tr><td>threads<td>v1.72
#= <tr><td>threads::shared<td>v1.12
#= <tr><td>Time::HiRes<td>v1.9707
#= <tr><td>Tk<td>v804.027;
#= <tr><td>Tk::ItemStyle<td>v4.004;
#= <tr><td>Tk::LabFrame<td>v4.010;
#= <tr><td>Tk::Tree<td>v4.005;
#= <tr><td>Win32::Capture<td>v1.1;
#= <tr><td>Win32::GUI<td>v1.06
#= <tr><td>Win32::GUI::DIBitmap<td>v0.17;
#= <tr><td>Win32::GuiTest<td>v1.54;
#= <tr><td>Win32::Mutex<td>v1.02;
#= <tr><td>Win32::OLE<td>v0.1707;
#= </table>
#
#=head2 Installation
#= Using activestate Perl v5.88 build 822 or later, the following additional actions are required:
#= <ul>
# not needed??  <li>for perl 5.10: ppm rep add uwinnipeg http://cpan.uwinnipeg.ca/PPMPackages/10xx/
# not needed??  <li>for perl 5.8 : ppm rep add uwinnipeg http://cpan.uwinnipeg.ca/PPMPackages/8xx/
#= <li>ppm rep add bribes  http://www.bribes.org/perl/ppm
#= <li>ppm install Win32-GUI (v1.06 or later)
#= <li>ppm install Win32-GuiTest
#= <li>ppm install Win32-Capture
#= <li>ppm install Tk   (for self-tests in testjietest.pl)
#= </ul>
#
#=head2 Known Bugs
#= <ul>
#= <li>Frames is partially working. Not fully tested.
#= <li>MSWord pages cause certain functions to fail with OLE errors: VerifyTitle, PrintObjectInfo. There may be others.
#= </ul>
#=end
#=
#=head2 Missing Features
#= <ul>
#= <li> add timeouts on page loads
#= <li> Form::Click click an element within a given form
#= <li> unordered lists
#= <li> ordered lists
#= <li> frames
#= <li> handle special characters in text
#= <li> map
#= <li> input type=file
#= <li> input type=hidden
#= <li> input type="image.png"
#= </ul>
#=end

use 5.8.8;
use strict;
use warnings;

use jIELogger;
use jIETestNode;
use GatedThread;

use Win32::OLE qw(EVENTS);
Win32::OLE->Option(_Unique => 1, Warn => 3);

use Win32::GUI();
use Win32::GUITEST();
use Win32::Capture();

use threads;
use threads::shared;
use Time::HiRes qw(gettimeofday);

require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
  ClearResult
  ToResult
);

#Coding Conventions:
#- return codes from type::Verifyxxx: 1 is ok, 0 an error occurred
#- return codes from type::Isxxx: 1 is ok, 0 an error occurred
#
#- subs that start with an upper case letter are external.
#- Internal subs must start with a lower case letter
#- Internal subs starting with findxxx return 1 if found, 0 if not
#- Internal subs starting with checkxxx do not return a value, and call TestResult()
#- subroutines starting with 'check' are internal
#- subroutines starting with 'Verify' are external (for users)

our $VERSION = '0.05';

#keeps track of hwnd's for every session started. It maps the hwnd to the self vrbl
our %gHwndHash = ();
our @gSessions = ();
our $gSessionId = 1;

#used for Message Box handling
#need to be shared since the message box is killed in a thread
our $gMessageBoxTimeout :shared = 0;
our @gMessageBoxText :shared = ();
our $gExpectedCompatMode :shared = 5;

#------------------------------------------------
#-- Common routines, IEApp Traversal routines
#------------------------------------------------

#------------------------
#-- dynamically called by perl if a method is not defined
our $AUTOLOAD;
sub AUTOLOAD
  {
  my ($self) = @_;
  my ($mname) = $AUTOLOAD =~ /::(.*)/;
  if ($mname eq 'DESTROY')
    {
    return 0;
    }

  jIELogger::CallerInfo(caller(0));
  jIELogger::CallerInfoSub($mname);

  jIETest::TestResult('SYNTAX', "Unknown method '$AUTOLOAD' called from " . (caller(1))[3] . " at " . (caller(1))[1] . "(" . (caller(1))[2] . ")");
  jIELogger::ClearCallerInfo();
  return 0;
  }

#------------------------
#-- use this to check syntax error of incoming parameters
sub checksyntax
  {
  my ($val, $msg) = @_;
  return if defined $val;
  TestResult('SYNTAX', $msg);
  jIELogger::ForceClearCallerInfo();
  die $msg . "\n";
  }

#------------------------
#-- use this to check valid values of incoming parameters
sub checkvalid
  {
  my $var = shift;
  my $prefix = shift;
  my @vals = @_;

  my $msg = $prefix . ": '$var' is invalid. Valid values are: " . join(', ', @vals);
  map { return if $var eq $_ } @vals;
  TestResult('SYNTAX', $msg);
  jIELogger::ForceClearCallerInfo();
  die $msg . "\n";
  }

#------------------------
#-- use this to check if the node exists, if not issue a warning to the Result log
sub checkexists
  {
  my $var = shift;
  return if defined $var;

  my $prefix = shift;
  my $value = shift;

  my $msg = $prefix . ": '$value' does not exist.";
  TestResult('WARNING', $msg);
  jIELogger::ForceClearCallerInfo();
  }

#------------------------
#-- get value of the field from the given object
sub getFieldValue
  {
  my ($object, $fieldname) = @_;

  my $val = eval { $object->$fieldname };
  $val = '' unless defined $val;
  $val =~ s/\s+$//;
  $val =~ s/^\s+//;
  return $val;
  }

#------------------------
# perform an action on all tags of the given type
sub forAllTags
  {
  my ($self, $tag, $raction) = @_;
  my $document = $self->{IEApp}->{Document};
  for (my $i = 0; $i < $document->all->length; $i++)
    {
    my $node = $document->all($i);
    next unless $document->all($i)->tagName eq $tag;
    &$raction($node);
    }
  $document = undef; #undef needed to release OLE memory
  }

#-------------
sub findDocumentAttribute
  {
  my ($self, $name, $value) = @_;

  my $document = $self->{IEApp}->{Document};
  my $actual = $document->{$name};
  $self->debug('findDocumentAttribute: found \'' . $actual . "'\n");
  my $rc = ($actual =~ /\Q$value\E/i) ? 1 : 0;
  $actual = undef; #undef needed to release OLE memory
  $document = undef; #undef needed to release OLE memory
  return $rc;
  }

#-------------
# returns 1 if found, else 0
sub checkDocumentAttribute
  {
  my ($self, $name, $value) = @_;

  my $rc = $self->findDocumentAttribute($name, $value);
  if ($rc)
    {
    TestResult('PASS', "Found $name '$value'");
    }
  else
    {
    TestResult('FAIL', "$name '$value' not found");
    }
  return $rc;
  }

#-------------
sub findNodeInnerText
  {
  my ($self, $tagname, $value, $count) = @_;

  my $foundnodetype = 0;
  my $tagcount = $count;
  my $document = $self->{IEApp}->{Document};
  next unless defined($document->DocumentElement);
  my $rc = 0;
  my $node;
  my $innertext;
  for (my $i = 0; $i < $document->all->length; $i++)
    {
    $innertext = undef; #undef needed to release OLE memory
    $node = undef; #undef needed to release OLE memory
    $node = $document->all($i);
    next unless $node->tagName eq $tagname;
    $foundnodetype++;

    $innertext = getFieldValue($node, 'innerText');
    $self->debug("found $tagname, innertext='$innertext'\n");
    next unless $innertext =~ /\Q$value\E/;
    if ($tagcount == 0)
      {
      $rc = 1;
      last;
      }
    $tagcount--;
    }
  $innertext = undef;
  $node = undef; #undef needed to release OLE memory
  $document = undef; #undef needed to release OLE memory
  return $rc;
  }

#-------------
# returns 1 if found, else 0
sub checkNodeInnerText
  {
  my ($self, $tagname, $value, $count) = @_;

  checksyntax($tagname, "Parameter 'tagname' is missing");
  checksyntax($value, "Parameter 'value' is missing");

  my $rc = 0;
  my $foundnodetype = 0;
  my $tagcount = $count;
  my $document = $self->{IEApp}->{Document};

  return $rc unless defined($document->DocumentElement);

  my $node;
  my $innertext;
  for (my $i = 0; $i < $document->all->length; $i++)
    {
    $node = undef; #release OLE memory
    $node = $document->all($i);
    next unless $node->tagName eq $tagname;
    $foundnodetype++;

    $innertext = undef; #release OLE memory
    $innertext = getFieldValue($node, 'innerText');
    $self->debug("found $tagname, innertext='$innertext'\n");
    next unless $innertext =~ /\Q$value\E/;
    if ($tagcount == 0)
      {
      TestResult('PASS', "'$tagname' found with value '$value'");
      $innertext = undef; #release OLE memory
      $node = undef; #release OLE memory
      $document = undef; #release OLE memory
      return 1;
      }
    $tagcount--;
    }

  $innertext = undef; #release OLE memory
  $node = undef; #release OLE memory
  $document = undef; #release OLE memory

  if ($foundnodetype == 0)
    {
    TestResult('FAIL', "'$tagname' not found.");
    }
  else
    {
    TestResult('FAIL', "$foundnodetype '$tagname' found, none had value '$value'");
    }
  return $rc;
  }

#-------------
#-- returns 1 if present, 0 otherwise
sub findIsTextPresent
  {
  my ($self, $text, $count) = @_;
  $count = 0 unless defined $count;

  my $tagcount = $count;
  my $document = $self->{IEApp}->{Document};
  die "Missing DocumentElement" unless defined($document->DocumentElement);
  my $rc = 0;
  my $node;
  my $innertext;
  for (my $i = 0; $i < $document->all->length; $i++)
    {
    $node = undef;
    $node = $document->all($i);

    $innertext = undef;
    $innertext = getFieldValue($node, 'innerText');
    if ($innertext =~ /\Q$text\E/)
      {
      if ($tagcount == 0)
        {
        $rc = 1;
        last;
        }
      $tagcount--;
      }
    }
  $innertext = undef;
  $node = undef;
  return $rc;
  }

#------------------------
#-- checks if the given parameter is a SCALAR or a regular expression
#-- returns the type, and a subroutine reference that can be use to match the value
sub getValueMatcher
  {
  my ($value) = @_;
  my $type = ref($value);
  my $rsub = sub {return ($_[0] =~ $_[1]) };
  if ($type eq '')
    {
    $type = ref(\$value);
    $rsub = sub {return  ($_[0] eq $_[1]) };
    }

  #check for unrecognized type (i.e. not scalar or regexp)
  if ($type ne 'SCALAR' and $type ne 'Regexp')
    {
    my $msg = "Parameter 'value' is not a scalar or a regular expression";
    TestResult('SYNTAX', $msg);
    jIELogger::ForceClearCallerInfo();
    die $msg . "\n";
    }
  return ($type, $rsub);
  }

#------------------------
# returns 0: field matches
# returns 1: field does not match
sub checkFieldMatch
  {
  my ($self, $elemname, $node, $i, $value, @fields) = @_;

  my ($type, $rmatcher) = getValueMatcher($value);

  my $fieldval;
  foreach my $field (@fields)
    {
    $fieldval = undef;
    $fieldval = getFieldValue($node, $field);
    next unless defined $fieldval;
    if (&$rmatcher($fieldval, $value))
      {
      $self->debug("found $elemname, i=$i match:  $field='$fieldval'\n");
      $fieldval = undef;
      return 0;
      }
    $self->debug("found $elemname, i=$i no match:  $field='$fieldval'\n");
    }
  $fieldval = undef;
  $self->debug("found $elemname, i=$i no field matched.\n");
  return 1;
  }

#------------------------
#- assumes:
#-   rsearch returns 0 if node found, 1 if not found
#-   raction returns void
sub getTagNode
  {
  my ($self, $tag, $type, $rsearch, $count) = @_;
  my $tagcount = $count;
  $self->debug("getTagNode: looking for tag='$tag' count=$tagcount\n");
  my $document = $self->{IEApp}->{Document};
  my $node;
  for (my $i = 0; $i < $document->all->length; $i++)
    {
    $node = undef;
    $node = $document->all($i);
    next unless $node->tagName eq $tag;
    $self->debug("getTagNode: [$i] found tag='$tag' \n");
    next if defined $type and !defined $node->type;
    next if defined $type and $node->type ne $type;
    $self->debug("getTagNode: calling search fn\n");
    my $rc = &$rsearch($node, $i);
    next if $rc == 1; #no match, keep looking.

    #matched, call the action
    if ($tagcount == 0)
      {
      $self->debug("getTagNode: found tag, tagcount=$tagcount\n");
      $document = undef;
      return $node;
      }
    $self->debug("getTagNode: found tag, tagcount=$tagcount, not zero, searching...\n");
    $tagcount--;
    }
  $node = undef;
  $document = undef;
  return $node;
  }

#------------------------
# get IE compatibility mode
sub compatMode
  {
  my ($self) = @_;
  my $document = $self->{IEApp}->{Document};

  #this code from MSDN site (originally in javascript)
  #also see http://msdn.microsoft.com/en-us/library/ms533876(VS.85).aspx

  my $mode;
  eval { $mode = $document->{documentMode} }; #wrap it in an eval, otherwise OLE call fails on non-IE8
  # IE8 if mode is defined, otherwise...
  if (!defined $mode)
    {
    $mode = 5; #Assume quirks mode unless proven otherwise.
    my $compatmode = $document->{compatMode};
    $mode = 7 if defined $compatmode and $compatmode eq 'CSS1Compat'; #standards mode
    }
  $gExpectedCompatMode = $mode;
  return $mode;
  }

##---------------------------------------------
#=head1 Session Routines
#=end

#------------------------
#= Creates an instance of jIETest object.
#=returns a jIETest object
#=parms
#=parm none:
#=endparms
sub new #=function
  {
  my ($class) = @_;
  my $self = {};
  $self->{Id} = $gSessionId++;
  $self->{MessageBoxThread} = 0;
  $self->{IEApp} = undef;
  $self->{RefreshPage} = 0;

  #indicates whether user is expecting a security alert popup or not
  $self->{CleanSecurityAlertPopup} = 0;

  #indicates whether user is expecting a login popup or not
  $self->{CleanLoginPopup} = 0;

  #parameters used by login popup
  $self->{LoginUserid} = '';
  $self->{LoginPassword} = '';
  $self->{LoginTitle} = '';

  #used to keep track of how many events have come in during a messageloop
  #we expect at least one event
  $self->{EventCount} = 0;

  #used to keep track of whether a QuitMessageLoop has been called
  $self->{QuitMessageLoop} = 0;

  #if a navigation error occurs, keep track of it
  #and clean up when other events come in
  $self->{NavigateError} = 0;

  #if the url loads multiple frames/pages, keep track of which one we're at
  $self->{DocCounter} = 0;

  #keeps track of the last set of status messages (at the bottom of IE window)
  @{ $self->{LastStatusMessages} } = ();

  bless($self, $class);
  return $self;
  }

#------------------------
#= Sets the Debug verbosity
#=
#=parms
#=parm mode: 'all' or ''; default ''
#=returns none
#=endparms
sub SetDebug #=function
  {
  my ($self, $mode) = @_;
  $mode = '' unless defined $mode;
  jIELogger::SetDebug($mode);
  }

#------------------------
#= Starts an Internet Explorer session. This must be the first command to be issued.<br>
#= If it fails, the script is exited.
#=returns none
#=parms
#=parm maximize: 1 (default) display window maximize, 0 display
#=endparms
sub Start #=function
  {
  my ($self, $maximized, $compatmode) = @_;
  jIELogger::CallerInfo(caller(0));

  $maximized = 1 unless defined $maximized;
  checkvalid($maximized, "Parameter 'maximized'", 0, 1);

  $compatmode = 8 unless defined $compatmode;
  checkvalid($compatmode, "Parameter 'compatmode'", 5, 7, 8);
  $gExpectedCompatMode = $compatmode;

  if ($self->{MessageBoxThread} == 0)
    {
    $self->debug("Start: creating thread\n");
    $self->{MessageBoxThread} = new GatedThread('waitForMessageBox', \&waitForMessageBoxIsDone, \&waitForMessageBox);
    }

  #the {IEApp} is an instance of the object InternetExplorer,
  # see http://msdn.microsoft.com/en-us/library/aa752084(VS.85).aspx

  $self->{IEApp} = Win32::OLE->new("InternetExplorer.Application") || die "Could not start Internet Explorer.Application\n";
  my $hwnd = $self->{IEApp}->{HWND};
  #associate the hwnd (which is unique) to self, so we
  #can find it later in the event handler
  $gHwndHash{$hwnd} = $self;

  Win32::OLE->WithEvents($self->{IEApp}, \&handleEvent, 'DWebBrowserEvents2');

  $self->{IEApp}->{menubar} = 1;
  $self->{IEApp}->{toolbar} = 1;
  $self->{IEApp}->{statusbar} = 1;
  $self->{IEApp}->{visible} = 1;

  if ($maximized)
    {
    $self->{IEApp}->{left} = 0;
    $self->{IEApp}->{top} = 0;
    $self->{IEApp}->{height} = 700;
    $self->{IEApp}->{width} = 1000;
    Win32::GUI::Maximize($hwnd);
    }

  Win32::GuiTest::SetActiveWindow($hwnd);
  $hwnd = undef;  #undef releases OLE memory
  jIELogger::ClearCallerInfo();
  }

#------------------------
#= Quits the current session.
#= If this command is not used, the last IE session remains up and you will
#= have to kill it manually.
#=returns none
#=parms
#=parm none:
#=endparms
sub Quit  #=function
  {
  my ($self) = @_;
  $self->{IEApp}->Quit();

  my $hwnd = $self->{IEApp}->{HWND};
  $self->{IEApp} = undef; #undef releases OLE memory
  $gHwndHash{$hwnd} = undef; #undef releases OLE memory
  }

#------------------------
#= Gets IE Compatibility mode
#=
#=returns 5, 6, 7 or 8
#=parms
#=parm none:
#=endparms
sub GetCompatMode #=function
  {
  my ($self) = @_;
  return $self->compatMode();
  }

#------------------------
#= Get a screen capture of the client area and save it to a file
#=
#=returns none
#=parms
#=parm filename: the file to save the screen to
#=endparms
sub CaptureWindow #=function
  {
  my ($self, $filename) = @_;

  my $hwnd = $self->{IEApp}->{HWND};
  #capture window; wait 1 second; capture client (has no effect)
  my $image = Win32::Capture::CaptureWindow($hwnd, 0, 1);
  $image->SaveToFile($filename);
  }

##---------------------------------------------
#=head1 Navigation Routines
#=end

#------------------------
#= Goes to the given url.
#=
#=returns none
#=parms
#=parm url: the url to navigate to
#=endparms
sub NavigateTo  #=function
  {
  my ($self, $url) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($url, "Parameter 'url' is missing");

  $self->{IEApp}->navigate($url);
  $self->debug("NavigateTo: '$url'\n");
  $self->waitForDocumentComplete('wait');
  jIELogger::ClearCallerInfo();
  }

#------------------------
#= Navigates back one page (if there is one). This is equivalent to
#= pressing the Back button on the browser.
#=returns none
#=parms
#=parm none:
#=endparms
#note: there is no return code because the back button always exists
sub ClickBackButton  #=function
  {
  my ($self) = @_;
  jIELogger::CallerInfo(caller(0));

  $self->debug("ClickBackButton: enter\n");
  $self->{IEApp}->GoBack;
  $self->debug("ClickBackButton: pressed, waiting for doc complete\n");
  $self->waitForDocumentComplete('wait');
  $self->debug("ClickBackButton: done waiting\n");
  jIELogger::ClearCallerInfo();
  }

#------------------------
# There is a known IE bug that DocumentComplete is not sent for a page refresh
#1. Register to BeforeNavigate2, DocumentComplete, DownloadComplete events.
#2. Declare a global boolean by the name of refresh and give is the value of true.
#3. On the BeforeNavigate2 event set the value of the boolean to false.
#4. On the DocumentComplete event set the value of the boolean to true.
#5. On the DownloadComplete event check the value of the boolean and if its true do whatever you want 
#
#= Refreshes the current page.
#= It is equivalent to pressing the Refresh button on the browser.
#=returns none
#=parms
#=parm none:
#=endparms
sub Refresh #=function
  {
  my ($self) = @_;
  $self->{IEApp}->Refresh();
  $self->{RefreshPage} = 1;
  $self->waitForDocumentComplete('wait');
  }

##---------------------------------------------
#=head1 Popup Routines
#=end

#------------------------
#= Get next popup session object.
#=returns jIETest object
#=parms
#=parm none:
#=endparms
sub GetNextPopup #=function
  {
  my ($self) = @_;
  return shift @gSessions;
  }

#------------------------
#= Expect a Security popup during the next operation.
#= If one occurs, the 'OK' button will be pressed and the popup cleared.
#=
#= Only one popup will be cleared at a time.
#=
#=returns none
#=parms
#=parm enable: 1 to clear the popup (default), 0 to ignore the popup
#=endparms
sub ExpectSecurityAlertPopup  #=function
  {
  my ($self, $enable) = @_;
  $enable = 1 unless defined $enable;
  $self->{CleanSecurityAlertPopup} = $enable;
  }

#------------------------
#= Expect a Login popup during the next operation. If one occurs, the userid and password
#= fields will be filled in and the 'OK' button will be pressed.
#=
#= Only one popup will be filled at a time.
#= call with no parameters to disable the check for the login popup
#=
#=returns none
#=parms
#=parm userid: the user id to use
#=parm password: the password to use
#=parm title: a portion of the title text of the message box. Default: 'Connect to'
#=endparms
sub ExpectLoginPopup  #=function
  {
  my ($self, $userid, $password, $title) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($userid, "Parameter 'userid' is missing");
  checksyntax($password, "Parameter 'password' is missing");

  my $enable = defined $userid ? 1 : 0;
  $self->{CleanLoginPopup} = $enable;

  #if the user disabled the search, we're done
  if ($enable)
    {
    $title = 'Connect to' unless defined $title;
    $self->{LoginUserid} = $userid;
    $self->{LoginPassword} = $password;
    $self->{LoginTitle} = $title;
    }

  jIELogger::ClearCallerInfo();
  }


##---------------------------------------------
#=head1 Reporting Routines
#=end

#----------------------
#= Print a message to the result file. It is also printed to the trace file.
#=
#=returns none
#=parms
#=parm message: the message to write to the Result file
#=parm type: 'append' (default) to append to the end of the Result file; 'write' to truncate first; 'nolast' used only by Self-test
#=endparms
sub ToResult  #=function
  {
  jIELogger::CallerInfo(caller(0));
  jIELogger::toresult(@_);
  jIELogger::ClearCallerInfo();
  }

#----------------------
#= Truncates the result file.
#=
#=returns none
#=parms
#=parm message: the message to write to the Result file
#=parm type: 'append' (default) to append to the end of the Result file; 'write' to truncate first; 'nolast' used only by Self-test
#=endparms
sub ClearResult  #=function
  {
  jIELogger::CallerInfo(caller(0));
  jIELogger::clearresult();
  jIELogger::ClearCallerInfo();
  }

#----------------------
#= Print a formatted test result.
#=
#=returns none
#=parms
#=parm testinfo: identifies the test
#=parm result: PASS, FAIL, or WARNING
#=parm msg:additional information
#=endparms
sub TestResult  #=function
  {
  my ($result, $msg) = @_;
  jIELogger::toresult("$result: $msg\n");
  }


##---------------------------------------------
##-- Click, Set, Edit and Verify routines
##---------------------------------------------

##---------------------------------------------
##-- Common routines
##---------------------------------------------

#-- print a debug line
sub debug
  {
  my ($self, $msg, $type) = @_;
  jIELogger::gdebug('[' . $self->{Id} . '] ' . $msg, $type);
  }

#-- verify a node exists
#   returns 1 if found, else 0
sub verifyNodeExists
  {
  my ($self, $getsub, $value, $count) = @_;
  my $node = $self->$getsub($value, $count);
  my $exist = $node->VerifyExists();
  $node = undef;
  return $exist;
  }

#-- click node
sub clickNode
  {
  my ($self, $getsub, $value, $wdc, $count) = @_;
  my $node = $self->$getsub($value, $count);
  if ($node->Exists())
    {
    $node->Click($wdc);
    return 1;
    }
  else
    {
    $node->WarningMissing();
    return 0;
    }
  }

##---------------------------------------------
#=head1 Checkbox Routines
#=end

#------------------------
#= Get a node representing a CheckBox
#=
#=returns node or undef
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext, default: 0
#=endparms
sub GetCheckBox  #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  $count = 0 unless defined $count;
  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Checkbox';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext'));
    } ;
  my $node = $self->getTagNode('INPUT', 'checkbox', $search, $count);
  checkexists($node, $type, $value);

  my $checkbox = new jIETestNode($self, $type, $value, $node);
  $checkbox->AddMethod('SetState', \&checkboxSetState);
  $checkbox->AddMethod('VerifyState', \&checkboxVerifyState);
  $checkbox->AddMethod('IsState', \&checkboxIsState);
  jIELogger::ClearCallerInfo();

  $node = undef;  #release OLE memory
  return $checkbox;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub checkboxExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub checkboxClick #=method

#------------------------
#= Set the state of the !CLASS!
#=
#=returns none
#=parms
#=parm state: 1 for on, 0 for off
#=endparms
sub checkboxSetState #=method
  {
  my ($self, $state) = @_;

  checksyntax($state, "Parameter 'state' is missing");
  checkvalid($state, "Parameter 'state'", 0, 1);

  $self->{Node}->{checked} = $state;
  }

#------------------------
#= Does the current state of the !CLASS! match the given state?
#=
#=returns 1 if it matches, else 0
#=parms
#=parm expectedstate: 1 for on, 0 for off
#=endparms
sub checkboxIsState #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expectedstate' is missing");
  checkvalid($expected, "Parameter 'expectedstate'", 0, 1);

  my $rc = 0;
  my $actual;
  if ($self->Exists())
    {
    $actual = $self->{Node}->{checked};
    $rc = 1 if ($actual =~ /^$expected$/);
    }

  $actual = undef;  #release OLE memory
  return $rc;
  }

#------------------------
#= Verify the current state matches the given state.
#=
#=returns 1 if found, else 0
#=parms
#=parm state: the expected state of the CheckBox
#=endparms
sub checkboxVerifyState #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'state' is missing");
  checkvalid($expected, "Parameter 'state'", 0, 1);

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->{Node}->{checked};
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    $actual = undef;  #release OLE memory
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

#---------------------------------------------
#=head1 Label Routines
#=end

#------------------------
#= Get a node representing a Label
#=
#=returns node or undef
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext
#=endparms
sub GetLabel  #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  $count = 0 unless defined $count;
  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Label';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext'));
    } ;
  my $node = $self->getTagNode('LABEL', undef, $search, $count);
  checkexists($node, $type, $value);

  my $label = new jIETestNode($self, $type, $value, $node);
  jIELogger::ClearCallerInfo();
  return $label;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub labelExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub labelClick #=method

##---------------------------------------------
#=head1 Link Routines
#=end

#------------------------
#= Get a node representing a Link
#=
#=returns node or undef
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext
#=endparms
sub GetLink  #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($value, "Parameter 'value' is missing");
  $count = 0 unless defined $count;

  my $type = 'Link';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext'));
    } ;
  my $node = $self->getTagNode('A', undef, $search, $count);
  checkexists($node, $type, $value);

  my $linknode = new jIETestNode($self, $type, $value, $node);
  $linknode->AddMethod('Click', \&linkClick);  #override base Click
  $linknode->AddMethod('VerifyText', \&linkVerifyText);
  $linknode->AddMethod('IsText', \&linkIsText);
  jIELogger::ClearCallerInfo();
  return $linknode;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub linkExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm wdc: wait (default) or nowait
#=endparms
sub linkClick #=method
  {
  my ($self, $wdc) = @_;
  jIELogger::CallerInfo(caller(0));

  $wdc = 'wait' unless defined($wdc); #default is wait
  jIETest::checkvalid($wdc, "Parameter 'wdc'", 'wait', 'nowait');

  $self->baseClick($wdc); #call base class
  jIELogger::ClearCallerInfo();
  }

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub linkVerifyText #=method
  {
  my ($self, $expected) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = $actual eq $expected ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->FailMissing();
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#------------------------
#= Does the inntertext of the !CLASS! match the given text?
#=
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub linkIsText #=method
  {
  my ($self, $expected) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = 1 if ($actual eq $expected);
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 DIV Routines
#=end

#------------------------
#= Get a node representing a DIV
#=
#=returns node or undef
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext
#=endparms
sub GetDiv #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Div';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext'));
    } ;
  my $node = $self->getTagNode('DIV', undef, $search, $count);
  checkexists($node, $type, $value);

  my $div = new jIETestNode($self, $type, $value, $node);
  $div->AddMethod('VerifyText', \&divVerifyText);
  $div->AddMethod('IsText', \&divIsText);
  jIELogger::ClearCallerInfo();
  return $div;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub divExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub divClick #=method

#------------------------
#= Verify the innertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm epected: the expected text
#=endparms
sub divVerifyText #=method
  {
  my ($self, $expected) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = $actual eq $expected ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->FailMissing();
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#------------------------
#= Does the innertext of the !CLASS! match the given text?
#=
#=returns 1 if it matches, else 0
#=parms
#=parm epected: the expected text
#=endparms
sub divIsText #=method
  {
  my ($self, $expected) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = 1 if ($actual eq $expected);
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 Button Routines
#=end

#------------------------
#= Get a node representing a Button
#=
#=returns node or undef
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext
#=endparms
sub GetButton #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Button';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext'));
    } ;
  my $node = $self->getTagNode('BUTTON', undef, $search, $count);
  checkexists($node, $type, $value);

  my $button = new jIETestNode($self, $type, $value, $node);
  $button->AddMethod('VerifyText', \&buttonVerifyText);
  $button->AddMethod('IsText', \&buttonIsText);
  jIELogger::ClearCallerInfo();
  $node = undef;
  return $button;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub buttonExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub buttonClick #=method

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub buttonVerifyText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = $actual eq $expected ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    $actual = undef;  #release OLE memory
    }
  else
    {
    $self->FailMissing();
    }
  return $rc;
  }

#------------------------
#= Does the inntertext of the !CLASS! match the given text?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub buttonIsText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  my $actual;
  if ($self->Exists())
    {
    $actual = getFieldValue($self->{Node}, 'innerText');
    $rc = 1 if ($actual eq $expected);
    }
  $actual = undef; #release OLE memory
  return $rc;
  }

#---------------------------------------------
#=head1 Submit Button Routines
#=end

#------------------------
#= Get a node representing a submit Button
#=
#=returns node or undef
#=parms
#=parm value: the id, name or value to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/value
#=endparms
sub GetSubmitButton #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  $count = 0 unless defined $count;
  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Submit Button';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'value'));
    } ;
  my $node = $self->getTagNode('INPUT', 'submit', $search, $count);
  checkexists($node, $type, $value);

  my $subbutton = new jIETestNode($self, $type, $value, $node);
  $subbutton->AddMethod('Click', \&submitbuttonClick);
  jIELogger::ClearCallerInfo();
  return $subbutton;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub submitbuttonExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm wdc: 'wait' (default): wait for DocumentComplete message, 'nowait': continue after clicking
#=endparms
sub submitbuttonClick #=method
  {
  my ($self, $wdc) = @_;
  $wdc = 'wait' unless defined($wdc);
  $self->baseClick($wdc);
  }

#---------------------------------------------
#=head1 Radio Button Routines
#=end

#------------------------
#= Get a node representing a Radio Button
#=
#=returns node or undef
#=parms
#=parm value: the id, name or value to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/value
#=endparms
sub GetRadioButton #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'RadioButton';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'value'));
    } ;
  my $node = $self->getTagNode('INPUT', 'radio', $search, $count);
  checkexists($node, $type, $value);

  my $radiobutton = new jIETestNode($self, $type, $value, $node);
  $radiobutton->AddMethod('VerifyState', \&radiobuttonVerifyState);
  $radiobutton->AddMethod('IsState', \&radiobuttonIsState);
  jIELogger::ClearCallerInfo();
  $node = undef;
  return $radiobutton;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub radiobuttonExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub radiobuttonClick #=method

#------------------------
#= Verify the state of the !CLASS! matches the given state
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected state
#=endparms
sub radiobuttonVerifyState #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");
  checkvalid($expected, "Parameter 'expected'", 0, 1);

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->{Node}->{checked};
    $rc = ($actual =~ /^$expected$/) ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    $actual = undef;
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

#------------------------
#= Does the state of the !CLASS! match the given state?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected state
#=endparms
sub radiobuttonIsState #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");
  checkvalid($expected, "Parameter 'expected'", 0, 1);

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->{Node}->{checked};
    $rc = 1 if ($actual =~ /^$expected$/);
    $actual = undef;
    }
  return $rc;
  }

##---------------------------------------------
#=head1 Image Routines
#=end

#------------------------
#= Get a node representing an Image
#=
#=returns node or undef
#=parms
#=parm value: the id, name, alt or src to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/alt/src
#=endparms
sub GetImage #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  $count = 0 unless defined $count;
  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Image';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'alt', 'src'));
    } ;
  my $node = $self->getTagNode('IMG', undef, $search, $count);
  checkexists($node, $type, $value);

  my $image = new jIETestNode($self, $type, $value, $node);
  $image->AddMethod('VerifyAltText', \&imageVerifyAltText);
  jIELogger::ClearCallerInfo();
  return $image;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub imageExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub imageClick #=method

#------------------------
#= Verify the ALT Text of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub imageVerifyAltText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'alt');
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc  ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }


##---------------------------------------------
#=head1 EditBox Routines
#=end

#------------------------
#= Get a node representing an Edit Box
#=
#=returns node or undef
#=parms
#=parm value: the id, name or value to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/value
#=endparms
sub GetEditBox #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'EditBox';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'value'));
    } ;
  my $node = $self->getTagNode('INPUT', 'text', $search, $count);
  checkexists($node, $type, $value);

  my $editbox = new jIETestNode($self, $type, $value, $node);
  $editbox->AddMethod('SetText', \&editboxSetText);
  $editbox->AddMethod('VerifyText', \&editboxVerifyText);
  $editbox->AddMethod('IsText', \&editboxIsText);
  jIELogger::ClearCallerInfo();
  return $editbox;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub editboxExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub editboxClick #=method

#------------------------
#= Set the text of the !CLASS!
#=returns none
#=parms
#=parm text: the text to set
#=endparms
sub editboxSetText #=method
  {
  my ($self, $text) = @_;
  checksyntax($text, "Parameter 'text' is missing");
  $self->{Node}->{value} = $text;
  }

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub editboxVerifyText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc  ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

#------------------------
#= Does the inntertext of the !CLASS! match the given text?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub editboxIsText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = 1 if ($actual =~ /^$expected$/);
    }
  return $rc;
  }

##---------------------------------------------
#=head1 TextArea Routines
#=end

#------------------------
#= Get a node representing an TextArea
#=
#=returns node or undef
#=parms
#=parm value: the id, name, value or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name/innertext
#=endparms
sub GetTextArea #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'TextArea';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'value', 'innertext'));
    } ;
  my $node = $self->getTagNode('TEXTAREA', undef, $search, $count);
  checkexists($node, $type, $value);

  my $textarea = new jIETestNode($self, $type, $value, $node);
  $textarea->AddMethod('SetText', \&textareaSetText);
  $textarea->AddMethod('VerifyText', \&textareaVerifyText);
  $textarea->AddMethod('IsText', \&textareaIsText);
  jIELogger::ClearCallerInfo();
  return $textarea;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub textareaExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub textareaClick #=method

#------------------------
#= Set the text of the !CLASS!
#=returns none
#=parms
#=parm text: the text to set
#=endparms
sub textareaSetText #=method
  {
  my ($self, $text) = @_;
  checksyntax($text, "Parameter 'text' is missing");
  $self->{Node}->{value} = $text;
  }

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub textareaVerifyText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc  ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

#------------------------
#= Does the inntertext of the !CLASS! match the given text?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub textareaIsText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'innertext');
    $rc = 1 if ($actual =~ /^$expected$/);
    }
  return $rc;
  }

##---------------------------------------------
#=head1 Password Box Routines
#=end

#------------------------
#= Get a node representing a Password Box
#=
#=returns node or undef
#=parms
#=parm value: the id or name to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetPasswordBox #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'PasswordBox';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name'));
    } ;
  my $node = $self->getTagNode('INPUT', 'password', $search, $count);
  checkexists($node, $type, $value);

  my $pwdbox = new jIETestNode($self, $type, $value, $node);
  $pwdbox->AddMethod('SetText', \&passwordboxSetText);
  $pwdbox->AddMethod('VerifyText', \&passwordboxVerifyText);
  $pwdbox->AddMethod('IsText', \&passwordboxIsText);
  jIELogger::ClearCallerInfo();
  return $pwdbox;
  }

#------------------------
#= Does the !CLASS! Exist?
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub passwordboxExists #=method

#------------------------
#= Click the !CLASS!
#=returns none
#=parms
#=parm none:
#=endparms
#sub passwordboxClick #=method

#------------------------
#= Set the !CLASS! to the given text
#=returns none
#=parms
#=parm text: the new value
#=endparms
sub passwordboxSetText #=method
  {
  my ($self, $text) = @_;
  checksyntax($text, "Parameter 'text' is missing");

  $self->{Node}->{value} = $text;
  }

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub passwordboxVerifyText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

#------------------------
#= Does the inntertext of the !CLASS! match the given text?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub passwordboxIsText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = 1 if ($actual =~ /^$expected$/);
    }
  return $rc;
  }

##---------------------------------------------
#=head1 ListBox Routines
#=end

#------------------------
#= Get a node representing a ListBox
#=
#=returns node or undef
#=parms
#=parm value: the id or name to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetListBox #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  $count = 0 unless defined $count;
  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'ListBox';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name'));
    } ;
  my $node = $self->getTagNode('SELECT', undef, $search, $count);
  checkexists($node, $type, $value);

  my $listbox = new jIETestNode($self, $type, $value, $node);
  $listbox->AddMethod('SetSelection', \&listboxSetSelection);
  $listbox->AddMethod('SetSelectionByText', \&listboxSetSelectionByText);
  $listbox->AddMethod('VerifyOptionExists', \&listboxVerifyOptionExists);
  $listbox->AddMethod('VerifySelection', \&listboxVerifySelection);
  $listbox->AddMethod('IsSelection', \&listboxIsSelection);
  $listbox->AddMethod('IsSelectionByText', \&listboxIsSelectionByText);
  jIELogger::ClearCallerInfo();
  return $listbox;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub listboxExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub listboxClick #=method

#------------------------
#= Set state of the !CLASS! to the given option name, id or value
#=returns none
#=parms
#=parm option: the option to set
#=endparms
sub listboxSetSelection #=method
  {
  my ($self, $option) = @_;

  checksyntax($option, "Parameter 'option' is missing");

  $self->{Node}->{value} = $option;
  }

#------------------------
#= Set state of the !CLASS! to the given option text
#=returns none
#=parms
#=parm option: the option to set
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=endparms
sub listboxSetSelectionByText #=method
  {
  my ($self, $option) = @_;

  checksyntax($option, "Parameter 'option' is missing");
  my ($type, $rmatcher) = getValueMatcher($option);

  foreach my $i (0..$self->{Node}->options->length - 1)
    {
    my $opt = $self->{Node}->item($i)->text;
    next unless defined $opt;
    if (&$rmatcher($opt, $option))
      {
      $self->{Node}->{selectedIndex} = $i;
      last;
      }
    }
  }

#------------------------
#= Check if the given option exists
#=returns 1 if it exists, else 0
#=parms
#=parm option: the option to search for.
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=endparms
sub listboxVerifyOptionExists #=method
  {
  my ($self, $option) = @_;

  checksyntax($option, "Parameter 'option' is missing");

  my ($type, $rmatcher) = getValueMatcher($option);

  foreach my $i (0..$self->{Node}->options->length - 1)
    {
    my $opt = $self->{Node}->item($i)->text;
    next unless defined $opt;
    return 1 if &$rmatcher($opt, $option);
    }
  return 0;
  }

#------------------------
#= Does the current selection of the !CLASS! match the given option?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected option
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=endparms
sub listboxIsSelection #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");
  my ($type, $rmatcher) = getValueMatcher($expected);

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = 1 if &$rmatcher($actual, $expected);
    }
  return $rc;
  }

#------------------------
#= Does the current selection of the !CLASS! match the given option's text?
#=returns 1 if it matches, else 0
#=parms
#=parm expected: the expected option's text
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=endparms
sub listboxIsSelectionByText #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");
  my ($type, $rmatcher) = getValueMatcher($expected);

  my $rc = 0;
  if ($self->Exists())
    {
    my $idx = $self->{Node}->{selectedIndex};
    my $actual = $self->{Node}->item($idx)->text;
    jIELogger::gdebug("listboxIsSelectionByText: actual='$actual' expected='$expected'\n");
    $rc = 1 if &$rmatcher($actual, $expected);
    }
  return $rc;
  }

#------------------------
#= Verify the current selection of the !CLASS! matches the given option
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected option
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=endparms
sub listboxVerifySelection #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");
  my ($type, $rmatcher) = getValueMatcher($expected);

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = getFieldValue($self->{Node}, 'value');
    $rc = (&$rmatcher($actual, $expected)) ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

##---------------------------------------------
#=head1 Form Routines
#=end

#------------------------
#= Get a node representing a Form
#=
#=returns node or undef
#=parms
#=parm value: the id or name to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetForm #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($value, "Parameter 'value' is missing");
  $count = 0 unless defined $count;

  my $type = 'Form';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name'));
    } ;
  my $node = $self->getTagNode('FORM', undef, $search, $count);
  checkexists($node, $type, $value);

  my $form = new jIETestNode($self, $type, $value, $node);
  $form->AddMethod('GetElement', \&formGetElement);
  jIELogger::ClearCallerInfo();
  return $form;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub formExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub formClick #=method

#------------------------
#= Get an element from the !CLASS!
#returns jIETestNode object
#=parms
#=parm value: the id, name or innertext to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub formGetElement #=method
  {
  my ($self, $value, $count) = @_;
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Form::GetElement';
  my $tagcount = $count;
  my $foundnode = undef;
  for (my $i = 0; $i < $self->{Node}->elements->length; $i++)
    {
    my $node = $self->{Node}->elements($i);
    next if $self->{Parent}->checkFieldMatch('element', $node, $i, $value, ('id', 'name', 'innertext')) == 1;

    #matched, return back the element
    if ($tagcount == 0)
      {
      $self->{Parent}->debug("$type: found tag, tagcount=$tagcount\n");
      $foundnode = $node;
      last;
      }
    $self->{Parent}->debug("$type: found tag, tagcount=$tagcount, not zero, searching...\n");
    $tagcount--;
    }
  my $elem = new jIETestNode($self->{Parent}, $type, $value, $foundnode);
  return $elem;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=returns none
#=parms
#=parm none:
#=endparms
#sub formelementExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub formelementClick #=method

##---------------------------------------------
#=head1 Table Routines
#=end

#------------------------
#= Gets a Table node
#=
#=returns jIETestNode object holding the Table
#=parms
#=parm value: the id or name to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetTable  #=function
  {
  my ($self, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($value, "Parameter 'value' is missing");

  my $type = 'Table';
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name'));
    } ;
  my $node = $self->getTagNode('TABLE', undef, $search, $count);
  checkexists($node, $type, $value);

  my $table = new jIETestNode($self, $type, $value, $node);
  $table->AddMethod('GetCell', \&tableGetCell);
  $table->AddMethod('GetNumRows', \&tableGetNumRows);
  $table->AddMethod('VerifyNumRows', \&tableVerifyNumRows);
  $table->AddMethod('GetRow', \&tableGetRow);
  jIELogger::ClearCallerInfo();
  return $table;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=returns none
#=parms
#=parm none:
#=endparms
#sub tableExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub tableClick #=method

#------------------------
#= Get the given cell from the !CLASS! at the given row and column
#=parms
#=parm row: row index (0-based)
#=parm col: column index (0-based)
#=endparms
#=returns a node representing a cell or undef
sub tableGetCell #=method
  {
  my ($self, $row, $col) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($row, "Parameter 'row' is missing");
  checksyntax($col, "Parameter 'col' is missing");

  my $ierow = $self->{Node}->rows($row);
  my $iecell = undef;
  if (!defined $ierow)
    {
    TestResult('WARNING', "Table does not have row $row");
    }
  else
    {
    $iecell = $ierow->cells($col);
    if (!defined $iecell)
      {
      TestResult('WARNING', "Table does not have column $col");
      }
    }

  my $cell = new jIETestNode($self->{Parent}, 'Table::Cell', $self->{Value}, $iecell);
  $cell->AddMethod('GetValue', \&tablecellGetValue);
  $cell->AddMethod('VerifyValue', \&tablecellVerifyValue);
  jIELogger::ClearCallerInfo();
  return $cell;
  }

#------------------------
#= Get the number of rows in the !CLASS!
#=returns the number of rows
#=parms
#=parm none:
#=endparms
sub tableGetNumRows #=method
  {
  my ($self) = @_;
  return $self->{Node}->rows->length;
  }

#------------------------
#= Verify the number of rows in the !CLASS!
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected number of rows
#=endparms
sub tableVerifyNumRows #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->GetNumRows();
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->FailMissing();
    }
  return $rc;
  }

#------------------------
#= Get the given row from the !CLASS!
#=returns a node representing the row or undef
#=parms
#=parm row: the row to get
#=endparms
sub tableGetRow #=method
  {
  my ($self, $row) = @_;

  checksyntax($row, "Parameter 'row' is missing");

  my $rownode = new jIETestNode($self->{Parent}, 'Table::Row', $self->{Value}, $self->{Node}->rows($row));
  $rownode->AddMethod('VerifyNumCols', \&tablerowVerifyNumCols);
  $rownode->AddMethod('GetNumCols', \&tablerowGetNumCols);
  return $rownode;
  }

##---------------------------------------------
#=head2 Table Row and Column Routines
#=end

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub tablerowExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub tablerowClick #=method

#------------------------
#= Get the number of columns in the !CLASS!
#=returns the number of columns
#=parms
#=parm none:
#=endparms
sub tablerowGetNumCols #=method
  {
  my ($self) = @_;
  return $self->{Node}->cells->length;
  }

#------------------------
#= Verify the number of columns in the !CLASS! matches the given number
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected number of columns
#=endparms
sub tablerowVerifyNumCols #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->GetNumCols();
    $rc = $actual =~ /^$expected$/ ? 1 : 0;
    TestResult($rc ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->FailMissing();
    }
  return $rc;
  }

##---------------------------------------------
#=head2 Table Cell Routines
#=end

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub tablecellExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub tablecellClick #=method

#------------------------
#= Get the value of the !CLASS!
#=returns the innertext value
#=parms
#=parm none:
#=endparms
sub tablecellGetValue #=method
  {
  my ($self) = @_;
  return getFieldValue($self->{Node}, 'innertext');
  }

#------------------------
#= Verify the inntertext of the !CLASS! matches the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm expected: the expected text
#=endparms
sub tablecellVerifyValue #=method
  {
  my ($self, $expected) = @_;

  checksyntax($expected, "Parameter 'expected' is missing");

  my $rc = 0;
  if ($self->Exists())
    {
    my $actual = $self->GetValue();
    $rc = 1 if $actual =~ /^$expected$/;
    TestResult($rc  ? 'PASS' : 'FAIL', "$self->{Type}: $self->{Value} Actual: '$actual' Expected: '$expected'");
    }
  else
    {
    $self->WarningMissing();
    }
  return $rc;
  }

##---------------------------------------------
#=head1 Generic Page Element Routines
#=end

#------------------------
#= Get a node representing a page element
#=
#=returns node or undef
#=parms
#=parm tagname: the tag name to search for, e.g. 'BUTTON'
#=parm value: the id, name, innertext or value to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetPageElement #=function
  {
  my ($self, $tagname, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($tagname, "Parameter 'tagname' is missing");
  checksyntax($value, "Parameter 'value' is missing");

  my $type = "tag:$tagname";
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext', 'value'));
    } ;
  my $node = $self->getTagNode($tagname, undef, $search, $count);
  checkexists($node, $type, $value);

  my $elem = new jIETestNode($self, $type, $value, $node);
  jIELogger::ClearCallerInfo();
  return $elem;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub pageelementExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub pageelementClick #=method

#------------------------
#= Get a node representing a page element
#=
#=returns node or undef
#=parms
#=parm tagname: the tag name to search for, e.g. 'INPUT'
#=parm tagtype: the type of tag name to search for, e.g. 'radio'
#=parm value: the id, name, innertext or value to search for (in that order).
#= Use qr/pattern/ to search for a pattern, or pass in a scalar to match exactly.
#=parm count: number of elements to skip with the same id/name
#=endparms
sub GetPageElementWithType #=function
  {
  my ($self, $tagname, $tagtype, $value, $count) = @_;
  jIELogger::CallerInfo(caller(0));
  $count = 0 unless defined $count;

  checksyntax($tagname, "Parameter 'tagname' is missing");
  checksyntax($tagtype, "Parameter 'tagtype' is missing");
  checksyntax($value, "Parameter 'value' is missing");

  my $type = "tag:$tagname";
  my $search = sub
    {
    my ($node, $i) = @_;
    return $self->checkFieldMatch($type, $node, $i, $value, ('id', 'name', 'innertext', 'value'));
    } ;
  my $node = $self->getTagNode($tagname, $tagtype, $search, $count);
  checkexists($node, $type, $value);

  my $elem = new jIETestNode($self, $type, $value, $node);
  jIELogger::ClearCallerInfo();
  return $elem;
  }

#------------------------
#= Does the !CLASS! Exist?
#=
#=returns 1 if exists, else 0
#=parms
#=parm none:
#=endparms
#sub pageelementwithtypeExists #=method

#------------------------
#= Click the !CLASS!
#=
#=returns none
#=parms
#=parm none:
#=endparms
#sub pageelementwithtypeClick #=method

##---------------------------------------------
#=head1 Text Routines
#=end

#------------------------
#= Does the current page have the given text somewhere on it (innerText fields only)?
#=
#=returns 1 if text is found, 0 if not
#=parms
#=parm text: the expected text
#=parm count: number of elements to skip
#=endparms
sub IsTextPresent  #=function
  {
  my ($self, $text, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = $self->findIsTextPresent($text, $count);
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#------------------------
#= Verify the given text is somewhere on the current page (innerText fields only)
#=
#=returns 1 if found, else 0
#=parms
#=parm text: the expected text
#=parm count: number of elements to skip
#=endparms
sub VerifyTextPresent  #=function
  {
  my ($self, $text, $count) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = $self->findIsTextPresent($text, $count);
  if ($rc)
    {
    TestResult('PASS', "Text was found: '$text'");
    }
  else
    {
    TestResult('FAIL', "Text was not found: '$text'");
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#-------------
#= Verify the given text is not on the current page (innerText fields only)
#=
#=returns 1 if found, else 0
#=parms
#=parm text: the expected text
#=endparms
sub VerifyTextNotPresent  #=function
  {
  my ($self, $text) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = $self->findIsTextPresent($text) ? 0 : 1;
  if ($rc)
    {
    TestResult('PASS', "Text was not found");
    }
  else
    {
    TestResult('FAIL', "Text was found");
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#-------------
#= Does the current page have all the given text strings somewhere on it (innerText fields only)?
#=
#=returns 1 if text is found, else 0
#=parms
#=parm list: the expected list of text strings
#=endparms
sub IsTextArrayPresent  #=function
  {
  my ($self) = shift @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($_[0], "Parameter 'list' is missing");

  my $rc = 0;
  my $failures = 0;
  foreach my $expectedText (@_)
    {
    $failures++ unless $self->findIsTextPresent($expectedText);
    }

  $rc = 1 if $failures == 0;
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#-------------
#= Verify that all the given text strings are somewhere on the current page (innerText fields only)
#=
#=returns 1 if found, else 0
#=parms
#=parm list: the expected list of text strings
#=endparms
sub VerifyTextArrayPresent  #=function
  {
  my ($self) = shift @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($_[0], "Parameter 'list' is missing");

  my $rc = 0;
  my $failures = 0;
  foreach my $expectedText (@_)
    {
    if (!$self->findIsTextPresent($expectedText))
      {
      TestResult('FAIL', "Text was not found: '$expectedText'");
      $failures++;
      }
    }

  if ($failures == 0)
    {
    TestResult('PASS', "All Text strings were found.");
    $rc = 1;
    }
  else
    {
    TestResult('FAIL', "$rc text strings were not found");
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 MessageBox Routines
#=end

#-------------
#= Expect a message box to pop up during the next action.
#=
#=returns none
#=parms
#=parm timeout: how long in seconds to wait for the timeout; use 0 to wait forever; default is 0
#=endparms
sub ExpectMessageBox #=function
  {
  my ($self, $timeout) = @_;
  $timeout = 0 unless defined $timeout;
  $gMessageBoxTimeout = $timeout;
  $self->{MessageBoxThread}->OpenGate;
  }

#-------------
#= Verify a message box contains the given text.
#= It also clears the cache of message box text lines
#=
#=returns 1 if found, else 0
#=parms
#=parm text: the expected text to verify
#=endparms
sub VerifyMessageBoxText #=function
  {
  my ($self, $text) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = 0;
  my $foundit = 0;
  $self->debug("VerifyMessageBoxText: #text entries: " . scalar @gMessageBoxText . "\n");
  foreach my $t (@gMessageBoxText)
    {
    $self->debug("VerifyMessageBoxText: check '$t'\n");
    next unless $t =~ /$text/;
    $foundit = 1;
    last;
    }
  if ($foundit)
    {
    TestResult('PASS', "MessageBox contains '$text'.");
    $rc = 1;
    }
  else
    {
    TestResult('FAIL', "MessageBox does not contain '$text'.");
    }

  foreach my $line (@gMessageBoxText)
    {
    $line = undef; #release OLE memory
    }
  @gMessageBoxText = (); #release OLE memory
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 Status Bar Routines
#=end

#-------------
#= Verify that the Status Bar either currently contains or has contained the given text
#=
#=returns 1 if found, else 0
#=parms
#=parm text: the expected text in the Status Bar
#=endparms
sub VerifyStatusBarMessage  #=function
  {
  my ($self, $msg) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($msg, "Parameter 'text' is missing");

  my $rc = 0;
  if ( $self->{IEApp}->{StatusText} =~ /\Q$msg\E/)
    {
    TestResult('PASS', "Status Bar message was found");
    jIELogger::ClearCallerInfo();
    return 1;
    }

  $self->debug("VerifyStatusBarMessage: no match, current statustext='" . $self->{IEApp}->{StatusText} . "'\n");
  $self->debug("VerifyStatusBarMessage: num lines='" . scalar @{ $self->{LastStatusMessages} } . "'\n");

  foreach my $stline (@{ $self->{LastStatusMessages} } )
    {
    if ($stline =~ /\Q$msg\E/)
      {
      $self->debug("VerifyStatusBarMessage: match: stline='$stline'\n");
      TestResult('PASS', "Status Bar message was found");
      jIELogger::ClearCallerInfo();
      return 1;
      }
    else
      {
      $self->debug("VerifyStatusBarMessage: no match: stline='$stline'\n");
      }
    }

  TestResult('FAIL', "Status Bar didn't have message: '$msg'");
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 URL Routines
#=end

#-------------
#= Is the current page at the given URL?
#=
#=returns 1 if current page is on given URL, 0 otherwise
#=parms
#=parm url: the expected URL
#=endparms
sub IsURL  #=function
  {
  my ($self, $url) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($url, "Parameter 'url' is missing");

  my $rc = $self->findDocumentAttribute('URL', $url);
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#-------------
#= Verify if the current page has the given URL.
#=
#=returns 1 if found, else 0
#=parms
#=parm url: the expected URL
#=endparms
sub VerifyURL  #=function
  {
  my ($self, $url) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($url, "Parameter 'url' is missing");

  my $rc = $self->checkDocumentAttribute('URL', $url);
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 Page Title Routines
#=end

#-------------
#= Does the current page have the given Title?
#=
#=returns 1 if title was found, 0 otherwise
#=parms
#=parm text: the expected title
#=endparms
sub IsTitle  #=function
  {
  my ($self, $text) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = $self->findNodeInnerText('TITLE', $text, 0);
  jIELogger::ClearCallerInfo();
  return $rc;
  }

#-------------
#= Verify if the current page has the given Title.
#=
#=returns 1 if found, else 0
#=parms
#=parm text: the expected title
#=endparms
sub VerifyTitle  #=function
  {
  my ($self, $text) = @_;
  jIELogger::CallerInfo(caller(0));

  checksyntax($text, "Parameter 'text' is missing");

  my $rc = $self->checkNodeInnerText('TITLE', $text, 0);
  jIELogger::ClearCallerInfo();
  return $rc;
  }

##---------------------------------------------
#=head1 Misc. Routines
#=end

#------------------------
#= Saves the current page's OuterText into the given filename.
#= The OuterText fields of the IE DOM contain a text-only
#= representation of that field, so the content of the file will
#= be the concatenation of all the OuterText fields of the current page.
#= There will not be any HTML in the OuterText.
#= If the file already exist, it will be overwritten.
#=
#=returns none
#=parms
#=parm filename: the name of the file to write to
#=endparms
sub SaveOuterText  #=function
  {
  my ($self, $filename) = @_;

  jIELogger::CallerInfo(caller(0));
  checksyntax($filename, "Parameter 'filename' is missing");

  open (HTML, ">$filename") or die "Could not open $filename\n";
  my $action = sub
    {
    my ($node) = @_;
    print HTML $node->outerText;
    } ;
  $self->forAllTags('HTML', $action);
  close(HTML);
  jIELogger::ClearCallerInfo();
  }


##@@@@@@@@@@@@@@@@@@@@@@
##todo: ClickFormxxx : click an element within a given form
##todo: unordered lists
##todo: ordered lists
##todo: frames
##todo: handle special characters in text
##todo: map
##todo: input type="image.png"
##todo: input type=file
##todo: input type=hidden

##----------------------------------------
##-- Dump routines
##----------------------------------------

#------------------------
sub safePrint
  {
  my ($object, $field) = @_;
  my $value = eval { $object->$field };
  my $m;
  if (!defined $value)
    {
    $m = sprintf ("   %-20.20s: <undefined>\n", $field);
    }
  elsif (length $value > 80)
    {
    $m = sprintf ("   %-20.20s: '%.80s...'\n", $field, $value);
    }
  else
    {
    $m = sprintf ("   %-20.20s: '%s'\n", $field, $value);
    }
  jIELogger::traceit($m);
  }

#------------------------
#= Print object information for all elements on the current page.
#= The information printed are those required by most of the Click or Set functions.
#=returns none
#=parms
#=parm none:
#=endparms
#todo: print a typical call for each element
sub PrintObjectInfo  #=function
  {
  my ($self) = @_;
  my $document = $self->{IEApp}->{Document};
  jIELogger::traceit("PrintObjectInfo: List of all elements: $@\n");
  safePrint($document, 'URL');
  my $all = $document->all;
  for (my $i = 0; $i<$all->length; $i++)
    {
    jIELogger::traceit("Object $i:\n");
    my $object = $document->all($i);
    next unless defined $object;
    safePrint($object, 'tagName');
    safePrint($object, 'id');
    safePrint($object, 'name');
    safePrint($object, 'innerText');
    safePrint($object, 'value');
    safePrint($object, 'text');
    safePrint($object, 'className');
    safePrint($object, 'classid');
    safePrint($object, 'form');
    safePrint($object, 'nodeType');
    safePrint($object, 'outerTEXT');
    safePrint($object, 'outerHTML');
    safePrint($object, 'tabIndex');
    safePrint($object, 'title');
    safePrint($object, 'type');
    }
  }

#------------------------
#= Print all object information for all elements on the current page
#=returns none
#=parms
#=parm none:
#=endparms
sub PrintAllObjects  #=function
  {
  my ($self) = @_;
  my $document = $self->{IEApp}->{Document};
  jIELogger::traceit("PrintAllObjects: List of all Elements: $@\n");
  safePrint($document, 'URL');
  my $all = $document->all;
  for (my $i = 0; $i<$all->length; $i++)
    {
    jIELogger::traceit("Object $i:\n");
    my $object = $document->all($i);
    next unless defined $object;
    safePrint($object, 'tagName');
    safePrint($object, 'id');
    safePrint($object, 'name');
    safePrint($object, 'innerText');
    safePrint($object, 'value');

    safePrint($object, 'className');
    safePrint($object, 'nodeName');
    safePrint($object, 'accessKey');
    safePrint($object, 'align');
    safePrint($object, 'alt ');
    safePrint($object, 'altHTML');
    safePrint($object, 'archive');
    safePrint($object, 'BaseHref');
    safePrint($object, 'border');
    safePrint($object, 'canHaveChildren');
    safePrint($object, 'canHaveHTML');
    safePrint($object, 'classid');
    safePrint($object, 'clientHeight');
    safePrint($object, 'clientLeft');
    safePrint($object, 'clientTop');
    safePrint($object, 'clientWidth');
    safePrint($object, 'code');
    safePrint($object, 'codeBase');
    safePrint($object, 'codeType');
    safePrint($object, 'data');
    safePrint($object, 'declare');
    safePrint($object, 'dir');
    safePrint($object, 'disabled');
    safePrint($object, 'form');
    safePrint($object, 'height');
    safePrint($object, 'hideFocus');
    safePrint($object, 'hspace');
    safePrint($object, 'isContentEditable');
    safePrint($object, 'isDisabled');
    safePrint($object, 'isMultiLine');
    safePrint($object, 'isTextEdit');
    safePrint($object, 'lang');
    safePrint($object, 'language');
    safePrint($object, 'nextSibling');
    safePrint($object, 'nameProp');
    safePrint($object, 'nodeType');
    safePrint($object, 'nodeValue');
    safePrint($object, 'object');
    safePrint($object, 'offsetHeight');
    safePrint($object, 'offsetLeft');
    safePrint($object, 'offsetParent');
    safePrint($object, 'offsetTop');
    safePrint($object, 'offsetWidth');
    safePrint($object, 'outerTEXT');
    safePrint($object, 'outerHTML');
    safePrint($object, 'parentElement');
    safePrint($object, 'parentNode');
    safePrint($object, 'parentTextEdit');
    safePrint($object, 'previousSibling');
    safePrint($object, 'readyState');
    safePrint($object, 'recordset');
    safePrint($object, 'scopeName');
    safePrint($object, 'scrollHeight');
    safePrint($object, 'scrollLeft');
    safePrint($object, 'scrollTop');
    safePrint($object, 'scrollWidth');
    safePrint($object, 'sourceIndex');
    safePrint($object, 'standby');
    safePrint($object, 'STYLE');
    safePrint($object, 'tabIndex');
    safePrint($object, 'tagName');
    safePrint($object, 'tagUrn');
    safePrint($object, 'title');
    safePrint($object, 'type');
    safePrint($object, 'uniqueID');
    safePrint($object, 'UNSELECTABLE');
    safePrint($object, 'useMap');
    safePrint($object, 'vspace');
    safePrint($object, 'width');
    }
  }


##------------------------------------------------------
##-- Message loops, events, etc.
##------------------------------------------------------

#-----
sub waitForMessageBoxIsDone
  {
  my ($self) = @_;
  return $gMessageBoxTimeout < 0;
  }

#------------------------
#NOTE: this subroutine runs in a separate thread!
#NOTE: all global variables must be :shared !
sub waitForMessageBox
  {
  my ($self) = @_;
  my $mbhandle = 0;

  Time::HiRes::usleep(100000); #sleep a little to allow rest of system to catch up
  jIELogger::gdebug("waitForMessageBox: enter timeout=$gMessageBoxTimeout mode=$gExpectedCompatMode\n");

  #note: the message box title is fixed for IE. It cannot be changed, except by MS itself...
  my $wintitle = 'Message from webpage'; #for IE8
  if ($gExpectedCompatMode != 8)
      {
      $wintitle = 'Microsoft Internet Explorer'; #for non-IE7
      }

  #find the message box, waiting up to gMessageBoxTimeout seconds
  my $elapsedtime = 0;
  while (1)
    {
    jIELogger::gdebug("waitForMessageBox: elapsedtime=$elapsedtime check for win title '$wintitle'\n");
    $mbhandle = undef; #undef releases OLE memory

    $mbhandle = Win32::GUI::FindWindow('#32770', $wintitle);
    last if $mbhandle != 0; #found it

    # if gMessageBoxTimeout == -1 => quit immediately
    # if gMessageBoxTimeout ==  0 => never quit
    # else if numtries > gMessageBoxTimeout => quit immediately
    if ($gMessageBoxTimeout == -1 || $elapsedtime >= $gMessageBoxTimeout)
      {
      jIELogger::gdebug("waitForMessageBox: timed out ($gMessageBoxTimeout seconds), exiting. \n");
      $mbhandle = undef; #undef releases OLE memory
      return;
      }
    sleep(1); #wait a full second
    $elapsedtime++;
    }

  #got it, get the title.
  my $message = Win32::GUI::Text($mbhandle);
  jIELogger::gdebug("waitForMessageBox: found message box, '$message'\n");

  #get the child windows, buttons, fields, etc. on the msg box
  #one of them should be an 'OK' button
  my @children = Win32::GuiTest::FindWindowLike($mbhandle, '.*', '.*');
  my $okchild = undef;
  foreach my $child (@children)
    {
    $message = Win32::GUI::Text($child);
    push @gMessageBoxText, $message;
    #if the text on this child is 'OK' then we assume it is an 'OK' pushbutton
    $okchild = $child if $message eq "OK";
    jIELogger::gdebug("waitForMessageBox: child: '$message'\n");
    }

  if (!$okchild)
    {
    #didn't find the 'OK' button, go clean up
    TestResult('WARNING', "Message Box does not have 'OK' button'");
    }
  else
    {
    #found the 'OK' button
    jIELogger::gdebug("waitForMessageBox: found msg box, pressing OK $mbhandle\n");

    #push the button; wait 150ms between button down and button up
    #this makes it a bit little slower but increases the reliability of the button press
    Win32::GuiTest::PushButton('OK', 0.150);
    jIELogger::gdebug("waitForMessageBox: pressed ok\n");
    Time::HiRes::usleep(10000); #sleep a little to allow msgbox to dissappear

    #check if the messagebox actually went away, if not, press open the gate again.
    jIELogger::gdebug("waitForMessageBox: checking if msg box is still there...\n");
    my $mbhandle2 = Win32::GUI::FindWindow('#32770', $wintitle);
    if ($mbhandle2 == 0)
      {
      jIELogger::gdebug("waitForMessageBox: no, msg box is gone\n");
      }
    elsif ($mbhandle2 != $mbhandle)
      {
      jIELogger::gdebug("waitForMessageBox: no, msg box is gone, but a new one is now there\n");
      }
    else
      {
      jIELogger::gdebug("waitForMessageBox: yes, msg box $mbhandle2 is still there, opening gate...\n");
      $self->OpenGate; #try again
      }
    $mbhandle2 = undef; #undef releases OLE memory
    }

  jIELogger::gdebug("waitForMessageBox: exiting\n");
  foreach my $child (@children)
    {
    $child = undef; #undef releases OLE memory
    }
  @children = undef; #undef releases OLE memory
  $mbhandle = undef; #undef releases OLE memory
  $message = undef; #undef releases OLE memory
  }

#------------------------
#todo: add timeout
sub waitForDocumentComplete
  {
  my ($self, $wdc) = @_;

  return unless defined($wdc);

  $self->debug("waitForDocumentComplete: enter wdc=$wdc\n");
  die "ERROR: bad parm '$wdc'" unless $wdc eq 'nowait' or $wdc eq 'wait';
  return if $wdc eq 'nowait';

  my $starttime = gettimeofday;
  $self->{NavigateError} = 0;
  foreach my $msg ( @{ $self->{LastStatusMessages} } )
    {
    $msg = undef; #undef releases OLE memory
    }
  @{ $self->{LastStatusMessages} } = ();

  $self->{QuitMessageLoop} = 0;
  if ($wdc eq 'wait')
    {
    $self->debug("waitForDocumentComplete: Blocking with MessageLoop\n");
    $self->{EventCount} = 0;

    my $count = 0;
    while (1)
      {
      $count++;
      Win32::OLE->SpinMessageLoop;
      if ($self->{QuitMessageLoop})
        {
        #there's usually a few more events after the DocumentComplete that we care about
        for (0..8)
          {
          Time::HiRes::usleep(10000);
          Win32::OLE->SpinMessageLoop; #once more...
          }
        if ($self->{EventCount} != 0)
          {
          $self->debug("waitForDocumentComplete: count=$count number of events == $self->{EventCount}\n");
          last;
          }
        }
      Time::HiRes::usleep(10000);
      }
    }

  my $t = sprintf("%.2f", gettimeofday - $starttime);
  $self->debug("waitForDocumentComplete: Finished Blocking, time=$t\n");
  }

#------------------
#assumes: title 'Security Alert' will never change
sub handleSecurityAlert
  {
  my ($self, $obj, $event, @args) = @_;
  $self->debug("handleSecurityAlert: searching\n");
  my @windows = Win32::GuiTest::FindWindowLike(undef, "Security Alert", undef, undef);
  return unless @windows;

  $self->{CleanSecurityAlertPopup} = 0;
  $self->debug("handleSecurityAlert: found it\n");
  $self->debug("handleSecurityAlert: @windows\n");
  Win32::GuiTest::SendKeys("Y");
  @windows = undef;  #undef releases OLE memory
  }

#------------------
sub handleLoginPopup
  {
  my ($self, $obj, $event, @args) = @_;
  $self->debug("handleLoginPopup: searching\n");
  my @windows = Win32::GuiTest::FindWindowLike(undef, $self->{LoginTitle}, undef, undef);
  return unless @windows;

  $self->{CleanLoginPopup} = 0;
  $self->debug("handleLoginPopup: Found Login window @windows\n");
  my $popup = $windows[0];

  @windows = undef; #undef releases OLE memory
  @windows = Win32::GuiTest::FindWindowLike($popup, undef, 'SysCredential', undef, undef);
  $self->debug("handleLoginPopup: Found SysCredential: @windows\n");
  my $syscred = $windows[0];

  @windows = undef; #undef releases OLE memory
  @windows = Win32::GuiTest::FindWindowLike($syscred,undef,'ComboBoxEx32',undef,undef);
  $self->debug("handleLoginPopup: Found username: @windows\n");
  Win32::GuiTest::WMSetText($windows[0], $self->{LoginUserid});

  @windows = undef; #undef releases OLE memory
  @windows = Win32::GuiTest::FindWindowLike($syscred,undef,'Edit',undef,undef);
  $self->debug("handleLoginPopup: Found password: @windows\n");
  Win32::GuiTest::WMSetText($windows[1], $self->{LoginPassword});
  Win32::GuiTest::PushButton("OK");

  @windows = undef; #undef releases OLE memory
  $popup = undef; #undef releases OLE memory
  $syscred = undef; #undef releases OLE memory
  sleep(1);
  }

#------------------
sub handleEvent
  {
  my ($session, $event, @args) = @_;
  return unless defined $event;

#  my $h = new LeakTest("nt");
#  $h->Report(); $h = undef;

  my $self = $gHwndHash{$session->{HWND}};
  $self->{EventCount}++;
  $self->debug("handleEvent: triggered:'$event'\n", 'event');

  #uncomment to see a dump of the event contents
  #$self->debugDumpEvent($session, $event, @args);

  $self->handleSecurityAlert($session, $event, @args) if $self->{CleanSecurityAlertPopup};
  $self->handleLoginPopup($session, $event, @args) if $self->{CleanLoginPopup};

  if ($event eq 'StatusTextChange')
    {
    $self->handleEventStatusTextChange($session, $event, @args);
    }
  elsif ($event eq "NavigateError")
    {
    $self->handleNavigateError($session, $event, @args);
    }
  elsif ($event eq "BeforeNavigate2")
    {
    $self->handleBeforeNavigate2($session, $event, @args);
    }
  elsif ($event eq "DownloadComplete")
    {
    $self->handleDownloadComplete($session, $event, @args);
    }
  elsif ($event eq "DocumentComplete")
    {
    $self->handleDocumentComplete($session, $event, @args);
    }
  elsif ($event eq "NewWindow2")
    {
    $self->handleNewWindow2($session, $event, @args);
    }
  elsif ($event eq "OnQuit")
    {
    $self->handleOnQuit($session, $event, @args);
    }

  #undefs required for OLE processing. These clean up the ole objects
  $event = undef;
  foreach my $i (0..(@args - 1))
    {
    next unless defined $args[$i];
    $args[$i] = undef; # if UNIVERSAL::isa($args[$i], 'Win32::OLE::Variant');
    }
  $self = undef;
  }

#------------------
sub debugDumpEvent
  {
  my ($self, $session, $event, @args) = @_;
  $self->debug("debugDumpEvent: session=$session\n");
  my $val = '';
  foreach my $i (0..(@args - 1))
    {
    if (!defined $args[$i])
      {
      $self->debug("   [$i] <undefined>\n");
      }
    else
      {
      if (UNIVERSAL::isa($args[$i], 'Win32::OLE::Variant'))
        {
        $val = $args[$i]->Value() if defined $args[$i]->Value();
        $self->debug("   [$i] variant:'" . $val . "'\n");
        }
      else
        {
        $self->debug("   [$i]         '" . $args[$i] . "'\n");
        }
      }
    }
  }

#------------------
sub handleEventStatusTextChange
  {
  my ($self, $session, $event, @args) = @_;
  my $msg = $args[0];
  $self->debug("handleEvent: StatusTextChange msg='$msg' " . scalar @args . "\n");
  if ($msg ne '')
    {
    push @{ $self->{LastStatusMessages} }, $msg;
    }
  $msg = undef; # required for OLE memory cleanup
  }

#------------------
sub handleNavigateError
  {
  my ($self, $session, $event, @args) = @_;
  #navigate error occurred, keep track so we can clean up when DocumentComplete comes in
  TestResult('WARNING', "NavigateError occurred ErrorCode=" . $args[3]->Value() . " URL=" . $args[1]->Value());
  $self->{NavigateError} = 1;
  }

#------------------
sub handleBeforeNavigate2
  {
  my ($self, $session, $event, @args) = @_;

  $self->{DocCounter}++;

  #note the next 3 lines "leak", but something else is cleaning up the memory
  my $rdystate = $session->ReadyState();
  $self->debug("handleEvent: BeforeNavigate2: doccounter = $self->{DocCounter} rdystate=$rdystate\n", 'event');
  $rdystate = undef;

  $self->{RefreshPage} = 0;
  }

#------------------
sub handleDownloadComplete
  {
  my ($self, $session, $event, @args) = @_;

  $self->debug("handleEvent: DownloadComplete: doccounter = $self->{DocCounter}\n", 'event');
  if ($self->{RefreshPage})
    {
    $self->debug("handleEvent: DownloadComplete: it was a RefreshPage\n", 'event');
    Win32::OLE->QuitMessageLoop;
    $self->{QuitMessageLoop} = 1;
    }
  }

#------------------
#frames is a collection of Windows which look very similar to a $self->{IEApp}
#see http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#
#
# A Frame differs from a $self->{IEApp}
#  - A Frame does not get an OnQuit event, but the $self->{IEApp} does
#  - the Status bar on $self->{IEApp}

sub DumpFrames
  {
  my ($self) = @_;
  $self->debug("DumpFrames: num frames: " . $self->{IEApp}->{Document}->frames->length . "\n", 'event');
  foreach my $i (0..$self->{IEApp}->{Document}->frames->length - 1)
    {
    my $frame = $self->{IEApp}->{Document}->frames($i);
    $self->debug("DumpFrames: frames($i): " . $frame . "\n", 'event');
    $self->debug("DumpFrames: frames($i): name:" . $frame->name . "\n", 'event');
    $self->debug("DumpFrames: frames($i): doc :" . $frame->document . "\n", 'event');

    }
  }

#------------------
sub handleDocumentComplete
  {
  my ($self, $session, $event, @args) = @_;

  $self->{RefreshPage} = 1;
  $self->debug("handleEvent: DocumentComplete: app : " . $self->{IEApp} . "\n", 'event');
  $self->debug("handleEvent: DocumentComplete: doc : " . $self->{IEApp}->{Document} . "\n", 'event');
  #todo: next line causes an embedded word doc to fail
  #$self->debug("handleEvent: DocumentComplete: doctype: " . $self->{IEApp}->{Document}->doctype . "\n", 'event');
  #$self->debug("handleEvent: DocumentComplete: num frames: " . $self->{IEApp}->{Document}->frames->length . "\n", 'event');

  #if the url loads multiple pages, keep track of which one we're at
  $self->{DocCounter}--;
  $self->debug("handleEvent: DocumentComplete: doccounter = $self->{DocCounter}\n", 'event');
  $self->debug("handleEvent: DocumentComplete: WaitForBusy = " . $session->{Busy} . "\n", 'event');
  $self->debug("handleEvent: DocumentComplete: ReadyState = " .  $session->ReadyState() . "\n", 'event');

  if ($self->{NavigateError})
    {
    #A navigation error previously occurred, we're done
    Win32::OLE->QuitMessageLoop;
    $self->{QuitMessageLoop} = 1;
    return;
    }
  elsif ($session->ReadyState() == 4)
    {
    $self->debug("handleEvent: DocumentComplete: Calling QuitMessageLoop; ReadyState == 4\n", 'event');
    $self->{DocCounter} = 0;
    Win32::OLE->QuitMessageLoop;
    $self->{QuitMessageLoop} = 1;
    }
  elsif ($self->{DocCounter} == 0 )
    {
    $self->debug("handleEvent: DocumentComplete: Calling QuitMessageLoop: doccounter==0\n", 'event');
    Win32::OLE->QuitMessageLoop;
    $self->{QuitMessageLoop} = 1;
    }
  elsif ($self->{DocCounter} > 0)
    {
    $self->debug("handleEvent: DocumentComplete: DocCounter=$self->{DocCounter}, waiting for more pages\n", 'event');
    return;
    }
  }

#------------------
sub handleNewWindow2
  {
  my ($self, $session, $event, @args) = @_;

  $self->debug("handleEvent: NewWindow2: Starting new window\n", 'event');

  my $popup = new jIETest();
  $popup->{IEApp} = Win32::OLE->new('InternetExplorer.Application') || die "Could not start Internet Explorer.Application popup\n";
  my $hwnd = $popup->{IEApp}->{HWND};
  $gHwndHash{$hwnd} = $popup;
  Win32::OLE->WithEvents($popup->{IEApp}, \&handleEvent, 'DWebBrowserEvents2');
  #print "here5: " . Win32::OLE->LastError() . "\n";
  push @gSessions, $popup;
  #print "here6: @gSessions ", $popup->{IEApp}->{Application}, "\n";
  $args[0]->Put($popup->{IEApp}->{Application});
  $args[1]->Put(0);
  }

#------------------
sub handleOnQuit
  {
  my ($self, $session, $event, @args) = @_;

  $self->debug("handleEvent: OnQuit: calling QuitMessageLoop\n", 'event');
  Win32::OLE->QuitMessageLoop;
  $self->{QuitMessageLoop} = 1;
  $self->{IEApp} = undef; #required for OLE cleanup
  }

1;
__END__

GatedThread.pm

Synopsis
#!perl -w

#== 
#- Gate a thread
package GatedThread;

use strict;
use warnings;
use 5.006;
use threads;
use Thread::Semaphore;

our $VERSION = '0.05';

#------
sub new
  {
  my ($class, $id, $rIsDone, $rWork) = @_;
  my $self = {};
  bless($self, $class);
  $self->{sem} = Thread::Semaphore->new(0);
  $self->{thread} = threads->create('workerbee', $self, $id, $rIsDone, $rWork);
  return $self;
  }

#------
sub WaitToExit
  {
  my ($self) = @_;
  $self->{thread}->join;
  }

#------
sub OpenGate
  {
  my ($self) = @_;
  $self->{sem}->up;
  }

#------
#-- private
sub waitForGate
  {
  my ($self) = @_;
  $self->{sem}->down;
  }

#------
#-- private
sub workerbee
  {
  my ($self, $id, $rIsDone, $rWork) = @_;

  jIELogger::gdebug("$id: enter\n");
  while (1)
    {
    jIELogger::gdebug("$id: waiting for gate to open...\n");
    $self->waitForGate;
    last if &$rIsDone($self);
    &$rWork($self);
    }
  jIELogger::gdebug("$id: exiting\n");
  }

1;

jIELogger.pm

Synopsis
#!perl -w

#== 
#- Common routines for logging
package jIELogger;

use strict;
use warnings;
use 5.006;
use Win32::Mutex;

our $VERSION = '0.05';

#keeps the log files from getting messed up by the threading
our $gFileLock = Win32::Mutex->new();

#trace file names
our $gTraceFile = 'trace.log';
our $gResultFile = 'result.log';

our $gDebugStdout = 1;
our $gDebugMode = '';
our $gLastResult = '';

our $gCallerFile = '';
our $gCallerLine = '';
our $gCallerSub = '';
our $gCallerLevel = 0;

#----------------------
sub CallerInfo
  {
  $gCallerLevel++;
  return unless $gCallerLevel == 1;
  $gCallerFile = $_[1];
  $gCallerLine = $_[2];
  ($gCallerSub) = $_[3] =~ /::(.*)/;
  }

#----------------------
sub CallerInfoSub
  {
  return unless $gCallerLevel == 1;
  ($gCallerSub) = @_;
  }

#----------------------
sub ClearCallerInfo
  {
  $gCallerLevel--;
  $gCallerLevel = 0 if $gCallerLevel < 0;
  return unless $gCallerLevel == 0;
  $gCallerFile = '';
  $gCallerLine = '';
  $gCallerSub = '';
  }

#----------------------
sub ForceClearCallerInfo
  {
  $gCallerLevel = 0;
  $gCallerFile = '';
  $gCallerLine = '';
  $gCallerSub = '';
  }

#----------------------
sub printline
  {
  my ($fname, $message, $type, $mode) = @_;
  $type = 'append' unless defined $type;
  $type = lc $type;
  die "type must be one of append, nolast: '$type'" unless $type =~ /^(append|nolast)$/;

  $gFileLock->wait;
  open (TFILE,">>$fname") || die "Could not open '$fname'";
  print TFILE $message;
  close TFILE;
  $gFileLock->release;

  if ($mode eq 'result')
    {
	  if ($type ne 'nolast')
	    {
	    $gLastResult = $message;
	    chomp $gLastResult;
	    }
	
	  traceit('Result: ' . $message, $type);
	  }
  }

#----------------------
sub clearresult
  {
  my ($message, $type) = @_;
  unlink $gResultFile;
  unlink $gTraceFile;
  }

#----------------------
sub toresult
  {
  my ($message, $type) = @_;
  printline($gResultFile,  "$gCallerFile($gCallerLine) $gCallerSub: " . $message, $type, 'result');
  }

#----------------------
# prints to trace file and standard out
# does not filter out messages
sub traceit
  {
  my ($message) = @_;
  printline($gTraceFile, $message, 'append', 'trace');
  print $message if $gDebugStdout;
  }

#----------------------
sub SetDebug
  {
  my ($mode) = @_;
  $mode = '' unless defined $mode;
  if ($mode eq 'nostdout')
    {
    $gDebugStdout = 0;
    }
  elsif ($mode eq 'stdout')   
    {
    $gDebugStdout = 1;
    }
  else
    {  
    $gDebugMode = $mode;
    }
  #print "x= mode=$gDebugMode stdout=$gDebugStdout\n";
  }

#----------------------
# prints to trace file and standard out
# filters out trace messages
sub gdebug
  {
  my ($message, $type) = @_;
  if ($gDebugMode ne 'all')
    {
    return if $gDebugMode eq '';
    return unless defined $type;
    return if $gDebugMode =~ /:no$type:/;
    }
  traceit("Debug : " . $message);
  }

1;

jIESelfTest.pm

Synopsis
#!perl -w

#== 
#- Common routines for SelfTest
package jIESelfTest;
use jIELogger;

our $VERSION = '0.05';

# SelfTest and Debug variables go here
our $gSelfTestRun = 0;
our $gSelfTestFailed = 0;

#------------------------------------------------
#-- Self-Test routines
#------------------------------------------------

#------------------------
#print summary of self test
sub SelfTestSummary
  {
  jIELogger::CallerInfo(caller(0));
  jIELogger::toresult("#########################################\n", 'nolast');
  jIELogger::toresult("SELFTEST: Total Tests run:    $gSelfTestRun\n", 'nolast');
  jIELogger::toresult("SELFTEST: Total Tests Failed: $gSelfTestFailed\n", 'nolast');
  jIELogger::ClearCallerInfo();
  my ($run, $failed) = ($gSelfTestRun, $gSelfTestFailed);
  $gSelfTestRun = 0;
  $gSelfTestFailed = 0;
  return ($run, $failed);
  }

#------------------------
# Check if all strings in the incoming array are in the jIELogger::gLastResult
sub SelfTestVerify
  {
  jIELogger::CallerInfo(caller(0));
  my $ok = 1;
  foreach my $text (@_)
    {
    $gSelfTestRun++;
    $ok = $jIELogger::gLastResult =~ /\Q$text\E/;
    jIELogger::toresult("SELFTEST: FAILED:\n   Expected: '$text'\n   Actual: '$jIELogger::gLastResult'\n") unless $ok;
    $gSelfTestFailed++ unless $ok;
    }

  $jIELogger::gLastResult = '';
  jIELogger::ClearCallerInfo();
  }

#------------------------
# Check if all strings in the incoming array are in the jIELogger::gLastResult
sub SelfTestContains
  {
  my $actual = shift;
  jIELogger::CallerInfo(caller(0));
  my $ok = 1;
  foreach my $text (@_)
    {
    $gSelfTestRun++;
    $ok = $actual =~ /\Q$text\E/;
    jIELogger::toresult("SELFTEST: FAILED:\n   Expected: '$text'\n   Actual: '$actual'\n") unless $ok;
    $gSelfTestFailed++ unless $ok;
    }
  $jIELogger::gLastResult = '';
  jIELogger::ClearCallerInfo();
  }

#------------------------
# Check if the actual equals expected
sub SelfTestAssert
  {
  jIELogger::CallerInfo(caller(0));
  my ($actual, $expected) = @_;
  $gSelfTestRun++;
  $actual  = '<undef>' if !defined $actual;
  $expected= '<undef>' if !defined $expected;
  my $ok = $actual eq $expected;
  jIELogger::toresult("SELFTEST: FAILED:\n   Expected: '$expected'\n   Actual: '$actual'\n") unless $ok;
  $gSelfTestFailed++ unless $ok;
  $jIELogger::gLastResult = '';
  jIELogger::ClearCallerInfo();
  }

#------------------------
# Check if the last result text was blank
sub SelfTestIsBlank
  {
  jIELogger::CallerInfo(caller(0));
  my $ok = $jIELogger::gLastResult eq '';
  $gSelfTestRun++;
  jIELogger::toresult("SELFTEST: FAILED:\n   Expected: <blank>\n   Actual: '$jIELogger::gLastResult'\n") unless $ok;
  $gSelfTestFailed++ unless $ok;
  $jIELogger::gLastResult = '';
  jIELogger::ClearCallerInfo();
  }

#------------------------
sub SelfTestIsPassed
  {
  jIELogger::CallerInfo(caller(0));
  SelfTestVerify(' PASS:', @_);
  jIELogger::ClearCallerInfo();
  }

#------------------------
sub SelfTestIsFailed
  {
  jIELogger::CallerInfo(caller(0));
  SelfTestVerify(' FAIL:', @_);
  jIELogger::ClearCallerInfo();
  }

#------------------------
sub SelfTestIsWarning
  {
  jIELogger::CallerInfo(caller(0));
  SelfTestVerify(' WARNING:', @_);
  jIELogger::ClearCallerInfo();
  }

#------------------------
sub SelfTestIsSyntax
  {
  jIELogger::CallerInfo(caller(0));
  SelfTestVerify(' SYNTAX:', @_);
  jIELogger::ClearCallerInfo();
  }


1;


jIETestNode.pm

Synopsis
#!perl -w

#== 
#- Common routines for tear-off classes
package jIETestNode;

use strict;
use warnings;
use 5.006;
use jIELogger;

our $VERSION = '0.05';
our $AUTOLOAD;

#there are no member variables
sub new
  {
  my ($class, $parent, $type, $value, $node) = @_;
  my $self = {};
  $self->{Methods} = ();
  $self->{Parent} = $parent;
  $self->{Node} = $node;
  $self->{Value} = $value;
  $self->{Type} = $type;
  bless($self, $class);
  
  $self->AddMethod('Click', \&baseClick);
  $self->AddMethod('Exists', \&baseExists);
  
  return $self;
  }

#-- call this to add a method to this class
sub AddMethod
  {
  my ($self, $mname, $mcode) = @_;
  $self->{Methods}{$mname} = $mcode;
  }

#--
sub baseExists
  {
  my ($self) = @_;
  return defined $self->{Node} ? 1 : 0;
  }

#-- click the node
sub baseClick
  {
  my ($self, $wdc) = @_;
  $wdc = 'nowait' unless defined($wdc);
  jIETest::checkvalid($wdc, "Parameter 'wdc'", 'wait', 'nowait');
  
  $self->{Node}->click();
  $self->{Parent}->waitForDocumentComplete($wdc);
  }

#--
sub WarningMissing
  {
  my ($self) = @_;
  jIETest::TestResult('WARNING', "Could not find $self->{Type} '$self->{Value}'");
  }

#--
sub FailMissing
  {
  my ($self) = @_;
  jIETest::TestResult('FAIL', "$self->{Type} '$self->{Value}' does not exist.")
  }

#--
sub PassExists
  {
  my ($self) = @_;
  jIETest::TestResult('PASS', "$self->{Type} '$self->{Value}' exists.")
  }

#--
sub VerifyExists
  {
  my ($self) = @_;
  my $rc = $self->Exists();
  if ($rc)
    {
    $self->PassExists();
    }
  else
    {
    $self->FailMissing();
    }
  return $rc;
  }

#dynamically called by perl if a method is not defined
sub AUTOLOAD
  {
  my ($self) = @_;
  my ($mname) = $AUTOLOAD =~ /::(.*)/;
  if ($mname eq 'DESTROY')
    {
#    print "Destroy: self=$self\n";	
#    print "Destroy: meth=$self->{Methods}\n";
#    print "Destroy: parn=$self->{Parent}\n";
#    print "Destroy: node=$self->{Node}\n";	
#    print "Destroy: valu=$self->{Value}\n";	
#    print "Destroy: type=$self->{Type}\n";
    $self->{Methods} = undef;
    $self->{Parent} = undef;
    $self->{Node} = undef;
    $self->{Value} = undef;
    $self->{Type} = undef;
    return;
    }
  
  
  jIELogger::CallerInfo(caller(0));
  jIELogger::CallerInfoSub($self->{Type} . '->' . $mname);

  my $rc = 0;
  if (exists $self->{Methods}{$mname})
    {
    $rc = $self->{Methods}{$mname} (@_);
    }
  else  
    {
    jIETest::TestResult('FAIL', "Unknown method '$AUTOLOAD' called from " . (caller(1))[3] . " at " . (caller(1))[1] . "(" . (caller(1))[2] . ")");
    }
  jIELogger::ClearCallerInfo();
  return $rc;
  }

1;

LeakTest.pm

Synopsis

package LeakTest;

use strict;
use Devel::Leak;

our $VERSION = '0.05';
our $gInstance = 0;

#------
sub new
  {
  my ($class, $msg) = @_;
  my $self = {};
  $self->{Msg} = $msg;
  $self->{Instance} = $gInstance++;
  $self->{Handle} = 0;
  print "$self->{Msg} - leaks - $self->{Instance}\n";
  bless($self, $class);
  Devel::Leak::NoteSV($self->{Handle});
  return $self;
  }

#---
sub Report
  {
  my ($self) = @_;	
  Devel::Leak::CheckSV($self->{Handle});
  print "$self->{Msg} - leaks - $self->{Instance} - end\n";
  }

1;

gendoc.pl

Synopsis
#! perl -w
use strict;

my $fname = "jIETest.pm";
my $outfname = "jIETestDocumentation.html";
my $state = 'out';

my @sublines = ();

#----------------------
sub printSubLines
  {
  my ($sub, $clazz, $meth) = @_;
  my $returnval;
	
  foreach my $line (@sublines)
    {
    $line =~ s/!SUB!/$sub/g if defined $sub;
    $line =~ s/!CLASS!/$clazz/g if defined $clazz;
    $line =~ s/!METHOD!/$meth/g if defined $meth;
    
	 if ($line =~ /^#=\s*$/)
      {
	    print OUTFH "<br>\n";
	    }
	  elsif ($line =~ /^#=returns\s+(.*)\s*$/)
	    {
 	    $returnval = $1;
	    }
	  elsif ($line =~ /^#=parms\s*$/)
	    {
	    print OUTFH "<br><table border='1' cellpadding='4' cellspacing='0' style='border-style:solid; border-width:thin; margin=0px;'>\n";
	    print OUTFH "<tr><td colspan='2'><strong>Parameters</strong>\n";
	    }  
	  elsif ($line =~ /^#=parm\s+(.*?)\s*:\s*(.*)\s*$/)
	    {
	    print OUTFH "<tr><td>$1<td>$2\n";	  
	    }  
	  elsif ($line =~ /^#=endparms\s*$/)
	    {
	    if (defined $returnval)
	      {
	      print OUTFH "<tr><td colspan='2'><strong>Return Value: </strong>$returnval</div>\n";
         $returnval = undef;
	      }
	    print OUTFH "</table>\n";	  
	    }  
	  else
	    {  
	    my ($x) = $line =~ /^#=\s+(.*)/;  
       print OUTFH "$x\n";	
       }
    }
  
  if (defined $returnval)  
	 {
   print OUTFH "<br><table border='1' cellpadding='4' cellspacing='0' style='border-style:solid; border-width:thin; margin=0px;'>\n";
	 print OUTFH "<tr><td colspan='2'><strong>Return Value: </strong>$returnval</div>\n";
	 print OUTFH "</table>\n";	  
   $returnval = undef;
   }
  }


#------------- MAIN -----------------------------------

open (FH, "< $fname");
open (OUTFH, "> $outfname") or die "Can't open $outfname";

print OUTFH "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
print OUTFH "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";

my $head;
while (<FH>)
  {
  chomp;
  
  my ($sub) = $_ =~/^sub\s+(.*)\s+#=function/;
  my ($method) = $_ =~/^sub\s+(.*)\s+#=method/;
  my ($method2) = $_ =~/^#sub\s+(.*)\s+#=method/;
  my $docline = $_ if /^#=/;
  
  next unless defined $sub or defined $method or defined $method2 or defined $docline;

  if (defined $docline)
    {  
	  my ($title) = $docline =~ /^#=title (.*)/;
	  if (defined $title)
	    {
	    print OUTFH "<head>\n";	
	    print OUTFH "<title>$title</title>\n";
	    print OUTFH "</head>\n";	
	    print OUTFH "<body>\n";	
	    next;	
	    }	
	  ($head) = $docline =~ /^#=head1 (.*)/;
	  if (defined $head)
	    {
	    print OUTFH "<h1 style='background:lightgreen; border-style:solid; border-width:thin;'>$head</h1>\n";
	    $state = 'in';
	    next;	
	    }	
	  ($head) = $docline =~ /^#=head2 (.*)/;
	  if (defined $head)
	    {
	    print OUTFH "<h2>$head</h2>\n";
	    $state = 'in';
	    next;	
	    }	
	  if ($docline =~ /^#=end$/)
	    {
	    $state = 'out';
	    next;	
	    }

    #not a headerline
    if ($state eq 'in')
      {
  	  if ($docline =~ /^#=\s*$/)
	      {
	      print OUTFH "<br>\n";
	      }
	    else
	      {
	      my ($x) = $_ =~ /^#=\s+(.*)/;	
	      print OUTFH "$x\n";
	      }  
      }
    else
	    {  
	    push @sublines, $_;
	    }
	  next;
	  }  

  #sub is defined at this point...
  if (defined $sub)
     {
	   print OUTFH "<h2 style='text-decoration: overline;'>";
	   print OUTFH "<a name='$sub'>Routine $sub</a>";
	   print OUTFH "</h2>\n";	
     print OUTFH "<div style='padding-left:20px'>";	
	   print OUTFH "<p>";
	   printSubLines($sub, undef, undef);
	   print OUTFH "</div>";
	   }
  else #$method or $method2 is defined at this point
     {
     my ($clazz, $meth);
     ($clazz, $meth) = $method =~ /([a-z]+)(.*)/ if defined $method;
     ($clazz, $meth) = $method2 =~ /([a-z]+)(.*)/ if defined $method2;
	   print OUTFH "<h2 style='text-decoration: overline;'>";
	   print OUTFH "&nbsp;&nbsp;&nbsp;<a name='$meth'>Method $clazz\:\:$meth</a>";
	   print OUTFH "</h2>\n";	
     print OUTFH "<div style='padding-left:20px'>";	
	   print OUTFH "<p>";
	   printSubLines(undef, $clazz, $meth);
	   print OUTFH "</div>";
     }	  
  print OUTFH "</p>\n";
  @sublines = ();  
  }

print OUTFH "</body></html>\n";	
close(FH);
close(OUTFH);

testjietest.html

Synopsis
<html>
  <head>
  	<meta http-equiv='X-UA-Compatible' content='IE=8' > 
    <title>TestjIETest Main</title>
		<SCRIPT LANGUAGE="JavaScript">
		<!--
    function enginemode()
      {
      engine = null;
			if (window.navigator.appName == "Microsoft Internet Explorer")
		    {
			  // This is an IE browser. What mode is the engine in?
			  if (document.documentMode) // IE8
			    engine = document.documentMode;
			  else // IE 5-7
			    {
			    engine = 5; // Assume quirks mode unless proven otherwise.
			    if (document.compatMode)
		        {
			      if (document.compatMode == "CSS1Compat")
			        engine = 7; // standards mode
			      }
			    }
			  }
			return engine  
			}
    
		function showpopup() 
		  {
		  //alert("mode " + enginemode())
		  pup = window.open("testjietest_popup1.html", "_blank", "width=150,height=210");
		  }
		// -->
		</SCRIPT>
  </head>
<body>

<p>Test Frames:<br>
<a id='testframes_id' name='testframes_name' href='testjietest_frames.html'>test frames</a>
<br><br>

<p>Test Embedded MSWord doc:<br>
<a href="testjietest_embbededword.doc">test_worddoc</a>
<br><br>

<p>Test Popups:<br>
<button id='testpopup1_id' name='testpopup1_name' onclick='javascript: showpopup()'>testpopup1</button>
<br><br>

<p>Test MessageBox: <br>
<button id='testmsgbox1_id' onclick="javascript:alert('MessageBox1 text');">Display a message box</button>
<br><br>

<p>Test Form: <br>
<form id='testform1_id' name='testform1_name'>
  <input name='testinput6_name' id='testinput6_id' type=submit>
</form>  
<br><br>

<p>Test Table: <br>
<input name='testinput5_name' id='testinput5_id' type=checkbox>
<table id='table1_id' name='table1_name' border>
  <tr><td onclick="testinput5_id.checked = !testinput5_id.checked;">row1 col1<td>row1 col2
  <tr><td>row2 col1<td>row2 col2
  <tr><td>row3 col1<td>row3 col2
</table>
<br><br>

<p>Test Listbox: <br>
<select id='listbox1_id' name='listbox1_name'>
  <option id='listbox1_id1' name='listbox1_name1' value='listbox1_option1'>listbox1 option1
  <option id='listbox1_id2' name='listbox1_name2' value='listbox1_option2'>listbox1 option2
  <option id='listbox1_id3' name='listbox1_name3' value='listbox1_option3'>listbox1 option3
</select>
<br><br>

<p>Test Links: <br>
<a id='testlink1_id' name='testlink1_name' href='TestjIETest_link.html'>testlink1 innertext</a>
<br><br>

<p>Test Labels: <br>
<label for='testinput1_id' id='testlabel1_id' name='testlabel1_name'>testlabel1 innertext
  <input name='testinput1_name' id='testinput1_id' type=checkbox>
</label>
<label for='testinput7_id' 
	id='testlabel2_id' 
	name='testlabel2_name' 
	onclick='window.navigate("TestjIETest_link.html");'>
	testlabel2 innertext
  <input name='testinput7_name' id='testinput7_id' type=checkbox>
</label>
<br><br>

<p>Test Buttons:<br>
<input name='testinput2_name' id='testinput2_id' type=checkbox>
<button id='testbutton1_id' name='testbutton1_name' onclick="testinput2_id.checked=true;"> <strong>testbutton1 checked</strong></button>
<button id='testbutton2_id' name='testbutton2_name' onclick="testinput2_id.checked=false;"> <strong>testbutton2 unchecked</strong></button>
<button id='testbutton3_id' name='testbutton3_name' onclick="window.location.href='TestjIETest_link.html';"> <strong>testbutton3 navigate</strong></button>

<input name='testinput8_name' id='testinput8_id' type=checkbox>
<button id='testbutton1_id' name='testbutton1_name' onclick="testinput8_id.checked=true;"> <strong>testbutton1.2nd checked</strong></button>
<button id='testbutton2_id' name='testbutton2_name' onclick="testinput8_id.checked=false;"> <strong>testbutton2.2nd unchecked</strong></button>
<br><br>

<p>Test Divs:<br>
  <input name='testinput3_name' id='testinput3_id' type=checkbox>
  <DIV id='testdiv1_id' name='testdiv1_name' onclick="testinput3_id.checked=true;">
  testdiv1 innertext
  </DIV>
<br><br>

<p>Test Images:<br>
  <input name='testinput4_name' id='testinput4_id' type=checkbox>
  <img alt="testimg1_alt" height='50' width='30' src='testjietest_img1src.jpg'
       id='testimg1_id' name='testimg1_name' onclick="testinput4_id.checked=true;">
<br><br>

<p>Test Radio Buttons:<br>
<input type=radio name='testradio_name' id='testradio1_id' value='testradio1_value'>testradio1<br>
<input type=radio name='testradio_name' id='testradio2_id' value='testradio2_value'>testradio2<br>
<input checked type=radio name='testradio_name' id='testradio3_id' value='testradio3_value'>testradio3<br>

<p>Test Edit Box:<br>
<input name='testedit1_name' id='testedit1_id' value='testedit1_value'><br>

<p>Test Password Box:<br>
<input type=password name='testpassword1_name' id='testpassword1_id' value='testpassword1_value'><br>

<p>Test Text: <br>
<div>Div text</div>
<span>Span text</span>
<p>Paragraph text

<p>Test Text Area: <br>
<textarea name='textarea1_name' id='textarea1_id' value='textarea1_value' COLS=40 ROWS=2>textarea1 value</TEXTAREA><br>

</body>
</html>

testjietest.pl

Synopsis
#!perl -w

#-- Runs a self-test on jIETest.pm
#--
#-- Memory Leaks:
#-- Note the "$box = undef;" and similar lines are not actually necessary.
#-- If you run a series of tests and look at memory usage in Task Manager for example,
#-- it looks like memory is used up and that there could potentially be a memory leak.
#-- However, if you let the TK application stay up and be idle for a long time (> 20 minutes?)
#-- the memory is reclaimed.
#--
#-- Using the "$box = undef;" mechanism forces the memory reclaimation to occur quicker
#-- and so longer series of tests can be done. For example, without the undef's I could
#-- only run 5,000 tests before allocation failures occurred. With the undef's in place,
#-- I have run 10,000 tests with no failures (and now quicker too ~40 minutes)
#--
#-- OLE Memory Leaks:
#-- The EnumAllObjects in the End section will detect any unreleased OLE objects. To
#-- release an object, set it to undef.

use strict;
use warnings;

use jIETest;
use jIESelfTest;
use Tk;
use Tk::Tree;
use Tk::LabFrame;
use Tk::ItemStyle;

#use Module::Versions::Report;
#use LeakTest;

$| = 1;
my $drive = 'c';
$drive = 'd' if ($ENV{COMPUTERNAME} eq 'JOHN6');
my $localroot = "$ENV{COMPUTERNAME}/$drive/projects/jIETest";

my $compatmode = 8;
$compatmode = 5 if ($ENV{COMPUTERNAME} ne 'JOHN6');

my $localURL  = "file://$localroot/TestjIETest.html";
my $localie7URL  = "file://$localroot/TestjIETest_ie7.html";
my $localie5URL  = "file://$localroot/TestjIETest_ie5.html";
my $remoteURL = "http://www.arrizza.com";
my $gCurrentURL = $remoteURL;

my $ie = new jIETest;
$ie->SetDebug('all');
$ie->SetDebug('nostdout');
ClearResult(); #truncate file

my $rc;

#todo: test all 'count' parameter
#todo: replace all SelfTestIsFailed with SelfTestContains to check failure msg

#---------------------------------------
#-- Frames
#---------------------------------------

#---------------------------------------
sub TestAlphaCode_Frames_x
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink(qr/testframes_id/);
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('Frame Test');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  #$ie->PrintObjectInfo();
  #$ie->PrintAllObjects();
  $ie->DumpFrames();

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

#  $rc = $ie->VerifyTitle('TestjIETest Main');
#  jIESelfTest::SelfTestIsPassed();
#  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
#-- CHECKBOX
#---------------------------------------

#---------------------------------------
sub TestCheckBox_VerifyExists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetCheckBox(qr/testinput1_id/);
  jIESelfTest::SelfTestIsBlank();
  $box = undef;

  my $box2 = $ie->GetCheckBox('xx');
  jIESelfTest::SelfTestIsWarning();

  $box  = undef;
  $box2 = undef;
  }

#---------------------------------------
sub TestCheckBox_Set_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetState(1);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();
  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Set_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetState(1);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox(qr/testinput2_name/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetState(1);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetState(0);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $box2 = $ie->GetCheckBox('testinput2x_name');
  jIESelfTest::SelfTestIsWarning();

  RestoreCheckBox2();

  $box = undef;
  $box2 = undef;
  }

#---------------------------------------
sub TestCheckBox_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $box = $ie->GetCheckBox() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');
  }

#---------------------------------------
sub TestCheckBox_Bad_SetState
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->SetState() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');

  eval { $box->SetState(3) };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Bad_IsState
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->IsState() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');

  eval { $box->IsState(3) };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Bad_VerifyState
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->VerifyState() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');

  eval { $box->VerifyState(3) };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $box = undef;
  }

#---------------------------------------
sub TestCheckBox_Bad_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $box = $ie->GetCheckBox(); } ;
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');
  }

#---------------------------------------
sub TestCheckBox_Bad_wdc
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->Click('testinput2_name', 'x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $box = undef;
  }


#todo: test with link
#sub TestClickCheckBox_withLink??
#  {
#  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
#  #todo: test with link
#  ClickX('testbutton3_id', 'wait');
#  VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  ClickBackButton();
#  VerifyTitle('TestjIETest Main');
#  }

#---------------------------------------
#-- LABEL
#---------------------------------------

#---------------------------------------
sub TestLabel_VerifyExists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lbl = $ie->GetLabel(qr/testlabel1_id/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $lbl->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lbl2 = $ie->GetLabel('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $lbl2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lbl = undef;
  $lbl2 = undef;
  }

#---------------------------------------
sub TestLabel_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lbl = $ie->GetLabel('testlabel1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lbl->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  my $box = $ie->GetCheckBox('testinput1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl = undef;
  $box = undef;
  }

#---------------------------------------
sub TestLabel_Click_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lbl = $ie->GetLabel('testlabel1 innertext');
  jIESelfTest::SelfTestIsBlank();

  $lbl->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl = undef;
  $box = undef;
  }

#---------------------------------------
sub TestLabel_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lbl = $ie->GetLabel('testlabel1_id');
  jIESelfTest::SelfTestIsBlank();

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl = undef;
  $box = undef;
  }

#---------------------------------------
sub TestLabel_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lbl = $ie->GetLabel('testlabel1_name');
  jIESelfTest::SelfTestIsBlank();

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl = undef;
  $box = undef;
  }

#---------------------------------------
sub TestLabel_Click_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  #todo: test with link

  my $lbl = $ie->GetLabel('testlabel2_id');
  jIESelfTest::SelfTestIsBlank();

  $lbl->Click('wait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lbl = undef;
  }

#---------------------------------------
sub TestLabel_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $lbl = $ie->GetLabel() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'missing');
  }

#---------------------------------------
sub TestLabel_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lbl = $ie->GetLabel('testlabel1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lbl->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are');
  jIESelfTest::SelfTestContains($@, 'Valid values are');

  $lbl = undef;
  }


#---------------------------------------
#-- Link
#---------------------------------------

#---------------------------------------
#-- ClickLink
sub TestLink_Click_withInnerText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lnk = $ie->GetLink(qr/testlink1 innertext/);
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lnk = $ie->GetLink('testlink1_id');
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_VerifyText_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->VerifyText('testlink1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_VerifyText_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->VerifyText('testlink1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_VerifyText_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lnk = $ie->GetLink('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->VerifyText('testlink1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Is_IsLinkText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->IsText('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = $ie->GetLink('testlink1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->IsText('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = $ie->GetLink('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->IsText('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lnk->IsText('xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Verify_Exists_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Verify_Exists_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Verify_Exists_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lnk->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lnk->IsText('testlink1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lnk->IsText('testlink1xxx innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lnk->VerifyText('testlink1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#---------------------------------------
sub TestAlphaCode_Link_Click_MSWord
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lnk = $ie->GetLink('test_worddoc');
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  #note: these lines will cause OLE failures
  #$ie->PrintObjectInfo();
  #$rc = $ie->VerifyTitle('TestjIETest Link');

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lnk = undef;
  }

#todo: test with class2

##---------------------------------------
#sub TestLink_withClass2
#  {
#  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
#
#  my $lnk = $ie->GetLink('testlink1 innertext');
#  jIESelfTest::SelfTestIsBlank();
#
#  $rc = $lnk->Exists();
#  jIESelfTest::SelfTestIsBlank();
#  jIESelfTest::SelfTestAssert($rc, 1);
#
#  #todo: changing to a new page invalidates the node $link.
#  #todo: Is there a way to detect that?
#  $lnk->Click();
#  jIESelfTest::SelfTestIsBlank();
#
#  $rc = $ie->VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  jIESelfTest::SelfTestAssert($rc, 1);
#
#  $rc = $ie->ClickBackButton();
#  jIESelfTest::SelfTestIsBlank();
#
#  $rc = $ie->VerifyTitle('TestjIETest Main');
#  jIESelfTest::SelfTestIsPassed();
#  jIESelfTest::SelfTestAssert($rc, 1);
#
#  $rc = $link->IsText('testlink1 innertext');
#  jIESelfTest::SelfTestIsBlank();
#  jIESelfTest::SelfTestAssert($rc, 1);
#
#  $rc = $link->IsText('testlink1xxx innertext');
#  jIESelfTest::SelfTestIsBlank();
#  jIESelfTest::SelfTestAssert($rc, 0);
#
#  $rc = $link->VerifyText('testlink1 innertext');
#  jIESelfTest::SelfTestIsPassed();
#  jIESelfTest::SelfTestAssert($rc, 1);
#  }

#---------------------------------------
sub TestLink_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $lnk = $ie->GetLink() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestLink_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lnk->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Bad_VerifyText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lnk->VerifyText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $lnk = undef;
  }

#---------------------------------------
sub TestLink_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lnk = $ie->GetLink('testlink1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lnk->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $lnk = undef;
  }

#---------------------------------------
#-- Div
#---------------------------------------

#---------------------------------------
sub TestDiv_Click_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput3_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $div = $ie->GetDiv(qr/testdiv1 innertext/);
  jIESelfTest::SelfTestIsBlank();

  $div->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $div = undef;
  $box = undef;
  }

#---------------------------------------
sub TestDiv_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $div = $ie->GetDiv('testdiv1_id');
  jIESelfTest::SelfTestIsBlank();

  $div->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $div = undef;
  $box = undef;
  }

#---------------------------------------
sub TestDiv_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput3_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $div = $ie->GetDiv('testdiv1_name');
  jIESelfTest::SelfTestIsBlank();

  $div->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $div = undef;
  $box = undef;
  }

#todo: test with link

#sub TestClickDiv_withId
#  {
#  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
#  ClickX('testbutton3_id', 'wait');
#  VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  ClickBackButton();
#  VerifyTitle('TestjIETest Main');
#  }

#---------------------------------------
sub TestDiv_Verify_Text
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $div = $ie->GetDiv('testdiv1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $div->VerifyText('testdiv1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $div->VerifyText('xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $div = undef;
  }

#---------------------------------------
sub TestDiv_Is_Text
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $div = $ie->GetDiv('testdiv1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $div->IsText('testdiv1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $div->IsText('xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $div = undef;
  }

#---------------------------------------
sub TestDiv_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $div = $ie->GetDiv('testdiv1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $div->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $div->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  my $box = $ie->GetCheckBox('testinput3_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $rc = $div->IsText('testdiv1 innertext');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $div->VerifyText('testdiv1 innertext');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $div = undef;
  $box = undef;
  }

#---------------------------------------
sub TestDiv_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $div = $ie->GetDiv() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestDiv_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $div = $ie->GetDiv('testdiv1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $div->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $div = undef;
  }

#---------------------------------------
sub TestDiv_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $div = $ie->GetDiv('testdiv1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $div ->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $div = undef;
  }

#---------------------------------------
#-- Button
#---------------------------------------

#---------------------------------------
sub TestButton_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton(qr/testbutton1_id/);
  jIESelfTest::SelfTestIsBlank();

  my $btn2 = $ie->GetButton('xxx');
  jIESelfTest::SelfTestIsWarning();

  $btn = undef;
  $btn2 = undef;
  }

#---------------------------------------
sub TestButton_Click_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetButton('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetButton('testbutton2 unchecked');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $btn2 = undef;
  $box = undef;
  }

#---------------------------------------
sub TestButton_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetButton('testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  my $box2 = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box2->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $box = undef;
  $box2 = undef;
  }

#---------------------------------------
sub TestButton_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetCheckBox('testinput2_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetButton('testbutton1_name');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $box = undef;
  }

#---------------------------------------
sub TestButton_Click_withId2
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton3_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('wait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Link');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn = undef;
  }

#---------------------------------------
sub TestButton_Click_withId3
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput8_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetButton('testbutton1_id', 1);
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetButton('testbutton2_id', 1);
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $btn2 = undef;
  $box = undef;
  }

#---------------------------------------
sub TestButton_Verify_Text
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn = $ie->GetButton('testbutton1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->VerifyText('testbutton1 checked');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetButton('testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn2->VerifyText('testbutton1 checked');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn3 = $ie->GetButton('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn3->VerifyText('testbutton1 checked');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->VerifyText('x');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $btn = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestButton_Is_Text
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->IsText('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetButton('testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn2->IsText('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn3 = $ie->GetButton('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn3->IsText('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->IsText('x');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $btn = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestButton_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->IsText('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn->IsText('testbuttonxx checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $btn = undef;
  }

#---------------------------------------
sub TestButton_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn->IsText('testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn->VerifyText('testbutton1 checked');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $box = undef;
  }

#---------------------------------------
sub TestButton_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $btn = $ie->GetButton() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');

  eval { my $btn = $ie->GetButton(['a']) };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'scalar');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'scalar');
  }

#---------------------------------------
sub TestButton_Bad_wdc
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $btn = undef;
  }

#---------------------------------------
sub TestButton_Bad_VerifyText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->VerifyText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $btn = undef;
  }

#---------------------------------------
sub TestButton_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton(qr/testbutton1_id/);
  jIESelfTest::SelfTestIsBlank();

  eval { $btn ->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $btn = undef;
  }

#---------------------------------------
#-- Submit Button
#---------------------------------------

#---------------------------------------
sub TestSubmit_Click_Button
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $ie->NavigateTo('http://www.htmlcodetutorial.com/forms/_INPUT_TYPE_SUBMIT.html');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('HTML SUBMIT - HTML Code Tutorial');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn1 = $ie->GetSubmitButton(qr/Send It!/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetSubmitButton('Submit Query');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $ebox = $ie->GetEditBox('realname');
  jIESelfTest::SelfTestIsBlank();

  $ebox->SetText('testsubmitbutton');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('Idocs Guide to HTML: My CGI');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyTextPresent('testsubmitbutton');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->NavigateTo($gCurrentURL);
  jIESelfTest::SelfTestIsBlank();

  RestoreDefaultPage();

  $btn = undef;
  $btn1 = undef;
  $ebox = undef;
  }

  #todo: test submit with id
  #todo: test submit with name
  #todo: test submit with 2nd button


#---------------------------------------
sub TestSubmit_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $submitbutton = $ie->GetSubmitButton() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestSubmit_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $ie->NavigateTo('http://www.htmlcodetutorial.com/forms/_INPUT_TYPE_SUBMIT.html');
  jIESelfTest::SelfTestIsBlank();

  my $submitbutton = $ie->GetSubmitButton('Submit Query');
  jIESelfTest::SelfTestIsBlank();

  eval { $submitbutton->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  RestoreDefaultPage();

  $submitbutton = undef;
  }

#---------------------------------------
#-- Radio Button
#---------------------------------------

#---------------------------------------
sub TestRadioButton_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn1 = $ie->GetRadioButton(qr/testradio1_id/);
  jIESelfTest::SelfTestIsBlank();
  my $btn2 = $ie->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn3 = $ie->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn1->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreRadioButtons();

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestRadioButton_Click_withValue
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn1 = $ie->GetRadioButton('testradio1_value');
  jIESelfTest::SelfTestIsBlank();
  my $btn2 = $ie->GetRadioButton('testradio2_value');
  jIESelfTest::SelfTestIsBlank();
  my $btn3 = $ie->GetRadioButton('testradio3_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn2->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  $btn3->Click();
  jIESelfTest::SelfTestIsBlank();

  RestoreRadioButtons();

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#  #todo: test with link

#sub TestClickRadioButton_withValue
#  {
#  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
#
#  ClickX('testbutton3_id', 'wait');
#  VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  ClickBackButton();
#  VerifyTitle('TestjIETest Main');
#  }

#---------------------------------------
sub TestRadioButton_VerifyExists()
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn1 = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetRadioButton('testradio1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn3 = $ie->GetRadioButton('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $btn3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestRadioButton_Is_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn1 = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn2 = $ie->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn3 = $ie->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn1->Click();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn1->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  $btn3->Click();
  jIESelfTest::SelfTestIsBlank();

  RestoreRadioButtons();

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestRadioButton_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn1 = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn2 = $ie->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn3 = $ie->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn1->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn1->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn1->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn1->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $btn3->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  $btn3->Click();
  jIESelfTest::SelfTestIsBlank();

  RestoreRadioButtons();

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub TestRadioButton_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $btn = $ie->GetRadioButton() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestRadioButton_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $btn = undef;
  }

#---------------------------------------
sub TestRadioButton_Bad_IsState
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->IsState() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  eval { $btn->IsState(3) };
  jIESelfTest::SelfTestIsSyntax('Valid values are', '0', '1');
  jIESelfTest::SelfTestContains($@, 'Valid values are', '0', '1');

  $btn = undef;
  }

#---------------------------------------
sub TestRadioButton_Bad_VerifyState
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->VerifyState() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  eval { $btn->VerifyState(3) };
  jIESelfTest::SelfTestIsSyntax('Valid values are', '0', '1');
  jIESelfTest::SelfTestContains($@, 'Valid values are', '0', '1');

  $btn = undef;
  }


#---------------------------------------
#-- Image
#---------------------------------------

#---------------------------------------
sub TestImage_Click_withAlt
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  #Test ClickImage: with alt
  my $box = $ie->GetCheckBox('testinput4_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $img = $ie->GetImage(qr/testimg1_alt/);
  jIESelfTest::SelfTestIsBlank();

  $img->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $img = undef;
  $box = undef;
  }

#---------------------------------------
sub TestImage_Click_withSrc
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput4_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $img = $ie->GetImage(qr/testjietest_img1src.jpg/);
  jIESelfTest::SelfTestIsBlank();

  $img->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $img = undef;
  $box = undef;
  }

#---------------------------------------
sub TestImage_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput4_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  $img->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $img = undef;
  $box = undef;
  }

#---------------------------------------
sub TestImage_Verify_AltText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $img->VerifyAltText('testimg1_alt');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $img = undef;
  }

#  #todo: test with link
#sub TestClickImage_withSrc
#  {
#  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
#
#  ClickX('testbutton3_id', 'wait');
#  VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  ClickBackButton();
#  VerifyTitle('TestjIETest Main');
#  }

#---------------------------------------
sub TestImage_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $img->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $img2 = $ie->GetImage('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $img2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $img = undef;
  $img2 = undef;
  }

#---------------------------------------
sub TestImage_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput4_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $img->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $img->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox($box, 0);

  $img = undef;
  $box = undef;
  }

#---------------------------------------
sub TestImage_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $img = $ie->GetImage() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestImage_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $img->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $img = undef;
  }

#---------------------------------------
sub TestImage_Bad_wdc
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $img = $ie->GetImage('testimg1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $img->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $img = undef;
  }

#---------------------------------------
#-- Edit Box
#---------------------------------------

#---------------------------------------
sub TestEditBox_Set_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $ebox = $ie->GetEditBox(qr/testedit1_name/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->VerifyText('xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $ebox->SetText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox->SetText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreEditBox1();

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Set_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->VerifyText('xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $ebox->SetText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox->SetText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreEditBox1();

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('xx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $ebox->Exists();
  jIESelfTest::SelfTestAssert($rc, 0);

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Is_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->IsText('xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $ebox->SetText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox->SetText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreEditBox1();

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->IsText('testedit1_valuexx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $ebox->SetText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreEditBox1();

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->IsText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox->SetText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->IsText('testedit1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ebox->VerifyText('testedit1_newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  RestoreEditBox1();

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $ebox = $ie->GetEditBox() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestEditBox_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $ebox->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Bad_SetText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $ebox->SetText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $ebox->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $ebox = undef;
  }

#---------------------------------------
sub TestEditBox_Bad_VerifyText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $ebox = $ie->GetEditBox('testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $ebox->VerifyText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $ebox = undef;
  }

#---------------------------------------
#-- TextArea
#---------------------------------------

#---------------------------------------
sub TestTextArea_Set_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt = $ie->GetTextArea(qr/textarea1_name/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->VerifyText('xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $txt->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt->SetText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreTextArea($txt);

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Set_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt = $ie->GetTextArea('textarea1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->VerifyText('textarea1 valuexx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $txt->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt->SetText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreTextArea($txt);

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Set_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $txt1 = $ie->GetTextArea('textarea1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt1->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $txt2 = $ie->GetTextArea('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $txt2->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt2->VerifyText('textarea1 newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt1->VerifyText('textarea1 newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $txt3 = $ie->GetTextArea('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $txt3->SetText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt3->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreTextArea($txt1);

  $txt1 = undef;
  $txt2 = undef;
  $txt3 = undef;
  }

#---------------------------------------
sub TestTextArea_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt1 = $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $txt2 = $ie->GetTextArea('textarea1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $txt3 = $ie->GetTextArea('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $txt4 = $ie->GetTextArea('xxx');
  jIESelfTest::SelfTestIsWarning();

  $txt1 = undef;
  $txt2 = undef;
  $txt3 = undef;
  $txt4 = undef;
  }

#---------------------------------------
sub TestTextArea_Is_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt = $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->IsText('textarea1 valuexx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $txt->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt->SetText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreTextArea($txt);

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt = $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->IsText('xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $txt->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreTextArea($txt);

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt= $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->IsText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt->SetText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->IsText('textarea1 newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $txt->VerifyText('textarea1 newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  RestoreTextArea($txt);

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $txt = $ie->GetTextArea() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestTextArea_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt= $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $txt->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Bad_SetText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt = $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $txt->SetText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt= $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $txt->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $txt = undef;
  }

#---------------------------------------
sub TestTextArea_Bad_VerifyText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $txt= $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $txt->VerifyText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $txt = undef;
  }

#---------------------------------------
#-- Password Box
#---------------------------------------

#---------------------------------------
sub TestPasswordBox_Set_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox(qr/testpassword1_name/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->VerifyText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box->SetText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Set_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox('testpassword1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->VerifyText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box->SetText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyText('testpassword1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Is_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->IsText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box->SetText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->IsText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box->SetText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->SetText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox('testpassword1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $box2 = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $box3 = $ie->GetPasswordBox('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $box3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box = undef;
  $box2 = undef;
  $box3 = undef;
  }

#---------------------------------------
sub TestPasswordBox_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->IsText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box->SetText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_newvalue');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  $box->SetText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->IsText('testpassword1_value');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->VerifyText('testpassword1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $box->VerifyText('testpassword1_valuexx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $box = $ie->GetPasswordBox() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestPasswordBox_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Bad_SetText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->SetText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Bad_IsText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->IsText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $box = undef;
  }

#---------------------------------------
sub TestPasswordBox_Bad_VerifyText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetPasswordBox('testpassword1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $box->VerifyText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $box = undef;
  }

#---------------------------------------
#-- List Box
#---------------------------------------

#---------------------------------------
sub TestListBox_Verify_SelectionwithName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox(qr/listbox1_name/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection(qr/listbox1_option2/);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('x');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option2');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_SetSelection_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection(qr/listbox1_option1/);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option2');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option2');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_SetSelection_withText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option2');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelectionByText('listbox1 option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->VerifySelection('listbox1_option2');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option3');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelectionByText('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_SetSelection_withInvalidOption
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $lb->SetSelection('xxx');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Is_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection(qr/listbox1_option2/);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Is_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelectionByText('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelectionByText(qr/listbox1 option2/);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelectionByText('listbox1 option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelectionByText('listbox1 optionxxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelectionByText('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelectionByText('listbox1 option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelectionByText('listbox1 option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelectionByText('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_SetSelection_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelectionByText('listbox1 option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelectionByText('listbox1 option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection(qr/listbox1_option1/);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelectionByText('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lb2 = $ie->GetListBox('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $lb2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb = undef;
  $lb2 = undef;
  }

#---------------------------------------
sub TestListBox_Verify_OptionExists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->VerifyOptionExists('listbox1 option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifyOptionExists(qr/listbox1 option2/);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifyOptionExists('x');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);
  }

#---------------------------------------
sub TestListBox_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option1xxx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $lb->IsSelection('listbox1_option2');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->IsSelection('listbox1_option3');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb->SetSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb->IsSelection('listbox1_option1');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $lb->VerifySelection('listbox1_option1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { my $lb = $ie->GetListBox() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestListBox_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lb->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Bad_SetSelection
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lb->SetSelection() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'option', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'option', 'missing');

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Bad_IsSelection
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lb->IsSelection() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $lb = undef;
  }

#---------------------------------------
sub TestListBox_Bad_VerifySelection
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $lb = $ie->GetListBox('listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  eval { $lb->VerifySelection() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $lb = undef;
  }

#---------------------------------------
#-- Generic Page Elements
#---------------------------------------

#---------------------------------------
sub TestPageElement_Click_withInnertext
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElement('BUTTON', qr/testbutton1 checked/);
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetPageElement('BUTTON', 'testbutton2 unchecked');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $btn2 = undef;
  $box = undef;
  }

#---------------------------------------
sub TestPageElement_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElement('BUTTON', 'testbutton1_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetPageElement('BUTTON', 'testbutton2_id');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $box = undef;
  $btn = undef;
  $btn2 = undef;
  }

#---------------------------------------
sub TestPageElement_Click_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElement('BUTTON', 'testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetPageElement('BUTTON', 'testbutton2 unchecked');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $btn2 = undef;
  $box = undef;
  }

#---------------------------------------
sub TestPageElementWithType_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $rbtn1 = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn2 = $ie->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn3 = $ie->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElementWithType('INPUT', 'radio', qr/testradio1_id/);
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  my $btn2 = $ie->GetPageElementWithType('INPUT', 'radio', 'testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  RestoreRadioButtons();

  $rbtn1 = undef;
  $rbtn2 = undef;
  $rbtn3 = undef;
  $btn = undef;
  $btn2 = undef;
  }

#---------------------------------------
sub TestPageElementWithType_Click_withValue
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $rbtn1 = $ie->GetRadioButton('testradio1_value');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn2 = $ie->GetRadioButton('testradio2_value');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn3 = $ie->GetRadioButton('testradio3_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElementWithType('INPUT', 'radio', 'testradio2_value');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  #restore
  my $btn2 = $ie->GetPageElementWithType('INPUT', 'radio', 'testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  RestoreRadioButtons();

  $rbtn1 = undef;
  $rbtn2 = undef;
  $rbtn3 = undef;
  $btn = undef;
  $btn2 = undef;
  }

#---------------------------------------
sub TestPageElement_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $lb1 = $ie->GetPageElement('SELECT', 'listbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lb2 = $ie->GetPageElement('SELECT', 'listbox1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $lb2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $lb3 = $ie->GetPageElement('SELECT', 'xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $lb3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $lb4 = $ie->GetPageElement('xxx', 'listbox1_id');
  jIESelfTest::SelfTestIsWarning();

  $rc = $lb4->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $lb1 = undef;
  $lb2 = undef;
  $lb3 = undef;
  $lb4 = undef;
  }

#---------------------------------------
sub TestPageElement_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->GetPageElement() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'tagname', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'tagname', 'missing');

  eval { $ie->GetPageElement('BUTTON') };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestPageElement_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn = $ie->GetPageElement('INPUT', 'testradio2_value');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $btn = undef;
  }

#---------------------------------------
sub TestPageElement_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn = $ie->GetPageElement('BUTTON', 'testbutton1 checked');
  jIESelfTest::SelfTestIsBlank();

  $rc = $btn->Exists();
  jIESelfTest::SelfTestIsBlank();

  $btn->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $ie->GetPageElement('BUTTON', 'testbutton2 unchecked');
  jIESelfTest::SelfTestIsBlank();

  $btn2->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox2();

  $btn = undef;
  $btn2 = undef;
  $box = undef;
  }

#---------------------------------------
sub TestPageElementWithType_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $eb1 = $ie->GetPageElementWithType('INPUT', 'text', 'testedit1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $eb1->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $eb2 = $ie->GetPageElementWithType('INPUT', 'text', 'testedit1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $eb2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $eb3 = $ie->GetPageElementWithType('INPUT', 'text', 'xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $eb3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $eb4 = $ie->GetPageElementWithType('xxx', 'text', 'testedit1_id');
  jIESelfTest::SelfTestIsWarning();

  $rc = $eb4->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $eb5 = $ie->GetPageElementWithType('INPUT', 'xxx', 'testedit1_id');
  jIESelfTest::SelfTestIsWarning();

  $rc = $eb5->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $eb1 = undef;
  $eb2 = undef;
  $eb3 = undef;
  $eb4 = undef;
  $eb5 = undef;
  }

#---------------------------------------
sub TestPageElementWithType_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $rbtn1 = $ie->GetRadioButton('testradio1_value');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn2 = $ie->GetRadioButton('testradio2_value');
  jIESelfTest::SelfTestIsBlank();
  my $rbtn3 = $ie->GetRadioButton('testradio3_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $elem = $ie->GetPageElementWithType('INPUT', 'radio', 'testradio1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $elem->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $elem->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rbtn1->IsState(1);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn2->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $rbtn3->IsState(0);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreRadioButtons();

  $rbtn1 = undef;
  $rbtn2 = undef;
  $rbtn3 = undef;
  $elem = undef;
  }

#---------------------------------------
sub TestPageElementWithType_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->GetPageElementWithType() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'tagname', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'tagname', 'missing');

  eval { $ie->GetPageElementWithType('INPUT') };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'tagtype', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'tagtype', 'missing');

  eval { $ie->GetPageElementWithType('INPUT', 'radio') };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestPageElementWithType_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $btn = $ie->GetPageElementWithType('INPUT', 'radio', 'testradio2_value');
  jIESelfTest::SelfTestIsBlank();

  eval { $btn->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $btn = undef;
  }

#---------------------------------------
#-- Form
#---------------------------------------

#---------------------------------------
sub TestForm_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $form = $ie->GetForm('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $form->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $form = undef;
  }

#---------------------------------------
sub TestForm_Element_Verify_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $form = $ie->GetForm(qr/testform1_id/);
  jIESelfTest::SelfTestIsBlank();

  my $elem = $form->GetElement('testinput6_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $elem->Exists();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $elem2 = $form->GetElement('xxx');
  jIESelfTest::SelfTestIsBlank();

  $rc = $elem2->Exists();
  jIESelfTest::SelfTestAssert($rc, 0);

  $form = undef;
  $elem = undef;
  $elem2 = undef;
  }

#---------------------------------------
sub TestForm_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $form = $ie->GetForm('testform1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $form->Exists();
  jIESelfTest::SelfTestAssert($rc, 1);

  $form->Click();
  jIESelfTest::SelfTestIsBlank();

  my $elem2 = $form->GetElement('testinputx');
  jIESelfTest::SelfTestIsBlank();

  $rc = $elem2->Exists();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $elem = $form->GetElement('testinput6_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $elem->Exists();
  jIESelfTest::SelfTestAssert($rc, 1);

  $elem->Click();
  jIESelfTest::SelfTestIsBlank();

  $form = undef;
  $elem = undef;
  $elem2 = undef;
  }

#---------------------------------------
sub TestForm_Bad_Get
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $form = $ie->GetForm() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestForm_Bad_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $form = $ie->GetForm('testform1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $form->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $form = undef;
  }

#---------------------------------------
sub TestForm_Bad_GetElement
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $form = $ie->GetForm('testform1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $form->GetElement() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');

  $form = undef;
  }

#---------------------------------------
#-- Table
#---------------------------------------

#---------------------------------------
sub TestTable_withClass
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $box = $ie->GetCheckBox('testinput5_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $table = $ie->GetTable(qr/table1_id/);
  jIESelfTest::SelfTestIsBlank();

  $rc = $table->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $table->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  $rc = $cell->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $cell->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $v = $cell->GetValue();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($v, 'row1 col1');

  $cell = $table->GetCell(1, 1);
  $v = $cell->GetValue();
  jIESelfTest::SelfTestAssert($v, 'row2 col2');

  my $numrows = $table->GetNumRows();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($numrows, 3);

  $rc = $table->VerifyNumRows(3);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $row = $table->GetRow(0);
  jIESelfTest::SelfTestIsBlank();

  my $numcols = $row->GetNumCols();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($numcols, 2);

  $rc = $row->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox5();

  $box = undef;
  $table = undef;
  $cell = undef;
  $row = undef;
  $v = undef;
  }

#---------------------------------------
sub TestTable_Get_Bad
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { my $table = $ie->GetTable() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'value', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'value', 'missing');
  }

#---------------------------------------
sub TestTable_CellValue
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  my $v = $cell->GetValue();
  jIESelfTest::SelfTestAssert($v, 'row1 col1');

  $cell = $table->GetCell(1, 1);
  jIESelfTest::SelfTestIsBlank();

  $v = $cell->GetValue();
  jIESelfTest::SelfTestAssert($v, 'row2 col2');

  $table = undef;
  $cell = undef;
  $v = undef;
  }

#---------------------------------------
sub TestTable_Exists
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $table->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $table2 = $ie->GetTable('table1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $table2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $table3 = $ie->GetTable('xxx');
  jIESelfTest::SelfTestIsWarning();

  $rc = $table3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $table = undef;
  $table2 = undef;
  $table3 = undef;
  }

#---------------------------------------
sub TestTable_Exists_BadCell
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { my $cell = $table->GetCell(); } ;
  jIESelfTest::SelfTestIsSyntax('Parameter', 'row', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'row', 'missing');

  eval { my $cell2 = $table->GetCell(0); } ;
  jIESelfTest::SelfTestIsSyntax('Parameter', 'col', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'col', 'missing');

  $table = undef;
  }

#---------------------------------------
sub TestTable_Exists_CellwithId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  $rc = $cell->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $v = $cell->GetValue();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($v, 'row1 col1');

  my $cell2 = $table->GetCell(4, 0);
  jIESelfTest::SelfTestIsWarning();

  $rc = $cell2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $cell3 = $table->GetCell(0, 4);
  jIESelfTest::SelfTestIsWarning();

  $rc = $cell3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $table = undef;
  $cell = undef;
  $cell2 = undef;
  $cell3 = undef;
  $v = undef;
  }

#---------------------------------------
sub TestTable_Exists_CellwithName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_name');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  $rc = $cell->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $v = $cell->GetValue();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($v, 'row1 col1');

  my $cell2 = $table->GetCell(4, 0);
  jIESelfTest::SelfTestIsWarning();

  $rc = $cell2->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  my $cell3 = $table->GetCell(0, 4);
  jIESelfTest::SelfTestIsWarning();

  $rc = $cell3->Exists();
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $table = undef;
  $cell = undef;
  $cell2 = undef;
  $cell3 = undef;
  $v = undef;
  }

#---------------------------------------
sub TestTable_Click_Bad
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $table->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $table = undef;
  }

#---------------------------------------
sub TestTable_Click_BadCell
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(1, 1);
  jIESelfTest::SelfTestIsBlank();

  eval { $cell->Click('x') };
  jIESelfTest::SelfTestIsSyntax('Valid values are', 'wait', 'nowait');
  jIESelfTest::SelfTestContains($@, 'Valid values are', 'wait', 'nowait');

  $table = undef;
  $cell = undef;
  }

#---------------------------------------
sub TestTable_Click_CellwithName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_name');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  $cell->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  my $box = $ie->GetCheckBox('testinput5_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $cell->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox5();

  $table = undef;
  $cell = undef;
  $box = undef;
  }

#---------------------------------------
sub TestTable_Click_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(0, 0);
  jIESelfTest::SelfTestIsBlank();

  $cell->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  my $box = $ie->GetCheckBox('testinput5_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $cell->Click('nowait');
  jIESelfTest::SelfTestIsBlank();

  $rc = $box->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreCheckBox5();

  $table = undef;
  $cell = undef;
  $box = undef;
  }

#  todo: test with link
#  ClickX('testbutton3_id', 'wait');
#  VerifyTitle('TestjIETest Link');
#  jIESelfTest::SelfTestIsPassed();
#  ClickBackButton();
#  VerifyTitle('TestjIETest Main');

#---------------------------------------
sub TestTable_Verify_Bad
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { $table->VerifyNumRows() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $table = undef;
  }

#---------------------------------------
sub TestTable_Get_BadGetRow
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { my $cell = $table->GetRow() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'row', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'row', 'missing');

  $table = undef;
  }

#---------------------------------------
sub TestTable_Get_BadNumCols
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $row = $table->GetRow(1);
  jIESelfTest::SelfTestIsBlank();

  eval { my $cols = $row->VerifyNumCols() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $table = undef;
  $row = undef;
  }

#---------------------------------------
sub TestTable_Get_BadGetCell
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  eval { my $cell = $table->GetCell() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'row', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'row', 'missing');

  eval { my $cell = $table->GetCell(1) };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'col', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'col', 'missing');

  $table = undef;
  }

#---------------------------------------
sub TestTable_Verify_TableCell_Bad
  {
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $cell = $table->GetCell(1, 1);
  jIESelfTest::SelfTestIsBlank();

  eval { $cell->VerifyValue() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'expected', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'expected', 'missing');

  $table = undef;
  $cell = undef;
  }

#---------------------------------------
sub TestTable_Verify_NumRows_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $table->VerifyNumRows(4);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $table->VerifyNumRows(3);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $table = undef;
  }

#---------------------------------------
sub TestTable_Verify_NumRows_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $table = $ie->GetTable('table1_name');
  jIESelfTest::SelfTestIsBlank();

  $rc = $table->VerifyNumRows(4);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $table->VerifyNumRows(3);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $table = undef;
  }

#---------------------------------------
sub TestTable_Verify_NumCols_withId
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_id');
  jIESelfTest::SelfTestIsBlank();

  my $row0 = $table->GetRow(0);
  jIESelfTest::SelfTestIsBlank();
  my $row1 = $table->GetRow(1);
  jIESelfTest::SelfTestIsBlank();
  my $row2 = $table->GetRow(2);
  jIESelfTest::SelfTestIsBlank();
  my $row3 = $table->GetRow(3);
  jIESelfTest::SelfTestIsBlank();

  $rc = $row0->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row0->VerifyNumCols(3);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $row1->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row2->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row3->VerifyNumCols(2);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $table = undef;
  $row0 = undef;
  $row1 = undef;
  $row2 = undef;
  $row3 = undef;
  }

#---------------------------------------
sub TestTable_Verify_NumCols_withName
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $table = $ie->GetTable('table1_name');
  jIESelfTest::SelfTestIsBlank();

  my $row0 = $table->GetRow(0);
  jIESelfTest::SelfTestIsBlank();
  my $row1 = $table->GetRow(1);
  jIESelfTest::SelfTestIsBlank();
  my $row2 = $table->GetRow(2);
  jIESelfTest::SelfTestIsBlank();
  my $row3 = $table->GetRow(3);
  jIESelfTest::SelfTestIsBlank();

  $rc = $row0->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row0->VerifyNumCols(3);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $row1->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row2->VerifyNumCols(2);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $row3->VerifyNumCols(2);
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $table = undef;
  $row0 = undef;
  $row1 = undef;
  $row2 = undef;
  $row3 = undef;
  }

#---------------------------------------
#-- StatusBar
#---------------------------------------

#---------------------------------------
sub TestStatusBar_VerifyStatusBarMessage_local
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $gCurrentURL = $localURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->VerifyStatusBarMessage('Done');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyStatusBarMessage('xx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestStatusBar_VerifyStatusBarMessage_remote
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->VerifyStatusBarMessage('Done');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyStatusBarMessage('xx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestStatusBar_VerifyStatusBarMessage_flipflop
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  if ($ie->IsURL($remoteURL))
    {
    $gCurrentURL = $localURL;
    }
  else
    {
    $gCurrentURL = $remoteURL;
    }
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->VerifyStatusBarMessage('Done');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyStatusBarMessage('xx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestStatusBar_Bad_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->VerifyStatusBarMessage() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');
  }

#---------------------------------------
#-- Text on page
#---------------------------------------

#---------------------------------------
sub TestText_Verify_Present
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->VerifyTextPresent('Paragraph text');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyTextPresent('Paragraphx textx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $ie->VerifyTextPresent('Div text');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyTextPresent('Span text');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  }

#---------------------------------------
sub TestText_Is_Present
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->IsTextPresent('Paragraph text');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->IsTextPresent('Paragraphx textx');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $ie->IsTextPresent('Div text');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->IsTextPresent('Span text');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  #todo: test count parm
  }

#---------------------------------------
sub TestText_Verify_NotPresent
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $rc = $ie->VerifyTextNotPresent('Paragraph text');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $rc = $ie->VerifyTextNotPresent('Paragraphx textx');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  }

#---------------------------------------
sub TestText_Verify_ArrayPresent
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->VerifyTextArrayPresent('Paragraph text', 'Div text', 'Span text');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyTextArrayPresent('Paragraphx textx', 'Div text', 'Span text');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);
  }

#---------------------------------------
sub TestText_Is_ArrayPresent
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->IsTextArrayPresent('Paragraph text', 'Div text', 'Span text');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->IsTextArrayPresent('Paragraphx textx', 'Div text', 'Span text');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);
  }

#---------------------------------------
sub TestText_Bad_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->VerifyTextPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  eval { $ie->VerifyTextNotPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  eval { $ie->VerifyTextArrayPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'list', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'list', 'missing');
  }

#---------------------------------------
sub TestText_Bad_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->IsTextPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  eval { $ie->VerifyTextNotPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');

  eval { $ie->IsTextArrayPresent() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'list', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'list', 'missing');
  }

#---------------------------------------
#-- Bad calls
#---------------------------------------

#---------------------------------------
sub TestWin_BadUrl
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  eval { $ie->NavigateTo() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'url', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'url', 'missing');
  }

#---------------------------------------
sub TestWin_BadMainlineCall
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $ie->BadCallIntoMainProgram('testinput2_name');
  jIESelfTest::SelfTestIsSyntax('Unknown method');
  }

#---------------------------------------
sub TestWin_BadClassMethodCall
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();

  $box->BadMethodCallInClass();
  jIESelfTest::SelfTestIsFailed();

  $box = undef;
  }

#---------------------------------------
sub TestWin_Unmaximized
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $ie2 = new jIETest();
  jIESelfTest::SelfTestIsBlank();

  #todo: this fails after 75 invocations
  #todo:    Free to wrong pool 6365fff8 not 235830 at e:/tools/perl/lib/Tk/Widget.pm line 98
  #todo:    during global destruction.
  $ie2->Start(0);
  sleep(1);
  $ie2->Quit();

  $ie2 = undef;
  }

#---------------------------------------
sub TestWin_BadMaximized
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  my $ie2 = new jIETest();
  jIESelfTest::SelfTestIsBlank();

  eval { $ie2->Start(2); } ;
  jIESelfTest::SelfTestIsSyntax('Parameter', 'maximized', 'invalid');

  eval { $ie2->Start(1, 99); } ;
  jIESelfTest::SelfTestIsSyntax('Parameter', 'compatmode', 'invalid');

  $ie2 = undef;
  }

#---------------------------------------
#-- Title
#---------------------------------------

#---------------------------------------
sub TestTitle_Verify2
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $rc = $ie->VerifyTitle('TestjIETest Main');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  }

#---------------------------------------
sub TestTitle_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->VerifyTitle('John Arrizza');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyTitle('Johns stuff');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }


#---------------------------------------
sub TestTitle_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->IsTitle('John Arrizza');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->IsTitle('Johns stuff');
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestTitle_Bad_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->VerifyTitle() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');
  }

#---------------------------------------
sub TestTitle_Bad_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->IsTitle() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');
  }

#---------------------------------------
#-- URL
#---------------------------------------

#---------------------------------------
sub TestURL_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->VerifyURL($remoteURL);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->VerifyURL($remoteURL . ".bob");
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestURL_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $rc = $ie->IsURL($remoteURL);
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $ie->IsURL($remoteURL . ".bob");
  jIESelfTest::SelfTestIsBlank();
  jIESelfTest::SelfTestAssert($rc, 0);

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestURL_Bad_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->VerifyURL() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'url', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'url', 'missing');
  }

#---------------------------------------
sub TestURL_Bad_Is
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->IsURL() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'url', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'url', 'missing');
  }

#---------------------------------------
#-- MessageBox
#---------------------------------------

#---------------------------------------
sub TestMessageBox_VerifyFullText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $ie->ExpectMessageBox(5);
  my $btn = $ie->GetButton('testmsgbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyMessageBoxText('MessageBox1 text');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn = undef;
  }

#---------------------------------------
sub TestMessageBox_VerifyShortenedText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $ie->ExpectMessageBox(2);
  my $btn = $ie->GetButton('testmsgbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyMessageBoxText('MessageBox1');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $btn = undef;
  }


#---------------------------------------
sub TestMessageBox_VerifyUnknownText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $ie->ExpectMessageBox(2);
  my $btn = $ie->GetButton('testmsgbox1_id');
  jIESelfTest::SelfTestIsBlank();

  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyMessageBoxText('xxx');
  jIESelfTest::SelfTestIsFailed();
  jIESelfTest::SelfTestAssert($rc, 0);

  $btn = undef;
  }

#---------------------------------------
sub TestMessageBox_Bad_Verify
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->VerifyMessageBoxText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'text', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'text', 'missing');
  }

#---------------------------------------
#-- Misc
#---------------------------------------

sub TestMisc_GetCompatMode
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $mode;
  my $expectedmode;

  #default page is IE8
  $mode = $ie->GetCompatMode();
  $expectedmode = ($mode == 5) ? 5 : 8;
  jIESelfTest::SelfTestAssert($mode, $expectedmode); #IE8 compat mode

  #check IE7
  $gCurrentURL = $localie7URL;
  $ie->NavigateTo($gCurrentURL);
  $mode = $ie->GetCompatMode();
  $expectedmode = ($mode == 5) ? 5 : 7;
  jIESelfTest::SelfTestAssert($mode, $expectedmode); #IE7 compat mode

  #check IE5
  $gCurrentURL = $localie5URL;
  $ie->NavigateTo($gCurrentURL);
  $mode = $ie->GetCompatMode();
  $expectedmode = 5;
  jIESelfTest::SelfTestAssert($mode, $expectedmode); #IE7 compat mode

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestMisc_BackButton_Click
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  my $lnk = $ie->GetLink('Sample Code');
  jIESelfTest::SelfTestIsBlank();

  $lnk->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('Downloads');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->ClickBackButton();
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('John Arrizza');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  RestoreDefaultPage();

  $lnk = undef;
  }

#---------------------------------------
sub TestMisc_SaveOuterText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  my $testfile = 'jietest_test.out';
  unlink $testfile;
  $ie->SaveOuterText($testfile);
  ToResult("SELFTEST: ERROR: $testfile not found\n") if !-e $testfile;

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestMisc_Bad_SaveOuterText
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->SaveOuterText() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'filename', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'filename', 'missing');
  }

#---------------------------------------
sub TestMisc_RefreshIE
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  $ie->Refresh();
  jIESelfTest::SelfTestIsBlank();
  $ie->Refresh();
  jIESelfTest::SelfTestIsBlank();
  $ie->Refresh();
  jIESelfTest::SelfTestIsBlank();
  }

#---------------------------------------
sub TestMisc_Navigate
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);

  $gCurrentURL = 'www.google.com';
  $ie->NavigateTo($gCurrentURL);
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('Google');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $gCurrentURL = $remoteURL;
  $ie->NavigateTo($gCurrentURL);
  jIESelfTest::SelfTestIsBlank();

  $rc = $ie->VerifyTitle('John Arrizza');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ie->NavigateTo("ThisShouldBeABadUrl.orgx");
  jIESelfTest::SelfTestIsWarning('NavigateError', 'ErrorCode=', 'URL=http://thisshouldbeabadurl.orgx/');

  RestoreDefaultPage();
  }

#---------------------------------------
sub TestMisc_Bad_Navigate
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->NavigateTo() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'url', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'url', 'missing');
  }

#---------------------------------------
sub TestMisc_Bad_ExpectLogin
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');

  eval { $ie->ExpectLoginPopup() };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'userid', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'userid', 'missing');

  eval { $ie->ExpectLoginPopup('bob') };
  jIESelfTest::SelfTestIsSyntax('Parameter', 'password', 'missing');
  jIESelfTest::SelfTestContains($@, 'Parameter', 'password', 'missing');
  }


#---------------------------------------
sub TestMisc_PrintObjects
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $ie->PrintObjectInfo();
  jIESelfTest::SelfTestIsBlank();
  }

#---------------------------------------
sub TestMisc_PrintAllObjects
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  $ie->PrintObjectInfo();
  jIESelfTest::SelfTestIsBlank();
  }

#---------------------------------------
#-- Popups
#---------------------------------------

sub TestAlphaCode_Popups_onepopup
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  #press the button to create the popup window
  my $btn = $ie->GetButton('testpopup1_id');
  jIESelfTest::SelfTestIsBlank();
  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  #the popup window handle is saved in the queue
  my $pup = $ie->GetNextPopup();
  my $empty = $ie->GetNextPopup();
  jIESelfTest::SelfTestAssert($empty, undef);

  $rc = $pup->VerifyTitle('TestjIETest Popup');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $rb1 = $pup->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();
  my $rb2 = $pup->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $rb3 = $pup->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $rc = $rb1->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  $rc = $rb2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  $rc = $rb3->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rb1->Click();
  jIESelfTest::SelfTestIsBlank();

  $rc = $rb1->VerifyState(1);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  $rc = $rb2->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);
  $rc = $rb3->VerifyState(0);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2 = $pup->GetButton('testpopup1_id');
  jIESelfTest::SelfTestIsBlank();
  $btn2->Click(); #closes the popup
  jIESelfTest::SelfTestIsBlank();
  }

sub TestAlphaCode_Popups_twopopups
  {
  ToResult("------- " . (caller(0))[3] . "\n", 'nolast');
  my $btn = $ie->GetButton('testpopup1_id');
  jIESelfTest::SelfTestIsBlank();

  #create one popup
  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  #create two popups
  $btn->Click();
  jIESelfTest::SelfTestIsBlank();

  #the popup window handles are saved in the queue
  my $pup1 = $ie->GetNextPopup();
  my $pup2 = $ie->GetNextPopup();
  my $empty = $ie->GetNextPopup();
  jIESelfTest::SelfTestAssert($empty, undef);

  $rc = $pup1->VerifyTitle('TestjIETest Popup');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $rc = $pup2->VerifyTitle('TestjIETest Popup');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  my $btn2;
  $btn2 = $pup1->GetButton('testpopup1_id');
  jIESelfTest::SelfTestIsBlank();
  $btn2->Click(); #closes the popup
  jIESelfTest::SelfTestIsBlank();

  $btn2 = $pup2->GetButton('testpopup1_id');
  jIESelfTest::SelfTestIsBlank();
  $btn2->Click(); #closes the popup
  jIESelfTest::SelfTestIsBlank();
  }

#---------------------------------------
#-- support routines
#---------------------------------------

#---------------------------------------
sub RestoreDefaultPage
  {
  #do not use IsURL in this routine, causes an exception
  ToResult("Restoring Default page...\n", 'nolast');
  $gCurrentURL = $localURL;
  $ie->NavigateTo($gCurrentURL);
  die "Could not restore default page!" unless $ie->IsTitle('TestjIETest Main');
  }

#---------------------------------------
sub RestoreRadioButtons
  {
  my $btn1 = $ie->GetRadioButton('testradio1_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn2 = $ie->GetRadioButton('testradio2_id');
  jIESelfTest::SelfTestIsBlank();
  my $btn3 = $ie->GetRadioButton('testradio3_id');
  jIESelfTest::SelfTestIsBlank();

  $btn3->Click();
  if (!$btn1->IsState(0) || !$btn2->IsState(0) || !$btn3->IsState(1))
    {
    ToResult("ERROR: Radiobutton restore failed " . (caller(0))[3] . "\n", 'nolast');
    die "radiobutton restore failed.";
    }

  $btn1 = undef;
  $btn2 = undef;
  $btn3 = undef;
  }

#---------------------------------------
sub RestoreEditBox1
  {
  my $ebox = $ie->GetEditBox('testedit1_name');
  $ebox->SetText('testedit1_value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $ebox->VerifyText('testedit1_value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $ebox = undef;
  }

#---------------------------------------
sub RestoreCheckBox
  {
  my ($box, $val) = @_;
  jIESelfTest::SelfTestIsBlank();
  $box->SetState($val);

  $rc = $box->VerifyState($val);
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $box = undef;
  }

#---------------------------------------
sub RestoreCheckBox2
  {
  my $box = $ie->GetCheckBox('testinput2_name');
  jIESelfTest::SelfTestIsBlank();
  RestoreCheckBox($box, 0);

  $box = undef;
  }

#---------------------------------------
sub RestoreCheckBox5
  {
  my $box = $ie->GetCheckBox('testinput5_name');
  jIESelfTest::SelfTestIsBlank();
  RestoreCheckBox($box, 0);

  $box = undef;
  }

#---------------------------------------
sub RestoreTextArea
  {
  my $txt = $ie->GetTextArea('textarea1_name');
  jIESelfTest::SelfTestIsBlank();

  $txt->SetText('textarea1 value');
  jIESelfTest::SelfTestIsBlank();

  $rc = $txt->VerifyText('textarea1 value');
  jIESelfTest::SelfTestIsPassed();
  jIESelfTest::SelfTestAssert($rc, 1);

  $txt = undef;
  }

#---------------------------------------
sub setup
  {
  ToResult("------- start compatibility mode=$compatmode\n", 'nolast');
  $ie->Start(undef, $compatmode);

  RestoreDefaultPage();
  }

#---------------------------------------
sub teardown
  {
  $ie->Quit();
  }

#-----------------------------------------------------------------------
#-- TK support code
#-----------------------------------------------------------------------

#holds the value of the entry field for the Random test selector
my $gRandomCount = 0;
#keeps track of the next testid to use
my $gNextTestId = 0;
#keeps track of the number of tests run in this session
my $gNumAllTestsRun = 0;

my $gNumTestsRun = 0;
my $gNumAsserts = 0;
my $gNumFailed = 0;

#main window
my $gMainWindow = new MainWindow;
my $gTitle = 'Test jIETest...';
my $gRandomCountField; # a forward decl
my $gTree; # a forward decl
my %gAllSelectedTests = (); #holds a list of all the tests and a state
my $gCfgFile = "testjitest.cfg";

#------------
sub InitTestSession
  {
  my ($title) = @_;
  $gNumTestsRun = 0;
  print "$title\n";
  }

#------------
sub TermTestSession
  {
  ($gNumAsserts, $gNumFailed) = jIESelfTest::SelfTestSummary();
  $gMainWindow->title($gTitle);
  }

#------------
sub AddTreeEntry
  {
  my ($tree, $entry) = @_;

  my (@items) = split '_', $entry;

  my $path = '';
  my $num = 0;
  foreach my $item (@items)
    {
    $path .= '_' unless $num == 0;
    $path .= $item;
    $num++;
    next if $tree->info('exists', $path);

    my $node = $tree->add($path,
                  -text=>$item,
                  -itemtype=>'text',
                  -data=>$gNextTestId);

    $tree->selectionSet($node) if (exists $gAllSelectedTests{$path});
    $gNextTestId++;
    }
 }

#------------
#- sets the random count entry field
sub SetRandomCount
  {
  my ($var) = @_;

  if ($var =~ m/^\d*$/)
    {
    $gRandomCountField->configure(-fg=>$gMainWindow->cget(-fg));
    $gRandomCount = scalar $var;
    #print "x= setting random count: ", $var, "\n";
    }
  else
    {
    $gRandomCountField->configure(-fg=>"red");
    }
  return 1;
  }

#------------
#runs the given test
#testcount - indicates how many tests we've run in this session
sub RunATest
  {
  my ($testid, $testname) = @_;

  $gNumTestsRun++;
  $gNumAllTestsRun++;
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
  my $msg = sprintf "%4d-%02d-%02d %02d:%02d:%02d: %4d: [%4d] %s", $year+1900,$mon+1,$mday,$hour,$min,$sec, $gNumAllTestsRun,$testid,$testname;
  print "$msg\n";
  $gMainWindow->title($gNumAllTestsRun . " " . $testname);
  #my $h = new LeakTest('runatest');
  my $before = $jIESelfTest::gSelfTestFailed;
#  print "OLE: Before:\n";
#  Win32::OLE->EnumAllObjects ( sub  {
#    my $object = shift;
#    my $class = Win32::OLE->QueryObjectType($object);
#    $class = '?' if !defined $class;
#    printf " Object=%s Class=%s\n", $object, $class;
#    }
#    );

  eval ( "&$testname()" );

#  print "OLE: After:\n";
#  Win32::OLE->EnumAllObjects ( sub  {
#    my $object = shift;
#    my $class = Win32::OLE->QueryObjectType($object);
#    $class = '?' if !defined $class;
#    printf " Object=%s Class=%s\n", $object, $class;
#    }
#  );

  my $after = $jIESelfTest::gSelfTestFailed;
  #print "run $testname\n";
  #$h->Report(); $h=undef;
  my $res = $@;
  if ($res)
    {
    chomp $res;
    $msg = "FAILED: $testname eval '$res'\n";
    ToResult($msg, 'nolast');
    print $msg;
    $gTree->entryconfigure($testname, '-style', 'testfailed');
    }
  elsif ($before == $after)
    {
    $gTree->entryconfigure($testname, '-style', 'testpassed');
    }
  else
    {
    $gTree->entryconfigure($testname, '-style', 'testfailed');
    }
  }

#------------
sub GetTests
  {
  my @todo = @_;

  %gAllSelectedTests = ();
  foreach my $t (@todo)
    {
    $gAllSelectedTests{$t} = 1;
    }

  my @tests = ();
  foreach my $item (@todo)
    {
    my @children = $gTree->info('children', $item);
    if (@children)
      {
      push @todo, @children;
      }
    else
      {
      push @tests, $item;
      }
    }
  return @tests;
  }

#------------
sub RunTests
  {
  setup();
  foreach my $testname (@_)
    {
    my $testid = $gTree->info('data', $testname);
    RunATest($testid, $testname);
    }
  teardown();
  }

#------------
sub RunClickedTreeItem
  {
  InitTestSession("RunClickedItem: Running item $_[0]...");
  RunTests(GetTests($_[0]));
  TermTestSession();
  $gTree->selectionClear();
  }

#------------
sub RunAllTests
  {
  return if $gNextTestId == 0;
  InitTestSession("RunAllTests: Running all tests...");
  RunTests(GetTests(''));
  TermTestSession();
  }

#------------
#runs selected tests
sub RunSelectedTests
  {
  my @tests = $gTree->info('selection');
  return unless (scalar @tests); # check if any selected
  @tests = GetTests(@tests);
  InitTestSession("RunSelectedTests: Running selected tests...");
  RunTests(@tests);
  TermTestSession();
  }

#------------
sub RunRandomTests
  {
  return if $gNextTestId  == 0;
  $gRandomCount = 5 if $gRandomCount <= 0;
  InitTestSession("RunRandomTests: Running $gRandomCount tests...");

  #if any selected, run randomly from that selection,
  #otherwise run all randomly
  my @tests = $gTree->info('selection');
  if (scalar @tests)
    {
    @tests = GetTests(@tests);
    }
  else
    {
    @tests = GetTests('');
    }
  setup();
  my $size = scalar @tests;
  for my $i (1..$gRandomCount)
    {
    my $j = int (rand() * $size);
    my $testid = $gTree->info('data', $tests[$j]);
    #print "x=$size $j  $testid\n";
    RunATest($testid, $tests[$j]);
    }
  teardown();
  TermTestSession();
  }

#-----------------------------------------------------------------------
#-- MAIN
#-----------------------------------------------------------------------

if (-e $gCfgFile)
  {
	open(FH, "< $gCfgFile");
	while (<FH>)
	  {
	  chomp;
	  next if /^$/;
    $gAllSelectedTests{$_} = 1;
	  }
	close(FH);
  }

$gMainWindow->title($gTitle);

my $row = 0;
my $lblframe = $gMainWindow->LabFrame(-label => 'Results', -labelside => 'acrosstop')->grid(-row=>$row++, -column=>0);

my $col = 0;
my $runalllblx = $lblframe->Label(-text=>'Total Tests Run:' )->grid(-row=>0, -column=>$col++);
my $runalllbl = $lblframe->Label(-relief=>'sunken',  -width=>10, -textvariable=>\$gNumAllTestsRun)->grid(-row=>0, -column=>$col++);

my $runlblx = $lblframe->Label(-text=>'Tests Run:' )->grid(-row=>0, -column=>$col++);
my $runlbl = $lblframe->Label(-relief=>'sunken',  -width=>10, -textvariable=>\$gNumTestsRun)->grid(-row=>0, -column=>$col++);

my $assertslblx = $lblframe->Label(-text=>'Asserts Run:' )->grid(-row=>0, -column=>$col++);
my $assertslbl = $lblframe->Label(-relief=>'sunken', -width=>10, -textvariable=>\$gNumAsserts)->grid(-row=>0, -column=>$col++);

my $failedlblx = $lblframe->Label(-text=>'Tests Failed:' )->grid(-row=>0, -column=>$col++);
my $failedlbl = $lblframe->Label(-relief=>'sunken',  -width=>10, -textvariable=>\$gNumFailed)->grid(-row=>0, -column=>$col++);

my $lblframe2 = $gMainWindow->LabFrame(-label => 'Go!', -labelside => 'acrosstop')->grid(-row=>$row++, -column=>0);
my $btncol = 0;
#my $selectall = $lblframe2->Button(-text =>'Select All', -command => \&SelectAll)->grid(-row=>0, -column=>$btncol++);
my $go = $lblframe2->Button(-text =>'Run tests', -command => \&RunSelectedTests)->grid(-row=>0, -column=>$btncol++);
my $all = $lblframe2->Button(-text =>'Run All', -command => \&RunAllTests)->grid(-row=>0, -column=>$btncol++);
my $rdm = $lblframe2->Button(-text =>'Random', -command => \&RunRandomTests)->grid(-row=>0, -column=>$btncol++);
$gRandomCountField = $lblframe2->Entry(-validate =>'key', -validatecommand => \&SetRandomCount )->grid(-row=>0, -column=>$btncol++);

$gTree = $gMainWindow->Scrolled("Tree",
                           -scrollbars=> "osoe",
                           -width=> 90,
                           -height=> 30,
                           -command=> \&RunClickedTreeItem,  #invoke a command on a double click
                           -selectmode=> "extended",
                           -separator=> '_')->grid(-row=>$row++);

#add support for the mouse wheel
$gTree->bind("<Button-4>", sub { $gTree->yview('scroll',1,"units") } );
$gTree->bind("<Button-5>", sub { $gTree->yview('scroll',-1,"units") });

$gTree->autosetmode;
$gTree->ItemStyle('text', -stylename=>'testpassed', -background=>'green');
$gTree->ItemStyle('text', -stylename=>'testfailed', -background=>'red');
$gTree->focus; #set the focus to the tree

#load the tree with all routines that start with "Testxxx"
local *sym = "main::";
foreach my $s (sort keys %{ *sym })
  {
  next unless $s =~ /^Test/;
  AddTreeEntry($gTree, $s);
  }

MainLoop;

#-- check for OLE memory Leaks
END
  {
  open(FH, "> $gCfgFile");
  foreach my $k (keys %gAllSelectedTests)
    {
    print FH "$k\n";
    }
  close(FH);

  # "The EnumAllObjects() method is primarily a debugging tool.
  # It can be used e.g. in an END block to check if all
  # external connections have been properly destroyed."
  print "BEGIN Test for OLE leaks:\n";
  Win32::OLE->EnumAllObjects ( sub  {
    my $object = shift;
    my $class = Win32::OLE->QueryObjectType($object);
    $class = '?' if !defined $class;
    printf " Object=%s Class=%s\n", $object, $class;
    }
   );
  print "END test for leaks.\n";
  }



testjietest_embbededword.doc

Synopsis
ࡱ>	!# 7 	&bjbjUU	"7|7|&lE$ :RRRR"RRrRȅ020EUBURHi there.
Do not touch this document.
&
&& 1h/ =!"#$%
i8@8NormalCJ_HaJmH	sH	tH	<A@<Default Paragraph Font&
(00&&&$%%(
(%(John0D:\projects\jietest\testjietest_embbededword.doc@%%$C%&@@UnknownGz Times New Roman5Symbol3&z Arial"1h%F%F	$0&JohnJohnOh+'0T	

(4<DLssJohnfohnNormal.dotJohnl.d2hnMicrosoft Word 9.0@@@՜.+,0hp
noneitl&
	Title	

"Root Entry	FЃ$1TableWordDocumentSummaryInformation(DocumentSummaryInformation8CompObjjObjectPoolЃЃ
	FMicrosoft Word Document
MSWordDocWord.Document.89q

testjietest_frame1.html

Synopsis
<html>
    <head><title>Frame1</title></head>
    <p>This is a test of Frame1
</html>


testjietest_frame2.html

Synopsis
<html>
    <head><title>Frame2</title></head>
    <p>This is a test of Frame2
</html>

testjietest_frames.html

Synopsis
<html>
    <head><title>Frame Test</title></head>
    <frameset cols="200,*">
        <frame src="testjietest_frame1.html" name="frame1"/>
        <frame src="testjietest_frame2.html" name="frame2"/>
    </frameset>
</html>


testjietest_ie5.html

Synopsis
<html>
  <head>
  	<meta http-equiv='X-UA-Compatible' content='IE=5' > 
    <title>TestjIETest Main (ie5)</title>
		<SCRIPT LANGUAGE="JavaScript">
		<!--
    function enginemode()
      {
      engine = null;
			if (window.navigator.appName == "Microsoft Internet Explorer")
		    {
			  // This is an IE browser. What mode is the engine in?
			  if (document.documentMode) // IE8
			    engine = document.documentMode;
			  else // IE 5-7
			    {
			    engine = 5; // Assume quirks mode unless proven otherwise.
			    if (document.compatMode)
		        {
			      if (document.compatMode == "CSS1Compat")
			        engine = 7; // standards mode
			      }
			    }
			  }
			return engine  
			}
    
		function showenginemode() 
		  {
		  alert("mode " + enginemode())
		  }
		// -->
		</SCRIPT>
  </head>
<body>

<p>Test IE Compatibility mode:<br>
<button id='testenginemode' name='testenginemode' onclick='javascript: showenginemode()'>test enginemode</button>
<br><br>


</body>
</html>

testjietest_ie7.html

Synopsis
<html>
  <head>
  	<meta http-equiv='X-UA-Compatible' content='IE=7' > 
    <title>TestjIETest Main (ie7)</title>
		<SCRIPT LANGUAGE="JavaScript">
		<!--
    function enginemode()
      {
      engine = null;
			if (window.navigator.appName == "Microsoft Internet Explorer")
		    {
			  // This is an IE browser. What mode is the engine in?
			  if (document.documentMode) // IE8
			    engine = document.documentMode;
			  else // IE 5-7
			    {
			    engine = 5; // Assume quirks mode unless proven otherwise.
			    if (document.compatMode)
		        {
			      if (document.compatMode == "CSS1Compat")
			        engine = 7; // standards mode
			      }
			    }
			  }
			return engine  
			}
    
		function showenginemode() 
		  {
		  alert("mode " + enginemode())
		  }
		// -->
		</SCRIPT>
  </head>
<body>

<p>Test IE Compatibility mode:<br>
<button id='testenginemode' name='testenginemode' onclick='javascript: showenginemode()'>test enginemode</button>
<br><br>


</body>
</html>

testjietest_img1src.jpg

Synopsis
JFIFHHPhotoshop 3.08BIMx(HHR[ (hht2HK'd5So 8BIMHH8BIM8BIM'
8BIMH/fflff/ff2Z5-8BIMp8BIMAdobedۄ		





;	
	
s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt&	
EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT	
&6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz(?FX튣`eiq~N6w)kNqN69k^~N^BO
BO^8ׅГptY}Z,qqgTkг)ׅߡgS7mxV"o8xZ:L'^(dļ/mx]&o83)ׅr.6-~g^~qZtkN;iw^GK፯GK
O^'6~'659<1hڿ6&(8FkJNyWv+AoojU52$p7?L #N%[*xSJx.w1kv,J15mF5P]?`OjܷبĦg*DuZ^4mjBP
4<6~2[*P")|56:}OF*+5hxľIx᩿2M6_m<iT$"?wߦ6C
_& !x'j1cNOnG燍G@^xƾJ4-T.y9mx'ߏM#q MB><tڽp*RV(iKs<E4>xihy>HTcƓ{9zcࡿfh<zxM>:;LVJ'P_-,YF;`-?qQJ7<h87^]1==MXijv^qgJM?#p5YEgՔM
TGd76:D_R*Ď%$
㕑ѻ"]ߐoL_6cRj?Nq!k6+!tQ;,:lzt_EF
E>[O4%XP<Hsh!jѩT
uHYV'OG
1?~60
߫R=G$(ۮö
z!aM	5?<[3Itb$eI%׉q":
ۊ;P6#| d|!3Un {|źDzE+HܘS}qYP
D$U	@KPP8,6"iqy<p[
XG/^~,R "n?2`ٹ-j3hA!|12P>k1{@kJL_p?<FFwl@@'ڟsva&Z~ہ̵E7	wYsbʫҟAQ$Ўlr5{е`jr<0y*ٵ B~DJѓ
lS$reZSH>881X@0_<~U`9pErm\|Z;~#j85$_l'	cڤV2oW`H87Cրu钴tx %w'1^	,5hFNJxZ}:
`z,xRjÂzcj^g8U]LfV,ϖޔ,D#&W Ct^ӧ(6/Fƻֿ䎙Y
@rT
( 섖BвDy7&ہ#}-&AA0ŔAWC'FWA$)z1rA,	zW٤p
Pr > ICF- קn]դP>%G<Ri߮7ʨY\.˶WwajmwÜt`JOjU q/QR'F"**#华{!}qpxvMJ*bT_ڔ?`)G<;<7v퍯	R}@jsR>XbtO8h`^iszeBʑ"Y~mp挪<?ki`w~a$/Cm}^HJ}\b?ArU#>A$s7uJ(y\4@jcH#u
cFlE6Е&;TY`KVi:cP6lߚ$	o?DGdszw!8(ID eq2,yߚY9K_\By573hĆMڲǶNL51+}JXPt*dґBd11Ρ{+2	v6x*NltMRq>`@{	ف]"+%Lǐ"4jZӐ;@ԎZBkP]1ƺ;҉,-A";$)_QH*Tq'%kTcR:)W4}j!ԀXTQĴd3
H2`:oe#וJ-Pq(?x$-%zpjs%v*W}_l{&tbSWoO^IB2ROA݈?/lUim:q	%<y|hZ"-SJjPRTq^j)Nk&H>PnW﷎ȵSȶ@zȻhvĒ|8t8AՆ
Z!yE$+2v@zҞ#rQ
cCSQ׭|#=Q-v*HMP)VRѸ2#JUV-YyN1*:~lHUf(hPd,Q[[[u4%~c,ӟU4ۣ:~=mF^jyXΎx&91=2yuIeP+4QM'TF?fpH%`Y
ڏzR	$ {i^6#`Z6䆣"q:N+9sW}FZKuiQS	ˏ+
OREaH 2˜DZu~Mer8}^8iuEqki"z
j|U:Lc0̷W,!T/$aP:6X%	!snO1Bj$rh'*ʥڈ:xT)D;֫\=Mt9²l惏%\ĞQv2%+3XWF䭷Ĕv;9;%O*Hjdv2ʡa#uhhz;a`b:-6ȭ'\PAv
9(qHRt	W(Ss
`p&؞Euj+@VUAZSu"Zrƹ<MhN̸:G/ᖸoߕޤ	-xEc@o<bET,O@hhֹkHgHP_׀0O5dPĢ2oo[5(c	a޸
2QU7[ZP(!7ܟp-tSt"Z`!@#%$
MYI`pY!@S;Ӧ<݅dCE;2=bNTZTƭڭM5>"J@Y颡
ԃz~Eu[e'HXr@):SL|1X=*!v;幥+!wm44*	UmTXW(샾A%ԒЃ^
|q?^5TZ|^eTVs+=C}S'yVgfEKzʭD
V__|Δag>Q
3O"ZЪỴ`@vߩg'@eg^Ȓ	%*
׌S%62:jl&6?EJUDi"V7e
ҘI=v̀N6U\=?Rմ
H򏄑~uzSE2ѰSՍ]9<Dr_Ͳ
?.?X5
VLX^N|2(ڹ]2X[YH-wGsHbGǖ~Hʶ}b]nч%NKoHPQcj-%N=C\&AӨ׋-Q̰OPIbڝ
\OK|צr,[JrnH^},ZMt2
G~IR1
9'4q*s;;ƪʡ{H7s@E~G}U(8OzPЍ탉s[ Ԛ_ƙlO&X<ڿvefaߕޔJ	-O@ 
Mw}l@{npBZoA㕓QRnBSn=)\JFiTl!CjVlrgm9+o+yZ_5:`A'K"v)C/T$`}a1Z
Hz v?#ؑiLjJzMq3%S>|CVHC?45Dny3op]ZZ+Vӡ4;ЍȨ$Uu,ܐZ
TƩ!U}F`G4lV&0e`Ě=f;щyΓ`K\2HK,ݒw#?Rdj<FWzFk}65qkMlbW2R~f~_w9c
&}wL֮e`uR"8hv|9;pGO6`8]SQe$.?hכS9@8_\LÇ4y3t-[Nt#T?iNk2GbO	GǐtJݮ-!Z!YbC<WO%|C8y^Zj8ՉU,ܨI%J_6}W(~8^{]8O>+ܬFï_|p"Aݒ:'&ҵ不 `Uiq10iQU!YR&rh.+2JsQߏ5H.ly. 1 ŋ
}'!+,Ls@B8ASKՐva!eSJlE=sٱZ죧_WU=r6$(lMoRwXfm-r@/%WF`6=&㔀vY͸D*?F`ʌ/
WTx8e4)CE>HH8xH5M1
o845s쿆Z?ߕޔ	?,DhEZu!p{^N&c"Q!s&J/FG^d_|Yhw5TJV$HVUPk޵bOvhUcXMhy,X ~fo6^Rt(54%DvҭP$s҃^N+{H
Bf1M6`(%|-J}n]8J@
;}%!~*j@Xw"j҅FRW5SmF_–D1ґ*w&s05V[$\%.‡z~,ɄHf3o4?ۼ%adԋ~fcx~?pܢ
ĽLH`"%ϦE#؏2-`%hcQ<ŤMpn&VU	qkJ3+G[s)ᐑ;rWOWcmyLkMոMl a8vDoF<5"zf	wA7$N ьȪ=^%KGھ9R~HV	r72Dr?-5ASuS$$ǓP(6m4E1)2J^(JTQs+D1Nԥ}qqq01<%`:e
\?I,(UX#ܚSf
!fe|7YWU{9$c1HK8z<qwTfWGp=3yŘ#*׭
(G\Il!1YYшY+|ڸ6CӘX_cNLt:˜mD'/ "vi˾W}̼n;쿆\?וޔH}7bAAq[=Ƽ~2*lvEc
XokOlޞ~槈<C޻Wzd%aTRƩN
zTӿD曵?I}Rw=wF$w@Vޕ"Ysǎ`	W|4Xa`Ӑ$/CJ"!5	M?Nwmu—ƤԊR+|2R#W+$ ׮"6O\5}'UTGϘ-FUE>kJ{dg1V1CYcc2[鷷
So(?_my,4toiIe$t>:8O,&@?5<󆿩귫m_T8iT$<xן.<>|YbquGRbij|%jx"љnY|p{2vie]rb!
T2fr'J'
kiEH8O($?/te{Rx@ٕ}P
wačch - [5klųw=@5}#:ʗV%>7řlvK8/Ԣk$q-Ib`"v=j}[`0رw#(RGJA1J&`e{ģ%PĄ"DT
ߗmKv'?eF2
׭V	yba^@r',B<&8X7>ᘥE6P]̖A(O
t|?k$G[LF@{Ml4q Jr+P3 og`I GoVE$ZH9Rƪ)_M:1b~۾J<ڲxh]6a]ז?ިn0$>2z(WG^F[7ƞa*pu!֛+kGDpīP+
A(s%QH=O|j'^
|$=xBš+Z0OR$r{U2Teo
֘K`5AGR@zFi]3U6###8]&;w)aHEƀIzPu,Nă~ҀOcӭZd8JhdbAۚ}%Trf"	N]Bfq2R*##3c>eZ‚7fH
чalщ$7s۪;ޤ9NY ko8VRT2	
F|,.eQ7qu7EZƐ&K	wr(Byq[9a6׌U̿/.dHmYU4V9@=q"RTeʵw%NQ&ˏ}VE<ꢾJQsXFD#}&h%Jj.}W`uX/3N
V8?~?<302j5<o4v<<hʲЖiJ1JD̵
qā2uvY(x!4O,rX7@h4ؐw%-f{c	@'Į~}F	DR%:[J}'Iqʌixhҟ'lR/y^%ms
TYGZԃtIJBVXJvnLǢ1e{FRW3r@m֙dZ<sͧs޻f7Owg2ז?ޔ}/iS
m+%!s7_槎wlXr7
MSJ	݁PM)В6=iMd(PK+~-K1|4

w6TVqBh=h+"C(W$PV[HH
x(=m*2tu'qe5ȝ sf!$M
j2EV$JeT"(z'n2=DCRo$&qoDM{\8Gu$ea @*ߣ>A`Csox
t~񕀨XkfUmӤ9
%]>`M??.\0JF?֦؞Onk42iiVG-@pqlq3$#TG$y3|_n6J#u=VLZj-DdOs*=B&6b	dnd!|#f3u,WC\86?ZY$~.h4|Cv.boד)n{#c\/sUA_Z6 E[N,,*$õd*)ޘWkw扌jJ`jbO,3ޖװ[n&7ZNBiEm{{m,|.bya֫ƃ
QoM	ދcP:tlSeeMJڇokx
Wed-T-J#~II
 ۠Z
CDlO"
2]?˖6m#!v]%s/YÌKv'^&jʆq|œf3v}aM܃L;L$8wH<?r+Ītw-ڲw[`hfu9'/8ϖOJWmD-YBESl7ʤ\=MҞ
;u6"dԐvڴm¬eF;)%ŠrO5j'zþEVgj&Sԏl%Z~&KTUtOM[Sb-ښ7}ى{ट&)jH`zu 
6#P]"EU[NAWHĄ?ۧL>l{ƏRIiM<$"Fb#>	ݜysC{@"~	Fc$)$71MHvTY|`<̗-w!r
2eF?gEOE`mźG;7D@cRޟRǃ:'><e=-1jRLזѳsCzGSOrDA!;?&{_:>y1汖'ՐPݦy/$c)?()=^mO8TJ4-LJ[Ʌ6}00V0/mS7P?8UKEDy*Z_ޘws$)ɚ1ހu^ m^dO=jS!?r[6@$:M|/͔K07QUwGpB2lΤ..2Fhzn*i2-y&&JA^;2Z2UeuPQ_l@4Iy$
oCb()qW{7r۫QfP#*s4'ypE}Sgced%^R##U16*<7QW#בZFcnH4	1?<MOEڀޛ988!qe|0~^ǖ.,Cȍ#ze2.T٭'8RAiM*2o{F'O Phn
kׯLl^LkQol|1u_CS=2TٖQ) I>{\deUɐԹڿFZŒ¢QJǶ<]cZV:	QX	*z-yS{`hR]7ۮʥ`{|a:

M!J0],y]<,'3@(@'RWgGd?5D&EڴpNF~ˮ~#v`2ʕSj`ۄQ^G赍*yd;}acV,@~hjqhhI?H[˷z.6E-ŔЈ4Uh#32dTF\qyWe[Ϸլ_%3E[i=$:'=#./?b0ɛ|?@Ӽ
#	Y>iT^Cg]N0F
ϔu
)
w=l;lN	4^
biË)O%L[?dW*d"̈ifwj9µMsZŻ)/iW.W4>>eb9~?pl~?a:v((9n1RXQV$EbmJ{icr
-hH׈S()N#M'I+_])Zށ˙q"9ˈ]o4X$ة$,Cb<^08e[,;8_T$P#Nv
<>> Rfz-G۱ B\/䲄=cҁ6	A>).)2޿/$t{{e7XОKM6NޫKfDOBV;L“HESE
ʻ/MZQw0㰐y
O”Ǚ9}fcu٘'.q_ބD˙Ub1Iʀ/hӮ8QR>!A@f(	_|ytS-\doB	6f^#fXO"kGJ"C6<=#PՊ+J2ib7<RE
+Ҹ	AoӅ\Ɗ_Lj85/*|"MƖNSTO&vȟ6AkHyZmDiNp>ǁV9$WU3/ˎv('îBUR
#XTw;Lj;2K-
><ry7:w!x2	;xqO̶๔R
Rr<A{mC5Ŕ3ɸO^|[̹m4T0ӎ4Bv0S$щ'4^呍2mP6فrAmQ/)DHSÃwQD	yUE674B=p>.L9Gnbqصl['?癅>ԒԳ߾do)JMs^:OVkke:=Ws)PܽiWxXٟ5k+Eea: nHƟdą0h@ӽI=F&BQn"_v]2I,Xd`)S
1vi>&V/IEU^JǑt:W4B&gā$<aZ|r41eoZ~?kv!xq @?yJ)$_F$;7QB
*Sp$#Z $(z\$֬iGGŚ|9wٙ
+XU	(-CR(
:SCWg)*+vewb~Bu5Eьxk}P#\|)#Sq^]g2)ɜ_E~\V<jd2bУ*ң}H~2 ס4PcvS*='qѨFb#zR]]T+^!IJ ~

ɍb;aMVG 7tf^V6]v4"t:6
OsHnc$\#14
b%GW9-0IPf+y M1+(fӃO%Ƥ!9S$
px2)
MW7QVGZ>8)p@J͹0^p$DV`@dAr5j<̠lv9'@RX*I5aң& I'i$|k	9nwZOz|\VfNYQgޱܻ=IwHv;˂#?9'e[-,בVIb'>HDDs!0e
DDr~99SQ`0{,c:X@:;Բ&zpg2~Lo.8X7(zǔāRZGDŽKs+JVAaq|/DΡsDn>z-Fܹ|8L
ߤ/!eHSL9+PF	`G/2&!ájokwlkXXA@+oXcmQ|Xe)xuJIw$|&C{}~a؎[~?RU%)II /*QĔxӒ*-BXTu?e6@N/5QyϓFjP<.$9)_H=]TpbQZGvijC=Z&}>5C#P#=ˏ=2
!P-Yy(](;[AO؍H?Fdpr^J
m\Ot
:(g37ذXnFM #S(!V;)T*ܷW$I1䉎xh	щR2HX06Gzv'qLE"8ƨؖ"J4׿k(R8Ȟ'i Rw#6ێ'z
{oK5:]8VM;*AB~iRP7]DXr^JAR:p l)mI*I54ʷPyȢY\@)I5RE((E(vk(j]րajZS\<7׋(2/'~Ҋ:LyOqk8Ǜ.ͼ)8Z3e&XޥiQUE₉C3c.L͡Ԛ[-:T/5c<Ѳ8.>S@d%ٸK25~-HoY#ċ3# 03YՈ~?rݶzE2)lfi"1z4W#LRE+%!Y5mj:d^"c3o$i%'"	(֠_;@=S;1]P
hK1p*ɾX_n_ro!CK.)B1ۿc~OV"N<?Uhp/_ q
KK%nW0
s'pm^+K螺S5jLM>2rfF?-W2$֩
P?9"(ڣՕ,YD!j7eVWPE ZJp<CWS.YGnO|{2LXΦ;掎kHØ2_Hx
J4e|Tv)文P69oO<l\5+S|r8y9kC?ބJgпbh@؞,K,
̟땖Я$wQ@`jܕH䴩ۧ]U>^\IߎswZHTm	YCS5]6)Tq@H5jrrwb]ݯEb"]7[u;RZec]1䲪9r=:SlxG"Z5i"%Idza-߯шdGT:dh
Ivr<GmVR¤Pj|ʶHVAPvFF1jdNFtR3BW-:R?h6溵y$./oVYZ>%ŏk/?JҔjpiB94/^r?xҵ>pJLý֗7*ߢv90%Deo\q 	Ye<'
ؽɎoE-F4e*7JV{	^9Z;OJF	f.*xfHwo3JuDhkFSQο|91
CiJvBŔzRk5iŦ"JFRp*7%*j2FYpz	OEiI޸xKdT+)f#/+oKJCȍ(WbNDbgdN+أfQ Oe</NO~sUzr4)	OP(с3&d-J>Ҋ>h+Ҙ/z,BK:e!T(E6K
nrdgw%V=yBry='Qi<sm1-zE,[tGs
+	QɁ*>Cxs͋Оmnn5eiC	Ϟo~7+2`M]ބd//+ێdՅvOTem=>JOՀFIx׉&a<ȒO"*6'燄HҚ#}r,ٸ9#'j
֣׏U$ܡ:؊Q{)\[/U*7C=
/8;nk%fjҕ#jb,;9$Z1Rh!dHiEOeބ ƉPЁȒ)USeJvqɃLr"E͖`A#|#\S{m>Q{xcQ.4AZ2Usm!i}?bwڒG$B(ᇣ-6bw4vQs{mr,e݈t9G;3\zYYCI%Wi|C0jl`,]NyQ$=kZ5dkfX%fcB5Nïd+e2^Œ<wۄF`svnk nWf.GW9O!i!د
vqƞN-liCbpER>%2i  )	 S&$+
l4	0$f
T(	ZpG,0aòlkl=ktEϘ}"QO	RAwRcIoIndhvև
*;v9-%%e,SP=?cl;-a
3ѹZZS?k)$r=V 6[tZF=9`@Rks>oOR2TfHBy)9A.C`G#Plh	Z1\|Ŕ85
S=0idmOA.Oɜ_C\QMiM1og2cF
w7 !v@ RP,)qZGoF1ƅk]$_4A	dhl4W]{rܟfVr6`	LkCDS槿aJGU'+ [TfP=P*iAؚj` 3BI?j0B401|	M)?vkm8#dWC
/) S/'Uck9"{EWY~J]LkLbYy,3oEKUc<
h

YFpĐJ5F[{뫛EBHyQY$hqr>~MRfj@=,qJ/fNr<҆/hP-
uKGA2<I=wnlG!C
^$>bF;֌w S#.nB&_qcqMl1RC_v'V,	;k@,+i9vAȍ H i.z	N*W`H#TK&TnZ^'"Jhu.AOV2&WDfxP7]jHݶm{,1"*+{rв8`_㐒
4W;LEկn#$R4B™>>"K~ѱoTqrWkv=ˑ$L#aMyJğ&5x?m"F\w
.瑓85MJӠI6e7nvvrJ&IGjAa5=7D̀5IGV"`FR)R0܇ZMc$o5>l_!4aAAZ	iaLVe'M2BʢZߦ2 ՙOӂ$z)4ڌR|uq)FT7Pg+J+tiҴ{2z
\IUDRn+ݗckg7W,vЉ@jT[n8<ƻZL*bO|A
X[HE8)&lʃ4/}ؘ>(w3#3ԣ9
?\ԭӒKnYj{x[]sLT
Tp=K)ʶJ	mM# %zOutf,ZА:U"Mhv"BH45ɈI;!O/ h݁#+B_=H<]*v?~m5AFa+8":+TjS=vXb"B>/@z`ޢTOhO{PBsVIPOa #E7a<7.\iNǿLsUp.%x֠aBEiBӤAACL5{qn>#MJ6FHDwOr9fJ%@UF%ʿz-._zJt+ƅxWɿf5GO˯5䧅y
(`=Eg^ی7PǛo\ǃ
;ܭM}5eu=^O]P
V=7)Vuq"z،kfUlj*8홐G65+uT'cv&2*`!*-ts"<Vx(cE 
#uT36dhQq `r@ؓ\nߢt
a
↌~mcMrt縺9Mc4 >yd"+<{5MFNq.<UAߛOÔWfz0
W6˖fF@-kGSP_꣸ uK6ʉ@~H#JywN1ic;T/ R(}Mg~H}FV2DB)q^*J9 G^6;J¤RcMɊ౩
x(Dk`*X2Zh5[9YV2q*RLdm
.x`Zܔ
v orILrH!Rv耞veR6ʫp9TԐA4=A3B;k4+M_aɓ[LG3_-Xgmpʪf'E֦hrJ͗"w&3U8.n+*%#ţaNhG}9(KA2e3OI_B_t`*cds=M!@
8⣦SV߲,^9-ւrSQ߶jIV
Z
744
*3o֞84XvK'R=T׉&n#JpeMw=+!T݇@h;z䀠#ٝ(N=[|$V`,ti8+uW4O=fqV!5xB@~*T-&5q4%;(pRpNRٲkyh-oRӠ%#jCfBҸ+E3j^- iMz(/m*Q7EޤLlv;hg|oaO8QTBi'fx@[i=4c\pUJuLymgKRBol"Mr
>;OB~#ACfsq6,ƠxdDdKf*1
LxE;x:^$T`|oՁ5+R۠v;{ag+CuȶAJ9>"ƫA"=CtTNdHv+P<yۯIzO&$R4 o~5+d WW{8j((J82IP*II!JbT^SطIrj\y#!f\nV
\g󧗉Sd$~`+Q&Js{=O *yTnkJ{z1Z^Bؐs2Hڛt|눗dvqIcF5chwSE.;h|r'͘p!q'v7{M)ܫ-[oǮ1jv#ZQ@A<}EjYҝ~y(*IB+VB\&Hf7K^Yz$kTڠG~~\dћ'x˵x;XTza>\s{GlYu@}vO[+1bwLqD&;jwSiR(Yx-pB!2,KRK"[ ;떎n4gdXcw	A@Yu(ǽyyVQK4qr {}Ku/	# ,^S҃}P
x1<in*1Q¿lZ*yΤqZR]W|y0ƯVurP#d)gbcJӐFJo4.n'W
EąS̕jISRwsIZ<ڔ|VȵHI'U"Hs{
j)i+[O;{X&`M_.\#[b9$7tӧZ[ZH`B֠lF54Y2H1j@$u<
0U-ŞnF	`);VUHZ=z-39o)jmeuX5we2󧗅n琓d_A~_qh#1f*S?
n;(Iw
\	
;
Ium҉ +W`62@A&'U] w=SQTs<$9"APTGJ~RFF%] GOSVd=hugAP*Xנ$oMVu<	>p#tF$
! t@N䜰vX9je%RՊ@	Y$`aU֋s~=W0M,!"EGo9CF͕s.8B6.!Fi$b>2ϟS;-3EɊO*w}2JKj20N (} )<xM%a^m_X-l;I'f$׶^bnISMKxZ[*S`zOm1%kyld2Mǔ)Z2)"?g.F6Jcޕ$o+9CZֿ,rF.kP=@I0JQ^$tz 3Aݕ}jSTWRRU"FSjoH&`̢{
S	eͳROj^%AZv,k9n*zic"JDl?),konHض®`krwetR|(Ap6Do:uL@*ceާd4r5SPI;1/I	v3֠Z2w<7\g
c\r}e3M.琓d_B]m,;&)<iQֻe;srvv ic}Hx&q4T2*JkۮP⾭%Kxҿ=+ΡABzW$zQy8қP5̫IԓF"Հ)b#WD$[0O56"I=>G@HE//%+ǀjW4IJ;יpe&'TqTۛQl{spF9\zc%̂*+58Q"c*WK.i+<`JDܭ8DnVK¢HmCOk&,kX彭h~hvؐKh~\czoٌJW2EL.uV)`Q
<Qˀ8SdWz*d澜LX
OӧL2i%-HZY&h?5 mR7dnj9s5VAIuAZW"%IU)aW/FP=̈MNҕ5dnRtR^=6;!S߷؉/IhKT|2"rLHP
zIʳ`+V}N uQ}RDGIim3\ȱ?=i"eV[q@̈97t84.?qv՘Ա>N#o]9KE5#~ƃ('f&4n RV-CO.*7T$McaZA%=5MsāiOrn쿆^󧗫$_'f PisqzT':oJVh#Z)bzbGF`jB(@@v=SN\VЏ`݊S2l~^z?rf5PWo;D"iHOAҝXwe\[~ىO	D/&`?z	` tJu]Yl,$+@Շe%"ן,qy>5Ʊ5?y̑D(iHվ$1TCs3GîjhA[v
7Ć/lȔlS{T_51:zhVmVwʣ!$Lt:/ֹO4Fs<kl ڌI{16rZy{E{e.@#=JZii*ܟn<J"q)$sr;~r<5,y0=f,ժRi-a2LpXs>yR?_'%q{ .FL`($c2U
ɮ+agu+I9v8Ic)\y6#;OԮ]|1jo~)܉$>Z'1 :PU4ee);*<Wr}[+jӡ w>eR)!b	DrYZJewbMX'%"#!b'ZA
^TsZBͽ\_+f}e6Ag:?樗o]Q
zFO#ȵ}U(54#ly\?e"Xߘ\jrW'e>p3q/ᗸ󧗿OBM{e;Wbd.~Mp@.En rǑn5ޟ%r)ʥS߶ۑ҂l%@!g4QS_cg[`HH)#uvBTJ>5
~<JrҽqÓ`ܠoʹ%BӠ!{21o8pġm,HAutewW)!S@VI.cB›u5f|h΢R3wWS$GŰb^Ǿʷe6jN(nu(	d21,W#]U{tYݦ&(@&AcEbHHߠ@Xժ$d;r	$RMT)˹͌voB	sSNN<ɗtNW~ wcpkRR\k-&ܪ+,HTefV02ߢ}b@
[Ri嘱I"%UQx(-|ɔ#A/
vp8Յ݀{0,5IbIf?޻nOZ%R4Ueب<7$sUHZGpb)IIYLv`UPI1,C!c!jo乥B=wYRm!*kB>^a_wpI#Jni&l)T&kLǞ")-:J"hZ=y$vaV;UB{dץ%[%)V>S%m9{U3q[e2󧗿_BM{XF{t9ع=v[-
I 3
}crDEDF+`ݑ+BP$퍲@^,Vۯ^ݍRnKpd'B
~"@8OlyljhԭE67B@*ݕPQ?7Ctv<:iPJKBIˆOq!
dHSQ	?	]z6lL).vQNT6x.<Gz痖.";x#jҪME\٪xWaIuņmh&]
mQwYh,(|LS#oWNّSI}%ի۸#eS39ɩJe=g^<XVȌ@rcf>u5ߑbN\F	$X?YCjv#ś%34!l P#;5J(ďHS;J_Wd`"Wש4<F]}(P[UdJ\#f>Ka9~"fR-RA+gfr^GjxJeUmuUjqm&e
D"q;nUGJҹI
se1/n,RūZhPU3Z'5{R<:nugl瑂~ʃ,v)AeOY"9{kGkn),Ff6^-DF,ޚħZf1M
E*ՈZ)D'%*(A=P}$l@icj9,'"GDeD܊;(v}OV;}XȎ;}d7qF<~63̈́e2|BM{N0M6L~0ki-óU#bI9"\G:9qRK`{cHSeA)$@)N섶^W%PlsZVFFWj8]gP#?EkA2"۪¤
̠1JQ~ɣvza=@ސQXC+~*<Nӛ`~䟙.Mgi-f*)C,c^G<	<oPFX}5a`ׁ1U2ˊ.܈651cm
4+Š\)'
rߛ}qt+.78fksYZAtز14<ep$ݛ9ѾJWs#d;c7WZӹ(EaqR3Q^R+HoQH fB#
5*,&C	5@8fF<v<y<dRB)U&$_.Kn,9)%ҎQZB#+Ey]\]Lfz
2GM)AQNL'jI+Ƈ잵jd7+b'޴G#ԭv|1mmQTh3WFք[#4MV"QN{92.FK,rsټ[EWeyI
Vj23ܽ~qdž?-)pTpN憦<>L45CF@Md6i7ȫFŘ*A#k(O|4B^t
âT˻1P{6KGaϒP>-yԾ wn?6˜W󧗇2l<[YacK1U<H_a.aEs
-En~	;!0۞_b|zrL7@hzmᒻdFuQv^gr5"6@!Y(Hb]lpUOuOVLPb!R2/	~{6|^Q+-ʅM8G:]>I=HNgcsu<0;ӯ\3Ć!gSY"@$y]4O
S鶁{t2΍ժ.\wayOKgU4YR0rPAo4e#vd2HwTω8gTHTBZHCPBb+$S?F퐑nH1rr#ُS
eݖ+]Hli_92"I\^A4.o#W0ɕK1"jw=N_TDZ
+"Cfqʍv=+ej&;eEhX+!_}dF<*.XEaִ(-`G/&Ϯ1[F\H(8ϜCnA02v?.hvl-oen]T/GQ@86<!PyFSvpFmU@=D(xC#mƘpbJzOJlKj;֧O%hvNX=ąXE5VzYAN(PG{|s$s3͇o__/pޅ$$Al{f$/QoF1"l$M1;xE]B	I|{| lLM9Qq$ԏ`Zs%H_M
`0[uףti3\2A#H+AzI^aY9P0܊c>jעtQdog5
+ :8@	^+ip<ܵԿ"&V<Ö)8#{$rJX\w]ٹ)jon]m4:cN͐kt]+81/fi^X'y[,`QpƠ{nVL1Ș-7~+,S2r!F!PVԔaϛ)b)=-A`IJ 94v˄#m\$ni%h+<Fy۹ÔOPNAf+PP0~M_>jI,*jiFk_"ۋhMͼgr84׾%@Se'G3%PnjS&U˚	ը={ncJvvRjweD"YvY@G'=]**?gcf;˴Oa4{+dAEA	ԚP~^I1b(
OrJ: mZ*+K,OjLIDbAh\9%<<֛**v8ܻ1]njTPl*qEv$lfF-ӫ*oN,69=z@28yC|Iw'2W_/pdn&4Of&B0oNaqɻBzuIrTŒI:IVP.#ڕ.al ‡%;DsCYF^ErHKIXH
ph#mR[,G<41o%MX>Y>O(4jfyh`bUy2\})},G?iSXi6cse%z|CƇKޔ|JIhvr3;K74uw6/,$hn(r}[q;[q'|䭴Kn(7P_a|2bnI&gi+Kh1c@kOӒEAȷz(C}EM[oLN뤒ʱuqAJP$UL
/+Kzqp(Ԓu9I6yfػQO
iYJT"KF
SC3ZAUu(tPG]#"NM@{:0W~q̃NSN1Wa^fڹ1ɐJ{43R!ͪ[-Qw
H$`"iBi
jP:"iUR+ۑ9f1%L{6ZHD_O47v\E)V,TTo`2&oIOy,#(
z?#t˚ϭrDwMwG\x:E`ITGQqVAvÅRS(sZf@xDp#M@Cr!.w	ȌuBIMZԵ`l
Iqpy3˨<32;el|~ Aޙ;vV4@ 
߶Q39\bʼ#2O@jiUfZ-"f
L
g( 푲@s<
yz̭H„H5Mxl5$#lym.OVCnH$c<Y+^ei'WcIxuU[j$Z3͉;\!sq^GxPly9'd`bO>hIT,`7Smd/&6[g(h?hlxJxx!N^FG ",ekrF^@2Mmد!)͈q=[:|"ߦ'/^,RR+2
<:)
2Nr杺)%؍
(TM7VqJ0FwDŽDiq"{	0k?/}4 Ix0yvAڝeƐORkDjթ_浙;4$>m󶣷d7.xT1$ZOiңF^JoOeDq<o1A$Vք@	Yl#u+V DV>k%@=ccKcv	j>UQNFGd@kMIJV(91M8
uȠ4&}`UNC3rZ.[`5%nGnpuR*Y^(nۜHJP	^)SSA StI50Š>TY_
(@ђqu̼djw̸Ge8o߮BM{ZPt9;OTT@ t'\[*A5<PiL$7	RsNIykMm#eetYHZ_v4`AB#j ; DP~1Ļl*2`WZ֠N$k!*~)UlhX}O+9C@A`7qX}wЯ׿vG#AF?y0PPB(#/vi(++H5}m{a{s3]@Z⠐~ѧӌs4VL8VKP+zdDA5͆(;'"@KV]%`G4-63.9[QPaJF@˗v? NOO3Ȣ؀z-kqqt')Aќ0W[3v8IpZK
Ԉ#'oi(m3뒙OvPݷK!Tl&|f4+4$>yMKӖ襌4MHE81;\=9e&Aa_iޅoJ7b
JOΏeB=xRԧuS{i6V4F4TC,ąJKZK56sp5m?<$ɪ p.Nz'1eͶ7OT.1,'@,;'fU\G^H=ݨT)ƒDWo@/=|]Joʮw=!iKjt6;TI*N+_xcET9X`p&o%]2I/2VEHRĀ>25KK۶UojmȀ6eU|A(@ƴEiV8܂Xxdl&巶ec,|< ?"6j	L'i^jf8rDH<
qH;%†܀­ɅONF
idx?LEjĮ[jPL"hi}čVVbAޛb9|߬q;V)@9A<"osy%֩<MgJE܋l	+7#9HlϗVg*= si6}T1@Յ	SUlE*}ENiVGAjV92[v
P@O/,I
vw0A8I̖47`, a(_G
F(<d˕<Ԯ##BKٝ枿h_,rj3ac/)QGOy{]K\J[ISPczw~]O8s3eɹIJU<M(¯v;ykI;S"d/MkAO'6Ly̹,x_IJi"fؐ(vs'(UոjT^i$XyלtmU5>4I%jfG^{{.YeOi.:ykI2ts;3~7vZ]pSī5ޠہ\B/{2XX%
(zN!;+?xO8s D!XsJ֙o"VB/E4ۧ\HZRA]6-9䢒MN*?ad@FFiw?"-3ԁm<M;{i4w,Hd˭l`C0,€{Szd8U^U>*VCis:.AKu])JCO292]'2-p+p!&=b>n{12l0zu<Ev>:1#eY>;E̱ y/Zo|F nY\U
Q#<;7B y]v4ӒJO:ؑ?7Ҿ
MW6K%$&QHkN7N+Vy*f$һ/\,cWއPHs'+c\c@R$B%H#F*N+/9\*h7M]9Ǵ&EDKӉ.xS`	@W?TjFhvQA>x|@$wrF 6\U6TL@I3Is@rZqKKNӣΦig;ߊԅ隼KM1H:IQ)<P0zT+
*`w`OdH+FdIӌx
R3T+)HjHT"n6]
^lMe4ɚȃӶC\BbuY#ZPG=:k8m44iCO!uׯ΃EA<jh<	z
MB]_Ts3nU8u5<A<AS4s7+
@à#@E=DЂ@!M1_P6iʣ!W
ԏ@}5e-o1
>06+uhooQ\QvzфALCitzqa^%HrYF$uc5$Zm4e<ُ~2 u\Is,P
zoC.Bޟc#+qMZuc9.w2/4 Ҁ5=A]/}aV
u$tƏA^hYH$J-)Y0!)խtY./e6**z*rda)
:{5V2
0_;/6n`85<펪<URYj{t'E"[
dkQ)^lG[{sD*P7w%lSjX+leu[DYzqUQU>gWDm"9*2@ęEK=6Unf3](mR8<g/2;qT_Ǔ|#m2xcՐɧE-g-JXpNÍ2yDVGT?pYF+29~kNa}ib0UڥAQ7:6]hޔu땖^I
</Ē]Ͻ14~kC#*1RhSZj}W@	>]p'đѥ@H<cXHNn)&GeHK/RicFcFմ׷CTnTUn#dj1G 1<]鷌[]-/=hGZxЌ6>!Ei/	e#yZʈ(;QNj5,z.CO7DBA@;tx݉"bl%wh͆{#ej2SJ|j6{H_)"[W'= j]ĜaZ+/ov$BC

 #z'F^"܍>lV(AI+@jQz]2SϵFcfT-p_O]~y	6AKr(@Zw^ً0nj	CND6sv TH-BΛ;;ҾF<ȥxUj@oV;=f1D,D*dv_̬%3교<s2]ݭ֠tZ+Vhޣ8;S5s#J+4ThAw˧M0Vz(#xIW)ߓdvh'fv?a&	tDYv36QNFqHQ)H,2z)<

;c]dF?RgpP
\!'~HW#=K",J8SFwK`jrߥ;;J1Lj)&WN	u15؆r:O>ʲ˦ΪW}?052zW|"Ó Zf
?;gh@E-~ZԬH/d;+*`7W\gHQ,gR*7l.҂xȨ
Ȣgzd'rH+,	Ie>/8|3rm^*c=Vʋ7"ԼWv$ap^&nieֳ!OJG=Kd?<}bۓ%oC_l: f:eH?iNgWT.(E%9(%OLVU( XHwb pѕs,R[j{{~qҋSPG+^A:/Z]NٔpDYsJ:tSU6}bFn\צTe)rr8:rK4I<TPCJzojly]67
v_Ō{_C}n`Y"K{R(hN-E9rS2&op_Izo+\z߾YQ\~ԙO㐓n0#A9/ hF=cH[ðz,7:,Q}Y(6#r+0DS4Rbk+]p8Zװ#ȊdrD)kLmlVj8?sy',+^A$G!Eze8#GUӃE$ҼZj:hZ%g$UA<;l9[GIjGko15pP g2MqrՕɌ};|[th3'(Tzxwو"<vo[L]:\VvZn7Oų>^Nӳt~!?L&#lŻ,:hvH$b^bau[e9.}u:\jYtzՠe@O%v9,x6SGq[^Z]v^"?Vfd{yKd{2ԧ`:_jcfg)9JLp o@:V}Oc0o2FFE=r'=l"=FΖ%%Kt?jƘM05<yvgSЀI;
't}jFb%`"!4`Fُ}v[…6X2@:wʀ'jRyäQ=
A􃀠Ss\1k+Jn~q'*Hna$u*+SͶ
y^Џ[Ā&*6܇lˎmma6*kH20b8j7m{FDP!	1OjM=eF2<μ_^#Dmr)ft
 SĹ܂k2e*RV	.nU(-m9PdyF]iUOO0MtzȓD#O*?
.гTA''.dr(4EgH?X?nnU!(	nK/DQ$(Jkoe4
A+%aJOݒlc(.AsEΤHbh#p
=/%לӨ,6{(gs:oFemNʬB?h0ޟN'n${}鴓6д1<GmC$uR2X5y/+/KUzvC$~#7;fƴ˟6b6E9)Pڇ|9%[6ΣPMuulO_(czI}H0HNM@Ykr\e`4NHlaۘ?xWnzMk0qǫYr!WBkjs?ܼE<F`_闙zȬ6i*}D
G21`F}X2m7@֞8PV8Olp¬亵Y+K{e$3}2#l&]lz[b7vS։F1v^Q*zrE,0({HGRz	z=&b^o!b)<K/c$S<ZX':G;Aδlc29E~[PeJ2LYTSbyÀ{VlisK'AjDHoBk},ZgҊ[%׽}NJ8G}'
DdV6|;>¿F@ٲ16KyKt4Zzxqy
pĩYHvأ*R&Sy]&V+CAs"B!d'qxdKdAEAbe<jR;Dʽ;aZeu?r^!&\޷g@
iwS9/IS{_1>_H,ӣ`xHե#PK>L>b0x;z'(qr¨Gʹǘ8a8=6ݠ5`R?Rv~%anrg*Ȟ@TR˗<#މtdRi^<HST]MP8n(*TS_){F\N--ż,}gZJt=z&LyQ(+_rm3
ieIޞz~qHatsKnqLGdd0I3qSCe`Iݾ(*IKKYu(%SyI{ӈO͎&TO/7ڜ~Y5IoJ;ILsůMX~z1WBtJ00F݇.FMVer?[:YB >~9;(Mm1R}_[.la!
푶T6bB

Gr$wBcqR{8GeCVlR]_[o^r(?cW3P>XaG
UIa&x|iC\M|꾤Rl984Q_,2G<+6հ;(۽C)Vm"#G"e$jf7NiDS}X(d:h˳VbUz,~ɑ+sU95GAC_!%ZqqB6>H(5Vm
=CRSPw(OInŧRbndHW:	Rٮed *z~UqM߯5\	bBA)FsX.kVI[	ɩ-欛^_Ui~7MdhYT'1֜LPcPe?vcxy0?7ju~	ّOQRG*hb"vǯ$U<?0T2|lˀuFkO)I.&Vlwkh5|;YrLVEks|3:ET2^(aJ~%hà)^+jlU	jƼQrDxjͻz{~\mibNDv{r8G8Lվ
G"59e##
(jLl9D,X"@SƝv$;D0ur
T;V*(6/'FCލLܴSp(i!v\H	zL6텔\QH-HQ]\wo^!,;$ݸzFƻWo H'0
*FޝYT
<0Q$ts\*5۶$(r<V|hy,iquy11>Vcw2w,*yNMP(Ǡ,pr21fg
ddMەfznr`U!W
C1RK.=lHzp2C'exZ3Kv2i
<rkJl=6π{eZ~cSWź;N{8.;9=;~	d2ѳ\UNMae5AڊL8n;Po[׷fb]*͹`uJc.Iev"4ZL[sSt^d݉4E2_l40oF2)ǟ
֕ͻtC'մs
t>R-IҴj̼5.qWҌiƒ2k{o"D2ћxy@Dޝ{5ӇݢvU	Hn6.ԠH˩:b'~99Yra%7@HzSӾBQi%&0T<6鈈6@Z(gri2d24
4}Of>MH~$ݐh
*Hȧ
x1%˻Ǥdm.* "2<[k%$^wڄ9CѲ+JJa,LG'Y$
aXW2q]NOy$K-
6;ޛf<+)#r`]wSs =@nFSL)
Z<n`U\#ljxP$Tt4Cda,{.4~}'
k1S&xME}`6qб0j(,ʁ
PîYhwIUIbvNj(YCQWiʅEz
91.]*I qr&A	nՖm2eJab~j"gͣLGQF# %Ք$'S׶OֲOCM?l&kKJS0UwZ#
qGnIJrc.P\^?zW!&\ޭXEz
i1f[#I*w~[T;hJ[.١Ra3 윑'__$
n7s,z؍;S!<Hw	[X,A*0F?8ZAKKˍp̢~⥥RG__`r#ط!!?ě'垐22:k)J'aӉoAВKe2 G#hU..#ddbZ/`È#)VAIj"&|#p~! WpqτstT>?N$4`Ԩ_a_'Y

]Z&M6v.4?_asaT7)װlr1F>$MߒSˠ!="Ezq]֦G'j؆D(Zʽ)1HI
Њy BNTr5p	8,x*va*`Y<fn	o"j*LI,m'.Nq@~?^K>]E41PpAy[^N4,GKs=0VY3}7Ca:uJ?G	#4qGy/R&=KђC0t,-(~p٫sNQbU|UkX4Hl{'^H@i>*wk@ϊP6Rk,51DO
N]!/A|aHdx=Xqijʴ*o~<u<6!<RSfQjJV\XGtJU,UZz 8qr`NdjNj\fOUkң#&|޽% UYxn,Θ!>l6RHݼ,lՔ2›wg)A]ev4߆0n7T>}0~ <0DRA3A醠=h+`jd^<b<>"3XցXq>>C!.T> 
wkScPIѾe(P=5P/z#[הp
hST\/6?`|!AK=8@b1ޣ6`RhZZH1]6fzObN4ib`Y| r^8ړ2sRЊ}-C*”z׏NN'Dʁ!2CF
!>OlxC
eہ
[ũ=JMckr@6nl9$@~~b<K/-2n
,+qG$$~\iE&a9V'G	P~Xxs-CMJ a	qG5HƩݬgVww'ؓOӐSE #0h	]cWT<FA=XBuP'DX,o_;ӵТӥ;Ԏ8NJPcrG`@%qwYKcK'p%dg@yy]20I绌4""b!Ōˬ^'J_C?KkEY.8e˥>&Z8{΃$b#=P+t.v%`aP
N?QrpbT+OCpTSnΛF&,-c+TSO]놐JW1ZZ)dd{n$ۏ<CGkv6T
ҕW	;(Hy"27"ʴT|'nXژ**Dʕ'|}U1ᛒ$RvuQP"^'ڤ`k*f]7XuSwi4pCNƝv	\2iI32RG=qH鲚@8,,s<)-erٺd?{mr_4
S}l	)&R` s;Nܞ; H%xЏ$hZlCzӊz" ,1m!ʑB
T
hhz
4{9uL,EWqI&zMr>ErQCSlBdG*L@ccR?i9TrYcHO
l[اH(ua؉Zb>6BKuřA	+_=w'ktUPv!:SxP$[Ub~xIAN(FHx {vu9.lolHP[2(,ETuJHIhG0
vӌd$h9
jS&i.豲T">l\Lss"!,{7nm<RW4ݦ	
zx}x1cW('Uah2@#a=]tSQJi$Ti
VMGT(2*^ԡ;wy#*+o$ܷhbeoIV܏蚢;#Fpa^vٜ
P*-GΠ֟L[c>m!TCW^.H^TjTBLM5X/1ZOٯ\$0IAjiJ㈦^)\Fޑw$xb2-criPE)C<1
5L4rnD.npFj2v
ƚڛn8Y	8%|i˗=(6TCRww^$<FAj)D<D5^
<f&IkƊ4xoVؐ
vۦ
EӮH22ٺNPz`![2$~K7@ 3m`\i`**"kP
<>QɻUGMx@kf2I$Sav8G6L{Xx5,h-y927̈^M>7	DzW5;kJ.v9/>aGZ`N<~=@@AZҀ0m"DqjM7YWS4rm+QC>8'!r45jUo7ǹWI-۵Yw6cey$~H3]O|e}B9&J0
MR,*5
GB AGO9D|{	ko7D
&o-)Vj|e%=oP;
V0p(	߯ς<~)<D##xY*PZ
ƒ<#ԁBN
3#hIS׷^lp6VBMDfڝqO%?k`qSE~qBp/.A;1i5ab`ף?Z~aHq-}3Ђ
iǁ?Zu7=k_ׇMG?0tA9#
o)sz|"(9_CooN@Iu=]\TɈO+
ֹhp2JҮ_&R5SkM]|`=|(r=pMێ8Ǚ{)wǁ|W/&9#pD<r>߮D|Gos>+g?`G?F<	[M8qDX/y=l<+<0lO#c+6<+▇eyS]%SZK_
|R,Ͷ]%_$XxWkG1xWZ|.Ö<+|->_:m
:͏|bפolx-vM.wZ;-)VrO<+╭kxyu'aJ"Yb

testjietest_link.html

Synopsis
<html>
<title>TestjIETest Link</title>

<p>Destination page for Test jIETest test of link click

</html>


testjietest_popup1.html

Synopsis
<html>
  <head>
    <meta http-equiv='X-UA-Compatible' content='IE=8' > 
    <title>TestjIETest Popup</title>
  </head>
<body>

<p>Destination page for jIETest test of window popup

<p>Test Buttons:<br>
<button id='testpopup1_id' name='testpopup1_name' onclick="window.close()">testpopup1 Close Window</button>

<p>Test Radio Buttons:<br>
<input type=radio name='testradio_name' id='testradio1_id' value='testradio1_value'>testradio1<br>
<input type=radio name='testradio_name' id='testradio2_id' value='testradio2_value'>testradio2<br>
<input checked type=radio name='testradio_name' id='testradio3_id' value='testradio3_value'>testradio3<br>

</body>
</html>


testjitest.cfg

Synopsis
TestTextArea_Bad_Get
TestImage_Click_withSrc
TestWin_BadClassMethodCall
TestLink_Is_IsLinkText
TestTitle_Is
TestRadioButton_VerifyExists
TestRadioButton
TestTitle_Bad_Is
TestTextArea_Bad_Click
TestTable_Get_BadNumCols
TestImage_withClass
TestButton_withClass
TestTextArea_Set
TestListBox_Verify
TestForm_Bad_Get
TestAlphaCode_Link_Click_MSWord
TestTitle_Verify2
TestEditBox_withClass
TestPageElementWithType_Click_withId
TestListBox_withClass
TestPasswordBox_Bad_Get
TestDiv
TestTable_Verify_NumCols
TestLink_withClass
TestForm_Bad_Click
TestCheckBox_Bad_Get
TestURL_Is
TestPasswordBox_Is_withClass
TestPageElementWithType_Bad_Click
TestLabel_Bad_Click
TestEditBox_Bad_IsText
TestLink_VerifyText_withName
TestListBox_Verify_Exists
TestWin_Unmaximized
TestButton_Is_Text
TestLabel_Click_withName
TestButton_Click_withName
TestLink_Click_withName
TestURL_Bad_Is
TestText_Bad
TestTable_Verify_NumRows
TestTextArea_Set_withId
TestPageElement_Click_withName
TestLabel_Bad_Get
TestPasswordBox_Bad_IsText
TestPageElement_Click_withInnertext
TestLink
TestCheckBox_Is
TestTable
TestButton_Verify_Text
TestListBox_Bad_Click
TestImage_Verify_Exists
TestForm_Element_Verify
TestButton_Bad_wdc
TestForm_Element
TestPasswordBox_Set_withName
TestCheckBox_Set
TestText_Verify
TestEditBox_Verify
TestPageElement_Click_withId
TestForm_withClass
TestRadioButton_Is_withClass
TestLink_Verify_Exists
TestTable_Click_withId
TestRadioButton_Bad_IsState
TestStatusBar_VerifyStatusBarMessage_local
TestMisc_BackButton
TestTextArea_Verify_Exists
TestCheckBox_Bad_Exists
TestDiv_Click
TestTable_Exists_BadCell
TestCheckBox_Bad_IsState
TestLink_Bad_VerifyText
TestDiv_Bad_IsText
TestAlphaCode_Popups_onepopup
TestImage_Click_withId
TestImage_Bad
TestPasswordBox_Bad_SetText
TestLink_Bad_Get
TestDiv_Bad
TestAlphaCode_Popups
TestDiv_Verify_Text
TestTable_Click_Bad
TestPageElement_Verify
TestMessageBox
TestPageElement_Verify_Exists
TestSubmit_Bad_Get
TestDiv_Verify
TestTable_Click
TestMisc_Bad_Navigate
TestTable_Verify
TestCheckBox_VerifyExists
TestPageElementWithType_Bad_Get
TestMisc_PrintAllObjects
TestTextArea_Bad_IsText
TestRadioButton_Is_withId
TestListBox_Verify_SelectionwithName
TestRadioButton_Is
TestDiv_Click_withId
TestButton_Click_withInnertext
TestMisc_GetCompatMode
TestMessageBox_VerifyFullText
TestButton_Click
TestEditBox_Set
TestCheckBox_Bad_VerifyState
TestLabel_withClass
TestRadioButton_Click_withId
TestListBox_SetSelection_withClass
TestAlphaCode
TestRadioButton_Bad_VerifyState
TestMessageBox_Bad_Verify
TestForm_Bad
TestMisc_RefreshIE
TestCheckBox_Set_withId
TestLink_VerifyText_withInnertext
TestLabel_Click
TestText
TestTextArea_Bad_SetText
TestEditBox_Bad_Click
TestTable_Exists_CellwithName
TestPageElementWithType_Verify_Exists
TestImage_Bad_Click
TestListBox_Bad_Get
TestLink_VerifyText
TestTable_Verify_NumCols_withName
TestButton_Verify
TestText_Is
TestTable_CellValue
TestPasswordBox_Is_withName
TestForm
TestTable_Verify_TableCell_Bad
TestPasswordBox_Set_withId
TestPageElement_Bad_Click
TestSubmit_Bad_Click
TestTable_Verify_TableCell
TestEditBox
TestText_Is_ArrayPresent
TestTextArea_Is_withClass
TestImage_Bad_Get
TestMisc_BackButton_Click
TestText_Bad_Is
TestURL_Bad
TestButton_Bad
TestTable_Get_BadGetCell
TestMessageBox_Bad
TestDiv_Bad_Get
TestPasswordBox_withClass
TestURL
TestLink_Is
TestListBox
TestDiv_Click_withInnertext
TestStatusBar_VerifyStatusBarMessage_remote
TestTextArea_Verify
TestDiv_Bad_Click
TestListBox_Bad_VerifySelection
TestText_Bad_Verify
TestPasswordBox_Verify
TestMisc_Navigate
TestImage_Click
TestPageElement_withClass
TestSubmit_Click
TestURL_Verify
TestButton_Click_withId
TestLink_Verify_Exists_withInnertext
TestMisc_SaveOuterText
TestCheckBox_Bad_SetState
TestMisc_PrintObjects
TestStatusBar_Bad_Verify
TestCheckBox_Bad
TestListBox_Verify_OptionExists
TestTable_Verify_NumCols_withId
TestTextArea_Bad_VerifyText
TestMisc_Bad
TestPageElementWithType_Click
TestEditBox_Verify_Exists
TestAlphaCode_Link
TestListBox_SetSelection_withId
TestTable_Exists
TestTable_Verify_NumRows_withId
TestTitle_Bad_Verify
TestListBox_Is
TestLink_Verify_Exists_withId
TestEditBox_Is_withName
TestDiv_Is
TestTextArea_Set_withInnertext
TestLabel_Click_withId
TestListBox_Bad
TestSubmit
TestLink_Click
TestButton
TestMessageBox_VerifyShortenedText
TestTextArea_Bad
TestPageElementWithType_Verify
TestButton_Verify_Exists
TestRadioButton_Bad_Get
TestForm_Element_Verify_Exists
TestPageElement_Bad_Get
TestSubmit_Click_Button
TestListBox_SetSelection_withInvalidOption
TestButton_Is
TestImage_Click_withAlt
TestCheckBox_Set_withName
TestLink_Click_withId
TestPasswordBox_Bad
TestLabel_Bad
TestURL_Bad_Verify
TestImage_Verify
TestLink_Verify
TestAlphaCode_Link_Click
TestPageElement_Bad
TestCheckBox_Click_withId
TestImage
TestButton_Bad_Get
TestImage_Verify_AltText
TestMisc_Bad_ExpectLogin
TestPageElement_Click
TestPasswordBox_Bad_Click
TestTable_Verify_NumRows_withName
TestPageElementWithType_withClass
TestRadioButton_Bad_Click
TestForm_Bad_GetElement
TestPageElementWithType_Click_withValue
TestCheckBox_Click
TestAlphaCode_Popups_twopopups
TestLabel_VerifyExists
TestTable_Verify_Bad
TestPageElementWithType
TestEditBox_Set_withName
TestButton_Click_withId2
TestStatusBar_Bad
TestTable_Get_BadGetRow
TestLink_Bad_IsText
TestLabel_Click_withClass
TestListBox_Bad_IsSelection
TestPageElementWithType_Bad
TestCheckBox
TestMessageBox_VerifyUnknownText
TestTextArea_Set_withName
TestText_Verify_Present
TestButton_Bad_IsText
TestWin_BadMainlineCall
TestButton_Is_withClass
TestText_Verify_ArrayPresent
TestCheckBox_Bad_Click
TestDiv_Is_Text
TestEditBox_Is
TestDiv_withClass
TestTable_Exists_CellwithId
TestWin
TestTextArea_Is_withName
TestStatusBar_VerifyStatusBarMessage
TestPasswordBox_Set
TestPasswordBox
TestEditBox_Is_withClass
TestWin_BadUrl
TestRadioButton_Click_withValue
TestButton_Click_withId3
TestListBox_Is_withName
TestImage_Bad_wdc
TestListBox_SetSelection_withText
TestEditBox_Set_withId
TestCheckBox_Click_withName
TestEditBox_Bad_VerifyText
TestTable_Click_CellwithName
TestText_Verify_NotPresent
TestText_Is_Present
TestStatusBar
TestPasswordBox_Verify_Exists
TestLabel_Click_withInnertext
TestTable_Get_Bad
TestStatusBar_VerifyStatusBarMessage_flipflop
TestPageElement
TestDiv_Click_withName
TestLink_Verify_Exists_withName
TestPasswordBox_Is
TestLabel
TestListBox_SetSelection
TestTable_Click_BadCell
TestRadioButton_Click
TestLink_VerifyText_withId
TestTable_Get
TestTitle_Bad
TestTitle
TestPasswordBox_Bad_VerifyText
TestTextArea_Is
TestMisc_Bad_SaveOuterText
TestEditBox_Bad_Get
TestListBox_Bad_SetSelection
TestLink_Click_withInnerText
TestAlphaCode_Frames_x
TestMisc
TestWin_BadMaximized
TestTextArea_withClass
TestRadioButton_Bad
TestSubmit_Bad
TestTextArea
TestEditBox_Bad
TestLink_Bad_Click
TestForm_Verify
TestButton_Bad_VerifyText
TestLink_Bad
TestEditBox_Bad_SetText
TestTable_withClass
TestListBox_Is_withClass
TestTitle_Verify
TestForm_Verify_Exists
TestCheckBox_Bad_wdc
TestAlphaCode_Frames






Contact me about content on this page using john_web-at-arrizza-dot-com
For Web Master or site problems contact: webadmin-at-arrizza-dot-com
Copyright John Arrizza (c) 2001-2010