ngcp-panel/t/lib/Selenium/Remote/Driver/FirefoxExtensions.pm

180 lines
4.6 KiB

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 find_text {
try {
my ($self, $text, $scheme) = @_;
$scheme //= "xpath";
return $self->find_element("//*[contains(text(),\"$text\")]", $scheme);
}
catch {
return;
};
}
sub select_if_unselected {
my ($self, $query, $scheme) = @_;
$scheme //= "xpath";
my $elem = $self->find_element($query, $scheme);
return 0 unless $elem;
return 0 unless $elem->is_displayed;
if (! $elem->is_selected() ) {
$elem->click;
}
return 1;
}
sub unselect_if_selected {
my ($self, $query, $scheme) = @_;
$scheme //= "xpath";
my $elem = $self->find_element($query, $scheme);
return 0 unless $elem;
return 0 unless $elem->is_displayed;
if ($elem->is_selected() ) {
$elem->click;
}
return 1;
}
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_id {
my ($self, $id) = @_;
my $script =
'var arg1 = arguments[0];' .
'var elem = window.document.getElementById(arg1);' .
'elem.scrollIntoView();' .
'return elem;';
my $elem = $self->execute_script($script,$id);
return $elem;
}
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 wait_for_text {
my ($self, $xpath, $expected, $timeout) = @_;
return unless $xpath && $expected;
$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{
return 1 if $self->find_element($xpath)->get_text() eq $expected;
};
}
return 0;
}
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 wait_for_attribute {
my ($self, $path, $attrib, $expected, $timeout) = @_;
return unless $path && $attrib && $expected;
$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{
return 1 if $self->find_element($path)->get_attribute($attrib, 1) eq $expected;
};
}
return 0;
}
sub get_text_safe {
my ($self, $path, $type) = @_;
$type = "xpath" unless $type;
if($type eq "css"){
try {
my $element = $self->find_element_by_css($path);
return $element->get_text();
} catch {
return 0;
};
} elsif($type eq "xpath"){
try {
my $element = $self->find_element_by_xpath($path);
return $element->get_text();
} catch {
return 0;
};
} else {
return "Unknown Element Type: " . $type;
}
}
1;