MockSeleniumRC.pm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package t::lib::MockSeleniumRC;
  2. use strict;
  3. use warnings;
  4. use LWP::Protocol::PSGI;
  5. use JSON;
  6. our $MockSeleniumRCObj;
  7. sub save_recording {
  8. my ($self) = @_;
  9. open(my $fh, '>', $self->{file});
  10. print $fh encode_json($self->{req_resp});
  11. close $fh;
  12. }
  13. sub load_recording {
  14. my ($self) = @_;
  15. open(my $fh, '<', $self->{file});
  16. my @lines = <$fh>;
  17. $self->{req_resp} = decode_json(join('', @lines));
  18. close $fh;
  19. }
  20. sub register {
  21. my $record = shift;
  22. $record = 0 if !defined $record;
  23. my $file = shift;
  24. my $self = {record => $record,
  25. req_index => 0,
  26. file => $file};
  27. bless $self,__PACKAGE__;
  28. if ($record) {
  29. require LWP::UserAgent;
  30. require HTTP::Headers;
  31. require HTTP::Request;
  32. $self->{req_resp} = [];
  33. } else {
  34. $self->load_recording;
  35. }
  36. LWP::Protocol::PSGI->register(\&t::lib::MockSeleniumRC::psgi_app);
  37. $MockSeleniumRCObj = $self;
  38. }
  39. sub psgi_app {
  40. my $env = shift;
  41. my $self = $MockSeleniumRCObj;
  42. my $uri =
  43. $env->{'psgi.url_scheme'} . '://'
  44. . $env->{SERVER_NAME} . ':'
  45. . $env->{SERVER_PORT}
  46. . $env->{REQUEST_URI};
  47. my $content = '';
  48. my $s;
  49. while (read($env->{'psgi.input'}, $s, 100)) {
  50. $content .= $s;
  51. }
  52. my $req_index = \$self->{req_index};
  53. if (!$self->{record}) {
  54. if ( $self->{req_resp}->[$$req_index]->{request}->{verb} eq $env->{REQUEST_METHOD}
  55. and $self->{req_resp}->[$$req_index]->{request}->{uri} eq $uri
  56. and $self->{req_resp}->[$$req_index]->{request}->{content} eq $content) {
  57. return $self->{req_resp}->[$$req_index++]->{response};
  58. } else {
  59. die
  60. "Request information has changed since recording... do you need to record webdriver responses again?";
  61. }
  62. } else {
  63. my $ua = LWP::UserAgent->new;
  64. my $h = HTTP::Headers->new;
  65. $h->header('Content-Type' => $env->{CONTENT_TYPE});
  66. $h->header('Accept' => $env->{HTTP_ACCEPT});
  67. my $req = HTTP::Request->new($env->{REQUEST_METHOD}, $uri, $h, $content);
  68. LWP::Protocol::PSGI->unregister;
  69. my $res = $ua->request($req);
  70. LWP::Protocol::PSGI->register(\&psgi_app);
  71. my $head = $res->{_headers}->clone;
  72. my $newhead = [];
  73. for my $key (keys %{$head}) {
  74. push @{$newhead}, $key;
  75. push @{$newhead}, $head->{$key};
  76. }
  77. my $response = [$res->code, $newhead, [$res->content]];
  78. my $request = {
  79. verb => $env->{REQUEST_METHOD},
  80. uri => $uri,
  81. content => $content
  82. };
  83. push @{$self->{req_resp}}, {request => $request, response => $response};
  84. return $response;
  85. }
  86. }
  87. sub DESTROY {
  88. my ($self) = @_;
  89. if($self->{record}) {
  90. $self->save_recording;
  91. }
  92. }
  93. 1;