author | Ting-Yu Lin <tlin@mozilla.com> |
Mon, 25 Mar 2019 20:28:44 +0000 | |
changeset 466026 | aad29c67d0ad810a4de5dac7bd8728e5d5b56d36 |
parent 466025 | 6d8c85e1f976c8ea68fc501cd144bfa717abe299 |
child 466027 | f9ec1b53fd9f918c471ebda7f898ae33e2cc34e9 |
push id | 81388 |
push user | aethanyc@gmail.com |
push date | Tue, 26 Mar 2019 00:44:12 +0000 |
treeherder | autoland@aad29c67d0ad [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | whimboo |
bugs | 1534584 |
milestone | 68.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/tests/marionette/selection.py +++ b/layout/base/tests/marionette/selection.py @@ -1,15 +1,75 @@ # -*- coding: utf-8 -*- # 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 __future__ import absolute_import +from marionette_driver.marionette import Actions + + +class CaretActions(Actions): + def __init__(self, marionette): + super(CaretActions, self).__init__(marionette) + self._reset_action_chain() + + def _reset_action_chain(self): + self.mouse_chain = self.sequence("pointer", "pointer_id", {"pointerType": "mouse"}) + self.key_chain = self.sequence("key", "keyboard_id") + + def flick(self, element, x1, y1, x2, y2, duration=200): + """Perform a flick gesture on the target element. + + :param element: The element to perform the flick gesture on. + :param x1: Starting x-coordinate of flick, relative to the top left + corner of the element. + :param y1: Starting y-coordinate of flick, relative to the top left + corner of the element. + :param x2: Ending x-coordinate of flick, relative to the top left + corner of the element. + :param y2: Ending y-coordinate of flick, relative to the top left + corner of the element. + + """ + rect = element.rect + el_x, el_y = rect['x'], rect['y'] + + # Add element's (x, y) to make the coordinate relative to the viewport. + from_x, from_y = int(el_x + x1), int(el_y + y1) + to_x, to_y = int(el_x + x2), int(el_y + y2) + + self.mouse_chain.pointer_move(from_x, from_y) \ + .pointer_down() \ + .pointer_move(to_x, to_y, duration=duration) \ + .pointer_up() + return self + + def send_keys(self, keys): + """Perform a keyDown and keyUp action for each character in `keys`. + + :param keys: String of keys to perform key actions with. + + """ + self.key_chain.send_keys(keys) + return self + + def perform(self): + """Perform the action chain built so far to the server side for execution + and clears the current chain of actions. + + Warning: This method performs all the mouse actions before all the key + actions! + + """ + self.mouse_chain.perform() + self.key_chain.perform() + self._reset_action_chain() + class SelectionManager(object): '''Interface for manipulating the selection and carets of the element. We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as caret for short. Simple usage example:
--- a/layout/base/tests/marionette/test_accessiblecaret_cursor_mode.py +++ b/layout/base/tests/marionette/test_accessiblecaret_cursor_mode.py @@ -6,20 +6,20 @@ import string import sys import os # Add this directory to the import path. sys.path.append(os.path.dirname(__file__)) from selection import ( + CaretActions, SelectionManager, ) from marionette_driver.by import By -from marionette_driver.legacy_actions import Actions from marionette_harness.marionette_test import ( MarionetteTestCase, parameterized, ) class AccessibleCaretCursorModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under cursor mode. @@ -43,17 +43,21 @@ class AccessibleCaretCursorModeTestCase( super(AccessibleCaretCursorModeTestCase, self).setUp() self.caret_tested_pref = 'layout.accessiblecaret.enabled' self.hide_carets_for_mouse = 'layout.accessiblecaret.hide_carets_for_mouse_input' self.prefs = { self.caret_tested_pref: True, self.hide_carets_for_mouse: False, } self.marionette.set_prefs(self.prefs) - self.actions = Actions(self.marionette) + self.actions = CaretActions(self.marionette) + + def tearDown(self): + self.marionette.actions.release() + super(AccessibleCaretCursorModeTestCase, self).tearDown() def open_test_html(self, test_html): self.marionette.navigate(self.marionette.absolute_url(test_html)) @parameterized(_input_id, el_id=_input_id) @parameterized(_textarea_id, el_id=_textarea_id) @parameterized(_contenteditable_id, el_id=_contenteditable_id) def test_move_cursor_to_the_right_by_one_character(self, el_id): @@ -74,17 +78,17 @@ class AccessibleCaretCursorModeTestCase( # Tap the front of the input to make first caret appear. el.tap(cursor0_x, cursor0_y) # Move first caret. self.actions.flick(el, first_caret0_x, first_caret0_y, first_caret1_x, first_caret1_y).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + self.actions.send_keys(content_to_add).perform() self.assertEqual(target_content, sel.content) @parameterized(_input_id, el_id=_input_id) @parameterized(_textarea_id, el_id=_textarea_id) @parameterized(_contenteditable_id, el_id=_contenteditable_id) def test_move_cursor_to_end_by_dragging_caret_to_bottom_right_corner(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) @@ -97,17 +101,17 @@ class AccessibleCaretCursorModeTestCase( sel.move_cursor_to_front() el.tap(*sel.cursor_location()) # Move first caret to the bottom-right corner of the element. src_x, src_y = sel.first_caret_location() dest_x, dest_y = el.rect['width'], el.rect['height'] self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + self.actions.send_keys(content_to_add).perform() self.assertEqual(target_content, sel.content) @parameterized(_input_id, el_id=_input_id) @parameterized(_textarea_id, el_id=_textarea_id) @parameterized(_contenteditable_id, el_id=_contenteditable_id) def test_move_cursor_to_front_by_dragging_caret_to_front(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) @@ -127,17 +131,17 @@ class AccessibleCaretCursorModeTestCase( sel.move_cursor_to_end() sel.move_cursor_by_offset(1, backward=True) el.tap(*sel.cursor_location()) src_x, src_y = sel.first_caret_location() # Move first caret to the front of the input box. self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + self.actions.send_keys(content_to_add).perform() self.assertEqual(target_content, sel.content) def test_caret_not_appear_when_typing_in_scrollable_content(self): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, self._input_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content + string.ascii_letters @@ -176,17 +180,17 @@ class AccessibleCaretCursorModeTestCase( # on the Y-axis. el.tap() sel.move_cursor_to_front() el.tap(*sel.cursor_location()) x, y = sel.first_caret_location() # Drag the caret down by 50px, and insert '!'. self.actions.flick(el, x, y, x, y + 50).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + self.actions.send_keys(content_to_add).perform() self.assertNotEqual(non_target_content, sel.content) @parameterized(_input_id, el_id=_input_id) @parameterized(_input_padding_id, el_id=_input_padding_id) @parameterized(_textarea_one_line_id, el_id=_textarea_one_line_id) @parameterized(_contenteditable_id, el_id=_contenteditable_id) def test_caret_not_jump_to_front_when_dragging_up_to_editable_content_boundary(self, el_id): self.open_test_html(self._cursor_html) @@ -198,19 +202,19 @@ class AccessibleCaretCursorModeTestCase( # Goal: the cursor position is not changed after dragging the caret down # on the Y-axis. el.tap() sel.move_cursor_to_end() sel.move_cursor_by_offset(1, backward=True) el.tap(*sel.cursor_location()) x, y = sel.first_caret_location() - # Drag the caret up by 50px, and insert '!'. - self.actions.flick(el, x, y, x, y - 50).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + # Drag the caret up by 40px, and insert '!'. + self.actions.flick(el, x, y, x, y - 40).perform() + self.actions.send_keys(content_to_add).perform() self.assertNotEqual(non_target_content, sel.content) def test_drag_caret_from_front_to_end_across_columns(self): self.open_test_html('layout/test_carets_columns.html') el = self.marionette.find_element(By.ID, 'columns-inner') sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add @@ -226,17 +230,17 @@ class AccessibleCaretCursorModeTestCase( sel.move_cursor_to_front() el.tap(*sel.cursor_location()) src_x, src_y = sel.first_caret_location() dest_x, dest_y = el.rect['width'], el.rect['height'] # Drag the first caret to the bottom-right corner of the element. self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() - self.actions.key_down(content_to_add).key_up(content_to_add).perform() + self.actions.send_keys(content_to_add).perform() self.assertEqual(target_content, sel.content) def test_move_cursor_to_front_by_dragging_caret_to_front_br_element(self): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, self._contenteditable_id) sel = SelectionManager(el) content_to_add_1 = '!' content_to_add_2 = '\n\n' @@ -260,10 +264,10 @@ class AccessibleCaretCursorModeTestCase( sel.move_cursor_to_end() sel.move_cursor_by_offset(1, backward=True) el.tap(*sel.cursor_location()) src_x, src_y = sel.first_caret_location() # Move first caret to the front of the input box. self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() - self.actions.key_down(content_to_add_1).key_up(content_to_add_1).perform() + self.actions.send_keys(content_to_add_1).perform() self.assertEqual(target_content, sel.content)
--- a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py +++ b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py @@ -6,35 +6,26 @@ import re import sys import os # Add this directory to the import path. sys.path.append(os.path.dirname(__file__)) from selection import ( + CaretActions, SelectionManager, ) from marionette_driver.by import By -from marionette_driver.legacy_actions import Actions from marionette_harness.marionette_test import ( MarionetteTestCase, SkipTest, parameterized ) - -def skip_if_not_rotatable(target): - def wrapper(self, *args, **kwargs): - if not self.marionette.session_capabilities.get('rotatable'): - raise SkipTest('skipping due to device not rotatable') - return target(self, *args, **kwargs) - return wrapper - - class AccessibleCaretSelectionModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under selection mode.''' # Element IDs. _input_id = 'input' _input_padding_id = 'input-padding' _input_size_id = 'input-size' _textarea_id = 'textarea' _textarea2_id = 'textarea2' @@ -59,17 +50,21 @@ class AccessibleCaretSelectionModeTestCa # Code to execute before every test is running. super(AccessibleCaretSelectionModeTestCase, self).setUp() self.carets_tested_pref = 'layout.accessiblecaret.enabled' self.prefs = { 'layout.word_select.eat_space_to_next_word': False, self.carets_tested_pref: True, } self.marionette.set_prefs(self.prefs) - self.actions = Actions(self.marionette) + self.actions = CaretActions(self.marionette) + + def tearDown(self): + self.marionette.actions.release() + super(AccessibleCaretSelectionModeTestCase, self).tearDown() def open_test_html(self, test_html): self.marionette.navigate(self.marionette.absolute_url(test_html)) def word_offset(self, text, ordinal): 'Get the character offset of the ordinal-th word in text.' tokens = re.split(r'(\S+)', text) # both words and spaces spaces = tokens[0::2] # collect spaces at odd indices @@ -587,18 +582,18 @@ class AccessibleCaretSelectionModeTestCa # Goal: the selection is not changed after dragging the caret on the # Y-axis. target_content = words[1] self.long_press_on_word(el, 1) (caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location() - # Drag the first caret up by 50px. - self.actions.flick(el, caret1_x, caret1_y, caret1_x, caret1_y - 50).perform() + # Drag the first caret up by 40px. + self.actions.flick(el, caret1_x, caret1_y, caret1_x, caret1_y - 40).perform() self.assertEqual(target_content, sel.selected_content) # Drag the second caret down by 50px. self.actions.flick(el, caret2_x, caret2_y, caret2_x, caret2_y + 50).perform() self.assertEqual(target_content, sel.selected_content) def test_carets_should_not_appear_when_long_pressing_svg_shapes(self): self.open_test_html(self._svg_shapes_html)