Bug 857582 - send mouse events if we can't send touch events, r=jgriffin

This commit is contained in:
Malini Das 2013-05-27 13:12:13 -04:00
parent 38e0ff4e07
commit a62ee3c399
18 changed files with 635 additions and 987 deletions

View File

@ -479,10 +479,6 @@ class Marionette(object):
response = self._send_message('setSearchTimeout', 'ok', value=timeout)
return response
def send_mouse_event(self, send):
response = self._send_message('sendMouseEvent', 'ok', value=send)
return response
@property
def current_window_handle(self):
self.window = self._send_message('getWindow', 'value')

View File

@ -159,6 +159,15 @@ class MarionetteTestCase(CommonTestCase):
qemu = self.marionette.extra_emulators[self.extra_emulator_index]
return qemu
def wait_for_condition(self, method, timeout=30):
timeout = float(timeout) + time.time()
while time.time() < timeout:
value = method(self.marionette)
if value:
return value
time.sleep(0.5)
else:
raise TimeoutException("wait_for_condition timed out")
class MarionetteJSTestCase(CommonTestCase):

View File

@ -31,11 +31,10 @@ class MarionetteTouchMixin(object):
self.execute_script("%s.tap(arguments[0], null, null, null, null, arguments[1]);" % self.library_name, [element, send_all])
def double_tap(self, element):
self.check_element(element)
self.execute_script("%s.dbltap(arguments[0]);" % self.library_name, [element])
action = Actions(self)
action.double_tap(element).perform()
def flick(self, element, x1, y1, x2, y2, duration=200):
self.check_element(element)
action = Actions(self)
action.flick(element, x1, y1, x2, y2, duration).perform()

View File

@ -0,0 +1,102 @@
from marionette import Actions
def press_release(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element("id", "button1")
action.press(button).release().perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def move_element(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element("id", "button1")
drop = marionette.find_element("id", "button2")
action = Actions(marionette)
action.press(ele).move(drop).release()
action.perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button2').innerHTML;"))
def move_element_offset(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(ele).move_by_offset(0,150).move_by_offset(0, 150).release()
action.perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button2').innerHTML;"))
def chain(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
marionette.set_search_timeout(15000)
action = Actions(marionette)
button1 = marionette.find_element("id", "button1")
action.press(button1).perform()
button2 = marionette.find_element("id", "delayed")
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
action.move(button2).release().perform()
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('delayed').innerHTML;"))
def chain_flick(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.flick(button, 0, 0, 0, 200).perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('buttonFlick').innerHTML;"))
def wait(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element("id", "button1")
action.press(button).wait().release().perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def wait_with_value(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(button).wait(0.01).release()
action.perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def context_menu(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(button).wait(5).perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
action.release().perform()
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button1').innerHTML;"))
def long_press_action(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.long_press(button, 5).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def single_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.tap(button).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def double_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.double_tap(button).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))

View File

@ -0,0 +1,32 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_test import MarionetteTestCase
from errors import MarionetteException
class testElementTouch(MarionetteTestCase):
def test_touch(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
button.tap()
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
button.tap(0, 300)
expected = "button2-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button2').innerHTML;") == expected)
def test_invisible(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
ele = self.marionette.find_element("id", "hidden")
self.assertRaises(MarionetteException, ele.tap)
def test_scrolling(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
ele = self.marionette.find_element("id", "buttonScroll")
ele.tap()
expected = "buttonScroll-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('buttonScroll').innerHTML;") == expected)

View File

@ -2,22 +2,35 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from gestures import smooth_scroll, pinch
class testGestures(MarionetteTestCase):
check_in_viewport = """
function elementInViewport(el) {
let rect = el.getBoundingClientRect();
return (rect.top >= window.pageYOffset &&
rect.left >= window.pageXOffset &&
rect.bottom <= (window.pageYOffset + window.innerHeight) &&
rect.right <= (window.pageXOffset + window.innerWidth)
);
};
"""
def test_smooth_scroll(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
smooth_scroll(self.marionette, button, "y", -1, 250)
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button2")
self.assertFalse(self.marionette.execute_script("%s; return elementInViewport(document.getElementById('buttonScroll'));" % self.check_in_viewport))
smooth_scroll(self.marionette, button, "y", -1, 800)
buttonScroll = self.marionette.find_element("id", "buttonScroll")
self.wait_for_condition(lambda m: m.execute_script("%s; return elementInViewport(arguments[0]);" % self.check_in_viewport, [buttonScroll]) == True)
self.assertEqual("button2-touchstart", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
"""
#This test doesn't manipulate the page, filed Bug 870377 about it.
def test_pinch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
pinch(self.marionette, button, 0, 0, 0, 0, 0, -50, 0, 50)
time.sleep(15)
"""

View File

@ -2,7 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import Marionette
from marionette_touch import MarionetteTouchMixin
@ -13,28 +12,45 @@ class TestTouchMixin(MarionetteTestCase):
super(TestTouchMixin, self).setUp()
self.marionette.__class__ = type('Marionette', (Marionette, MarionetteTouchMixin), {})
self.marionette.setup_touch()
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
def tap(self):
button = self.marionette.find_element("id", "button1")
self.marionette.tap(button)
def double_tap(self):
button = self.marionette.find_element("id", "button1")
self.marionette.double_tap(button)
def test_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
self.marionette.tap(button)
time.sleep(10)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
self.tap()
expected = "button1-touchstart-touchend-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
def test_dbtap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozMouse")
self.marionette.double_tap(button)
time.sleep(10)
self.assertEqual("TouchEnd2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_tap_mouse_shim(self):
self.marionette.execute_script("window.wrappedJSObject.MouseEventShim = 'mock value';")
self.tap()
expected = "button1-touchstart-touchend"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
def test_double_tap(self):
self.double_tap()
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
#Enable this when we have logic in double_tap to handle the shim
def test_double_tap_mouse_shim(self):
self.marionette.execute_script("window.wrappedJSObject.MouseEventShim = 'mock value';")
self.double_tap()
expected = "button1-touchstart-touchend-touchstart-touchend"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
def test_flick(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
self.marionette.flick(button, 0, 0, 0, -250)
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
self.assertEqual("Start", self.marionette.execute_script("return document.getElementById('mozLinkScrollStart').innerHTML;"))
button = self.marionette.find_element("id", "button1")
self.marionette.flick(button, 0, 0, 0, 200)
expected = "button1-touchstart-touchmove"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("buttonFlick-touchmove-touchend", self.marionette.execute_script("return document.getElementById('buttonFlick').innerHTML;"))

View File

@ -2,61 +2,64 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import MultiActions, Actions
class testSingleFinger(MarionetteTestCase):
class testMultiFinger(MarionetteTestCase):
def test_move_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start = self.marionette.find_element("id", "mozLink")
drop = self.marionette.find_element("id", "mozLinkPos")
ele = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start = self.marionette.find_element("id", "button1")
drop = self.marionette.find_element("id", "button2")
ele = self.marionette.find_element("id", "button3")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action1.press(start).move(drop).wait(3).release()
action2.press(ele).wait().release()
multi_action.add(action1).add(action2).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
self.assertIn("button3-touchstart-touchend", self.marionette.execute_script("return document.getElementById('button3').innerHTML;"))
def test_move_offset_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start = self.marionette.find_element("id", "mozLink")
ele = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start = self.marionette.find_element("id", "button1")
ele = self.marionette.find_element("id", "button3")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action1.press(start).move_by_offset(0,300).wait().release()
action2.press(ele).wait(5).release()
multi_action.add(action1).add(action2).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
self.assertIn("button3-touchstart-touchend", self.marionette.execute_script("return document.getElementById('button3').innerHTML;"))
def test_three_fingers(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start_one = self.marionette.find_element("id", "mozLink")
start_two = self.marionette.find_element("id", "mozLinkStart")
drop_two = self.marionette.find_element("id", "mozLinkEnd")
ele = self.marionette.find_element("id", "mozLinkCopy2")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start_one = self.marionette.find_element("id", "button1")
start_two = self.marionette.find_element("id", "button2")
element1 = self.marionette.find_element("id", "button3")
element2 = self.marionette.find_element("id", "button4")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action3 = Actions(self.marionette)
action1.press(start_one).move_by_offset(0,300).release()
action2.press(ele).wait().wait(5).release()
action3.press(start_two).move(drop_two).wait(2).release()
action2.press(element1).wait().wait(5).release()
action3.press(element2).wait().wait().release()
multi_action.add(action1).add(action2).add(action3).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertTrue(self.marionette.execute_script("return document.getElementById('mozLinkCopy2').innerHTML >= 5000;"))
self.assertTrue(self.marionette.execute_script("return document.getElementById('mozLinkEnd').innerHTML >= 5000;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
button3_text = self.marionette.execute_script("return document.getElementById('button3').innerHTML;")
button4_text = self.marionette.execute_script("return document.getElementById('button4').innerHTML;")
self.assertIn("button3-touchstart-touchend", button3_text)
self.assertIn("button4-touchstart-touchend", button4_text)
self.assertTrue(int(button3_text.rsplit("-")[-1]) >= 5000)
self.assertTrue(int(button4_text.rsplit("-")[-1]) >= 5000)

View File

@ -2,210 +2,83 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import Actions
from errors import NoSuchElementException, MarionetteException
from errors import MarionetteException
#add this directory to the path
import os
import sys
sys.path.append(os.path.dirname(__file__))
from single_finger_functions import *
class testSingleFinger(MarionetteTestCase):
def test_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.press(button).wait(0.2).release()
action.perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
def test_press_release(self):
press_release(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_move_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "mozLink")
drop = self.marionette.find_element("id", "mozLinkPos")
action = Actions(self.marionette)
action.press(ele).move(drop).release()
action.perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
move_element(self.marionette, self.wait_for_condition, "button1-touchstart", "button2-touchmove-touchend")
"""
#Skipping due to Bug 874914
def test_move_by_offset(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "mozLink")
action = Actions(self.marionette)
action.press(ele).move_by_offset(0,150).move_by_offset(0,150).release()
action.perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
def test_chain(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
action = Actions(self.marionette)
button1 = self.marionette.find_element("id", "mozLinkCopy2")
action.press(button1).perform()
button2 = self.marionette.find_element("id", "delayed")
time.sleep(5)
action.move(button2).release().perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('delayed').innerHTML;"))
move_element_offset(self.marionette, self.wait_for_condition, "button1-touchstart", "button2-touchmove-touchend")
"""
def test_no_press(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
action = Actions(self.marionette)
action.release()
self.assertRaises(NoSuchElementException, action.perform)
self.assertRaises(MarionetteException, action.perform)
def test_mouse_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait().release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_wait(self):
wait(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_wait_more(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait(0.1).release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_wait_with_value(self):
wait_with_value(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_no_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_no_mouse_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait().release().perform()
time.sleep(15)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_no_mouse_no_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).release().perform()
time.sleep(15)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_long_press(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.press(button).wait(5).perform()
time.sleep(10)
self.assertEqual("Context", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
action.release().perform()
time.sleep(10)
self.assertEqual("ContextEnd", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
def test_context_menu(self):
context_menu(self.marionette, self.wait_for_condition, "button1-touchstart-contextmenu", "button1-touchstart-contextmenu-touchend")
def test_long_press_action(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.long_press(button, 5).perform()
time.sleep(10)
self.assertEqual("ContextEnd", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
long_press_action(self.marionette, self.wait_for_condition, "button1-touchstart-contextmenu-touchend")
"""
#Skipping due to Bug 865334
def test_long_press_fail(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1Copy")
action = Actions(self.marionette)
action.press(button).long_press(button, 5)
self.assertRaises(MarionetteException, action.perform)
"""
def test_wrong_value(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.assertRaises(MarionetteException, self.marionette.send_mouse_event, "boolean")
def test_chain(self):
chain(self.marionette, self.wait_for_condition, "button1-touchstart", "delayed-touchmove-touchend")
"""
#Skipping due to Bug 874914. Flick uses chained moveByOffset calls
def test_chain_flick(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
action = Actions(self.marionette)
action.flick(button, 0, 0, 0, -250).perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
self.assertEqual("Start", self.marionette.execute_script("return document.getElementById('mozLinkScrollStart').innerHTML;"))
chain_flick(self.marionette, self.wait_for_condition, "button1-touchstart-touchmove", "buttonFlick-touchmove-touchend")
"""
"""
#Skipping due to Bug 865334
def test_touchcancel_chain(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCancel")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
action = Actions(self.marionette)
action.press(button).wait(5).cancel()
action.perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCancel').innerHTML;"))
expected = "button1-touchstart-touchcancel"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
def test_mouse_single_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.tap(button).perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_single_tap(self):
single_tap(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_double_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.double_tap(button).perform()
time.sleep(15)
self.assertEqual("MouseClick2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_double_tap(self):
double_tap(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_touch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.tap(button).perform()
time.sleep(10)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_dbtouch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.double_tap(button).perform()
time.sleep(10)
self.assertEqual("TouchEnd2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))

View File

@ -0,0 +1,98 @@
from marionette_test import MarionetteTestCase
from marionette import Actions
from errors import MarionetteException
#add this directory to the path
import os
import sys
sys.path.append(os.path.dirname(__file__))
from single_finger_functions import *
class testSingleFingerMouse(MarionetteTestCase):
def setUp(self):
super(MarionetteTestCase, self).setUp()
# set context menu related preferences needed for some tests
self.marionette.set_context("chrome")
self.enabled = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = false;
try {
value = prefs.getBoolPref("ui.click_hold_context_menus");
}
catch (e) {}
prefs.setBoolPref("ui.click_hold_context_menus", true);
return value;
""")
self.wait_time = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = 750;
try {
value = prefs.getIntPref("ui.click_hold_context_menus.delay");
}
catch (e) {}
prefs.setIntPref("ui.click_hold_context_menus.delay", value);
return value;
""")
self.marionette.set_context("content")
def tearDown(self):
self.marionette.set_context("chrome")
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setBoolPref("ui.click_hold_context_menus", arguments[0]);
""", [self.enabled])
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]);
""", [self.wait_time])
self.marionette.set_context("content")
super(MarionetteTestCase, self).tearDown()
def test_press_release(self):
press_release(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_move_element(self):
move_element(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_move_by_offset(self):
move_element_offset(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_wait(self):
wait(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_wait_with_value(self):
wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_context_menu(self):
context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click")
def test_long_press_action(self):
long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click")
"""
//Skipping due to Bug 865334
def test_long_press_fail(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1Copy")
action = Actions(self.marionette)
action.press(button).long_press(button, 5)
assertRaises(MarionetteException, action.perform)
"""
def test_chain(self):
chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup")
def test_chain_flick(self):
chain_flick(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mousemove", "buttonFlick-mousemove-mouseup")
def test_single_tap(self):
single_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_double_tap(self):
double_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click-mousemove-mousedown-mouseup-click")

View File

@ -1,26 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import HTMLElement
class testSingleFinger(MarionetteTestCase):
def test_mouse_single_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
button.tap()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_touch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
button.tap()
time.sleep(10)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))

View File

@ -1,35 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import time
from marionette_test import MarionetteTestCase
from marionette import HTMLElement
from errors import MarionetteException
class testTouch(MarionetteTestCase):
def test_touch(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLink")
button.tap(0, 300)
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
button.tap()
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
def test_invisible(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "testh2")
self.assertRaises(MarionetteException, ele.tap)
def test_scrolling(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "scroll")
ele.tap()
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('scroll').innerHTML;"))

View File

@ -11,9 +11,6 @@ b2g = true
; true if the test should be skipped
skip = false
; true if the test requires unagi
unagi = false
[test_getstatus.py]
[test_import_script.py]
[test_import_script_content.py.py]
@ -46,14 +43,13 @@ b2g = false
[test_timeouts.py]
b2g = false
[test_touch.py]
[test_element_touch.py]
b2g = true
browser = false
[test_gesture.py]
b2g = true
browser = false
unagi = true
[test_marionette_touch.py]
b2g = true
@ -62,15 +58,13 @@ browser = false
[test_single_finger.py]
b2g = true
browser = false
[test_single_finger_desktop.py]
b2g = false
[test_multi_finger.py]
b2g = true
browser = false
[test_tap.py]
b2g = true
browser = false
[test_simpletest_pass.js]
[test_simpletest_sanity.py]
[test_simpletest_chrome.js]

View File

@ -5,259 +5,90 @@
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
<title>Marionette Test</title>
</head>
<body>
<h1 id="testh1">Test Page</h1>
<!-- "mozLink" and "mozLinkPos" work together to perform touchdown on mozLink, vertical move and then touchup on mozLinkPos-->
<button id="mozLink" style="position:absolute;left:0px;top:55px;" type="button" allowevents=true>Button1</button>
<button id="mozLinkPos" style="position:absolute;left:0px;top:355px;" type="button" allowevents=true>Button2</button>
<!-- "mozLinkCopy" listens for a touchdown and touchup -->
<button id="mozLinkCopy" style="position:absolute;left:0px;top:455px;" type="button" allowevents=true>Button3</button>
<!-- "mozLinkScroll" listens for scroll -->
<button id="mozLinkScroll" style="position:absolute;left:0px;top:655px;" type="button" allowevents=true>Button8</button>
<!-- "mozLinkScrollStart" listens for scroll -->
<button id="mozLinkScrollStart" style="position:absolute;left:0px;top:405px;" type="button" allowevents=true>Button9</button>
<!-- "mozLinkStart" and "mozLinkEnd" work together to perform touchdown on mozLinkStart, horizontal move and then touchup on mozLinkEnd -->
<button id="mozLinkStart" style="position:absolute;left:10px;top:200px;" type="button" allowevents=true>Press</button>
<button id="mozLinkEnd" style="position:absolute;left:140px;top:200px;" type="button" allowevents=true>Release</button>
<!-- "mozLinkCopy2" listens for a touchdown and touchup. It shows the time when it's fired-->
<button id="mozLinkCopy2" style="position:absolute;left:80px;top:455px;" type="button" allowevents=true>Button4</button>
<!-- "mozLinkCancel" listens for a touchdown and touchcancel -->
<button id="mozLinkCancel" style="position:absolute;left:0px;top:255px;" type="button" allowevents=true>Button5</button>
<!-- "mozMouse" listens for mouse events -->
<button id="mozMouse" style="position:absolute;left:0px;top:305px;" type="button" allowevents=true>Button7</button>
<button id="button1" style="position:absolute;left:0px;top:55px;" type="button" allowevents=true>button1</button>
<button id="button2" style="position:absolute;left:0px;top:355px;" type="button" allowevents=true>button2</button>
<button id="button3" style="position:absolute;left:0px;top:455px;" type="button" allowevents=true>button3</button>
<button id="button4" style="position:absolute;left:100px;top:455px;" type="button" allowevents=true>button4</button>
<button id="buttonScroll" style="position:absolute;left:100px;top:855px;" type="button" allowevents=true>buttonScroll</button>
<h2 id="hidden" style="visibility: hidden" class="linkClass">Hidden</h2>
<button id="buttonFlick" style="position:absolute;left:0px;top:255px;" type="button" allowevents=true>buttonFlick</button>
<script type="text/javascript">
window.ready = true;
var press = document.getElementById("mozLink");
var second = document.getElementById("mozLinkCopy");
var third = document.getElementById("mozLinkStart");
var fourth = document.getElementById("mozLinkCopy2");
var fifth = document.getElementById("mozLinkCancel");
var sixth = document.getElementById("mozMouse");
var seventh = document.getElementById("mozLinkScrollStart");
// touchmove and touchend must be performed on the same element as touchstart
// here is press for vertical move
press.addEventListener("touchstart", function(){changePressText("mozLink")}, false);
press.addEventListener("touchmove", changeMoveText, false);
press.addEventListener("touchend", changeReleaseText, false);
// here is second for a tap
second.addEventListener("touchstart", function(){changePressText("mozLinkCopy")}, false);
second.addEventListener("touchend", function(){changeClickText("mozLinkCopy")}, false);
// change for contextmenu
second.addEventListener("contextmenu", onContextMenuChange, false);
// here is third for horizontal move
third.addEventListener("touchstart", function(){changePressText("mozLinkStart")}, false);
third.addEventListener("touchmove", changeHorizontalMove, false);
third.addEventListener("touchend", changeHorizontalRelease, false);
// here is fourth for touch up and down with time shown
fourth.addEventListener("touchstart", changeTimePress, false);
fourth.addEventListener("touchend", changeTimeRelease, false);
// here is fifth for a cancel
fifth.addEventListener("touchstart", function(){changePressText("mozLinkCancel")}, false);
fifth.addEventListener("touchcancel", function(){changeClickText("mozLinkCancel")}, false);
// here is sixth for mouse event
sixth.addEventListener("touchstart", function(){changeMouseText("TouchStart")}, false);
sixth.addEventListener("touchend", function(){changeMouseText("TouchEnd")}, false);
sixth.addEventListener("mousemove", function(){changeMouseText("MouseMove")}, false);
sixth.addEventListener("mousedown", function(){changeMouseText("MouseDown")}, false);
sixth.addEventListener("mouseup", function(){changeMouseText("MouseUp")}, false);
sixth.addEventListener("click", function(){changeMouseText("MouseClick")}, false);
// here is seventh for a scroll
seventh.addEventListener("touchstart", function(){changePressText("mozLinkScrollStart")}, false);
seventh.addEventListener("touchend", function(){changeScrollText("mozLinkScroll")}, false);
function changeMouseText(strId) {
var mouse = document.getElementById("mozMouse");
switch(strId) {
case "TouchStart":
if (mouse.innerHTML == "MouseClick") {
mouse.innerHTML = "TouchStart2";
}
else if (mouse.innerHTML == "TouchEnd") {
mouse.innerHTML = "TouchStart2";
}
else {
mouse.innerHTML = strId;
}
break;
case "TouchEnd":
if (mouse.innerHTML == "TouchStart") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "TouchStart2") {
mouse.innerHTML = "TouchEnd2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseMove":
if (mouse.innerHTML == "TouchEnd") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "TouchEnd2") {
mouse.innerHTML = "MouseMove2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseDown":
if (mouse.innerHTML == "MouseMove") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseMove2") {
mouse.innerHTML = "MouseDown2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseUp":
if (mouse.innerHTML == "MouseDown") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseDown2") {
mouse.innerHTML = "MouseUp2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseClick":
if (mouse.innerHTML == "MouseUp") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseUp2") {
mouse.innerHTML = "MouseClick2";
}
else {
mouse.innerHTML = "Error";
}
break;
default:
mouse.innerHTML = "Error";
break;
}
var button3Timer = null;
var button4Timer = null;
//appends passed in text to the innerHTML of the event's target
function appendText(text) {
return function(evt) {
var element;
if (evt.type.indexOf("touch") !== -1) {
if (evt.type == "touchstart") {
element = evt.target;
}
else {
//since the target of touchstart is the target of all subsequent events, then
//changedTouches holds the current coordinates of this touch event, so we
//use these coordinates to find the element under the touch event
var touches = evt.changedTouches;
var x = touches[0].clientX;
var y = touches[0].clientY;
element = document.elementFromPoint(x,y);
}
}
//handle mouse events or contextmenu
else {
element = evt.target;
}
element.innerHTML += text;
};
};
//use this function outside of attachListeners when you want to test sendMouseOnlyEvents on a target
function attachMouseListeners(element) {
element.addEventListener("contextmenu", appendText("-contextmenu"), false);
element.addEventListener("mousedown", appendText("-mousedown"), false);
element.addEventListener("mousemove", appendText("-mousemove"), false);
element.addEventListener("mouseup", appendText("-mouseup"), false);
element.addEventListener("click", appendText("-click"), false);
};
function attachListeners(id) {
var element = document.getElementById(id);
element.addEventListener("touchstart", appendText("-touchstart"), false);
element.addEventListener("touchmove", appendText("-touchmove"), false);
element.addEventListener("touchend", appendText("-touchend"), false);
element.addEventListener("touchcancel", appendText("-touchcancel"), false);
attachMouseListeners(element);
};
//for tracking time on an element
function addTimers(id, timer) {
var element = document.getElementById(id);
element.addEventListener("touchstart", function(evt) { timer = (new Date()).getTime();}, false);
element.addEventListener("touchend", function(evt) { timer = (new Date()).getTime() - timer; evt.target.innerHTML += "-" + timer;}, false);
}
function changePressText(strId) {
var press = document.getElementById(strId);
press.innerHTML = "Start";
}
function changeMoveText() {
var move = document.getElementById("mozLink");
move.innerHTML = "Move";
}
function checkPosition(event, ele) {
var touches = event.changedTouches;
var clientX = touches[0].clientX;
var clientY = touches[0].clientY;
var release = document.getElementById(ele);
var boxr = release.getBoundingClientRect();
return (clientY >= boxr.top &&
clientY <= boxr.bottom &&
clientX >= boxr.left &&
clientX <= boxr.right);
}
function changeReleaseText(event) {
if (checkPosition(event, "mozLinkPos")) {
document.getElementById("mozLinkPos").innerHTML = "End";
}
}
function changeHorizontalMove() {
var press = document.getElementById("mozLinkStart");
if (press.innerHTML == "Start") {
var d = new Date();
press.innerHTML = d.getTime();
}
}
function changeHorizontalRelease(event) {
if (checkPosition(event, "mozLinkEnd")) {
var press = document.getElementById("mozLinkStart");
var d = new Date();
var timeDiff = d.getTime() - press.innerHTML;
document.getElementById("mozLinkEnd").innerHTML = timeDiff;
}
}
function changeClickText(strId) {
var second = document.getElementById(strId);
if (second.innerHTML == "Start") {
second.innerHTML = "End";
}
else if (second.innerHTML == "Context") {
second.innerHTML = "ContextEnd";
}
else {
second.innerHTML = "Error";
}
}
function changeScrollText(strId) {
var seventh = document.getElementById(strId);
if (elementInViewport(seventh)) {
seventh.innerHTML = "End";
}
else {
seventh.innerHTML = "Error";
}
}
function changeTimePress() {
var fourth = document.getElementById("mozLinkCopy2");
var d = new Date();
fourth.innerHTML = d.getTime();
attachListeners("button1");
attachListeners("button2");
attachListeners("button3");
attachListeners("button4");
attachListeners("buttonScroll");
addTimers("button3");
addTimers("button4");
var buttonFlick = document.getElementById("buttonFlick");
attachMouseListeners(buttonFlick);
function createDelayed() {
var newButton = document.createElement("button");
newButton.id = "delayed";
newButton.setAttribute("style", "position:absolute;left:220px;top:455px;");
var content = document.createTextNode("Button6");
var content = document.createTextNode("delayed");
newButton.appendChild(content);
document.body.appendChild(newButton);
}
function changeTimeRelease(event) {
var fourth = document.getElementById("mozLinkCopy2");
if (fourth.innerHTML != "Button4") {
var d = new Date();
var timeDiff = d.getTime() - fourth.innerHTML;
fourth.innerHTML = timeDiff;
}
else {
fourth.innerHTML = "Error";
}
if (checkPosition(event, "delayed")) {
document.getElementById("delayed").innerHTML = "End";
}
}
function onContextMenuChange() {
var context = document.getElementById("mozLinkCopy");
context.innerHTML = "Context";
}
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (top >= window.pageYOffset &&
left >= window.pageXOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight) &&
(left + width) <= (window.pageXOffset + window.innerWidth));
}
newButton.addEventListener("mousemove", appendText("-mousemove"), false);
newButton.addEventListener("mouseup", appendText("-mouseup"), false);
newButton.addEventListener("click", appendText("-click"), false);
};
window.setTimeout(createDelayed, 5000);
</script>
</body>
</html>

View File

@ -1,51 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html>
<head>
<script type="application/javascript" src="shim.js">
</script>
<title>Marionette Test</title>
</head>
<body>
<h1 id="testh1">Test Page</h1>
<script type="text/javascript">
window.ready = true;
setTimeout(addDelayedElement, 1000);
function addDelayedElement() {
var newDiv = document.createElement("div");
newDiv.id = "newDiv";
var newContent = document.createTextNode("I am a newly created div!");
newDiv.appendChild(newContent);
document.body.appendChild(newDiv);
}
function clicked() {
var link = document.getElementById("mozLink");
link.innerHTML = "Clicked";
}
function clicked2() {
var link2 = document.getElementById("scroll");
link2.innerHTML = "Clicked";
}
function clicked3() {
var link3 = document.getElementById("mozLinkPos");
link3.innerHTML = "Clicked";
}
</script>
<button id="mozLink" style="position:absolute;left:0px;top:55px;" type="button" onclick="clicked()" allowevents=true>Click Me!</button>
<button id="mozLinkPos" style="position:absolute;left:0px;top:355px;" type="button" onclick="clicked3()" allowevents=true>Position!</button>
<div id="testDiv">
<a href="#" id="divLink" class="linkClass" onclick="clicked()">Div click me!</a>
<a href="#" id="divLink2" class="linkClass" onclick="clicked()">Div click me!</a>
</div>
<input name="myInput" type="text" value="asdf"/>
<input name="myCheckBox" type="checkbox" />
<h2 id="testh2" style="visibility: hidden" class="linkClass">Hidden</h2>
<h3 id="testh3">Voluntary Termination</h3>
<br style="margin-bottom:600px;"/>
<button id="scroll" type="button" onclick="clicked2()" allowevents=true>Click Me!</button>
</body>
</html>

View File

@ -1,7 +1,7 @@
import os
from setuptools import setup, find_packages
version = '0.5.27'
version = '0.5.28'
# get documentation from the README
try:

View File

@ -1319,23 +1319,6 @@ MarionetteDriverActor.prototype = {
}
},
/**
* Set a value to decide if sending mouse event
*
* @param object aRequest
* 'value' holds the boolean value
*/
sendMouseEvent: function MDA_sendMouseEvent(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
}
else {
this.sendAsync("sendMouseEvent", {value: aRequest.value,
command_id: this.command_id});
}
},
/**
* Set timeout for page loading, searching and scripts
*
@ -1379,7 +1362,7 @@ MarionetteDriverActor.prototype = {
let x = aRequest.x;
let y = aRequest.y;
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'singleTap' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("singleTap",
@ -1401,7 +1384,7 @@ MarionetteDriverActor.prototype = {
actionChain: function MDA_actionChain(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'actionChain' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("actionChain",
@ -1425,7 +1408,7 @@ MarionetteDriverActor.prototype = {
multiAction: function MDA_multiAction(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'multiAction' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("multiAction",
@ -2220,7 +2203,6 @@ MarionetteDriverActor.prototype.requestTypes = {
"executeAsyncScript": MarionetteDriverActor.prototype.executeWithCallback,
"executeJSScript": MarionetteDriverActor.prototype.executeJSScript,
"setSearchTimeout": MarionetteDriverActor.prototype.setSearchTimeout,
"sendMouseEvent": MarionetteDriverActor.prototype.sendMouseEvent,
"findElement": MarionetteDriverActor.prototype.findElement,
"findElements": MarionetteDriverActor.prototype.findElements,
"clickElement": MarionetteDriverActor.prototype.clickElement,

View File

@ -57,19 +57,16 @@ let originalOnError;
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
// Send move events about this often
let EVENT_INTERVAL = 30; // milliseconds
// The current array of all pending touches
let touches = [];
// For assigning unique ids to all touches
let nextTouchId = 1000;
//Keep track of active Touches
let touchIds = {};
// last touch for each fingerId
let multiLast = {};
// last touch for single finger
let lastTouch = null;
// last touch type
let isTouchStart = false;
let lastCoordinates = null;
let isTap = false;
// whether to send mouse event
let mouseEvent = true;
let mouseEventsOnly = false;
/**
* Called when listener is first started up.
* The listener sends its unique window ID and its current URI to the actor.
@ -111,7 +108,6 @@ function startListeners() {
addMessageListenerId("Marionette:singleTap", singleTap);
addMessageListenerId("Marionette:actionChain", actionChain);
addMessageListenerId("Marionette:multiAction", multiAction);
addMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
addMessageListenerId("Marionette:goUrl", goUrl);
addMessageListenerId("Marionette:getUrl", getUrl);
addMessageListenerId("Marionette:getTitle", getTitle);
@ -186,7 +182,6 @@ function deleteSession(msg) {
removeMessageListenerId("Marionette:singleTap", singleTap);
removeMessageListenerId("Marionette:actionChain", actionChain);
removeMessageListenerId("Marionette:multiAction", multiAction);
removeMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
removeMessageListenerId("Marionette:goUrl", goUrl);
removeMessageListenerId("Marionette:getTitle", getTitle);
removeMessageListenerId("Marionette:getPageSource", getPageSource);
@ -224,7 +219,6 @@ function deleteSession(msg) {
// reset frame to the top-most frame
curWindow = content;
curWindow.focus();
touches = [];
touchIds = {};
}
@ -277,6 +271,7 @@ function sendError(message, status, trace, command_id) {
function resetValues() {
sandbox = null;
curWindow = content;
mouseEventsOnly = false;
}
/*
@ -539,20 +534,6 @@ function executeWithCallback(msg, useFinish) {
}
}
/**
* This function sets a value for mouseEvent to decide if we want to send mouse events
*/
function sendMouseEvent(msg) {
let command_id = msg.json.command_id;
if (typeof msg.json.value === 'boolean') {
mouseEvent = msg.json.value;
sendOk(msg.json.command_id);
}
else {
sendError("Json value is not boolean as expected", 500, null, command_id);
}
}
/**
* This function creates a touch event given a touch type and a touch
*/
@ -569,209 +550,42 @@ function emitTouchEvent(type, touch) {
* detail is the number of clicks, button notes the mouse button
* elClientX and elClientY are the coordinates of the mouse relative to the viewport
*/
function emitMouseEvent(doc, type, detail, button, elClientX, elClientY) {
function emitMouseEvent(doc, type, elClientX, elClientY, detail, button) {
detail = detail || 1;
button = button || 0;
var win = doc.defaultView;
// Figure out the element the mouse would be over at (x, y)
var target = doc.elementFromPoint(elClientX, elClientY);
utils.synthesizeMouse(target, win.mozInnerScreenX, win.mozInnerScreenY, {type: type, button: button, clickCount: detail}, win);
utils.synthesizeMouseAtPoint(elClientX, elClientY, {type: type, button: button, clickCount: detail}, win);
}
/**
* This function create a mouse and emit mouse events
* @param 'xt' and 'yt' are functions of t that specify the mouse coordinates at time t
* Helper function that perform a mouse tap
*/
function mouse(doc, duration, xt, yt, then, detail, button) {
detail = detail || 1;
button = button || 0;
var x = xt;
if (typeof xt !== 'function') {
x = function(t) {
return xt[0] + t / duration * (xt[1] - xt[0]);
}
}
var y = yt;
if (typeof yt !== 'function') {
y = function(t) {
return yt[0] + t / duration * (yt[1] - yt[0]);
}
}
// viewport coordinates
var clientX = Math.round(x(0)), clientY = Math.round(y(0));
// Remember the coordinates
var lastX = clientX, lastY = clientY;
emitMouseEvent(doc, 'mousedown', detail, button, clientX, clientY);
// now send a sequence of mousemove events followed by mouse up
let startTime = Date.now();
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
function nextEvent() {
// figure out if we've sent all the mousemove events
var time = Date.now();
var dt = time - startTime;
let last = dt + EVENT_INTERVAL / 2 > duration;
// New coordinates of the touch
clientX = Math.round(x(dt));
clientY = Math.round(y(dt));
// If we moved, send a move event
if (clientX !== lastX || clientY !== lastY) { // If we moved
lastX = clientX;
lastY = clientY;
emitMouseEvent(doc, 'mousemove', detail, button, clientX, clientY);
}
// If this was the last move, send a mouse up and call the callback
// Otherwise, schedule the next move event
if (last) {
emitMouseEvent(doc, 'mouseup', detail, button, lastX, lastY);
if (then) {
checkTimer.initWithCallback(then, 0, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
else {
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
function mousetap(doc, x, y) {
emitMouseEvent(doc, 'mousemove', x, y);
emitMouseEvent(doc, 'mousedown', x, y);
emitMouseEvent(doc, 'mouseup', x, y);
}
/**
* This function creates a touch and emit touch events
* @param 'xt' and 'yt' are two-element array [from, to] and then is a callback that will be invoked after touchend event is sent
*/
function touch(target, duration, xt, yt, then) {
let doc = target.ownerDocument;
let win = doc.defaultView;
let touchId = nextTouchId++;
let x = xt;
if (typeof xt !== 'function') {
x = function(t) { return xt[0] + t / duration * (xt[1] - xt[0]); };
}
let y = yt;
if (typeof yt !== 'function') {
y = function(t) { return yt[0] + t / duration * (yt[1] - yt[0]); };
}
// viewport coordinates
let clientX = Math.round(x(0)), clientY = Math.round(y(0));
// document coordinates
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
// screen coordinates
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
// Remember the coordinates
let lastX = clientX, lastY = clientY;
// Create the touch object
let touch = doc.createTouch(win, target, touchId,
pageX, pageY,
screenX, screenY,
clientX, clientY);
// Add this new touch to the list of touches
touches.push(touch);
// Send the start event
emitTouchEvent('touchstart', touch);
let startTime = Date.now();
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
function nextEvent() {
// Figure out if this is the last of the touchmove events
let time = Date.now();
let dt = time - startTime;
let last = dt + EVENT_INTERVAL / 2 > duration;
// Find our touch object in the touches[] array.
// Note that its index may have changed since we pushed it
let touchIndex = touches.indexOf(touch);
// If this is the last move event, make sure we move all the way
if (last)
dt = duration;
// New coordinates of the touch
clientX = Math.round(x(dt));
clientY = Math.round(y(dt));
// If we've moved, send a move event
if (clientX !== lastX || clientY !== lastY) { // If we moved
lastX = clientX;
lastY = clientY;
pageX = clientX + win.pageXOffset;
pageY = clientY + win.pageYOffset;
screenX = clientX + win.mozInnerScreenX;
screenY = clientY + win.mozInnerScreenY;
// Since we moved, we've got to create a new Touch object
// with the new coordinates
touch = doc.createTouch(win, target, touchId,
pageX, pageY,
screenX, screenY,
clientX, clientY);
// Replace the old touch object with the new one
touches[touchIndex] = touch;
// And send the touchmove event
emitTouchEvent('touchmove', touch);
}
// If that was the last move, send the touchend event
// and call the callback
if (last) {
touches.splice(touchIndex, 1);
emitTouchEvent('touchend', touch);
if (then)
checkTimer.initWithCallback(then, 0, Ci.nsITimer.TYPE_ONE_SHOT);
}
// Otherwise, schedule the next event
else {
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
}
/**
* This function generates the coordinates of the element
* @param 'x0', 'y0', 'x1', and 'y1' are the relative to the target.
* This function generates a pair of coordinates relative to the viewport given a
* target element and coordinates relative to that element's top-left corner.
* @param 'x', and 'y' are the relative to the target.
* If they are not specified, then the center of the target is used.
*/
function coordinates(target, x0, y0, x1, y1) {
let coords = {};
function coordinates(target, x, y) {
let box = target.getBoundingClientRect();
let tx0 = typeof x0;
let ty0 = typeof y0;
let tx1 = typeof x1;
let ty1 = typeof y1;
function percent(s, x) {
s = s.trim();
let f = parseFloat(s);
if (s[s.length - 1] === '%')
f = f * x / 100;
return f;
if (x == null) {
x = box.width / 2;
}
function relative(s, x) {
let factor;
if (s[0] === '+')
factor = 1;
else
factor = -1;
return factor * percent(s.substring(1), x);
}
if (tx0 === 'number')
coords.x0 = box.left + x0;
else if (tx0 === 'string')
coords.x0 = box.left + percent(x0, box.width);
//check tx1 point
if (tx1 === 'number')
coords.x1 = box.left + x1;
else if (tx1 === 'string') {
x1 = x1.trim();
if (x1[0] === '+' || x1[0] === '-')
coords.x1 = coords.x0 + relative(x1, box.width);
else
coords.x1 = box.left + percent(x1, box.width);
}
// check ty0
if (ty0 === 'number')
coords.y0 = box.top + y0;
else if (ty0 === 'string')
coords.y0 = box.top + percent(y0, box.height);
//check ty1
if (ty1 === 'number')
coords.y1 = box.top + y1;
else if (ty1 === 'string') {
y1 = y1.trim();
if (y1[0] === '+' || y1[0] === '-')
coords.y1 = coords.y0 + relative(y1, box.height);
else
coords.y1 = box.top + percent(y1, box.height);
if (y == null) {
y = box.height / 2;
}
let coords = {};
coords.x = box.left + x;
coords.y = box.top + y;
return coords;
}
@ -790,7 +604,7 @@ function elementInViewport(el) {
/**
* This function throws the visibility of the element error
*/
function checkVisible(el, command_id) {
function checkVisible(el) {
//check if the element is visible
let visible = utils.isElementDisplayed(el);
if (!visible) {
@ -814,35 +628,110 @@ function checkVisible(el, command_id) {
return true;
}
//x and y are coordinates relative to the viewport
function generateEvents(type, x, y, touchId, target) {
lastCoordinates = [x, y];
let doc = curWindow.document;
switch (type) {
case 'tap':
if (mouseEventsOnly) {
mousetap(target.ownerDocument, x, y);
}
else {
let touchId = nextTouchId++;
let touch = createATouch(target, x, y, touchId);
emitTouchEvent('touchstart', touch);
emitTouchEvent('touchend', touch);
mousetap(target.ownerDocument, x, y);
}
lastCoordinates = null;
break;
case 'press':
isTap = true;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mousemove', x, y);
emitMouseEvent(doc, 'mousedown', x, y);
}
else {
let touchId = nextTouchId++;
let touch = createATouch(target, x, y, touchId);
emitTouchEvent('touchstart', touch);
touchIds[touchId] = touch;
return touchId;
}
break;
case 'release':
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mouseup', lastCoordinates[0], lastCoordinates[1]);
}
else {
let touch = touchIds[touchId];
touch = createATouch(touch.target, lastCoordinates[0], lastCoordinates[1], touchId);
emitTouchEvent('touchend', touch);
if (isTap) {
mousetap(touch.target.ownerDocument, touch.clientX, touch.clientY);
}
delete touchIds[touchId];
}
isTap = false;
lastCoordinates = null;
break;
case 'cancel':
isTap = false;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mouseup', lastCoordinates[0], lastCoordinates[1]);
}
else {
emitTouchEvent('touchcancel', touchIds[touchId]);
delete touchIds[touchId];
}
lastCoordinates = null;
break;
case 'move':
isTap = false;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mousemove', x, y);
}
else {
touch = createATouch(touchIds[touchId].target, x, y, touchId);
touchIds[touchId] = touch;
emitTouchEvent('touchmove', touch);
}
break;
case 'contextmenu':
isTap = false;
let event = curWindow.document.createEvent('HTMLEvents');
event.initEvent('contextmenu', true, true);
if (mouseEventsOnly) {
target = doc.elementFromPoint(lastCoordinates[0], lastCoordinates[1]);
}
else {
target = touchIds[touchId].target;
}
target.dispatchEvent(event);
break;
default:
throw {message:"Unknown event type: " + type, code: 500, stack:null};
}
}
/**
* Function that perform a single tap
*/
function singleTap(msg) {
let command_id = msg.json.command_id;
let el;
try {
el = elementManager.getKnownElement(msg.json.value, curWindow);
let x = msg.json.corx;
let y = msg.json.cory;
if (!checkVisible(el, command_id)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
let el = elementManager.getKnownElement(msg.json.value, curWindow);
// after this block, the element will be scrolled into view
if (!checkVisible(el)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
if (x == null) {
x = '50%';
}
if (y == null) {
y = '50%';
}
let c = coordinates(el, x, y);
if (mouseEvent) {
touch(el, 25, [c.x0, c.x0], [c.y0, c.y0], function() {
mousetap(el, 25, c.x0, c.y0, 1, 0, null);
});
}
else {
touch(el, 25, [c.x0, c.x0], [c.y0, c.y0], null);
if (!curWindow.document.createTouch) {
mouseEventsOnly = true;
}
let c = coordinates(el, msg.json.corx, msg.json.cory);
generateEvents('tap', c.x, c.y, null, el);
sendOk(msg.json.command_id);
}
catch (e) {
@ -850,171 +739,103 @@ function singleTap(msg) {
}
}
/**
* Function that perform a mouse tap
*/
function mousetap(target, duration, x, y, detail, button, then) {
var doc = target.ownerDocument;
detail = detail || 1;
button = button || 0;
emitMouseEvent(doc, 'mousemove', detail, button, x, y);
mouse(doc, duration, [x, x], [y, y], then, detail, button);
}
/**
* Function to create a touch based on the element
* corx and cory are related to the el, id is the touchId
* corx and cory are relative to the viewport, id is the touchId
*/
function createATouch(el, corx, cory, id) {
function createATouch(el, corx, cory, touchId) {
let doc = el.ownerDocument;
let win = doc.defaultView;
if (corx == null) {
corx = '50%';
}
if (cory == null){
cory = '50%';
}
// corx and cory are relative to the el target. They must be within the same viewport
// c are the coordinates relative to the current viewport
let c = coordinates(el, corx, cory);
let clientX = Math.round(c.x0),
clientY = Math.round(c.y0);
let clientX = corx;
let clientY = cory;
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
let atouch = doc.createTouch(win, el, id, pageX, pageY, screenX, screenY, clientX, clientY);
let atouch = doc.createTouch(win, el, touchId, pageX, pageY, screenX, screenY, clientX, clientY);
return atouch;
}
/**
* Function to emit touch events for each finger. e.g. finger=[['press', id], ['wait', 5], ['release']]
* touchId represents the finger id, i keeps track of the current action of the finger
* touchId represents the finger id, i keeps track of the current action of the chain
*/
function actions(finger, touchId, command_id, i){
function actions(chain, touchId, command_id, i) {
if (typeof i === "undefined") {
i = 0;
}
if (i == finger.length) {
if (i == chain.length) {
sendResponse({value: touchId}, command_id);
return;
}
let pack = finger[i];
let pack = chain[i];
let command = pack[0];
// el has the id
let el;
let corx;
let cory;
let touch;
let contextmenu = false;
let c;
i++;
if (command != 'press') {
//if mouseEventsOnly, then touchIds isn't used
if (!(touchId in touchIds) && !mouseEventsOnly) {
sendError("Element has not been pressed", 500, null, command_id);
return;
}
}
switch(command) {
case 'press':
if (lastTouch != null) {
touch = lastTouch;
emitTouchEvent('touchcancel', touch);
lastTouch = null;
sendError("Invalid Command: long_press cannot follow an active touch event", 500, null, command_id);
if (lastCoordinates) {
generateEvents('cancel', lastCoordinates[0], lastCoordinates[1], touchId);
sendError("Invalid Command: press cannot follow an active touch event", 500, null, command_id);
return;
}
el = elementManager.getKnownElement(pack[1], curWindow);
corx = pack[2];
cory = pack[3];
// after this block, the element will be scrolled into view
if (!checkVisible(el, command_id)) {
if (!checkVisible(el)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
touch = createATouch(el, corx, cory, touchId);
lastTouch = touch;
isTouchStart = true;
emitTouchEvent('touchstart', touch);
actions(finger,touchId, command_id, i);
c = coordinates(el, pack[2], pack[3]);
touchId = generateEvents('press', c.x, c.y, null, el);
actions(chain, touchId, command_id, i);
break;
case 'release':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
touch = lastTouch;
lastTouch = null;
emitTouchEvent('touchend', touch);
if (isTouchStart && mouseEvent) {
emitMouseEvent(touch.target.ownerDocument, 'mousemove', 1, 0, touch.clientX, touch.clientY);
emitMouseEvent(touch.target.ownerDocument, 'mousedown', 1, 0, touch.clientX, touch.clientY);
emitMouseEvent(touch.target.ownerDocument, 'mouseup', 1, 0, touch.clientX, touch.clientY);
}
isTouchStart = false;
actions(finger, touchId, command_id, i);
generateEvents('release', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, null, command_id, i);
break;
case 'move':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
el = elementManager.getKnownElement(pack[1], curWindow);
let boxTarget = el.getBoundingClientRect();
let startElement = lastTouch.target;
let boxStart = startElement.getBoundingClientRect();
corx = boxTarget.left - boxStart.left + boxTarget.width * 0.5;
cory = boxTarget.top - boxStart.top + boxTarget.height * 0.5;
touch = createATouch(startElement, corx, cory, touchId);
lastTouch = touch;
isTouchStart = false;
emitTouchEvent('touchmove', touch);
actions(finger, touchId, command_id, i);
c = coordinates(el);
generateEvents('move', c.x, c.y, touchId);
actions(chain, touchId, command_id, i);
break;
case 'moveByOffset':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
el = lastTouch.target;
let doc = el.ownerDocument;
let win = doc.defaultView;
let clientX = lastTouch.clientX + pack[1],
clientY = lastTouch.clientY + pack[2];
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
touch = doc.createTouch(win, el, touchId, pageX, pageY, screenX, screenY, clientX, clientY);
lastTouch = touch;
isTouchStart = false;
emitTouchEvent('touchmove', touch);
actions(finger, touchId, command_id, i);
generateEvents('move', lastCoordinates[0] + pack[1], lastCoordinates[1] + pack[2], touchId);
actions(chain, touchId, command_id, i);
break;
case 'wait':
if (pack[1] != null ) {
let time = pack[1]*1000;
// standard waiting time to fire contextmenu
let standard = Services.prefs.getIntPref("ui.click_hold_context_menus.delay");
if (time >= standard && isTouchStart && !contextmenu) {
finger.splice(i, 0, ['longPress'], ['wait', (time-standard)/1000]);
let standard = 750;
try {
standard = Services.prefs.getIntPref("ui.click_hold_context_menus.delay");
}
catch (e){}
if (time >= standard && isTap) {
chain.splice(i, 0, ['longPress'], ['wait', (time-standard)/1000]);
time = standard;
}
checkTimer.initWithCallback(function(){actions(finger, touchId, command_id, i);}, time, Ci.nsITimer.TYPE_ONE_SHOT);
checkTimer.initWithCallback(function(){actions(chain, touchId, command_id, i);}, time, Ci.nsITimer.TYPE_ONE_SHOT);
}
else {
actions(finger, touchId, command_id, i);
actions(chain, touchId, command_id, i);
}
break;
case 'cancel':
touch = lastTouch;
emitTouchEvent('touchcancel', touch);
lastTouch = null;
isTouchStart = false;
actions(finger, touchId, command_id, i);
generateEvents('cancel', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, touchId, command_id, i);
break;
case 'longPress':
isTouchStart = false;
contextmenu = true;
let event = curWindow.document.createEvent('HTMLEvents');
event.initEvent('contextmenu',
true,
true);
lastTouch.target.dispatchEvent(event);
actions(finger, touchId, command_id, i);
generateEvents('contextmenu', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, touchId, command_id, i);
break;
}
}
@ -1032,6 +853,9 @@ function actionChain(msg) {
if (touchId == null) {
touchId = nextTouchId++;
}
if (!curWindow.document.createTouch) {
mouseEventsOnly = true;
}
actions(commandArray, touchId, command_id);
}
catch (e) {
@ -1102,6 +926,7 @@ function setDispatch(batches, touches, command_id, batchIndex) {
let touchIndex;
let waitTime = 0;
let maxTime = 0;
let c;
batchIndex++;
// loop through the batch
for (let i = 0; i < batch.length; i++) {
@ -1111,14 +936,8 @@ function setDispatch(batches, touches, command_id, batchIndex) {
switch (command) {
case 'press':
el = elementManager.getKnownElement(pack[2], curWindow);
// after this block, the element will be scrolled into view
if (!checkVisible(el, command_id)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
corx = pack[3];
cory = pack[4];
touch = createATouch(el, corx, cory, touchId);
c = coordinates(el, pack[3], pack[4]);
touch = createATouch(el, c.x, c.y, touchId);
multiLast[touchId] = touch;
touches.push(touch);
emitMultiEvents('touchstart', touch, touches);
@ -1132,15 +951,8 @@ function setDispatch(batches, touches, command_id, batchIndex) {
break;
case 'move':
el = elementManager.getKnownElement(pack[2], curWindow);
lastTouch = multiLast[touchId];
let boxTarget = el.getBoundingClientRect();
let startTarget = lastTouch.target;
let boxStart = startTarget.getBoundingClientRect();
// note here corx and cory are relative to the target, not the viewport
// we always want to touch the center of the element if the element is specified
corx = boxTarget.left - boxStart.left + boxTarget.width * 0.5;
cory = boxTarget.top - boxStart.top + boxTarget.height * 0.5;
touch = createATouch(startTarget, corx, cory, touchId);
c = coordinates(el);
touch = createATouch(multiLast[touchId].target, c.x, c.y, touchId);
touchIndex = touches.indexOf(lastTouch);
touches[touchIndex] = touch;
multiLast[touchId] = touch;
@ -1355,7 +1167,7 @@ function clickElement(msg) {
let el;
try {
el = elementManager.getKnownElement(msg.json.element, curWindow);
if (checkVisible(el, command_id)) {
if (checkVisible(el)) {
if (utils.isElementEnabled(el)) {
utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView)
}
@ -1502,7 +1314,7 @@ function sendKeysToElement(msg) {
let command_id = msg.json.command_id;
try {
let el = elementManager.getKnownElement(msg.json.element, curWindow);
if (checkVisible(el, command_id)) {
if (checkVisible(el)) {
utils.type(curWindow.document, el, msg.json.value.join(""), true);
sendOk(command_id);
}