AnyEvent-WebDriver

 view release on metacpan or  search on metacpan

WebDriver.pm  view on Meta::CPAN


   $wd->element_send_keys ($searchbox => "free software");
   $wd->element_click ($wd->find_element (css => 'input[type="submit"]'));

   # session gets autodeleted by default, so wait a bit
   sleep 10;

   # this is an example of an action sequence
   $wd->actions
      ->move ($wd->find_element (...), 40, 5)
      ->click
      ->type ("some text")
      ->key ("{Enter}")
      ->perform;

=head1 DESCRIPTION

This module aims to implement the L<W3C
WebDriver|https://www.w3.org/TR/webdriver1/> specification which is the
standardised equivalent to the Selenium WebDriver API, which in turn aims
at remotely controlling web browsers such as Firefox or Chromium.

One of the design goals of this module was to stay very close to the
language and words used in the WebDriver specification itself, so to make
most of this module, or, in fact, to make any reasonable use of this
module, you would need to refer to the W3C WebDriver recommendation, which
can be found L<here|https://www.w3.org/TR/webdriver1/>:

   https://www.w3.org/TR/webdriver1/

Mozilla's C<geckodriver> has had webdriver support for a long time, while
C<chromedriver> only has basic and mostly undocumented webdriver support
as of release 77.

In Debian GNU/Linux, you can install the chromedriver for chromium
via the C<chromium-driver> package. Unfortunately, there is no
(working) package for geckodriver, but you can download it from
L<github|https://github.com/mozilla/geckodriver/releases>.

=head2 CONVENTIONS

Unless otherwise stated, all delays and time differences in this module
are represented as an integer number of milliseconds, which is perhaps
surprising to users of my other modules but is what the WebDriver spec
uses.

=cut

package AnyEvent::WebDriver;

use common::sense;

use Carp ();
use AnyEvent ();
use AnyEvent::HTTP ();

our $VERSION = '1.2';

our $WEB_ELEMENT_IDENTIFIER = "element-6066-11e4-a52e-4f735466cecf";
our $WEB_WINDOW_IDENTIFIER  =  "window-fcc6-11e5-b4f8-330a88ab9d7f";
our $WEB_FRAME_IDENTIFIER   =   "frame-075b-4da1-b6ba-e579c2d3230a";

my $json = eval { require JSON::XS; JSON::XS:: } || do { require JSON::PP; JSON::PP:: };
$json = $json->new->utf8;

$json->boolean_values (0, 1)
   if $json->can ("boolean_values");

sub _decode_base64 {
   require MIME::Base64;

   MIME::Base64::decode_base64 (shift)
}

sub req_ {
   my ($self, $method, $ep, $body, $cb) = @_;

   AnyEvent::HTTP::http_request $method => "$self->{_ep}$ep",
      body => $body,
      $self->{persistent} ? (persistent => 1) : (),
      $self->{proxy} eq "default" ? () : (proxy => $self->{proxy}),
      timeout => $self->{timeout},
      headers => { "content-type" => "application/json; charset=utf-8", "cache-control" => "no-cache" },
      sub {
         my ($res, $hdr) = @_;

         $res = eval { $json->decode ($res) };
         $hdr->{Status} = 500 unless exists $res->{value};

         $cb->($hdr->{Status}, $res->{value});
      }
   ;
}

sub get_ {
   my ($self, $ep, $cb) = @_;

   $self->req_ (GET => $ep, undef, $cb)
}

sub post_ {
   my ($self, $ep, $data, $cb) = @_;

   $self->req_ (POST => $ep, $json->encode ($data || {}), $cb)
}

sub delete_ {
   my ($self, $ep, $cb) = @_;

   $self->req_ (DELETE => $ep, "", $cb)
}

sub AUTOLOAD {
   our $AUTOLOAD;

   $_[0]->isa (__PACKAGE__)
      or Carp::croak "$AUTOLOAD: no such function";

   (my $name = $AUTOLOAD) =~ s/^.*://;

   my $name_ = "$name\_";

WebDriver.pm  view on Meta::CPAN

}

sub refresh_ {
   $_[0]->post_ (refresh => undef, $_[1]);
}

=item $title = $wd->get_title

Returns the current document title.

=cut

sub get_title_ {
   $_[0]->get_ (title => $_[1]);
}

=back

=head3 COMMAND CONTEXTS

=over

=cut

=item $handle = $wd->get_window_handle

Returns the current window handle.

=item $wd->close_window

Closes the current browsing context.

=item $wd->switch_to_window ($handle)

Changes the current browsing context to the given window.

=cut

sub get_window_handle_ {
   $_[0]->get_ (window => $_[1]);
}

sub close_window_ {
   $_[0]->delete_ (window => $_[1]);
}

sub switch_to_window_ {
   $_[0]->post_ (window => { handle => "$_[1]" }, $_[2]);
}

=item $handles = $wd->get_window_handles

Return the current window handles as an array-ref of handle IDs.

=cut

sub get_window_handles_ {
   $_[0]->get_ ("window/handles" => $_[1]);
}

=item $handles = $wd->switch_to_frame ($frame)

Switch to the given frame identified by C<$frame>, which must be either
C<undef> to go back to the top-level browsing context, an integer to
select the nth subframe, or an element object.

=cut

sub switch_to_frame_ {
   $_[0]->post_ (frame => { id => "$_[1]" }, $_[2]);
}

=item $handles = $wd->switch_to_parent_frame

Switch to the parent frame.

=cut

sub switch_to_parent_frame_ {
   $_[0]->post_ ("frame/parent" => undef, $_[1]);
}

=item $rect = $wd->get_window_rect

Return the current window rect(angle), e.g.:

   $rect = $wd->get_window_rect
   => { height => 1040, width => 540, x => 0, y => 0 }

=item $wd->set_window_rect ($rect)

Sets the window rect(angle), e.g.:

   $wd->set_window_rect ({ width => 780, height => 560 });
   $wd->set_window_rect ({ x => 0, y => 0, width => 780, height => 560 });

=cut

sub get_window_rect_ {
   $_[0]->get_ ("window/rect" => $_[1]);
}

sub set_window_rect_ {
   $_[0]->post_ ("window/rect" => $_[1], $_[2]);
}

=item $wd->maximize_window

=item $wd->minimize_window

=item $wd->fullscreen_window

Changes the window size by either maximising, minimising or making it
fullscreen. In my experience, this will timeout if no window manager is
running.

=cut

sub maximize_window_ {
   $_[0]->post_ ("window/maximize" => undef, $_[1]);
}

sub minimize_window_ {
   $_[0]->post_ ("window/minimize" => undef, $_[1]);
}

sub fullscreen_window_ {
   $_[0]->post_ ("window/fullscreen" => undef, $_[1]);
}

=back

=head3 ELEMENT RETRIEVAL

To reduce typing and memory strain, the element finding functions accept
some shorter and hopefully easier to remember aliases for the standard
locator strategy values, as follows:

   Alias   Locator Strategy
   css     css selector



( run in 0.434 second using v1.01-cache-2.11-cpan-df04353d9ac )