diff --git a/testing/marionette/client/marionette/__init__.py b/testing/marionette/client/marionette/__init__.py
index e3f8e4f8702f..7708df085194 100644
--- a/testing/marionette/client/marionette/__init__.py
+++ b/testing/marionette/client/marionette/__init__.py
@@ -2,7 +2,7 @@
# 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 import Marionette, HTMLElement, Actions
+from marionette import Marionette, HTMLElement, Actions, MultiActions
from marionette_test import MarionetteTestCase, CommonTestCase
from marionette_touch import MarionetteTouchMixin
from emulator import Emulator
diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py
index 7029ec487e93..0775fda07cdf 100644
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -134,6 +134,21 @@ class Actions(object):
def perform(self):
return self.marionette._send_message('actionChain', 'ok', value=self.action_chain)
+class MultiActions(object):
+ def __init__(self, marionette):
+ self.multi_actions = []
+ self.max_length = 0
+ self.marionette = marionette
+
+ def add(self, action):
+ self.multi_actions.append(action.action_chain)
+ if len(action.action_chain) > self.max_length:
+ self.max_length = len(action.action_chain)
+ return self
+
+ def perform(self):
+ return self.marionette._send_message('multiAction', 'ok', value=self.multi_actions, max_length=self.max_length)
+
class Marionette(object):
CONTEXT_CHROME = 'chrome'
diff --git a/testing/marionette/client/marionette/tests/unit/test_multi_finger.py b/testing/marionette/client/marionette/tests/unit/test_multi_finger.py
new file mode 100644
index 000000000000..ff35d0a79b0d
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_multi_finger.py
@@ -0,0 +1,62 @@
+# 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 MultiActions, Actions
+
+class testSingleFinger(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")
+ 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;"))
+
+ 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")
+ 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;"))
+
+ 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")
+ 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()
+ 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;"))
diff --git a/testing/marionette/client/marionette/tests/unit/unit-tests.ini b/testing/marionette/client/marionette/tests/unit/unit-tests.ini
index 9eec80c20603..5524c9ded7ff 100644
--- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini
@@ -55,6 +55,10 @@ browser = false
b2g = true
browser = false
+[test_multi_finger.py]
+b2g = true
+browser = false
+
[test_simpletest_pass.js]
[test_simpletest_sanity.py]
[test_simpletest_chrome.js]
diff --git a/testing/marionette/client/marionette/www/testAction.html b/testing/marionette/client/marionette/www/testAction.html
index 0d35f8ed6f4e..57e2888059d4 100644
--- a/testing/marionette/client/marionette/www/testAction.html
+++ b/testing/marionette/client/marionette/www/testAction.html
@@ -15,20 +15,34 @@
+
+
+
+
+