mozilla / geckodriver

WebDriver for Firefox
https://firefox-source-docs.mozilla.org/testing/geckodriver/
Mozilla Public License 2.0
7.08k stars 1.52k forks source link

moveToElement(WebElement, xOffset, yOffset).click generate an error but not scroll #1123

Open hqbrice opened 6 years ago

hqbrice commented 6 years ago

System

1500, 150 become 2008,408 because this is computed from the center of the img element.

Page

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Titre</title>
    </head>

    <body>
    <div id="mydiv" style="overflow: scroll;width:1000px; height:500px; border:1px black; solid">
        <img id="thing" src="http://kirupa.com/images/smiley_red.png" style="position:relative; left:50px; right:50px; transition: left .5s ease-in, top .5s ease-in;">
        <img style="width:5444px; height:4083px;"  id=picture= src="http://blogs.sciences-po.fr/prospectibles/files/2014/03/big-data-will-drive-the-next-phase-of-innovation-in-mobile-computing.jpg">

    </div>
    </body>
</html>

<script src="http://kirupa.com/prefixfree.min.js"></script>
<script>
var theThing = document.getElementById("thing");
var container = document.getElementById("mydiv");

container.addEventListener("click", getClickPosition, false);

function getClickPosition(e) {
    var parentPosition = getPosition(e.currentTarget);
    var xPosition = e.clientX - parentPosition.x - (theThing.clientWidth / 2);
    var yPosition = e.clientY - parentPosition.y - (theThing.clientHeight / 2);

    theThing.style.left = xPosition + "px";
    theThing.style.top = yPosition + "px";
}

// Helper function to get an element's exact position
function getPosition(el) {
  var xPos = 0;
  var yPos = 0;

  while (el) {
    if (el.tagName == "BODY") {
      // deal with browser quirks with body/window/document and page scroll
      var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
      var yScroll = el.scrollTop || document.documentElement.scrollTop;

      xPos += (el.offsetLeft - xScroll + el.clientLeft);
      yPos += (el.offsetTop - yScroll + el.clientTop);
    } else {
      // for all other non-BODY elements
      xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
      yPos += (el.offsetTop - el.scrollTop + el.clientTop);
    }

    el = el.offsetParent;
  }
  return {
    x: xPos,
    y: yPos
  };
}
</script>

Testcase

Actions action = new Actions(driver); WebElement pic=webDriver.findElement(By.id("picture")); action.moveToElement(pic, 1500, 150).click().build().perform();

Stacktrace

org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: (2008, 408) is out of bounds of viewport width (1920) and height (966) Build info: version: '3.8.1', revision: '8a0099a', time: '2017-11-06T21:01:39.354Z' System info: host: 'WS-R0-BR01', ip: '10.1.19.157', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_91' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: true, browserName: firefox, browserVersion: 59.0a1, javascriptEnabled: true, moz:accessibilityChecks: false, moz:headless: false, moz:processID: 3104, moz:profile: C:\Users\admin\AppData\Loca..., moz:webdriverClick: true, pageLoadStrategy: normal, platform: XP, platformName: XP, platformVersion: 6.1, rotatable: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}} Session ID: 6f5e3af3-56eb-4bb2-a240-5f20c97db372 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:164) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:600) at org.openqa.selenium.remote.RemoteWebDriver.perform(RemoteWebDriver.java:666) at org.openqa.selenium.interactions.Actions$BuiltAction.perform(Actions.java:638) )

Trace-level log

18:22:56.681 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession@584a90ab
18:22:59.681 INFO - Handler thread for session 6f5e3af3-56eb-4bb2-a240-5f20c97db372 (firefox): Executing POST on /session/6f5e3af3-56eb-4bb2-a240-5f20c97db372/actions (handler: ServicedSession)
18:22:59.681 INFO - To upstream: {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":1500,"y":150,"type":"pointerMove","origin":{"ELEMENT":"ad3f242e-043f
-4019-adef-a63d03b81669","element-6066-11e4-a52e-4f735466cecf":"ad3f242e-043f-4019-adef-a63d03b81669"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]}
1515518579681   webdriver::server       DEBUG   -> POST /session/6f5e3af3-56eb-4bb2-a240-5f20c97db372/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration"
:100,"x":1500,"y":150,"type":"pointerMove","origin":{"ELEMENT":"ad3f242e-043f-4019-adef-a63d03b81669","element-6066-11e4-a52e-4f735466cecf":"ad3f242e-043f-4019-adef-a63d03b81669"}},{"button":0,"type":"pointerDown"},{"but
ton":0,"type":"pointerUp"}]}]}
1515518579697   geckodriver::marionette TRACE   -> 335:[0,31,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"ad3f242e-043f-4019-adef-a63d03b81669"},"type":"pointe
rMove","x":1500,"y":150},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}]
1515518579693   Marionette      TRACE   0 -> [0,31,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"ad3f242e-043f ... pointerDown"},{"button":0,"type":"pointerUp"}
],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}]
1515518579726   Marionette      TRACE   0 <- [1,31,{"error":"move target out of bounds","message":"(2008, 408) is out of bounds of viewport width (1920) and height (966)" ... ch/</req<@chrome://marionette/content/listene
r.js:483:14\ndispatch/<@chrome://marionette/content/listener.js:476:15\n"},null]
1515518579759   geckodriver::marionette TRACE   <- [1,31,{"error":"move target out of bounds","message":"(2008, 408) is out of bounds of viewport width (1920) and height (966)","stacktrace":"WebDriverError@chrome://mario
nette/content/error.js:172:5\nMoveTargetOutOfBoundsError@chrome://marionette/content/error.js:386:5\ndispatchPointerMove/<@chrome://marionette/content/action.js:1325:13\18:22:59.759 INFO - To downstream: {"value":{"error
":"move target out of bounds","message":"(2008, 408) is out of bounds of viewport width (1920) and height (966)","stacktrace":"WebDriverError@chrome://marionette/content/error.js:172:5\nMoveTargetOutOfBoundsError@chrome:
//marionette/content/error.js:386:5\ndispatchPointerMove/<@chrome://marionette/content/action.js:1325:13\ndispatchPointerMove@chrome://marionette/content/action.js:1316:10\ntoEvents/<@chrome://marionette/content/action.j
s:1103:16\naction.dispatchTickActions@chrome://marionette/content/action.js:1013:23\naction.dispatch/chainEvents<@chrome://marionette/content/action.js:981:13\nasync*action.dispatch@chrome://marionette/content/action.js:
979:22\nperformActions@chrome://marionette/content/listener.js:837:9\nasync*dispatch/</req<@chrome://marionette/content/listener.js:483:14\ndispatch/<@chrome://marionette/content/listener.js:476:15\n"}}
ndispatchPointerMove@chrome://marionette/content/action.js:1316:10\ntoEvents/<@chrome://marionette/content/action.js:1103:16\naction.dispatchTickActions@chrome://marionette/content/action.js:1013:23\naction.dispatch/chai
nEvents<@chrome://marionette/content/action.js:981:13\nasync*action.dispatch@chrome://marionette/content/action.js:979:22\nperformActions@chrome://marionette/content/listener.js:837:9\nasync*dispatch/</req<@chrome://mari
onette/content/listener.js:483:14\ndispatch/<@chrome://marionette/content/listener.js:476:15\n"},null]
1515518579759   webdriver::server       DEBUG   <- 500 Internal Server Error {"value":{"error":"move target out of bounds","message":"(2008, 408) is out of bounds of viewport width (1920) and height (966)","stacktrace":"
WebDriverError@chrome://marionette/content/error.js:172:5\nMoveTargetOutOfBoundsError@chrome://marionette/content/error.js:386:5\ndispatchPointerMove/<@chrome://marionette/content/action.js:1325:13\ndispatchPointerMove@c
hrome://marionette/content/action.js:1316:10\ntoEvents/<@chrome://marionette/content/action.js:1103:16\naction.dispatchTickActions@chrome://marionette/content/action.js:1013:23\naction.dispatch/chainEvents<@chrome://mari
onette/content/action.js:981:13\nasync*action.dispatch@chrome://marionette/content/action.js:979:22\nperformActions@chrome://marionette/content/listener.js:837:9\nasync*dispatch/</req<@chrome://marionette/content/listene
r.js:483:14\ndispatch/<@chrome://marionette/content/listener.js:476:15\n"}}
andreastt commented 6 years ago

Judging by the error message (2008, 408) is out of bounds of viewport width (1920) and height (966), I’m not sure this is a geckodriver bug. The X coordinate 2008 is larger than the viewport’s width, which means the pointer can’t be positioned there.

Am I missing anything?

hqbrice commented 6 years ago

Possible : 1920x966 seems to match with the resolution screen, The div width is 1000 but the picture inside width is 5444. I need click on picture at x=1500 (this is hidden by scroll but reachable).

On FF 57 this scroll the div.

Else, how can I click on picture at x = 1500 ? Thanks

hqbrice commented 6 years ago

Of course, even if I scroll manually to xOffset = 1500 on the screen, the exception is thrown

whimboo commented 6 years ago

@hqbrice can you please also check the latest Firefox 58 beta if it also misbehaves? If there is a real regression we might still have the time to get this fixed.

whimboo commented 6 years ago

I can reproduce and as it looks like this is caused by https://bugzilla.mozilla.org/show_bug.cgi?id=1393831. I will file a bug for that. Thanks for reporting!

whimboo commented 6 years ago

I filed the regression bug as https://bugzilla.mozilla.org/show_bug.cgi?id=1429338. CC @mjzffr

hqbrice commented 6 years ago

I also tried on V58 with 0,0, it's easier to get coordonate. So, contrary to what is saied in javadoc, Gecko compute coordinate from the center of the element where Chrome Driver from top left corner.

When I try 0,0 (the center of the picture), I wait click on 2722 and 2041,5 from top left but click is at 3267.5 and 2053.5. You are right, it looks like a bad coordinates computing.

Now, I wait V59 release to use doubleclic and regression fixing.

Thanks

whimboo commented 6 years ago

Hm, sounds like this is related to https://github.com/w3c/webdriver/issues/1171, and that we cannot return to top/left? @andreastt am I right, and this is an expected behavior now?

andreastt commented 6 years ago

Yes, the default for the pointerMove action is the centre point of the element as far as I know, and we can’t change that now because it is in the specification and in implementations… I believe @mjzffr has better insight than me on this matter.

hqbrice commented 6 years ago

If you change this now, many users will be impacted... There is a contradiction into the Actions class of selenium (org.openqa.selenium.interactions.Actions). The Javadoc says "Moves the mouse to an offset from the top-left corner of the element." but there is a log info which says LOG.info("When using the W3C Action commands, offsets are from the center of element");

May be the Chrome driver has to update their method. I have also open an issue for a problem like this one, but no answer for 2 days...

whimboo commented 6 years ago

AFAIK the chrome driver still doesn't use the webdriver spec implementation by default. There should be a separate flag for it.

hqbrice commented 6 years ago

Chrome driver seems late... Unfortunately

whimboo commented 6 years ago

For now we backed out the changes from bug 1393831 for Firefox 58. It means the old behavior should be back with the next beta release. @hqbrice would you mind moving further discussion to https://bugzilla.mozilla.org/show_bug.cgi?id=1429338 in case you want to create an account on Bugzilla? If not we will have to continue on this issue.

We will have some questions in a bit...

whimboo commented 6 years ago

@hqbrice for now I would like to know which selenium binding you are using. And would you mind to run the following test just with your binding? https://bug1429338.bmoattachments.org/attachment.cgi?id=8941588 A tracelog from that execution would be kinda appreciated. Thanks.

hqbrice commented 6 years ago

No, you can move the discussion to bugzilla

hqbrice commented 6 years ago

What do you need by " which selenium binding " ? I use Selenium standalone and giving the geckodriver path. And instance driver by : DesiredCapabilities capability = new DesiredCapabilities(); capability.setBrowserName(navigateur.toString()); FirefoxOptions firefoxOptions = new FirefoxOptions(); firefoxOptions.setLogLevel(FirefoxDriverLogLevel.TRACE); if (isTestEnv()) {firefoxOptions.addArguments("--headless");} capability.setCapability(FirefoxOptions.FIREFOX_OPTIONS, firefoxOptions); WebDriver webDriver = new RemoteWebDriver(new URL(url), capability);

On V58 : action.moveToElement(pic).click().perform(); --> click on element, but red circle doesn't move

action.moveToElement(pic, 0, 0).click().perform(); --> click on element when the center of the picture is visible but the click does not happen at center

whimboo commented 6 years ago

Which language is that? Java, C#, ...

whimboo commented 6 years ago

Also please attach a tracelevel log from the code you run in the last comment. Thanks.

whimboo commented 6 years ago

Oh, and as best use my example testcase as referenced above on Bugzilla.

hqbrice commented 6 years ago

Language is Java This ar 3 logs 1) action.moveToElement(pic).click().perform(); 14:29:50.279 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession@18d6145d 14:29:50.279 INFO - Handler thread for session 2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b (firefox): Executing POST on /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions (handler: ServicedSession) 14:29:50.311 INFO - To upstream: {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f -859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]} 1515677390311 webdriver::server DEBUG -> POST /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration" :100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button": 0,"type":"pointerUp"}]}]} 1515677390326 geckodriver::marionette TRACE -> 330:[0,34,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"},"type":"pointe rMove","x":0,"y":0},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677390321 Marionette TRACE 0 -> [0,34,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f ... pointerDown"},{"button":0,"type":"pointerUp"} ],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677390501 Marionette TRACE 0 <- [1,34,null,{}] 1515677390514 geckodriver::marionette TRACE <- [1,34,null,{}] 1515677390514 webdriver::server DEBUG <- 200 OK {"value": {}} 14:29:50.514 INFO - To downstream: {"value": {}} 2) action.moveToElement(pic, 0, 0).click().perform(); when picture isn't scrolled at center 14:30:13.955 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession@18d6145d 14:30:13.955 INFO - Handler thread for session 2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b (firefox): Executing POST on /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions (handler: ServicedSession) 14:30:13.955 INFO - To upstream: {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f -859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]} 1515677413955 webdriver::server DEBUG -> POST /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration" :100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button": 0,"type":"pointerUp"}]}]} 1515677413971 geckodriver::marionette TRACE -> 330:[0,35,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"},"type":"pointe rMove","x":0,"y":0},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677413972 Marionette TRACE 0 -> [0,35,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f ... pointerDown"},{"button":0,"type":"pointerUp"} ],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677414131 Marionette TRACE 0 <- [1,35,null,{}] 1515677414142 geckodriver::marionette TRACE <- [1,35,null,{}] 1515677414142 webdriver::server DEBUG <- 200 OK {"value": {}} 3) action.moveToElement(pic, 0, 0).click().perform(); when picture is scrolled at center 14:31:04.097 INFO - Found handler: org.openqa.selenium.remote.server.ServicedSession@18d6145d 14:31:04.097 INFO - Handler thread for session 2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b (firefox): Executing POST on /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions (handler: ServicedSession) 14:31:04.175 INFO - To upstream: {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f -859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]} 1515677464191 webdriver::server DEBUG -> POST /session/2a6fbd7f-34a8-492d-b55a-d7bcc4469c9b/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration" :100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354","element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"}},{"button":0,"type":"pointerDown"},{"button": 0,"type":"pointerUp"}]}]} 1515677464191 geckodriver::marionette TRACE -> 330:[0,37,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f-4e3f-859d-1f0aaf798354"},"type":"pointe rMove","x":0,"y":0},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677464189 Marionette TRACE 0 -> [0,37,"performActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"4f2bd04c-b14f ... pointerDown"},{"button":0,"type":"pointerUp"} ],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}] 1515677464445 Marionette TRACE 0 <- [1,37,null,{}] 1515677464456 geckodriver::marionette TRACE <- [1,37,null,{}] 1515677464456 webdriver::server DEBUG <- 200 OK {"value": {}}

mjzffr commented 6 years ago

FYI https://bugzilla.mozilla.org/show_bug.cgi?id=1429338#c4