|
|
@@ -0,0 +1,150 @@
|
|
|
+package Selenium::Remote::Driver::v4;
|
|
|
+
|
|
|
+use strict;
|
|
|
+use warnings;
|
|
|
+
|
|
|
+# Wrapper shim class for Selenium::Client and S::R::D
|
|
|
+sub new {
|
|
|
+ my ( $class, %opts ) = @_;
|
|
|
+ require Selenium::Client;
|
|
|
+ my $self = bless {
|
|
|
+ '_client' => Selenium::Client->new(
|
|
|
+ 'version' => 'stable',
|
|
|
+ %opts,
|
|
|
+ ),
|
|
|
+ }, $class;
|
|
|
+ $self->{'debug'} = $opts{'debug'};
|
|
|
+
|
|
|
+ $self->_install_wrapper_subs();
|
|
|
+ return $self;
|
|
|
+}
|
|
|
+
|
|
|
+our %cmd_map = (
|
|
|
+ 'NewSession' => 'new_session',
|
|
|
+ 'Status' => 'status',
|
|
|
+ 'GetTimeouts' => 'get_timeouts',
|
|
|
+ 'SetTimeouts' => 'set_timeout',
|
|
|
+ 'NavigateTo' => 'navigate',
|
|
|
+ 'GetCurrentUrl' => 'get_current_url',
|
|
|
+ 'Back' => 'go_back',
|
|
|
+ 'Forward' => 'go_forward',
|
|
|
+ 'Refresh' => 'refresh',
|
|
|
+ 'GetTitle' => 'get_title',
|
|
|
+ 'GetWindowHandle' => 'get_current_window_handle', # TODO test this, no idea
|
|
|
+ 'CloseWindow' => 'close',
|
|
|
+ 'SwitchToWindow' => 'switch_to_window',
|
|
|
+ 'GetWindowHandles' => 'get_window_handles',
|
|
|
+ 'SwitchToFrame' => 'switch_to_frame',
|
|
|
+ 'SwitchToParentFrame' => 'switch_to_parent_frame',
|
|
|
+ 'GetWindowRect' => 'get_window_size',
|
|
|
+ 'SetWindowRect' => 'set_window_rect',
|
|
|
+ 'MaximizeWindow' => 'maximize_window',
|
|
|
+ 'MinimizeWindow' => 'minimize_window',
|
|
|
+ 'FullscreenWindow' => 'fullscreen_window',
|
|
|
+ 'GetActiveElement' => 'get_active_element',
|
|
|
+ 'FindElement' => 'find_element',
|
|
|
+ 'FindElements' => 'find_elements',
|
|
|
+ 'GetPageSource' => 'get_page_source',
|
|
|
+ 'ExecuteScript' => 'execute_script',
|
|
|
+ 'ExecuteAsyncScript' => 'execute_async_script',
|
|
|
+ 'GetAllCookies' => 'get_all_cookies',
|
|
|
+ 'GetNamedCookie' => 'get_cookie_named',
|
|
|
+ 'AddCookie' => 'add_cookie',
|
|
|
+ 'DeleteCookie' => 'delete_cookie_named',
|
|
|
+ 'DeleteAllCookies' => 'delete_all_cookies',
|
|
|
+ 'PerformActions' => 'general_action',
|
|
|
+ 'ReleaseActions' => 'release_general_actions',
|
|
|
+ 'DismissAlert' => 'dismiss_alert',
|
|
|
+ 'AcceptAlert' => 'accept_alert',
|
|
|
+ 'GetAlertText' => 'get_alert_text',
|
|
|
+ 'SendAlertText' => 'send_keys_to_prompt',
|
|
|
+ 'TakeScreenshot' => 'screenshot',
|
|
|
+ 'TakeElementScreenshot',
|
|
|
+);
|
|
|
+
|
|
|
+my @element_methods = (
|
|
|
+ 'FindElementFromElement',
|
|
|
+ 'FindElementsFromElement',
|
|
|
+ 'IsElementSelected',
|
|
|
+ 'GetElementAttribute',
|
|
|
+ 'GetElementProperty',
|
|
|
+ 'GetElementCSSValue',
|
|
|
+ 'GetElementText',
|
|
|
+ 'GetElementTagName',
|
|
|
+ 'GetElementRect',
|
|
|
+ 'IsElementEnabled',
|
|
|
+ 'ElementClick',
|
|
|
+ 'ElementClear',
|
|
|
+ 'ElementSendKeys',
|
|
|
+)
|
|
|
+
|
|
|
+my @unimplemented = qw{
|
|
|
+ new_desired_session
|
|
|
+ mouse_move_to_location
|
|
|
+ move_to
|
|
|
+ get_capabilities
|
|
|
+ set_async_script_timeout
|
|
|
+ set_implicit_wait_timeout
|
|
|
+ pause
|
|
|
+ get_window_position
|
|
|
+ capture_screenshot
|
|
|
+ available_engines
|
|
|
+ set_window_position
|
|
|
+};
|
|
|
+
|
|
|
+sub _install_wrapper_subs {
|
|
|
+ my ( $self ) = @_;
|
|
|
+ foreach my $sub_per_spec keys(%{$self->{client}{spec}}) {
|
|
|
+ my $sub2install = $cmd_map{$sub_per_spec};
|
|
|
+ if( !$sub2install ) {
|
|
|
+ print "Can't install a subroutine to match '$sub_per_spec', as it isn't mapped to the S::R::D equivalent!" if $self->{'debug'};
|
|
|
+ next;
|
|
|
+ }
|
|
|
+
|
|
|
+ # Yo dawg... I herd u like Sub::Install
|
|
|
+ Sub::Install::install_sub(
|
|
|
+ {
|
|
|
+ code => sub {
|
|
|
+ my $self = shift;
|
|
|
+ my $sub_from_client = $self->{'_client'}->can($sub);
|
|
|
+ return $sub_from_client->( $self->{'_client'}, @_ );
|
|
|
+ },
|
|
|
+ as => $sub2install,
|
|
|
+ into => "Selenium::Remote::Driver::v4",
|
|
|
+ }
|
|
|
+ ) unless "Selenium::Remote::Driver::v4"->can($sub);
|
|
|
+ }
|
|
|
+ foreach my $die_on (@unimplemented) {
|
|
|
+ Sub::Install::install_sub(
|
|
|
+ {
|
|
|
+ code => sub { my $self = shift; die "$die_on is unimplemented in " . ref $self },
|
|
|
+ as => $die_on,
|
|
|
+ into => "Selenium::Remote::Driver::v4",
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ *send_keys_to_alert = \&send_keys_to_prompt;
|
|
|
+ *get = \&navigate;
|
|
|
+}
|
|
|
+
|
|
|
+# Helpers from base module not in Client
|
|
|
+sub is_webdriver_3 { return 0 }
|
|
|
+sub has_javascript { return 1 }
|
|
|
+sub debug_on { return $_[0]->{'debug'} = 1 }
|
|
|
+sub debug_off { return $_[0]->{'debug'} = 0 }
|
|
|
+sub get_sessions { return $_[0]->{'client'}{'sessions'} }
|
|
|
+
|
|
|
+sub send_keys_to_active_element {
|
|
|
+ my ($self, $keys) = @_;
|
|
|
+ my $elem = $self->get_active_element();
|
|
|
+ return $elem->send_keys($keys); # TODO test
|
|
|
+}
|
|
|
+
|
|
|
+sub quit {
|
|
|
+ my ($self) = @_;
|
|
|
+ undef $self->{'client'};
|
|
|
+ return undef $self;
|
|
|
+}
|
|
|
+*DESTROY = \&quit;
|
|
|
+
|
|
|
+1;
|