package Selenium::Remote::Driver::FirefoxExtensions; use warnings; use strict; use TryCatch; use Moo; use Selenium::Remote::WDKeys; use Selenium::ActionChains; use Test::More import => [qw(diag ok is)]; extends 'Selenium::Firefox'; # important so that S:F doesn't start an own instance of geckodriver has '+remote_server_addr' => ( default => '127.0.0.1', ); has '+port' => ( default => '4444', ); has '+proxy' => ( default => sub { return {proxyType => 'system'}; }, ); sub BUILD { my $self = shift; my ($window_h,$window_w) = ($ENV{WINDOW_SIZE} || '1024x1280') =~ /([0-9]+)x([0-9]+)/i; my $browsername = $self->browser_name; $self->set_timeout("implicit", 10_000); } sub select_if_unselected { my ($self, $query, $scheme) = @_; $scheme //= "xpath"; try { my $elem = $self->find_element($query, $scheme); if (! $elem->is_selected() ) { $elem->click; } return 1; }; return 0; } sub unselect_if_selected { my ($self, $query, $scheme) = @_; $scheme //= "xpath"; try { my $elem = $self->find_element($query, $scheme); if ($elem->is_selected() ) { $elem->click; } return 1; }; return 0; } sub fill_element { my ($self, $query, $scheme, $filltext) = @_; my $elem = $self->find_element($query, $scheme); $self->scroll_to_element($elem); return 0 unless $elem; $elem->send_keys(KEYS->{'control'}, 'A'); $elem->send_keys($filltext); return 1; } sub scroll_to_element { my ($self, $elem) = @_; my $script = 'var arg1 = arguments[0];' . 'arg1.scrollIntoView();' . 'return arg1;'; $self->execute_script($script,$elem); return $elem; } sub browser_name_in { my ($self, @names) = @_; my $browser_name = $self->browser_name; return scalar grep {/^$browser_name$/} @names; } sub move_and_click { my ($self, $path, $type, $fallback, $timeout) = @_; return unless $path && $type; my $action_chains = Selenium::ActionChains->new(driver => $self); $timeout = 20 unless $timeout; # seconds. Default timeout value if none is specified. my $started = time(); my $elapsed = time(); while ($elapsed - $started <= $timeout){ $elapsed = time(); try{ if($fallback) { $action_chains->move_to_element($self->find_element($fallback, $type)); } $action_chains->move_to_element($self->find_element($path, $type)); $action_chains->click($self->find_element($path, $type)); $action_chains->perform; return 1; }; } return 0; } sub get_text_safe { my ($self, $path, $type) = @_; return unless $path; $type //= "xpath"; try { my $element = $self->find_element($path, $type); return $element->get_text(); } catch { $self->capture_screenshot('/results/alert' . int(rand(1000)) . '.png'); return 'Element not found'; }; } 1;