RemoteConnection.pm 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package Selenium::Remote::RemoteConnection;
  2. use Moo;
  3. use Try::Tiny;
  4. use LWP::UserAgent;
  5. use HTTP::Headers;
  6. use HTTP::Request;
  7. use Net::Ping;
  8. use Carp qw(croak);
  9. use JSON;
  10. use Data::Dumper;
  11. use Selenium::Remote::ErrorHandler;
  12. has 'remote_server_addr' => (
  13. is => 'rw',
  14. );
  15. has 'port' => (
  16. is => 'rw',
  17. );
  18. has 'debug' => (
  19. is => 'rw',
  20. default => sub { 0 }
  21. );
  22. has 'ua' => (
  23. is => 'lazy',
  24. builder => sub { return LWP::UserAgent->new; }
  25. );
  26. sub BUILD {
  27. my $self = shift;
  28. my $status;
  29. try {
  30. $status = $self->request('GET','status');
  31. }
  32. catch {
  33. croak "Could not connect to SeleniumWebDriver: $_" ;
  34. };
  35. if($status->{cmd_status} ne 'OK') {
  36. # Could be grid, see if we can talk to it
  37. $status = undef;
  38. $status = $self->request('GET', 'grid/api/testsession');
  39. }
  40. unless ($status->{cmd_status} eq 'OK') {
  41. croak "Selenium server did not return proper status";
  42. }
  43. }
  44. # This request method is tailored for Selenium RC server
  45. sub request {
  46. my ($self, $method, $url, $params) = @_;
  47. my $content = '';
  48. my $fullurl = '';
  49. # Construct full url.
  50. if ($url =~ m/^http/g) {
  51. $fullurl = $url;
  52. }
  53. elsif ($url =~ m/grid/g) {
  54. $fullurl =
  55. "http://"
  56. . $self->remote_server_addr . ":"
  57. . $self->port
  58. . "/$url";
  59. }
  60. else {
  61. $fullurl =
  62. "http://"
  63. . $self->remote_server_addr . ":"
  64. . $self->port
  65. . "/wd/hub/$url";
  66. }
  67. if ((defined $params) && $params ne '') {
  68. my $json = JSON->new;
  69. $json->allow_blessed;
  70. $content = $json->allow_nonref->utf8->encode($params);
  71. }
  72. print "REQ: $url, $content\n" if $self->debug;
  73. # HTTP request
  74. my $header =
  75. HTTP::Headers->new(Content_Type => 'application/json; charset=utf-8');
  76. $header->header('Accept' => 'application/json');
  77. my $request = HTTP::Request->new($method, $fullurl, $header, $content);
  78. my $response = $self->ua->request($request);
  79. return $self->_process_response($response);
  80. }
  81. sub _process_response {
  82. my ($self, $response) = @_;
  83. my $data; # server response 'value' that'll be returned to the user
  84. my $json = JSON->new;
  85. if ($response->is_redirect) {
  86. return $self->request('GET', $response->header('location'));
  87. }
  88. else {
  89. my $decoded_json = undef;
  90. print "RES: ".$response->decoded_content."\n\n" if $self->debug;
  91. if (($response->message ne 'No Content') && ($response->content ne '')) {
  92. if ($response->content_type !~ m/json/i) {
  93. $data->{'cmd_return'} = 'Server returned error message '.$response->content.' instead of data';
  94. return $data;
  95. }
  96. $decoded_json = $json->allow_nonref(1)->utf8(1)->decode($response->content);
  97. $data->{'sessionId'} = $decoded_json->{'sessionId'};
  98. }
  99. if ($response->is_error) {
  100. my $error_handler = Selenium::Remote::ErrorHandler->new;
  101. $data->{'cmd_status'} = 'NOTOK';
  102. if (defined $decoded_json) {
  103. $data->{'cmd_return'} = $error_handler->process_error($decoded_json);
  104. }
  105. else {
  106. $data->{'cmd_return'} = 'Server returned error code '.$response->code.' and no data';
  107. }
  108. return $data;
  109. }
  110. elsif ($response->is_success) {
  111. $data->{'cmd_status'} = 'OK';
  112. if (defined $decoded_json) {
  113. $data->{'cmd_return'} = $decoded_json->{'value'};
  114. }
  115. else {
  116. $data->{'cmd_return'} = 'Server returned status code '.$response->code.' but no data';
  117. }
  118. return $data;
  119. }
  120. else {
  121. # No idea what the server is telling me, must be high
  122. $data->{'cmd_status'} = 'NOTOK';
  123. $data->{'cmd_return'} = 'Server returned status code '.$response->code.' which I don\'t understand';
  124. return $data;
  125. }
  126. }
  127. }
  128. 1;
  129. __END__
  130. =pod
  131. =head1 NAME
  132. Selenium::Remote::RemoteConnection - Connect to a selenium server
  133. =head1 SEE ALSO
  134. For more information about Selenium, visit the website at
  135. L<http://code.google.com/p/selenium/>.
  136. =head1 BUGS
  137. The Selenium issue tracking system is available online at
  138. L<http://github.com/gempesaw/Selenium-Remote-Driver/issues>.
  139. =head1 CURRENT MAINTAINER
  140. Daniel Gempesaw C<< <gempesaw@gmail.com> >>