1
0

Binary.pm 1.9 KB

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