def edge_scroll(self, frame, direction, dist, release=True): """edge scroll - performs task switching action. direction = 'LtoR' or 'RtoL' (finger movement direction) dist = percentage of horizontal distance travel, max is 1.0 release = if set to False, the Action object will be returned so the user can complete the release action""" start_x = 0 dist_travelled = 0 time_increment = 0.01 if dist > 1: dist = 1 if direction == 'LtoR': start_x = 0 elif direction == 'RtoL': start_x = frame.size['width'] dist *= -1 # travel opposite direction limit = dist * frame.size['width'] dist_unit = limit * time_increment action = Actions(self.marionette) action.press(frame, start_x, frame.size['height'] / 2) # press either the left or right edge while abs(dist_travelled) < abs(limit): action.move_by_offset(dist_unit, 0) action.wait(time_increment) dist_travelled += dist_unit if release: action.release() action.perform() return action
def press_release(marionette, times, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) action = Actions(marionette) button = marionette.find_element(By.ID, "button1") action.press(button).release() # Insert wait between each press and release chain. for _ in range(times-1): action.wait(0.1) action.press(button).release() action.perform() wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def press_release(marionette, times, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) action = Actions(marionette) button = marionette.find_element(By.ID, "button1") action.press(button).release() # Insert wait between each press and release chain. for _ in range(times - 1): action.wait(0.1) action.press(button).release() action.perform() wait_for_condition_else_raise( marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
class CommonCaretTestCase(object): '''Common test cases for a collapsed selection with a single caret. To run these test cases, a subclass must inherit from both this class and MarionetteTestCase. ''' _input_selector = (By.ID, 'input') _textarea_selector = (By.ID, 'textarea') _contenteditable_selector = (By.ID, 'contenteditable') def setUp(self): # Code to execute before a test is being run. super(CommonCaretTestCase, self).setUp() self.actions = Actions(self.marionette) # The caret to be tested. self.caret_tested_pref = None # The caret to be disabled in this test suite. self.caret_disabled_pref = None self.caret_timeout_ms_pref = None def set_pref(self, pref_name, value): '''Set a preference to value. For example: >>> set_pref('layout.accessiblecaret.enabled', True) ''' pref_name = repr(pref_name) if isinstance(value, bool): value = 'true' if value else 'false' func = 'setBoolPref' elif isinstance(value, int): value = str(value) func = 'setIntPref' else: value = repr(value) func = 'setCharPref' with self.marionette.using_context('chrome'): script = 'Services.prefs.%s(%s, %s)' % (func, pref_name, value) self.marionette.execute_script(script) def timeout_ms(self): 'Return touch caret expiration time in milliseconds.' with self.marionette.using_context('chrome'): return self.marionette.execute_script( 'return Services.prefs.getIntPref("%s");' % self.caret_timeout_ms_pref) def open_test_html(self, enabled=True, timeout_ms=0): '''Open html for testing and locate elements, enable/disable touch caret, and set touch caret expiration time in milliseconds). ''' self.set_pref(self.caret_tested_pref, enabled) self.set_pref(self.caret_disabled_pref, False) self.set_pref(self.caret_timeout_ms_pref, timeout_ms) test_html = self.marionette.absolute_url('test_touchcaret.html') self.marionette.navigate(test_html) self._input = self.marionette.find_element(*self._input_selector) self._textarea = self.marionette.find_element(*self._textarea_selector) self._contenteditable = self.marionette.find_element( *self._contenteditable_selector) def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[ 1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size['width'], el.size['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() assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get touch caret location at the front. el.tap() sel.move_caret_to_front() dest_x, dest_y = sel.touch_caret_location() # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) src_x, src_y = sel.touch_caret_location() # Move touch 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() assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.timeout_ms() / 1000.0 # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect['x'], el.rect['y'] self.marionette.execute_script(''' var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0); ''', script_args=[el_center_x, el_center_y], sandbox='system') 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() assertFunc(non_target_content, sel.content) def _test_caret_not_appear_when_typing_in_scrollable_content( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + string.ascii_letters + content_to_add el.tap() sel.move_caret_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should be inserted at the end of the <input>. el.send_keys(content_to_add) assertFunc(target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._input, self.assertEqual) def test_input_caret_not_appear_when_typing_in_scrollable_content(self): self.open_test_html() self._test_caret_not_appear_when_typing_in_scrollable_content( self._input, self.assertEqual) def test_input_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._input, self.assertNotEqual) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character( self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._textarea, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character( self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._textarea, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertEqual) def test_contenteditable_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._contenteditable, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled( self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character( self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertNotEqual)
class TouchCaretTest(MarionetteTestCase): _input_selector = (By.ID, 'input') _textarea_selector = (By.ID, 'textarea') _contenteditable_selector = (By.ID, 'contenteditable') _large_expiration_time = 3000 * 20 # 60 seconds def setUp(self): # Code to execute before a test is being run. MarionetteTestCase.setUp(self) self.actions = Actions(self.marionette) self.original_expiration_time = self.expiration_time def tearDown(self): # Code to execute after a test is being run. self.expiration_time = self.original_expiration_time MarionetteTestCase.tearDown(self) @property def expiration_time(self): 'Return touch caret expiration time in milliseconds.' return self.marionette.execute_script( 'return SpecialPowers.getIntPref("touchcaret.expiration.time");') @expiration_time.setter def expiration_time(self, expiration_time): 'Set touch caret expiration time in milliseconds.' self.marionette.execute_script( 'SpecialPowers.setIntPref("touchcaret.expiration.time", arguments[0]);', script_args=[expiration_time]) def openTestHtml(self, enabled=True, expiration_time=None): '''Open html for testing and locate elements, enable/disable touch caret, and set touch caret expiration time in milliseconds). ''' self.marionette.execute_async_script( 'SpecialPowers.pushPrefEnv({"set": [["touchcaret.enabled", %s]]}, marionetteScriptFinished);' % ('true' if enabled else 'false')) # Set a larger expiration time to avoid intermittent test failures. if expiration_time is not None: self.expiration_time = expiration_time test_html = self.marionette.absolute_url('test_touchcaret.html') self.marionette.navigate(test_html) self._input = self.marionette.find_element(*self._input_selector) self._textarea = self.marionette.find_element(*self._textarea_selector) self._contenteditable = self.marionette.find_element(*self._contenteditable_selector) def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size['width'], el.size['height'] self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Move touch caret to the top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.expiration_time / 1000.0 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect['x'], el.rect['y'] self.marionette.execute_script( '''var utils = SpecialPowers.getDOMWindowUtils(window); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0);''', script_args=[el_center_x, el_center_y] ) self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(non_target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_the_right_by_one_character(self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._input, self.assertEqual) def test_input_touch_caret_timeout(self): self.openTestHtml(enabled=True) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._input, self.assertNotEqual) def test_input_touch_caret_hides_after_receiving_wheel_event(self): self.openTestHtml(enabled=True, expiration_time=0) self._test_touch_caret_hides_after_receiving_wheel_event(self._input, self.assertNotEqual) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): self.openTestHtml(enabled=True) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._textarea, self.assertNotEqual) def test_textarea_touch_caret_hides_after_receiving_wheel_event(self): self.openTestHtml(enabled=True, expiration_time=0) self._test_touch_caret_hides_after_receiving_wheel_event(self._textarea, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._textarea, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.openTestHtml(enabled=True, expiration_time=self._large_expiration_time) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._contenteditable, self.assertEqual) def test_contenteditable_touch_caret_timeout(self): self.openTestHtml(enabled=True) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._contenteditable, self.assertNotEqual) def test_contenteditable_touch_caret_hides_after_receiving_wheel_event(self): self.openTestHtml(enabled=True, expiration_time=0) self._test_touch_caret_hides_after_receiving_wheel_event(self._contenteditable, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.openTestHtml(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._contenteditable, self.assertNotEqual)
class CommonCaretTestCase(object): """Common test cases for a collapsed selection with a single caret. To run these test cases, a subclass must inherit from both this class and MarionetteTestCase. """ def setUp(self): # Code to execute before a test is being run. super(CommonCaretTestCase, self).setUp() self.actions = Actions(self.marionette) def timeout_ms(self): "Return touch caret expiration time in milliseconds." return self.marionette.get_pref(self.caret_timeout_ms_pref) def open_test_html(self): "Open html for testing and locate elements." test_html = self.marionette.absolute_url("test_touchcaret.html") self.marionette.navigate(test_html) self._input = self.marionette.find_element(By.ID, "input") self._textarea = self.marionette.find_element(By.ID, "textarea") self._contenteditable = self.marionette.find_element(By.ID, "contenteditable") def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size["width"], el.size["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() assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" target_content = content_to_add + sel.content # Get touch caret location at the front. el.tap() sel.move_caret_to_front() dest_x, dest_y = sel.touch_caret_location() # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) src_x, src_y = sel.touch_caret_location() # Move touch 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() assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.timeout_ms() / 1000.0 # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect["x"], el.rect["y"] self.marionette.execute_script( """ var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0); """, script_args=[el_center_x, el_center_y], sandbox="system", ) 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() assertFunc(non_target_content, sel.content) def _test_caret_not_appear_when_typing_in_scrollable_content(self, el, assertFunc): sel = SelectionManager(el) content_to_add = "!" target_content = sel.content + string.ascii_letters + content_to_add el.tap() sel.move_caret_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should be inserted at the end of the <input>. el.send_keys(content_to_add) assertFunc(target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertEqual) def test_input_caret_not_appear_when_typing_in_scrollable_content(self): self.open_test_html() self._test_caret_not_appear_when_typing_in_scrollable_content(self._input, self.assertEqual) def test_input_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._input, self.assertNotEqual ) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._textarea, self.assertNotEqual ) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._textarea, self.assertNotEqual ) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._contenteditable, self.assertEqual ) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertEqual ) def test_contenteditable_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._contenteditable, self.assertNotEqual ) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertNotEqual )
class AccessibleCaretCursorModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under cursor mode. We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as caret for short. ''' # Element IDs. _input_id = 'input' _input_padding_id = 'input-padding' _textarea_id = 'textarea' _textarea_one_line_id = 'textarea-one-line' _contenteditable_id = 'contenteditable' # Test html files. _cursor_html = 'test_carets_cursor.html' def setUp(self): # Code to execute before every test is running. super(AccessibleCaretCursorModeTestCase, self).setUp() self.caret_tested_pref = 'layout.accessiblecaret.enabled' self.caret_timeout_ms_pref = 'layout.accessiblecaret.timeout_ms' self.hide_carets_for_mouse = 'layout.accessiblecaret.hide_carets_for_mouse_input' self.prefs = { self.caret_tested_pref: True, self.caret_timeout_ms_pref: 0, self.hide_carets_for_mouse: False, } self.marionette.set_prefs(self.prefs) self.actions = Actions(self.marionette) 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): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get first caret (x, y) at position 1 and 2. el.tap() sel.move_cursor_to_front() cursor0_x, cursor0_y = sel.cursor_location() first_caret0_x, first_caret0_y = sel.first_caret_location() sel.move_cursor_by_offset(1) first_caret1_x, first_caret1_y = sel.first_caret_location() # 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.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) sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make first caret appear. el.tap() 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.size['width'], el.size['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.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) sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get first caret location at the front. el.tap() sel.move_cursor_to_front() dest_x, dest_y = sel.first_caret_location() # Tap to make first caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() 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.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_dragging_caret_to_top_left_corner_after_timeout(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Set caret timeout to be 1 second. timeout = 1 self.marionette.set_pref(self.caret_timeout_ms_pref, timeout * 1000) # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make first caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_cursor_to_end() sel.move_cursor_by_offset(1, backward=True) el.tap(*sel.cursor_location()) # Wait until first caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.first_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).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.assertNotEqual(non_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 = '!' target_content = sel.content + string.ascii_letters + content_to_add el.tap() sel.move_cursor_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.first_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should be inserted at the end of the <input>. el.send_keys(content_to_add) self.assertEqual(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_when_dragging_to_editable_content_boundary(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = sel.content + content_to_add # Goal: the cursor position is not changed after dragging the caret down # 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.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) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # 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() self.assertNotEqual(non_target_content, sel.content) def test_drag_caret_from_front_to_end_across_columns(self): self.open_test_html('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 # Goal: the cursor position can be changed by dragging the caret from # the front to the end of the content. # Tap to make the cursor appear. before_image_1 = self.marionette.find_element(By.ID, 'before-image-1') before_image_1.tap() # Tap the front of the content to make first caret appear. sel.move_cursor_to_front() el.tap(*sel.cursor_location()) src_x, src_y = sel.first_caret_location() dest_x, dest_y = el.size['width'], el.size['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.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' target_content = content_to_add_1 + content_to_add_2 + sel.content # Goal: the cursor position can be changed by dragging the caret from # the end of the content to the front br element. Because we cannot get # caret location if it's on a br element, we need to get the first caret # location then adding the new lines. # Get first caret location at the front. el.tap() sel.move_cursor_to_front() dest_x, dest_y = sel.first_caret_location() # Append new line to the front of the content. el.send_keys(content_to_add_2); # Tap to make first caret appear. el.tap() 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.assertEqual(target_content, sel.content)
def wait(self, seconds: int): actions = Actions(self.marionette) actions.wait(seconds).perform()
class CommonCaretTestCase(object): '''Common test cases for a collapsed selection with a single caret. To run these test cases, a subclass must inherit from both this class and MarionetteTestCase. ''' _input_selector = (By.ID, 'input') _textarea_selector = (By.ID, 'textarea') _contenteditable_selector = (By.ID, 'contenteditable') def setUp(self): # Code to execute before a test is being run. super(CommonCaretTestCase, self).setUp() self.actions = Actions(self.marionette) # The caret to be tested. self.caret_tested_pref = None # The caret to be disabled in this test suite. self.caret_disabled_pref = None self.caret_timeout_ms_pref = None def set_pref(self, pref_name, value): '''Set a preference to value. For example: >>> set_pref('layout.accessiblecaret.enabled', True) ''' pref_name = repr(pref_name) if isinstance(value, bool): value = 'true' if value else 'false' func = 'setBoolPref' elif isinstance(value, int): value = str(value) func = 'setIntPref' else: value = repr(value) func = 'setCharPref' with self.marionette.using_context('chrome'): script = 'Services.prefs.%s(%s, %s)' % (func, pref_name, value) self.marionette.execute_script(script) def timeout_ms(self): 'Return touch caret expiration time in milliseconds.' with self.marionette.using_context('chrome'): return self.marionette.execute_script( 'return Services.prefs.getIntPref("%s");' % self.caret_timeout_ms_pref) def open_test_html(self, enabled=True, timeout_ms=0): '''Open html for testing and locate elements, enable/disable touch caret, and set touch caret expiration time in milliseconds). ''' self.set_pref(self.caret_tested_pref, enabled) self.set_pref(self.caret_disabled_pref, False) self.set_pref(self.caret_timeout_ms_pref, timeout_ms) test_html = self.marionette.absolute_url('test_touchcaret.html') self.marionette.navigate(test_html) self._input = self.marionette.find_element(*self._input_selector) self._textarea = self.marionette.find_element(*self._textarea_selector) self._contenteditable = self.marionette.find_element(*self._contenteditable_selector) def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size['width'], el.size['height'] self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get touch caret location at the front. el.tap() sel.move_caret_to_front() dest_x, dest_y = sel.touch_caret_location() # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) src_x, src_y = sel.touch_caret_location() # Move touch caret to the front of the input box. self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.timeout_ms() / 1000.0 # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect['x'], el.rect['y'] self.marionette.execute_script( ''' var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0); ''', script_args=[el_center_x, el_center_y], sandbox='system' ) self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() el.send_keys(content_to_add) assertFunc(non_target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertEqual) def test_input_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._input, self.assertNotEqual) def test_input_touch_caret_hides_after_receiving_wheel_event(self): self.open_test_html() self._test_touch_caret_hides_after_receiving_wheel_event(self._input, self.assertNotEqual) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._textarea, self.assertNotEqual) def test_textarea_touch_caret_hides_after_receiving_wheel_event(self): self.open_test_html() self._test_touch_caret_hides_after_receiving_wheel_event(self._textarea, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._textarea, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._contenteditable, self.assertEqual) def test_contenteditable_touch_caret_timeout(self): self.open_test_html(timeout_ms=1000) self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._contenteditable, self.assertNotEqual) def test_contenteditable_touch_caret_hides_after_receiving_wheel_event(self): self.open_test_html() self._test_touch_caret_hides_after_receiving_wheel_event(self._contenteditable, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): self.open_test_html(enabled=False) self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._contenteditable, self.assertNotEqual)
class AccessibleCaretCursorModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under cursor mode. We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as caret for short. ''' # Element IDs. _input_id = 'input' _input_padding_id = 'input-padding' _textarea_id = 'textarea' _textarea_one_line_id = 'textarea-one-line' _contenteditable_id = 'contenteditable' # Test html files. _cursor_html = 'test_carets_cursor.html' def setUp(self): # Code to execute before every test is running. super(AccessibleCaretCursorModeTestCase, self).setUp() self.caret_tested_pref = 'layout.accessiblecaret.enabled' self.caret_timeout_ms_pref = 'layout.accessiblecaret.timeout_ms' self.hide_carets_for_mouse = 'layout.accessiblecaret.hide_carets_for_mouse_input' self.prefs = { self.caret_tested_pref: True, self.caret_timeout_ms_pref: 0, self.hide_carets_for_mouse: False, } self.marionette.set_prefs(self.prefs) self.actions = Actions(self.marionette) 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): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get first caret (x, y) at position 1 and 2. el.tap() sel.move_cursor_to_front() cursor0_x, cursor0_y = sel.cursor_location() first_caret0_x, first_caret0_y = sel.first_caret_location() sel.move_cursor_by_offset(1) first_caret1_x, first_caret1_y = sel.first_caret_location() # 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.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) sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make first caret appear. el.tap() 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.size['width'], el.size['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.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) sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get first caret location at the front. el.tap() sel.move_cursor_to_front() dest_x, dest_y = sel.first_caret_location() # Tap to make first caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() 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.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_dragging_caret_to_top_left_corner_after_timeout(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Set caret timeout to be 1 second. timeout = 1 self.marionette.set_pref(self.caret_timeout_ms_pref, timeout * 1000) # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make first caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_cursor_to_end() sel.move_cursor_by_offset(1, backward=True) el.tap(*sel.cursor_location()) # Wait until first caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.first_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).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.assertNotEqual(non_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 el.tap() sel.move_cursor_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.first_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should not be inserted at the front of the <input>. el.send_keys(content_to_add) 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_when_dragging_to_editable_content_boundary(self, el_id): self.open_test_html(self._cursor_html) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = sel.content + content_to_add # Goal: the cursor position is not changed after dragging the caret down # 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.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) el = self.marionette.find_element(By.ID, el_id) sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # 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() self.assertNotEqual(non_target_content, sel.content) def test_drag_caret_from_front_to_end_across_columns(self): self.open_test_html('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 # Goal: the cursor position can be changed by dragging the caret from # the front to the end of the content. # Tap to make the cursor appear. before_image_1 = self.marionette.find_element(By.ID, 'before-image-1') before_image_1.tap() # Tap the front of the content to make first caret appear. sel.move_cursor_to_front() el.tap(*sel.cursor_location()) src_x, src_y = sel.first_caret_location() dest_x, dest_y = el.size['width'], el.size['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.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' target_content = content_to_add_1 + content_to_add_2 + sel.content # Goal: the cursor position can be changed by dragging the caret from # the end of the content to the front br element. Because we cannot get # caret location if it's on a br element, we need to get the first caret # location then adding the new lines. # Get first caret location at the front. el.tap() sel.move_cursor_to_front() dest_x, dest_y = sel.first_caret_location() # Append new line to the front of the content. el.send_keys(content_to_add_2); # Tap to make first caret appear. el.tap() 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.assertEqual(target_content, sel.content)
class AccessibleCaretCursorModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under cursor mode, aka touch caret. ''' def setUp(self): # Code to execute before a test is being run. super(AccessibleCaretCursorModeTestCase, self).setUp() self.caret_tested_pref = 'layout.accessiblecaret.enabled' self.caret_timeout_ms_pref = 'layout.accessiblecaret.timeout_ms' self.prefs = { self.caret_tested_pref: True, self.caret_timeout_ms_pref: 0, } self.marionette.set_prefs(self.prefs) self.actions = Actions(self.marionette) def timeout_ms(self): 'Return touch caret expiration time in milliseconds.' return self.marionette.get_pref(self.caret_timeout_ms_pref) def open_test_html(self): 'Open html for testing and locate elements.' test_html = self.marionette.absolute_url('test_touchcaret.html') self.marionette.navigate(test_html) self._input = self.marionette.find_element(By.ID, 'input') self._textarea = self.marionette.find_element(By.ID, 'textarea') self._contenteditable = self.marionette.find_element(By.ID, 'contenteditable') def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size['width'], el.size['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() assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get touch caret location at the front. el.tap() sel.move_caret_to_front() dest_x, dest_y = sel.touch_caret_location() # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) src_x, src_y = sel.touch_caret_location() # Move touch 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() assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.timeout_ms() / 1000.0 # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect['x'], el.rect['y'] self.marionette.execute_script( ''' var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0); ''', script_args=[el_center_x, el_center_y], sandbox='system' ) 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() assertFunc(non_target_content, sel.content) def _test_caret_not_appear_when_typing_in_scrollable_content(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + string.ascii_letters + content_to_add el.tap() sel.move_caret_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should be inserted at the end of the <input>. el.send_keys(content_to_add) assertFunc(target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertEqual) def test_input_caret_not_appear_when_typing_in_scrollable_content(self): self.open_test_html() self._test_caret_not_appear_when_typing_in_scrollable_content(self._input, self.assertEqual) def test_input_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._input, self.assertNotEqual) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._textarea, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._textarea, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._contenteditable, self.assertEqual) def test_contenteditable_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._contenteditable, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content(self._contenteditable, self.assertNotEqual) def test_caret_does_not_jump_when_dragging_to_editable_content_boundary(self): self.open_test_html() el = self._input sel = SelectionManager(el) content_to_add = '!' non_target_content = sel.content + content_to_add # Goal: the cursor position does not being changed after dragging the # caret down on the Y-axis. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) x, y = sel.touch_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.assertNotEqual(non_target_content, sel.content)
class AccessibleCaretCursorModeTestCase(MarionetteTestCase): '''Test cases for AccessibleCaret under cursor mode, aka touch caret. ''' def setUp(self): # Code to execute before a test is being run. super(AccessibleCaretCursorModeTestCase, self).setUp() self.caret_tested_pref = 'layout.accessiblecaret.enabled' self.caret_timeout_ms_pref = 'layout.accessiblecaret.timeout_ms' self.prefs = { self.caret_tested_pref: True, self.caret_timeout_ms_pref: 0, } self.marionette.set_prefs(self.prefs) self.actions = Actions(self.marionette) def timeout_ms(self): 'Return touch caret expiration time in milliseconds.' return self.marionette.get_pref(self.caret_timeout_ms_pref) def open_test_html(self): 'Open html for testing and locate elements.' test_html = self.marionette.absolute_url('test_touchcaret.html') self.marionette.navigate(test_html) self._input = self.marionette.find_element(By.ID, 'input') self._textarea = self.marionette.find_element(By.ID, 'textarea') self._contenteditable = self.marionette.find_element( By.ID, 'contenteditable') def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content target_content = target_content[:1] + content_to_add + target_content[ 1:] # Get touch caret (x, y) at position 1 and 2. el.tap() sel.move_caret_to_front() caret0_x, caret0_y = sel.caret_location() touch_caret0_x, touch_caret0_y = sel.touch_caret_location() sel.move_caret_by_offset(1) touch_caret1_x, touch_caret1_y = sel.touch_caret_location() # Tap the front of the input to make touch caret appear. el.tap(caret0_x, caret0_y) # Move touch caret self.actions.flick(el, touch_caret0_x, touch_caret0_y, touch_caret1_x, touch_caret1_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(target_content, sel.content) def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + content_to_add # Tap the front of the input to make touch caret appear. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) # Move touch caret to the bottom-right corner of the element. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = el.size['width'], el.size['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() assertFunc(target_content, sel.content) def _test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = content_to_add + sel.content # Get touch caret location at the front. el.tap() sel.move_caret_to_front() dest_x, dest_y = sel.touch_caret_location() # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) src_x, src_y = sel.touch_caret_location() # Move touch 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() assertFunc(target_content, sel.content) def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Get touch caret expiration time in millisecond, and convert it to second. timeout = self.timeout_ms() / 1000.0 # Set a 3x timeout margin to prevent intermittent test failures. timeout *= 3 # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Wait until touch caret disappears, then pretend to move it to the # top-left corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform() self.actions.key_down(content_to_add).key_up(content_to_add).perform() assertFunc(non_target_content, sel.content) def _test_touch_caret_hides_after_receiving_wheel_event( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' non_target_content = content_to_add + sel.content # Tap to make touch caret appear. Note: it's strange that when the caret # is at the end, the rect of the caret in <textarea> cannot be obtained. # A bug perhaps. el.tap() sel.move_caret_to_end() sel.move_caret_by_offset(1, backward=True) el.tap(*sel.caret_location()) # Send an arbitrary scroll-down-10px wheel event to the center of the # input box to hide touch caret. Then pretend to move it to the top-left # corner of the input box. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 el_center_x, el_center_y = el.rect['x'], el.rect['y'] self.marionette.execute_script(''' var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendWheelEvent(arguments[0], arguments[1], 0, 10, 0, WheelEvent.DOM_DELTA_PIXEL, 0, 0, 0, 0); ''', script_args=[el_center_x, el_center_y], sandbox='system') 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() assertFunc(non_target_content, sel.content) def _test_caret_not_appear_when_typing_in_scrollable_content( self, el, assertFunc): sel = SelectionManager(el) content_to_add = '!' target_content = sel.content + string.ascii_letters + content_to_add el.tap() sel.move_caret_to_end() # Insert a long string to the end of the <input>, which triggers # ScrollPositionChanged event. el.send_keys(string.ascii_letters) # The caret should not be visible. If it does appear wrongly due to the # ScrollPositionChanged event, we can drag it to the front of the # <input> to change the cursor position. src_x, src_y = sel.touch_caret_location() dest_x, dest_y = 0, 0 self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform() # The content should be inserted at the end of the <input>. el.send_keys(content_to_add) assertFunc(target_content, sel.content) ######################################################################## # <input> test cases with touch caret enabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._input, self.assertEqual) def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._input, self.assertEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._input, self.assertEqual) def test_input_caret_not_appear_when_typing_in_scrollable_content(self): self.open_test_html() self._test_caret_not_appear_when_typing_in_scrollable_content( self._input, self.assertEqual) def test_input_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._input, self.assertNotEqual) ######################################################################## # <input> test cases with touch caret disabled ######################################################################## def test_input_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._input, self.assertNotEqual) def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._input, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret enabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._textarea, self.assertEqual) def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._textarea, self.assertEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._textarea, self.assertEqual) def test_textarea_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._textarea, self.assertNotEqual) ######################################################################## # <textarea> test cases with touch caret disabled ######################################################################## def test_textarea_move_caret_to_the_right_by_one_character_disabled(self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._textarea, self.assertNotEqual) def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._textarea, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret enabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character(self): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self): self.open_test_html() self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner( self._contenteditable, self.assertEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner( self): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertEqual) def test_contenteditable_touch_caret_timeout(self): with self.marionette.using_prefs({self.caret_timeout_ms_pref: 1000}): self.open_test_html() self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout( self._contenteditable, self.assertNotEqual) ######################################################################## # <div> contenteditable test cases with touch caret disabled ######################################################################## def test_contenteditable_move_caret_to_the_right_by_one_character_disabled( self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_the_right_by_one_character( self._contenteditable, self.assertNotEqual) def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled( self): with self.marionette.using_prefs({self.caret_tested_pref: False}): self.open_test_html() self._test_move_caret_to_front_by_dragging_touch_caret_to_front_of_content( self._contenteditable, self.assertNotEqual) def test_caret_does_not_jump_when_dragging_to_editable_content_boundary( self): self.open_test_html() el = self._input sel = SelectionManager(el) content_to_add = '!' non_target_content = sel.content + content_to_add # Goal: the cursor position does not being changed after dragging the # caret down on the Y-axis. el.tap() sel.move_caret_to_front() el.tap(*sel.caret_location()) x, y = sel.touch_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.assertNotEqual(non_target_content, sel.content)