Binary.pm 2.3 KB

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