Reputation: 13
I'm trying to automate login into https://strade.sharekhan.com
my $driver = Selenium::Remote::Driver->new;
$driver->get("https://strade.sharekhan.com/");
I'm able to successfully open the firefox browser and fetch the page. But the input elements aren't visible.
my $page_source = $driver->get_page_source();
$driver->find_element('emailLoginId')->send_keys("abcdefg");
The login section seems to be inside a separate class item,whose html source appears in the browser debugger,but when trying via selenium,the class item is empty. I only know basic Javascript/jQuery... kindly help me out,what is it that I'm missing
my $login_element = $driver->find_element_by_class('loginresponsive');
Upvotes: 1
Views: 441
Reputation: 386361
You can always wait for it to show up.
The following was written for Selenium::Chrome, but it demonstrates a portable principle.
use constant POLL_INTERVAL => 0.1;
use Time::HiRes qw( sleep time );
sub wait_for {
my ($xpath, $max_wait) = @_;
my $wait_until = time() + $max_wait;
while (1) {
if ( my $nodes = nf_find_elements($xpath) ) {
return wantarray ? @$nodes : $nodes->[0];
}
my $time_left = $wait_until - time();
return () if $time_left <= 0;
sleep(min($time_left, POLL_INTERVAL));
}
}
# Version of `find_elements` that doesn't die (non-fatal) when the element isn't found.
sub nf_find_elements {
my $nodes;
if (!eval {
$nodes = $web_driver->find_elements(@_);
return 1; # No exception.
}) {
return undef if $@ =~ /Unable to locate element|An element could not be located on the page using the given search parameters/;
die($@);
}
return wantarray ? @$nodes : $nodes;
}
Example usage:
my $node = wait_for('//some/path', 4.0) # Wait up to 4s
or die("Login was unsuccessful.\n");
Time::HiRes's sleep
doesn't get interrupted by signals, so I used the following to make my Ctrl-C handler responsive:
use Time::HiRes qw( );
use constant SLEEP_INTERVAL => 0.1;
# Hi-res sleep that gives signal handlers a chance to run.
use subs qw( sleep );
sub sleep {
if (!$_[0]) {
Time::HiRes::sleep(SLEEP_INTERVAL) while 1;
return; # Never reached.
}
my $sleep_until = time() + $_[0];
while (1) {
my $time_left = $sleep_until - Time::HiRes::time();
return if $time_left <= 0;
Time::HiRes::sleep(min($time_left, SLEEP_INTERVAL));
}
}
Make sure not to import sleep
from Time::HiRes.
Upvotes: 1
Reputation: 40778
I tested this with Selenium::Chrome and it seems to work fine:
use strict;
use warnings;
use Selenium::Chrome;
# Enter your driver path here. See https://sites.google.com/a/chromium.org/chromedriver/
# for download instructions
my $driver_path = '/home/hakon/chromedriver/chromedriver';
my $driver = Selenium::Chrome->new( binary => $driver_path );
$driver->get("https://strade.sharekhan.com/");
$driver->find_element_by_name('emailLoginId')->send_keys("abcdefg");
sleep 45;
Screen shot taken while sleeping (see last line in code above):
Upvotes: 0