Kaynağa Gözat

Mocking class works

Emmanuel Peroumalnaik 11 yıl önce
ebeveyn
işleme
87752cc8a5

+ 30 - 9
lib/Selenium/Remote/Driver.pm

@@ -20,6 +20,8 @@ use Scalar::Util;
 use Selenium::Remote::RemoteConnection;
 use Selenium::Remote::Commands;
 use Selenium::Remote::WebElement;
+use Selenium::Remote::MockRemoteConnection;
+use Selenium::Remote::MockCommands;
 
 use constant FINDERS => {
     class             => 'class name',
@@ -313,14 +315,27 @@ has 'remote_conn' => (
     is      => 'lazy',
     builder => sub {
         my $self = shift;
-        return Selenium::Remote::RemoteConnection->new(
-            remote_server_addr => $self->remote_server_addr,
-            port               => $self->port,
-            ua                 => $self->ua
-        );
+        if ( $self->testing ) {
+            return Selenium::Remote::MockRemoteConnection->new(
+                spec      => $self->spec,
+                mock_cmds => $self->commands,
+            );
+        }
+        else {
+            return Selenium::Remote::RemoteConnection->new(
+                remote_server_addr => $self->remote_server_addr,
+                port               => $self->port,
+                ua                 => $self->ua
+            );
+        }
     },
 );
 
+has 'spec' => ( 
+    is => 'ro', 
+    default => sub { {}} ,
+);
+
 has 'ua' => (
     is      => 'lazy',
     builder => sub { return LWP::UserAgent->new }
@@ -328,7 +343,15 @@ has 'ua' => (
 
 has 'commands' => (
     is      => 'lazy',
-    builder => sub { return Selenium::Remote::Commands->new; },
+    builder => sub {
+        my $self = shift;
+        if ( $self->testing ) {
+            return Selenium::Remote::MockCommands->new;
+        }
+        else {
+            return Selenium::Remote::Commands->new;
+        }
+    },
 );
 
 has 'auto_close' => (
@@ -423,8 +446,6 @@ has 'testing' => (
 sub BUILD {
     my $self = shift;
 
-    # disable server connection when testing attribute is on
-    unless ($self->testing) {
 
         if ($self->has_desired_capabilities) {
             $self->new_desired_session( $self->desired_capabilities );
@@ -441,7 +462,6 @@ sub BUILD {
             my $size = $self->inner_window_size;
             $self->set_inner_window_size(@$size);
         }
-    }
 }
 
 sub new_from_caps {
@@ -466,6 +486,7 @@ sub DEMOLISH {
 sub _execute_command {
     my ( $self, $res, $params ) = @_;
     $res->{'session_id'} = $self->session_id;
+    $DB::single = 1;
     my $resource = $self->commands->get_params($res);
 
     if ($resource) {

+ 33 - 0
lib/Selenium/Remote/MockCommands.pm

@@ -0,0 +1,33 @@
+package Selenium::Remote::MockCommands; 
+use Moo; 
+extends 'Selenium::Remote::Commands';
+
+
+# override get_params so we do not rewrite the parameters
+
+sub get_params { 
+    my $self = shift;
+    my $args = shift;
+    my $data = {};
+    my $command = $args->{command};
+    $data->{'url'} = $self->get_url($command);
+    $data->{'method'} = $self->get_method($command);
+    $data->{'no_content_success'} = $self->get_no_content_success($command);
+    return $data; 
+}
+
+sub get_method_name_from_parameters { 
+    my $self = shift; 
+    my $params = shift;
+    my $method_name = '';
+    my $cmds = $self->get_cmds();
+    foreach my $cmd (keys %{$cmds}) { 
+        if (($cmds->{$cmd}->{method} eq $params->{method}) && ($cmds->{$cmd}->{url} eq $params->{url})) { 
+            $method_name = $cmd; 
+            last;
+        }
+    }
+    return $method_name;
+}
+
+1;

+ 58 - 0
lib/Selenium/Remote/MockRemoteConnection.pm

@@ -0,0 +1,58 @@
+package Selenium::Remote::MockRemoteConnection;
+
+# ABSTRACT: utility class to mock the responses from Selenium server
+
+use Moo; 
+use JSON; 
+use Try::Tiny;
+
+has 'spec' => (
+    is       => 'ro',
+    required => 1,
+);
+
+has 'mock_cmds' => ( 
+    is => 'ro', 
+);
+
+has 'session_id' => ( 
+    is => 'lazy', 
+    builder => sub { 
+        my $id = join '',
+        map +( 0 .. 9, 'a' .. 'z', 'A' .. 'Z' )[ rand( 10 + 26 * 2 ) ], 1 .. 50;
+        return $id;
+    },
+);
+
+sub request { 
+    my $self = shift;
+    my ($method, $url, $no_content_success, $params) = @_;
+    my $mock_cmds = $self->mock_cmds;
+    my $spec = $self->spec; 
+    my $cmd = $mock_cmds->get_method_name_from_parameters({method => $method,url => $url});
+    my $ret = {cmd_status => 'OK', cmd_return => 1};
+    if (defined($spec->{$cmd})) { 
+        my $return_sub = $spec->{$cmd};
+        if ($no_content_success) { 
+            $ret->{cmd_return} = 1;
+        }
+        else { 
+            my $mock_return = $return_sub->($params);
+            if (ref($mock_return) eq 'HASH') { 
+                $ret->{cmd_status} = $mock_return->{status};
+                $ret->{cmd_return} = $mock_return->{return};
+                $ret->{cmd_error} = $mock_return->{error} // ''
+            }
+            else { 
+                $ret = $mock_return;
+            }
+        }
+        $ret->{session_id} = $self->session_id if (ref($ret) eq 'HASH');
+    }
+    else { 
+        $ret->{sessionId} = $self->session_id;
+    }
+    return $ret;
+}
+
+1;

+ 17 - 116
t/Test-Selenium-Remote-Driver.t

@@ -1,125 +1,26 @@
 #!/usr/bin/env perl
 use Test::Tester;
 use Test::More;
-use Test::MockObject;
-use Test::MockObject::Extends;
+use Test::Exception;
 use Test::Selenium::Remote::Driver;
 use Selenium::Remote::WebElement;
 use Carp;
 
-my $successful_driver = Test::Selenium::Remote::Driver->new( testing => 1 );
-$successful_driver = Test::MockObject::Extends->new($successful_driver);
-
-my $element = Test::Selenium::Remote::WebElement->new(
-    id     => '1342835311100',
-    parent => $successful_driver,
-);
-
-
-# find_element_ok
-{
-    $successful_driver->mock( 'find_element', sub {$element} );
-    check_tests(
-        sub {
-            my $rc = $successful_driver->find_element_ok( 'q',
-                'find_element_ok works' );
-            is( $rc, 1, 'returns true' );
-        },
-        [   {   ok   => 1,
-                name => "find_element_ok works",
-                diag => "",
-            },
-            {   ok   => 1,
-                name => "returns true",
-                diag => "",
-            },
-        ]
-    );
-
-    $successful_driver->mock( 'find_element', sub {0} );
-    check_tests(
-        sub {
-            my $rc = $successful_driver->find_element_ok( 'q',
-                'find_element_ok works, falsey test' );
-            is( $rc, 0, 'returns false' );
-        },
-        [   {   ok   => 0,
-                name => "find_element_ok works, falsey test",
-                diag => "",
-            },
-            {   ok   => 1,
-                name => "returns false",
-                diag => "",
-            },
-        ]
-    );
-}
-
-# find_no_element_ok
-{
-    $successful_driver->mock( 'find_element', sub { die $_[1] } );
-    check_tests(
-        sub {
-            my $rc = $successful_driver->find_no_element_ok( 'BOOM',
-                'find_no_element_ok works, expecting to find nothing.' );
-            is( $rc, 1, 'returns true' );
-        },
-        [   {   ok   => 1,
-                name => "find_no_element_ok works, expecting to find nothing.",
-                diag => "",
-            },
-            {   ok   => 1,
-                name => "returns true",
-                diag => "",
-            },
-        ]
-    );
-
-    $successful_driver->mock( 'find_element', sub {$element} );
-    check_tests(
-        sub {
-            my $rc =
-              $successful_driver->find_no_element_ok( 'q',
-                'find_no_element_ok works, expecting a false value if a element exists'
-              );
-            is( $rc, 0, 'returns false' );
-        },
-        [   {   ok => 0,
-                name =>
-                  "find_no_element_ok works, expecting a false value if a element exists",
-                diag => "",
-            },
-            {   ok   => 1,
-                name => "returns false",
-                diag => "",
-            },
-        ]
-    );
-
-
-}
-
-# content_like
-{
-    $successful_driver->mock( 'get_page_source', sub { 'this output matches regex' } );
-    check_tests(
-        sub {
-            my $rc = $successful_driver->content_like( qr/matches/,
-                'content_like works' );
-            is( $rc, 1, 'returns true' );
-        },
-        [   {   ok   => 1,
-                name => "content_like works",
-                diag => "",
-            },
-            {   ok   => 1,
-                name => "returns true",
-                diag => "",
-            },
-        ]
-    );
-
-}
-
+my $spec = {
+    findElement => sub {
+        my $searched_item = shift;
+        return { status => 'OK', return => { ELEMENT => '123456' } }
+          if ( $searched_item->{value} eq 'q' );
+        return { status => 'NOK', return => 0, error => 'element not found' };
+    },
+    getPageSource => sub { return 'this output matches regex'},
+};
+
+my $successful_driver = Test::Selenium::Remote::Driver->new( testing => 1, spec => $spec);
+$successful_driver->find_element_ok('q','find_element_ok works');
+dies_ok { $successful_driver->find_element_ok('notq') } 'find_element_ok dies if element not found';
+$successful_driver->find_no_element_ok('notq','find_no_element_ok works');
+$successful_driver->content_like( qr/matches/, 'content_like works');
+$successful_driver->content_unlike( qr/nomatch/, 'content_unlike works');
 
 done_testing();