teodesian / Selenium-Remote-Driver

Perl Bindings to the Selenium Webdriver server
173 stars 91 forks source link

executeScript seems broken in 1.23 #367

Closed aaannz closed 6 years ago

aaannz commented 6 years ago

After update to 1.23 version all executeScript calls ends with similar error to this:

Prepping executeScript Executing executeScript REQ: POST, http://10.1.0.4:4444/wd/hub/session/51b2e98b9937fb6e7f0591b28538bd70/execute/sync, {"args":[{"ELEMENT":null,"element-6066-11e4-a52e-4f735466cecf":"0.28720910722599124-1"}],"script":"arguments[0].scrollIntoView(false);"} RES: {"sessionId":"51b2e98b9937fb6e7f0591b28538bd70","status":10,"value":{"message":"stale element reference: element is not attached to the page document\n (Session info: chrome=64.0.3282.140)\n (Driver info: chromedriver=2.33 (0),platform=Linux 4.4.103-6.38-default x86_64)"}}

Fortunately setting $driver->{is_wd3} = 0; avoid this problem, but I'm not sure if it is correct solution. I'm using chrome and chromedriver v64.0.3282.140

teodesian commented 6 years ago

stale element reference: element is not attached to the page document

That means you've found an element which has been removed from the DOM in the time since you found it. Unfortunately, a lot of the newer JS templating frameworks such as angular will sort of strobe the elements (now you see me, now you don't, now you see me) around the time of page load. This can also happen when DOM changes happen around AJAX requests. I get around this personally by adding an error handler that just re-acquires target lock as it were and re-executes.

That said, it could be some kind of quirk to chromedriver I'm not accounting for. Feel free to post me steps to reproduce and I'll be glad to look into it further. The fact that is_wd3 = 0 is fixing your problem certainly makes me suspect it's a chromedriver quirk.

It would be very helpful to know the version of chrome/chromedriver you are using as well.

aaannz commented 6 years ago

You are right about this error being sometimes due to JS templating, however in this case I don't think it is it.

Consider trivial example, have a static html file: index.html:

<html>
        <head>
                <title>test</title>
        </head>
        <body>
                <div id='test'>Test</div>
        </body>
</html>

and this perl source: chrometest.pl

use strict;
use Selenium::Remote::Driver;
use Selenium::Chrome;

my $driver = Selenium::Chrome->new(binary => '/usr/lib64/chromium/chromedriver');
$driver->get('file:///home/aaannz/index.html');
my $el = $driver->find_element_by_xpath('//div');
$driver->execute_script("arguments[0].scrollIntoView(false);", $el);
sleep(5);

Running it produce this error:

perl chrometest.pl
Error while executing command: stale element reference: element is not attached to the page document
  (Session info: chrome=64.0.3282.140)
  (Driver info: chromedriver=2.33 (0),platform=Linux 4.14.15-1-default x86_64) at /usr/lib/perl5/vendor_perl/5.26.1/Selenium/Remote/Driver.pm line 388.
 at /usr/lib/perl5/vendor_perl/5.26.1/Selenium/Remote/Driver.pm line 345.

When I set $driver->{is_wd3} = 0; then all is fine.

rpm -q chromedriver

chromedriver-64.0.3282.140-1.1.x86_64

rpm -q chromium

chromium-64.0.3282.140-1.1.x86_64

teodesian commented 6 years ago

Thank you for the information, I had a feeling this was something strange chromedriver was doing. I'll look into this further today.

teodesian commented 6 years ago

Forgive the tardy reply.

It seems that just passing the old ELEMENT => makes it travel the working old JSONWire code path, even on the latest chromedriver. So, I'm just going to exempt us from using WC3 execute script on chrome. This should obviate the need to set is_wd3=0.

teodesian commented 6 years ago

I'll try and release a new version of the module tonight.