Commit 089c3dde authored by samuong's avatar samuong Committed by Commit bot

[chromedriver] Use center of first ClientRect when moving mouse to an element.

Previously we used the center of the bounding box, but this can cause problems if the center of the bounding box is outside the element.

This CL also changes the behavior of the GetElementLocationOnceScrolledIntoView command in the same way.

BUG=

Review URL: https://codereview.chromium.org/848483002

Cr-Commit-Position: refs/heads/master@{#311423}
parent 41d8d3c2
...@@ -445,7 +445,7 @@ Status ExecuteGetElementLocationOnceScrolledIntoView( ...@@ -445,7 +445,7 @@ Status ExecuteGetElementLocationOnceScrolledIntoView(
scoped_ptr<base::Value>* value) { scoped_ptr<base::Value>* value) {
WebPoint location; WebPoint location;
Status status = ScrollElementIntoView( Status status = ScrollElementIntoView(
session, web_view, element_id, &location); session, web_view, element_id, nullptr, &location);
if (status.IsError()) if (status.IsError())
return status; return status;
value->reset(CreateValueFrom(location)); value->reset(CreateValueFrom(location));
......
...@@ -577,14 +577,21 @@ Status ScrollElementIntoView( ...@@ -577,14 +577,21 @@ Status ScrollElementIntoView(
Session* session, Session* session,
WebView* web_view, WebView* web_view,
const std::string& id, const std::string& id,
const WebPoint* offset,
WebPoint* location) { WebPoint* location) {
WebSize size; WebRect region;
Status status = GetElementSize(session, web_view, id, &size); Status status = GetElementRegion(session, web_view, id, &region);
if (status.IsError()) if (status.IsError())
return status; return status;
return ScrollElementRegionIntoView( status = ScrollElementRegionIntoView(session, web_view, id, region,
session, web_view, id, WebRect(WebPoint(0, 0), size),
false /* center */, std::string(), location); false /* center */, std::string(), location);
if (status.IsError())
return status;
if (offset)
location->Offset(offset->x, offset->y);
else
location->Offset(region.size.width / 2, region.size.height / 2);
return Status(kOk);
} }
Status ScrollElementRegionIntoView( Status ScrollElementRegionIntoView(
......
...@@ -131,6 +131,7 @@ Status ScrollElementIntoView( ...@@ -131,6 +131,7 @@ Status ScrollElementIntoView(
Session* session, Session* session,
WebView* web_view, WebView* web_view,
const std::string& element_id, const std::string& element_id,
const WebPoint* offset,
WebPoint* location); WebPoint* location);
// |element_id| refers to the element which is to be scrolled into view. // |element_id| refers to the element which is to be scrolled into view.
......
...@@ -571,6 +571,29 @@ class ChromeDriverTest(ChromeDriverBaseTest): ...@@ -571,6 +571,29 @@ class ChromeDriverTest(ChromeDriverBaseTest):
self._driver.MouseMoveTo(div, 10, 10) self._driver.MouseMoveTo(div, 10, 10)
self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) self.assertEquals(1, len(self._driver.FindElements('tag name', 'br')))
def testMoveToElementAndClick(self):
self._driver.Load(self.GetHttpUrlForFile('/chromedriver/multiline.html'))
# Check that link element spans two lines and that the first ClientRect is
# above the second.
link = self._driver.FindElements('tag name', 'a')[0]
client_rects = self._driver.ExecuteScript(
'return arguments[0].getClientRects();', link)
self.assertEquals(2, len(client_rects))
self.assertTrue(client_rects[0]['bottom'] < client_rects[1]['top'])
# Check that the center of the link's bounding ClientRect is outside the
# element.
bounding_client_rect = self._driver.ExecuteScript(
'return arguments[0].getBoundingClientRect();', link)
center = bounding_client_rect['left'] + bounding_client_rect['width'] / 2
self.assertTrue(client_rects[1]['right'] < center)
self.assertTrue(center < client_rects[0]['left'])
self._driver.MouseMoveTo(link)
self._driver.MouseClick()
self.assertTrue(self._driver.GetCurrentUrl().endswith('#top'))
def testMouseClick(self): def testMouseClick(self):
div = self._driver.ExecuteScript( div = self._driver.ExecuteScript(
'document.body.innerHTML = "<div>old</div>";' 'document.body.innerHTML = "<div>old</div>";'
......
...@@ -470,22 +470,15 @@ Status ExecuteMouseMoveTo( ...@@ -470,22 +470,15 @@ Status ExecuteMouseMoveTo(
WebPoint location; WebPoint location;
if (has_element) { if (has_element) {
Status status = ScrollElementIntoView( WebPoint offset(x_offset, y_offset);
session, web_view, element_id, &location); Status status = ScrollElementIntoView(session, web_view, element_id,
has_offset ? &offset : nullptr, &location);
if (status.IsError()) if (status.IsError())
return status; return status;
} else { } else {
location = session->mouse_position; location = session->mouse_position;
} if (has_offset)
location.Offset(x_offset, y_offset);
if (has_offset) {
location.Offset(x_offset, y_offset);
} else {
WebSize size;
Status status = GetElementSize(session, web_view, element_id, &size);
if (status.IsError())
return status;
location.Offset(size.width / 2, size.height / 2);
} }
std::list<MouseEvent> events; std::list<MouseEvent> events;
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A multi-line link</title>
</head>
<body>
<p style="max-width: 11em">
This test page contains <a href="#top">a link</a> that spans two lines.
The center of the bounding box of the link is not inside the link element.
</p>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment