Binary.pm 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package Selenium::Binary;
  2. use File::Which qw/which/;
  3. use IO::Socket::INET;
  4. use Selenium::Waiter qw/wait_until/;
  5. require Exporter;
  6. our @ISA = qw/Exporter/;
  7. our @EXPORT = qw/start_binary_on_port/;
  8. sub start_binary_on_port {
  9. my ($process, $port) = @_;
  10. my $executable = _find_executable($process);
  11. $port = _find_open_port_above($port);
  12. my $command = _construct_command($executable, $port);
  13. system($command);
  14. my $success = wait_until { _probe_port($port) } timeout => 10;
  15. if ($success) {
  16. return $port;
  17. }
  18. else {
  19. die 'Unable to connect to the ' . $executable . ' binary on port ' . $port;
  20. }
  21. }
  22. sub _find_executable {
  23. my ($binary) = @_;
  24. my $executable = which($binary);
  25. if (not defined $executable) {
  26. die qq(Unable to find the $binary binary in your \$PATH. We'll try falling back to standard Remote Driver);
  27. }
  28. else {
  29. return $executable;
  30. }
  31. }
  32. sub _construct_command {
  33. my ($executable, $port) = @_;
  34. my %args;
  35. if ($executable =~ /chromedriver$/) {
  36. %args = (
  37. port => $port,
  38. 'base-url' => 'wd/hub'
  39. );
  40. }
  41. elsif ($executable =~ /phantomjs$/) {
  42. %args = (
  43. webdriver => '127.0.0.1:' . $port
  44. );
  45. }
  46. my @args = map { '--' . $_ . '=' . $args{$_} } keys %args;
  47. return join(' ', ($executable, @args, '> /dev/null 2>&1 &') );
  48. }
  49. sub _find_open_port_above {
  50. my ($port) = @_;
  51. my $free_port = wait_until {
  52. if (_probe_port($port)) {
  53. $port++;
  54. return 0;
  55. }
  56. else {
  57. return $port;
  58. }
  59. };
  60. return $free_port;
  61. }
  62. sub _probe_port {
  63. my ($port) = @_;
  64. return IO::Socket::INET->new(
  65. PeerAddr => '127.0.0.1',
  66. PeerPort => $port,
  67. Timeout => 3
  68. );
  69. }
  70. 1;