1
0

MockSeleniumWebDriver.pm 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package t::lib::MockSeleniumWebDriver;
  2. use strict;
  3. use warnings;
  4. use LWP::Protocol::PSGI 0.04;
  5. use JSON;
  6. our $MockSeleniumWebDriverObj;
  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::MockSeleniumWebDriver::psgi_app);
  37. $MockSeleniumWebDriverObj = $self;
  38. }
  39. sub psgi_app {
  40. my $env = shift;
  41. my $self = $MockSeleniumWebDriverObj;
  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. my $expected = $self->{req_resp}->[$$req_index]->{request}->{content};
  55. $expected = $expected eq "" ? $expected : decode_json($expected);
  56. my $actual = $content eq "" ? $content : decode_json($content);
  57. if ( $self->{req_resp}->[$$req_index]->{request}->{verb} eq $env->{REQUEST_METHOD}
  58. and $self->{req_resp}->[$$req_index]->{request}->{uri} eq $uri
  59. and ( $self->{req_resp}->[$$req_index]->{request}->{content} eq $content
  60. or deeply_equal($expected, $actual))) {
  61. return $self->{req_resp}->[$$req_index++]->{response};
  62. } else {
  63. die
  64. "Request information has changed since recording... do you need to record webdriver responses again?";
  65. }
  66. } else {
  67. my $ua = LWP::UserAgent->new;
  68. my $h = HTTP::Headers->new;
  69. $h->header('Content-Type' => $env->{CONTENT_TYPE});
  70. $h->header('Accept' => $env->{HTTP_ACCEPT});
  71. my $req = HTTP::Request->new($env->{REQUEST_METHOD}, $uri, $h, $content);
  72. LWP::Protocol::PSGI->unregister;
  73. my $res = $ua->request($req);
  74. LWP::Protocol::PSGI->register(\&psgi_app);
  75. my $head = $res->{_headers}->clone;
  76. my $newhead = [];
  77. for my $key (keys %{$head}) {
  78. push @{$newhead}, $key;
  79. push @{$newhead}, $head->{$key};
  80. }
  81. my $response = [$res->code, $newhead, [$res->content]];
  82. my $request = {
  83. verb => $env->{REQUEST_METHOD},
  84. uri => $uri,
  85. content => $content
  86. };
  87. push @{$self->{req_resp}}, {request => $request, response => $response};
  88. return $response;
  89. }
  90. }
  91. sub deeply_equal {
  92. my ( $a_ref, $b_ref ) = @_;
  93. local $Storable::canonical = 1;
  94. return Storable::freeze( $a_ref ) eq Storable::freeze( $b_ref );
  95. }
  96. sub DESTROY {
  97. my ($self) = @_;
  98. if($self->{record}) {
  99. $self->save_recording;
  100. }
  101. }
  102. 1;