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(); # Create the session, as users expect this $self->{'_client'}->NewSession(); 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', ); my @element_methods = ( 'FindElementFromElement', 'FindElementsFromElement', 'IsElementSelected', 'GetElementAttribute', 'GetElementProperty', 'GetElementCSSValue', 'GetElementText', 'GetElementTagName', 'GetElementRect', 'IsElementEnabled', 'ElementClick', 'ElementClear', 'ElementSendKeys', 'TakeElementScreenshot', ); 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}; next if( !$sub2install ); # 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_per_spec); return $sub_from_client->( $self->{'_client'}, @_ ); }, as => $sub2install, into => "Selenium::Remote::Driver::v4", } ) unless "Selenium::Remote::Driver::v4"->can($sub2install); } 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;