This is an automated email from the git hooks/post-receive script. jame-guest pushed a commit to tag v0.02 in repository libweasel-perl.
commit ba87673400a9711cbe3e3a3d84fac3e7fad1ad07 Author: Erik Huelsmann <[email protected]> Date: Wed Jun 22 12:28:57 2016 +0200 * In preparation of a release, add significant amounts of documentation --- lib/Weasel.pm | 72 +++++++++++++++++++++++++++++++++++ lib/Weasel/DriverRole.pm | 98 +++++++++++++++++++++++++++++++++++++++++++++++- lib/Weasel/Element.pm | 52 ++++++++++++++++++++++++- lib/Weasel/Session.pm | 74 +++++++++++++++++++++++++----------- 4 files changed, 271 insertions(+), 25 deletions(-) diff --git a/lib/Weasel.pm b/lib/Weasel.pm index 602bd14..3745b8b 100644 --- a/lib/Weasel.pm +++ b/lib/Weasel.pm @@ -28,6 +28,78 @@ Weasel - Perl's php/Mink-inspired abstracted web-driver framework This module abstracts away the differences between the various web-driver protocols, like the Mink project does for PHP. +While heavily inspired by Mink, C<Weasel> aims to improve over it +by being extensible, providing not just access to the underlying +browser, yet to provide building blocks for further development +and abstraction. + +L<Pherkin::Extension::Weasel> provides integration with +L<Test::BDD::Cucumber> (aka pherkin), for BDD testing. + +For the actual page interaction, this module needs a driver to +be installed. Currently, that means L<Weasel::Driver::Selenium2>. +Other driver implementations, such as L<Sahi|http://sahipro.com/> +can be independently developed and uploaded to CPAN, or contributed. +(We welcome and encourage both!) + + +=head2 DIFFERENCES WITH OTHER FRAMEWORKS + +=over + +=item Mnemonics for element lookup patterns + +The central registry of xpath expressions to find common page elements +helps to keep page access code clean. E.g. compare: + + use Weasel::FindExpanders::HTML; + $session->page->find('*contains', text => 'Some text'); + +With + + $session->page->find(".//*[contains(.,'Some text')] + [not(.//*[contains(.,'Some text')])]"); + +Multiple patterns can be registered for a single mnemonic, which +will be concatenated to a single xpath expression to find the matching +tags in a single driver query. + +Besides good performance, this has the benefit that the following + + $session->page->find('*button', text => 'Click!'); + +can be easily extended to match +L<Dojo toolkit's|http://dojotoolkit.org/documentation/> buttons, which +on the HTML level don't contain visible button or input tags, simply +by using the widget support set: + + use Weasel::Widgets::Dojo; + +=item Widgets encapsulate specific behaviours + +All elements in C<Weasel> are of the base type C<Weasel::Element>, which +encapsulates the regular element interactions (click, find children, etc). + +While most elements will be represented by C<Weasel::Element>, it's possible +to implement other wrappers. These offer a logical extension point to +implement tag-specific utility functions. E.g. +C<Weasel::Widgets::HTML::Select>, which adds the utility function +C<select_option>. + +These widgets also offer a good way to override default behaviours. One +such case is the Dojo implementation of a 'select' element. This element +replaces the select tag entirely and in contrast with the original, doesn't +keep the options as child elements of the 'select'-replacing tag. By using +the Dojo widget library + + use Weasel::Widget::Dojo; + +the lack of the parent/child relation between the the select and its options +is transparently handled by overriding the widget's C<find> and C<find_all> +methods. + +=back + =cut diff --git a/lib/Weasel/DriverRole.pm b/lib/Weasel/DriverRole.pm index 496b0c9..2addf46 100644 --- a/lib/Weasel/DriverRole.pm +++ b/lib/Weasel/DriverRole.pm @@ -18,6 +18,10 @@ Weasel::DriverRole - API definition for driver wrappers =head1 DESCRIPTION +This module defines the API for all Weasel drivers to be implemented. + +By using this role in the driver implementation module, an abstract +method is implmented croak()ing if it's called. =cut @@ -29,12 +33,20 @@ use warnings; use Carp; use Moose::Role; +our $VERSION = '0.01'; + =head1 ATTRIBUTES =over =item started +Every session is associated with a driver instance. The C<started> attribute +holds a boolean value indicating whether or not the driver is ready to +receive driver commands. + +The value managed by the C<start> and C<stop> methods. + =cut has 'started' => (is => 'rw', @@ -49,6 +61,13 @@ has 'started' => (is => 'rw', =item implements +This method returns the version number of the API which it fully +implements. + +L<Weasel::Session> may carp (warn) the user about mismatching API levels +in case a driver is coded against an earlier version than +C<$Weasel::DriverRole::VERSION>. + =cut sub implements { @@ -59,28 +78,65 @@ sub implements { =item start +This method allows setup of the driver. It is invoked before any web +driver methods as per the Web driver methods section below. + =cut sub start { my $self = shift; $self->started(1); } =item stop +This method allows tear-down of the driver. After tear-down, the C<start> +method may be called again, so the this function should leave the driver +in a restartable state. + =cut sub stop { my $self = shift; $self->started(0); } =item restart +This function stops (if started) and starts the driver. + + =cut sub restart { my $self = shift; $self->stop; $self->start; } +=back + +=head2 Web driver methods + +=head3 Terms + +=over + +=item element_id / parent_id + +These are opaque values used by the driver to identify DOM elements. + +Note: The driver should always accept an xpath locator as an id value + as well as id values returned from earlier driver calls + + +=back + + +=head3 API + +=over + =item find_all( $parent_id, $locator, $scheme ) Returns the _id values for the elements to be instanciated, matching the C<$locator> using C<scheme>. -Depending on context, the return value is a list or an arrayref. +Depending on array or scalar context, the return value is +a list or an arrayref. + +Note: there's no function to find a single element. That function +is implemented on the C<Weasel::Session> level. =cut @@ -90,6 +146,11 @@ sub find_all { =item get( $url ) +Loads the page at C<$url> into the driver's browser (browser emulator). + +The C<$url> passed in has been expanded by C<Weasel::Session>, prepending +a registered prefix. + =cut sub get { @@ -98,6 +159,9 @@ sub get { =item is_displayed($element_id) +Returns a boolean value indicating whether the element indicated by +C<$element_id> is interactable (can be selected, clicked on, etc) + =cut sub is_displayed { @@ -112,6 +176,12 @@ The driver may interpret the 'poll_delay' in one of two ways: 2. The 'poll_delay' equals the number of seconds to wait between the end of one poll request and the start of the next +Note: The user should catch inside the callback any exceptions that are + thrown inside the callback, unless such exceptions are allowed to + terminate further polling attempts. + I.e. this function doesn't guard against early termination by + catching exceptions. + =cut sub wait_for { @@ -153,6 +223,9 @@ sub dblclick { =item get_attribute($element_id, $attribute_name) +Returns the value of the attribute named by C<$attribute_name> +of the element indicated by C<$element_id>. + =cut sub get_attribute { @@ -161,6 +234,9 @@ sub get_attribute { =item get_text($element_id) +Returns the HTML content of the element identified by C<$element_id>, +the so-called 'innerHTML'. + =cut sub get_text { @@ -169,6 +245,9 @@ sub get_text { =item set_attribute($element_id, $attribute_name, $value) +Changes the value of the attribute named by C<$attribute_name> to C<$value> +for the element identified by C<$element_id>. + =cut sub set_attribute { @@ -193,6 +272,12 @@ sub set_selected { =item screenshot($fh) +Takes a screenshot and writes the image to the file handle C<$fh>. + +Note: In the current version of the driver, it's assumed the + driver writes a PNG image. Later versions may add APIs to + get/set the type of image generated. + =cut sub screenshot { @@ -201,6 +286,15 @@ sub screenshot { =item send_keys($element_id, @keys) +Simulates key input into the element identified by C<$element_id>. + +C<@keys> is an array of (groups of) inputs; multiple multi-character +strings may be listed. In such cases the input will be appended. E.g. + + $driver->send_keys($element_id, "hello", ' ', "world"); + +is valid input to enter the text "hello world" into C<$element_id>. + =cut sub send_keys { @@ -209,6 +303,8 @@ sub send_keys { =item tag_name($element_id) +The name of the HTML tag identified by C<$element_id>. + =cut sub tag_name { diff --git a/lib/Weasel/Element.pm b/lib/Weasel/Element.pm index 5472c36..5fac30c 100644 --- a/lib/Weasel/Element.pm +++ b/lib/Weasel/Element.pm @@ -14,6 +14,10 @@ Weasel::Element - The base HTML/Widget element class =head1 DESCRIPTION +This module provides the base class for all page elements, encapsulating +the regular element interactions, such as finding child element, querying +attributes and the tag name, etc. + =cut package Weasel::Element; @@ -29,6 +33,9 @@ use Moose; =item session +Required. Holds a reference to the L<Weasel::Session> to which the element +belongs. Used to access the session's driver to query element properties.x + =cut has session => (is => 'ro', @@ -37,6 +44,9 @@ has session => (is => 'ro', =item _id +Required. Holds the I<element_id> used by the session's driver to identify +the element. + =cut has _id => (is => 'ro', @@ -48,8 +58,15 @@ has _id => (is => 'ro', =over -=item find($locator [, $scheme]) +=item find($locator [, scheme => $scheme] [, %locator_args]) + +Finds the first child element matching c<$locator>. Returns C<undef> +when not found. Optionally takes a scheme argument to identify non-xpath +type locators. +In case the C<$locator> is a mnemonic (starts with an asterisk ['*']), +additional arguments may be provided for expansion of the mnemonic. See +L<Weasel::FindExpanders::HTML> for documentation of the standard expanders. =cut @@ -59,7 +76,16 @@ sub find { return $self->session->find($self, @args); } -=item find_all($locator [, $scheme]) +=item find_all($locator [, scheme => $scheme] [, %locator_args]) + +Returns, depending on scalar vs array context, a list or an arrayref +with matching elements. Returns an empty list or ref to an empty array +when none found. Optionally takes a scheme argument to identify non-xpath +type locators. + +In case the C<$locator> is a mnemonic (starts with an asterisk ['*']), +additional arguments may be provided for expansion of the mnemonic. See +L<Weasel::FindExpanders::HTML> for documentation of the standard expanders. =cut @@ -72,6 +98,14 @@ sub find_all { =item get_attribute($attribute) +Returns the value of the element's attribute named in C<$attribute> or +C<undef> if none exists. + +Note: Some browsers apply default values to attributes which are not + part of the original page. As such, there's no direct relation between + the existence of attributes in the original page and this function + returning C<undef>. + =cut sub get_attribute { @@ -82,6 +116,8 @@ sub get_attribute { =item get_text() +Returns the element's 'innerHTML'. + =cut sub get_text { @@ -93,6 +129,9 @@ sub get_text { =item is_displayed +Returns a boolean indicating if an element is visible (e.g. +can potentially be scrolled into the viewport for interaction). + =cut sub is_displayed { @@ -103,6 +142,8 @@ sub is_displayed { =item click() +Scrolls the element into the viewport and simulates it being clicked on. + =cut sub click { @@ -112,6 +153,11 @@ sub click { =item send_keys(@keys) +Focusses the element and simulates keyboard input. C<@keys> can be any +number of strings containing unicode characters to be sent. E.g. + + $element->send_keys("hello", ' ', "world"); + =cut sub send_keys { @@ -122,6 +168,8 @@ sub send_keys { =item tag_name() +Returns the name of the tag of the element, e.g. 'div' or 'input'. + =cut sub tag_name { diff --git a/lib/Weasel/Session.pm b/lib/Weasel/Session.pm index 2162681..decb357 100644 --- a/lib/Weasel/Session.pm +++ b/lib/Weasel/Session.pm @@ -38,14 +38,12 @@ use warnings; use Moose; -use Try::Tiny; use Weasel::Element::Document; use Weasel::FindExpanders qw/ expand_finder_pattern /; use Weasel::WidgetHandlers qw| best_match_handler_class |; =head1 ATTRIBUTES - =over =item driver @@ -84,6 +82,8 @@ has 'base_url' => (is => 'rw', =item page +Returns the root element of the target HTML page (the 'html' tag). + =cut has 'page' => (is => 'ro', @@ -130,6 +130,9 @@ has 'poll_delay' => (is => 'rw', =item clear($element) +Clears any input entered into elements supporting it. Generally applies to +textarea elements and input elements of type text and password. + =cut sub clear { @@ -140,6 +143,10 @@ sub clear { =item click([$element]) +Simulates a single mouse click. If an element argument is provided, that +element is clicked. Otherwise, the browser window is clicked at the +current mouse location. + =cut sub click { @@ -148,7 +155,11 @@ sub click { $self->driver->click(($element) ? $element->_id : undef); } -=item find($element, $pattern, $args) +=item find($element, $locator [, scheme => $scheme] [, %locator_args]) + +Finds the first child of C<$element> matching C<$locator>. + +See L<Weasel::Element>'s C<find> function for more documentation. =cut @@ -156,23 +167,22 @@ sub find { my ($self, @args) = @_; my $rv; - $self->wait_for( sub { - my @rv; - try { - @rv = @{$self->find_all(@args)}; - } - catch { - ###TODO add logger statement warning of consumed error - print STDERR $_ . "\n"; - }; - return $rv = shift @rv; - - }); + $self->wait_for( + sub { + my @rv = @{$self->find_all(@args)}; + return $rv = shift @rv; + }); return $rv; } -=item find_all($element, $pattern, $args) +=item find_all($element, $locator, [, scheme => $scheme] [, %locator_args ]) + +Finds all child elements of C<$element> matching C<$locator>. Returns, +depending on scalar or list context, an arrayref or a list with matching +elements. + +See L<Weasel::Element>'s C<find_all> function for more documentation. =cut @@ -209,6 +219,9 @@ sub get { =item get_attribute($element, $attribute) +Returns the value of the attribute named by C<$attribute> of the element +identified by C<$element>, or C<undef> if the attribute isn't defined. + =cut sub get_attribute { @@ -219,6 +232,8 @@ sub get_attribute { =item get_text($element) +Returns the 'innerHTML' of the element identified by C<$element>. + =cut sub get_text { @@ -229,6 +244,10 @@ sub get_text { =item is_displayed($element) +Returns a boolean value indicating if the element identified by +C<$element> is visible on the page, i.e. that it can be scrolled into +the viewport for interaction. + =cut sub is_displayed { @@ -239,6 +258,12 @@ sub is_displayed { =item screenshot($fh) +Writes a screenshot of the browser's window to the filehandle C<$fh>. + +Note: this version assumes pictures of type PNG will be written; + later versions may provide a means to query the exact image type of + screenshots being generated. + =cut sub screenshot { @@ -249,6 +274,9 @@ sub screenshot { =item send_keys($element, @keys) +Send the characters specified in the strings in C<@keys> to C<$element>, +simulating keyboard input. + =cut sub send_keys { @@ -259,6 +287,8 @@ sub send_keys { =item tag_name($element) +Returns the tag name of the element identified by C<$element>. + =cut sub tag_name { @@ -267,13 +297,13 @@ sub tag_name { return $self->driver->tag_name($element->_id); } -=item wait_for($callback, [ retry_timeout => $number,] [poll_delay => number]) +=item wait_for($callback, [ retry_timeout => $number,] [poll_delay => $number]) -Waits until $callback->() returns true, or C<wait_timeout> expires -- whichever -comes first. +Polls $callback->() until it returns true, or C<wait_timeout> expires +-- whichever comes first. The arguments retry_timeout and poll_delay can be used to override the -session-global settings for the duration of the call. +session-global settings. =cut @@ -288,10 +318,10 @@ sub wait_for { =item _wrap_widget($_id) -Finds all matching widget selectors to instantiate an element off of. +Finds all matching widget selectors to wrap the driver element in. In case of multiple matches, selects the most specific match -(most matched criteria). +(the one with the highest number of requirements). =cut -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libweasel-perl.git _______________________________________________ Pkg-perl-cvs-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits
