浏览代码

Fix WebElement construction from execute_script

The previous checks made assumptions that are no longer true (like the
return value would only have one key, or that the return value key name
would only be called ELEMENT). Currently, the return value has two
keys (ELEMENT) and the spec key (element-6066-11e4-a52e-4f735466cecf).
Daniel Gempesaw 9 年之前
父节点
当前提交
f6d29226c3
共有 4 个文件被更改,包括 53 次插入10 次删除
  1. 15 6
      lib/Selenium/Remote/Driver.pm
  2. 17 0
      t/02-webelement.t
  3. 18 0
      t/CanStartBinary.t
  4. 3 4
      t/mock-recordings/02-webelement-mock.json

+ 15 - 6
lib/Selenium/Remote/Driver.pm

@@ -1403,7 +1403,7 @@ sub execute_async_script {
         # JSON representation
         # JSON representation
         for ( my $i = 0; $i < @args; $i++ ) {
         for ( my $i = 0; $i < @args; $i++ ) {
             if ( Scalar::Util::blessed( $args[$i] )
             if ( Scalar::Util::blessed( $args[$i] )
-                and $args[$i]->isa('Selenium::Remote::WebElement') )
+                 and $args[$i]->isa('Selenium::Remote::WebElement') )
             {
             {
                 $args[$i] = { 'ELEMENT' => ( $args[$i] )->{id} };
                 $args[$i] = { 'ELEMENT' => ( $args[$i] )->{id} };
             }
             }
@@ -1413,9 +1413,9 @@ sub execute_async_script {
         my $ret = $self->_execute_command( $res, $params );
         my $ret = $self->_execute_command( $res, $params );
 
 
         # replace any ELEMENTS with WebElement
         # replace any ELEMENTS with WebElement
-        if (    ref($ret)
-            and ( ref($ret) eq 'HASH' )
-            and exists $ret->{'ELEMENT'} )
+        if ( ref($ret)
+             and ( ref($ret) eq 'HASH' )
+             and $self->_looks_like_element($ret) )
         {
         {
             $ret = $self->webelement_class->new(
             $ret = $self->webelement_class->new(
                 id => $ret,
                 id => $ret,
@@ -1485,6 +1485,16 @@ sub execute_script {
     }
     }
 }
 }
 
 
+# _looks_like_element
+# An internal method to check if a return value might be an element
+
+sub _looks_like_element {
+    my ($self, $maybe_element) = @_;
+
+    return exists $maybe_element->{ELEMENT}
+      or $maybe_element->{'element-6066-11e4-a52e-4f735466cecf'};
+}
+
 # _convert_to_webelement
 # _convert_to_webelement
 # An internal method used to traverse a data structure
 # An internal method used to traverse a data structure
 # and convert any ELEMENTS with WebElements
 # and convert any ELEMENTS with WebElements
@@ -1493,8 +1503,7 @@ sub _convert_to_webelement {
     my ( $self, $ret ) = @_;
     my ( $self, $ret ) = @_;
 
 
     if ( ref($ret) and ( ref($ret) eq 'HASH' ) ) {
     if ( ref($ret) and ( ref($ret) eq 'HASH' ) ) {
-        if ( ( keys %$ret == 1 ) and exists $ret->{'ELEMENT'} ) {
-
+        if ( $self->_looks_like_element($ret) ) {
             # replace an ELEMENT with WebElement
             # replace an ELEMENT with WebElement
             return $self->webelement_class->new(
             return $self->webelement_class->new(
                 id => $ret,
                 id => $ret,

+ 17 - 0
t/02-webelement.t

@@ -104,6 +104,23 @@ VISIBILITY: {
     ok($elem->is_hidden(), 'Hidden elements are hidden.');
     ok($elem->is_hidden(), 'Hidden elements are hidden.');
 }
 }
 
 
+EXECUTE_SCRIPT: {
+    $driver->get("$website/index.html");
+
+    my $elem = $driver->find_element('div', 'css');
+    my $script_elem = $driver->execute_script('return arguments[0]', $elem);
+    isa_ok($script_elem, 'Selenium::Remote::WebElement', 'execute_script element return');
+    is($elem->id, $script_elem->id, 'Sync script returns identical WebElement id');
+
+    my $async = q{
+        var callback = arguments[arguments.length - 1];
+        callback(arguments[0]);
+    };
+    my $async_elem = $driver->execute_async_script($async, $elem);
+    isa_ok($async_elem, 'Selenium::Remote::WebElement', 'execute_async_script element return');
+    is($elem->id, $async_elem->id, 'Async script returns identical WebElement id');
+}
+
 QUIT: {
 QUIT: {
     $ret = $driver->quit();
     $ret = $driver->quit();
     ok((not defined $driver->{'session_id'}), 'Killed the remote session');
     ok((not defined $driver->{'session_id'}), 'Killed the remote session');

+ 18 - 0
t/CanStartBinary.t

@@ -83,6 +83,24 @@ FIREFOX: {
 
 
             ok(Selenium::CanStartBinary::probe_port($firefox->marionette_port),
             ok(Selenium::CanStartBinary::probe_port($firefox->marionette_port),
                'the firefox binary is listening on its marionette port');
                'the firefox binary is listening on its marionette port');
+
+            EXECUTE_SCRIPT: {
+                  $firefox->get("https://www.google.com");
+
+                  my $elem = $firefox->find_element('div', 'css');
+                  my $script_elem = $firefox->execute_script('return arguments[0]', $elem);
+                  isa_ok($script_elem, 'Selenium::Remote::WebElement', 'execute_script element return');
+                  is($elem->id, $script_elem->id, 'Sync script returns identical WebElement id');
+
+                  my $async = q{
+var callback = arguments[arguments.length - 1];
+callback(arguments[0]);
+};
+                  my $async_elem = $firefox->execute_async_script($async, $elem);
+                  isa_ok($async_elem, 'Selenium::Remote::WebElement', 'execute_async_script element return');
+                  is($elem->id, $async_elem->id, 'Async script returns identical WebElement id');
+              }
+
             $firefox->shutdown_binary;
             $firefox->shutdown_binary;
         }
         }
 
 

文件差异内容过多而无法显示
+ 3 - 4
t/mock-recordings/02-webelement-mock.json


部分文件因为文件数量过多而无法显示