From 80117e6c52d1ecc26c24474e4b4d4ac61d3fb725 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Fri, 27 Feb 2015 17:30:07 -0800 Subject: [PATCH] Bug 1129702 - Add support for double clicks to marionette's action chains.;r=automatedtester --- .../marionette/tests/unit/test_click.py | 40 +++++++++++++++++++ .../driver/marionette_driver/marionette.py | 21 ++++++++++ testing/marionette/marionette-listener.js | 9 +++++ 3 files changed, 70 insertions(+) diff --git a/testing/marionette/client/marionette/tests/unit/test_click.py b/testing/marionette/client/marionette/tests/unit/test_click.py index 91f08314f557..0006b5ea511d 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click.py +++ b/testing/marionette/client/marionette/tests/unit/test_click.py @@ -5,6 +5,8 @@ from marionette_driver.by import By from marionette_driver.errors import NoSuchElementException, ElementNotVisibleException from marionette_test import MarionetteTestCase +from marionette_driver.marionette import Actions +from marionette_driver.keys import Keys from marionette_driver.wait import Wait @@ -30,3 +32,41 @@ class TestClick(MarionetteTestCase): with self.assertRaises(ElementNotVisibleException): self.marionette.find_element(By.ID, 'child').click() + +class TestClickAction(MarionetteTestCase): + + def setUp(self): + MarionetteTestCase.setUp(self) + if self.marionette.session_capabilities['platformName'] == 'DARWIN': + self.mod_key = Keys.META + else: + self.mod_key = Keys.CONTROL + self.action = Actions(self.marionette) + + def test_click_action(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + link = self.marionette.find_element(By.ID, "mozLink") + self.action.click(link).perform() + self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;")) + + def test_clicking_element_out_of_view_succeeds(self): + # The action based click doesn't check for visibility. + test_html = self.marionette.absolute_url('hidden.html') + self.marionette.navigate(test_html) + el = self.marionette.find_element(By.ID, 'child') + self.action.click(el).perform() + + def test_double_click_action(self): + test_html = self.marionette.absolute_url("javascriptPage.html") + self.marionette.navigate(test_html) + el = self.marionette.find_element(By.ID, 'displayed') + # The first click just brings the element into view so text selection + # works as expected. (A different test page could be used to isolate + # this element and make sure it's always in view) + el.click() + self.action.double_click(el).perform() + el.send_keys(self.mod_key + 'c') + rel = self.marionette.find_element("id", "keyReporter") + rel.send_keys(self.mod_key + 'v') + self.assertEqual(rel.get_attribute('value'), 'Displayed') diff --git a/testing/marionette/driver/marionette_driver/marionette.py b/testing/marionette/driver/marionette_driver/marionette.py index 4e67dd1fdfbf..604b40627bb4 100644 --- a/testing/marionette/driver/marionette_driver/marionette.py +++ b/testing/marionette/driver/marionette_driver/marionette.py @@ -329,6 +329,27 @@ class Actions(object): self.action_chain.append(['release']) return self + def click(self, element, count=1): + ''' + Performs a click with additional parameters to allow for double clicking, + right click, middle click, etc. + + :param element: The element to click. + :param count: Optional, the count of clicks to synthesize (for double + click events). + ''' + el = element.id + self.action_chain.append(['click', el, None, count]) + return self + + def double_click(self, element): + ''' + Performs a double click on the specified element. + + :param element: The element to double click. + ''' + return self.click(element, count=2) + def flick(self, element, x1, y1, x2, y2, duration=200): ''' Performs a flick gesture on the target element. diff --git a/testing/marionette/marionette-listener.js b/testing/marionette/marionette-listener.js index c8cecc7aa203..2aefe5fcabf6 100644 --- a/testing/marionette/marionette-listener.js +++ b/testing/marionette/marionette-listener.js @@ -1127,6 +1127,15 @@ function actions(chain, touchId, command_id, i, keyModifiers) { utils.sendKeyUp(pack[1], keyModifiers, curFrame); actions(chain, touchId, command_id, i, keyModifiers); break; + case 'click': + el = elementManager.getKnownElement(pack[1], curFrame); + let clickCount = pack[3]; + c = coordinates(el, null, null); + emitMouseEvent(el.ownerDocument, 'mousemove', c.x, c.y, null, clickCount, keyModifiers); + emitMouseEvent(el.ownerDocument, 'mousedown', c.x, c.y, null, clickCount, keyModifiers); + emitMouseEvent(el.ownerDocument, 'mouseup', c.x, c.y, null, clickCount, keyModifiers); + actions(chain, touchId, command_id, i, keyModifiers); + break; case 'press': if (lastCoordinates) { generateEvents('cancel', lastCoordinates[0], lastCoordinates[1],