ericmckean / chromedriver

Automatically exported from code.google.com/p/chromedriver
0 stars 0 forks source link

Chromedriver 2.14 cannot find the middle of an element due to its use of getClientRects #1069

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
** Versions

Chromedriver version: 2.14
Selenium version: 2.45.0
Browser: Chrome 41, 39
OS: Irrelevant (reproduced on Debian testing up to date as of 2015/3/26, OS X 
10.9, Windows 8.1, etc.)

** What steps will reproduce the problem?

1. Download the `issue.py` file. It reproduces the problem 100% of the time 
here.

2. If you have Chrome 41 and chromedriver 2.14 installed locally, make sure 
they are accessible to the script, and run:

    python ./issue.py

  If somehow your local machine cannot handle it or you want to check other platforms and you have a Sauce Labs account you can run the script as:

    python ./issue.py sauce-user-id:sauce-key

where `sauce-user-id` is your user id at Sauce Labs and `sauce-key` is the key 
you use to run remote tests.

** What is the expected output?

After the dump of platform name, driver name and browser version, this is what 
should come up. The important part is that "Log:" should contain the text 
'titleabcdtitle2':

Client rects before [{u'right': 29, u'bottom': 25, u'top': 8, u'height': 17, 
u'width': 21, u'left': 8}, {u'right': 59, u'bottom': 25, u'top': 8, u'height': 
17, u'width': 30, u'left': 29}, {u'right': 88, u'bottom': 25, u'top': 8, 
u'height': 17, u'width': 29, u'left': 59}]
Log: [u'titleabcdtitle2']
Client rects after [{u'right': 88, u'bottom': 25, u'top': 8, u'height': 17, 
u'width': 80, u'left': 8}]

The output above is actually what I get when running with chromedriver 2.13.

** What do you see instead?

Client rects before [{u'right': 29, u'bottom': 25, u'top': 8, u'height': 17, 
u'width': 21, u'left': 8}, {u'right': 59, u'bottom': 25, u'top': 8, u'height': 
17, u'width': 30, u'left': 29}, {u'right': 88, u'bottom': 25, u'top': 8, 
u'height': 17, u'width': 29, u'left': 59}]
Log: [u'title']
Client rects after [{u'right': 88, u'bottom': 25, u'top': 8, u'height': 17, 
u'width': 80, u'left': 8}]

What happens here is that instead of clicking in the middle of the element that 
I requested (the element with the id "title"), Selenium clicks in the middle of 
the first <span> inside the element I requested.

** Observations

1. The specification for `click` is here:

https://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/interactio
ns/Actions.html#click-org.openqa.selenium.WebElement-

  It states "Equivalent to: Actions.moveToElement(onElement).click()"

  The specification for `moveToElement` is here:

https://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/interactio
ns/Actions.html#moveToElement-org.openqa.selenium.WebElement-

  It states "Moves the mouse to the middle of the element. The element is scrolled into view and its location is calculated using **getBoundingClientRect**." (Emphasis mine.)

  Chromedriver is ignoring Selenium's documentation by using getClientRects. Whatever faults getBoundingClientRect may have, the fact of the matter is that a developer who has read the documentation will be able to anticipate how Selenium will behave and work around those cases where Selenium may not behave well because getBoundingClientRect gives a misleading middle point. The use of getClientRects instead of getBoundingClientRect makes it so that the documentation is no longer helpful in determining how Selenium will perform an action.

2. I found nothing in the specification of getClientRects that indicates that a 
browser **must** return a single rectangle if it is **possible** to return a 
single rectangle. In other words, there is nothing that indicates that the 
initial 3 rectangles returned by getClientRects is an incorrect result.

3. The 3 rectangles initially returned by getClientRects have the same top and 
bottom coordinates and are immediately adjacent to one another.

4. For some reason, changing the color of the element with 
`arguments[0].style.backgroundColor = 'blue';` is enough to trigger something 
in Chrome that makes it so that the next call to getClientRects returns a 
combined rectangle.

Original issue reported on code.google.com by avaktav...@gmail.com on 26 Mar 2015 at 8:19

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by samu...@chromium.org on 2 Apr 2015 at 10:19