Bug 937053 - tap() method should calculate elementInView from the coordinates of the tap. r=mdas

This commit is contained in:
Dave Hunt 2014-10-16 10:32:00 +02:00
Родитель 8af6a16821
Коммит 6aed832e63
3 изменённых файлов: 83 добавлений и 12 удалений

Просмотреть файл

@ -77,6 +77,31 @@ class TestClickScrolling(MarionetteTestCase):
# If we dont throw we are good
self.marionette.find_element(By.ID, "radio").click()
def test_should_scroll_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
test_html = self.marionette.absolute_url("element_outside_viewport.html")
for s in ["top", "bottom"]:
self.marionette.navigate(test_html)
scroll_y = self.marionette.execute_script("return window.scrollY;")
self.marionette.find_element(By.ID, "%s-70" % s).click()
self.assertNotEqual(scroll_y, self.marionette.execute_script("return window.scrollY;"))
for s in ["left", "right"]:
self.marionette.navigate(test_html)
scroll_x = self.marionette.execute_script("return window.scrollX;")
self.marionette.find_element(By.ID, "%s-70" % s).click()
self.assertNotEqual(scroll_x, self.marionette.execute_script("return window.scrollX;"))
def test_should_not_scroll_elements_if_click_point_is_in_view(self):
test_html = self.marionette.absolute_url("element_outside_viewport.html")
for s in ["top", "right", "bottom", "left"]:
for p in ["50", "30"]:
self.marionette.navigate(test_html)
scroll = self.marionette.execute_script("return [window.scrollX, window.scrollY];")
self.marionette.find_element(By.ID, "%s-%s" % (s, p)).click()
self.assertEqual(scroll, self.marionette.execute_script("return [window.scrollX, window.scrollY];"))
@skip("Bug 1003687")
def test_should_scroll_overflow_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
test_html = self.marionette.absolute_url("scroll5.html")

Просмотреть файл

@ -0,0 +1,41 @@
<!DOCTYPE html>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
}
.top { background-color: red; }
#top-70 { left: 80px; top: 0; }
#top-50 { left: 190px; top: 20px; }
#top-30 { left: 300px; top: 40px; }
.right { background-color: black; }
#right-70 { top: 80px; right: -140px;}
#right-50 { top: 190px; right: -120px;}
#right-30 { top: 300px; right: -100px;}
.bottom { background-color: blue; }
#bottom-70 { right: -50px; bottom: -140px; }
#bottom-50 { right: 60px; bottom: -120px; }
#bottom-30 { right: 170px; bottom: -100px; }
.left { background-color: green; }
#left-70 { bottom: -50px; left: 0; }
#left-50 { bottom: 60px; left: 20px; }
#left-30 { bottom: 170px; left: 40px; }
</style>
<body onload="window.scrollTo(70, 70);">
<div id="top-70" class="top"></div>
<div id="top-50" class="top"></div>
<div id="top-30" class="top"></div>
<div id="right-70" class="right"></div>
<div id="right-50" class="right"></div>
<div id="right-30" class="right"></div>
<div id="bottom-70" class="bottom"></div>
<div id="bottom-50" class="bottom"></div>
<div id="bottom-30" class="bottom"></div>
<div id="left-70" class="left"></div>
<div id="left-50" class="left"></div>
<div id="left-30" class="left"></div>
</body>

Просмотреть файл

@ -779,24 +779,29 @@ function coordinates(target, x, y) {
}
/**
* This function returns if the element is in viewport
* This function returns true if the given coordinates are in the viewport.
* @param 'x', and 'y' are the coordinates relative to the target.
* If they are not specified, then the center of the target is used.
*/
function elementInViewport(el) {
let rect = el.getBoundingClientRect();
function elementInViewport(el, x, y) {
let c = coordinates(el, x, y);
let viewPort = {top: curFrame.pageYOffset,
left: curFrame.pageXOffset,
bottom: (curFrame.pageYOffset + curFrame.innerHeight),
right:(curFrame.pageXOffset + curFrame.innerWidth)};
return (viewPort.left <= rect.right + curFrame.pageXOffset &&
rect.left + curFrame.pageXOffset <= viewPort.right &&
viewPort.top <= rect.bottom + curFrame.pageYOffset &&
rect.top + curFrame.pageYOffset <= viewPort.bottom);
return (viewPort.left <= c.x + curFrame.pageXOffset &&
c.x + curFrame.pageXOffset <= viewPort.right &&
viewPort.top <= c.y + curFrame.pageYOffset &&
c.y + curFrame.pageYOffset <= viewPort.bottom);
}
/**
* This function throws the visibility of the element error
* This function throws the visibility of the element error if the element is
* not displayed or the given coordinates are not within the viewport.
* @param 'x', and 'y' are the coordinates relative to the target.
* If they are not specified, then the center of the target is used.
*/
function checkVisible(el) {
function checkVisible(el, x, y) {
//check if the element is visible
let visible = utils.isElementDisplayed(el);
if (!visible) {
@ -805,7 +810,7 @@ function checkVisible(el) {
if (el.tagName.toLowerCase() === 'body') {
return true;
}
if (!elementInViewport(el)) {
if (!elementInViewport(el, x, y)) {
//check if scroll function exist. If so, call it.
if (el.scrollIntoView) {
el.scrollIntoView(false);
@ -934,14 +939,14 @@ function singleTap(msg) {
try {
let el = elementManager.getKnownElement(msg.json.id, curFrame);
// after this block, the element will be scrolled into view
if (!checkVisible(el)) {
if (!checkVisible(el, msg.json.corx, msg.json.cory)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
if (!curFrame.document.createTouch) {
mouseEventsOnly = true;
}
let c = coordinates(el, msg.json.corx, msg.json.cory);
c = coordinates(el, msg.json.corx, msg.json.cory);
generateEvents('tap', c.x, c.y, null, el);
sendOk(msg.json.command_id);
}