コード例 #1
0
 def send_message(self, to_user, message, wait_load=0.5):
     # Make firefox go to the users page.
     self.client.navigate("https://www.messenger.com/t/{}".format(to_user))
     # Give a little bit of time to load.
     time.sleep(wait_load)
     for letter in message:
         # Make the typing look realistic.
         keep_down = random.uniform(0.005, 0.010)
         wait_time = keep_down + random.uniform(0.02, 0.05)
         # Send off the action
         action = Actions(self.client)
         if letter != '\n':
             action.key_down(letter).wait(keep_down).key_up(letter)
         else:
             # Handle multi line messages.
             action.key_down(Keys.SHIFT).key_down(Keys.ENTER)\
                 .wait(keep_down).key_up(Keys.SHIFT).key_up(Keys.ENTER)
         action.perform()
         # wait for it to complete.
         time.sleep(wait_time)
     # Send message.
     action.key_down('\n').wait(keep_down).key_up('\n')
     action.perform()
コード例 #2
0
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)
コード例 #3
0
ファイル: test_touchcaret.py プロジェクト: kapeels/gecko-dev
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
            )
コード例 #4
0
class TestKeyActions(MarionetteTestCase):
    def setUp(self):
        MarionetteTestCase.setUp(self)
        if self.marionette.session_capabilities["platformName"] == "Darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("javascriptPage.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT)
                        .key_down("a")
                        .key_up(Keys.SHIFT)
                        .key_down("b")
                        .key_down("c")
                        .perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_up(self.mod_key)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .wait(.5)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")

    @skip_if_b2g
    def test_open_in_new_window_shortcut(self):
        el = self.marionette.find_element(By.ID, "updatediv")
        start_win = self.marionette.current_chrome_window_handle
        (self.key_action.key_down(Keys.SHIFT)
                        .press(el)
                        .release()
                        .key_up(Keys.SHIFT)
                        .perform())
        self.wait_for_condition(
            lambda mn: len(self.marionette.window_handles) == 2)
        chrome_window_handles = self.marionette.chrome_window_handles
        chrome_window_handles.remove(start_win)
        [new_win] = chrome_window_handles
        self.marionette.switch_to_window(new_win)
        self.marionette.close()
        self.marionette.switch_to_window(start_win)
        self.assertEqual(self.key_reporter_value, "")
コード例 #5
0
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):
    def setUp(self):
        super(TestKeyActions, self).setUp()
        if self.marionette.session_capabilities["platformName"] == "mac":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("keyboard.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(
            By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT).key_down("a").key_up(
            Keys.SHIFT).key_down("b").key_down("c").perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key).key_down("a").key_up(
            self.mod_key).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(
            self.mod_key).key_down("a").key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(
            self.mod_key).key_down("a").wait(.5).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")
コード例 #6
0
class TestKeyActions(MarionetteTestCase):

    def setUp(self):
        MarionetteTestCase.setUp(self)
        if self.marionette.session_capabilities['platformName'] == 'DARWIN':
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("javascriptPage.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element("id", "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_attribute('value')

    def test_key_action_basic_input(self):
        self.key_action.key_down('a').key_down('b').key_down('c').perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT)
                        .key_down('a')
                        .key_up(Keys.SHIFT)
                        .key_down('b')
                        .key_down('c')
                        .perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down('a').key_down('b').key_down('c').perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down('a')
                        .key_up(self.mod_key)
                        .key_down('x')
                        .perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down('a').key_down('b').key_down('c').perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down('a')
                        .key_down('x')
                        .perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down('a').key_down('b').key_down('c').perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down('a').key_down('b').key_down('c').perform()
        (self.key_action.key_down(self.mod_key)
                        .key_down('a')
                        .wait(.5)
                        .key_down('x')
                        .perform())
        self.assertEqual(self.key_reporter_value, "")

    @skip_if_b2g
    def test_open_in_new_window_shortcut(self):
        el = self.marionette.find_element('id', 'updatediv')
        start_win = self.marionette.current_chrome_window_handle
        (self.key_action.key_down(Keys.SHIFT)
                        .press(el)
                        .release()
                        .key_up(Keys.SHIFT)
                        .perform())
        self.wait_for_condition(
            lambda mn: len(self.marionette.window_handles) == 2)
        chrome_window_handles = self.marionette.chrome_window_handles
        chrome_window_handles.remove(start_win)
        [new_win] = chrome_window_handles
        self.marionette.switch_to_window(new_win)
        self.marionette.close()
        self.marionette.switch_to_window(start_win)
        self.assertEqual(self.key_reporter_value, "")
コード例 #7
0
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)
コード例 #8
0
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):

    def setUp(self):
        super(TestKeyActions, self).setUp()
        if self.marionette.session_capabilities["platformName"] == "darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("javascriptPage.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT)
                        .key_down("a")
                        .key_up(Keys.SHIFT)
                        .key_down("b")
                        .key_down("c")
                        .perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_up(self.mod_key)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .wait(.5)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")

    def test_open_in_new_window_shortcut(self):
        def open_window_with_action():
            el = self.marionette.find_element(By.ID, "updatediv")
            # Ensure that the element is in the current view port because press() doesn't
            # handle that inside the action chain (bug 1295538).
            self.marionette.execute_script('arguments[0].scrollIntoView()', script_args=[el])
            (self.key_action.key_down(Keys.SHIFT)
                            .press(el)
                            .release()
                            .key_up(Keys.SHIFT)
                            .perform())

        new_window = self.open_window(trigger=open_window_with_action)
        self.marionette.switch_to_window(new_window)
        self.marionette.close_chrome_window()
        self.marionette.switch_to_window(self.start_window)
        self.assertEqual(self.key_reporter_value, "")
コード例 #9
0
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):

    def setUp(self):
        super(TestKeyActions, self).setUp()
        if self.marionette.session_capabilities["platformName"] == "darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("keyboard.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT)
                        .key_down("a")
                        .key_up(Keys.SHIFT)
                        .key_down("b")
                        .key_down("c")
                        .perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_up(self.mod_key)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .wait(.5)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")

    @skip_if_mobile("Interacting with chrome windows not available for Fennec")
    def test_open_in_new_window_shortcut(self):

        def open_window_with_action():
            el = self.marionette.find_element(By.TAG_NAME, "a")
            (self.key_action.key_down(Keys.SHIFT)
                            .press(el)
                            .release()
                            .key_up(Keys.SHIFT)
                            .perform())

        self.marionette.navigate(inline("<a href='#'>Click</a>"))
        new_window = self.open_window(trigger=open_window_with_action)

        self.marionette.switch_to_window(new_window)
        self.marionette.close_chrome_window()

        self.marionette.switch_to_window(self.start_window)
コード例 #10
0
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.hide_carets_for_mouse = 'layout.accessiblecaret.hide_carets_for_mouse_input'
        self.prefs = {
            self.caret_tested_pref: True,
            self.hide_carets_for_mouse: False,
        }
        self.marionette.set_prefs(self.prefs)
        self.actions = Actions(self.marionette)

    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)

    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)
コード例 #11
0
class TestKeyActions(MarionetteTestCase):
    def setUp(self):
        MarionetteTestCase.setUp(self)
        if self.marionette.session_capabilities["platformName"] == "darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("javascriptPage.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT)
                        .key_down("a")
                        .key_up(Keys.SHIFT)
                        .key_down("b")
                        .key_down("c")
                        .perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_up(self.mod_key)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(self.mod_key)
                        .key_down("a")
                        .wait(.5)
                        .key_down("x")
                        .perform())
        self.assertEqual(self.key_reporter_value, "")

    def test_open_in_new_window_shortcut(self):
        start_win = self.marionette.current_chrome_window_handle
        el = self.marionette.find_element(By.ID, "updatediv")
        # Ensure that the element is in the current view port because press() doesn't
        # handle that inside the action chain (bug 1295538).
        self.marionette.execute_script('arguments[0].scrollIntoView()', script_args=[el])
        (self.key_action.key_down(Keys.SHIFT)
                        .press(el)
                        .release()
                        .key_up(Keys.SHIFT)
                        .perform())
        self.wait_for_condition(
            lambda mn: len(self.marionette.window_handles) == 2)
        chrome_window_handles = self.marionette.chrome_window_handles
        chrome_window_handles.remove(start_win)
        [new_win] = chrome_window_handles
        self.marionette.switch_to_window(new_win)
        self.marionette.close()
        self.marionette.switch_to_window(start_win)
        self.assertEqual(self.key_reporter_value, "")
コード例 #12
0
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):
    def setUp(self):
        super(TestKeyActions, self).setUp()
        if self.marionette.session_capabilities["platformName"] == "darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("javascriptPage.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(
            By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT).key_down("a").key_up(
            Keys.SHIFT).key_down("b").key_down("c").perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key).key_down("a").key_up(
            self.mod_key).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(
            self.mod_key).key_down("a").key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(
            self.mod_key).key_down("a").wait(.5).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")

    @skip_if_mobile("Interacting with chrome windows not available for Fennec")
    def test_open_in_new_window_shortcut(self):
        def open_window_with_action():
            el = self.marionette.find_element(By.ID, "updatediv")
            # Ensure that the element is in the current view port because press() doesn't
            # handle that inside the action chain (bug 1295538).
            self.marionette.execute_script('arguments[0].scrollIntoView()',
                                           script_args=[el])
            (self.key_action.key_down(Keys.SHIFT).press(el).release().key_up(
                Keys.SHIFT).perform())

        new_window = self.open_window(trigger=open_window_with_action)
        self.marionette.switch_to_window(new_window)
        self.marionette.close_chrome_window()
        self.marionette.switch_to_window(self.start_window)
        self.assertEqual(self.key_reporter_value, "")
コード例 #13
0
class TestKeyActions(WindowManagerMixin, MarionetteTestCase):
    def setUp(self):
        super(TestKeyActions, self).setUp()
        if self.marionette.session_capabilities["platformName"] == "darwin":
            self.mod_key = Keys.META
        else:
            self.mod_key = Keys.CONTROL
        test_html = self.marionette.absolute_url("keyboard.html")
        self.marionette.navigate(test_html)
        self.reporter_element = self.marionette.find_element(
            By.ID, "keyReporter")
        self.reporter_element.click()
        self.key_action = Actions(self.marionette)

    @property
    def key_reporter_value(self):
        return self.reporter_element.get_property("value")

    def test_key_action_basic_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_upcase_input(self):
        (self.key_action.key_down(Keys.SHIFT).key_down("a").key_up(
            Keys.SHIFT).key_down("b").key_down("c").perform())
        self.assertEqual(self.key_reporter_value, "Abc")

    def test_replace_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(self.mod_key).key_down("a").key_up(
            self.mod_key).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "x")

    def test_clear_input(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")
        (self.key_action.key_down(
            self.mod_key).key_down("a").key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        self.assertEqual(self.key_reporter_value, "abc")

    def test_input_with_wait(self):
        self.key_action.key_down("a").key_down("b").key_down("c").perform()
        (self.key_action.key_down(
            self.mod_key).key_down("a").wait(.5).key_down("x").perform())
        self.assertEqual(self.key_reporter_value, "")

    @skip_if_mobile("Interacting with chrome windows not available for Fennec")
    def test_open_in_new_window_shortcut(self):
        def open_window_with_action():
            el = self.marionette.find_element(By.TAG_NAME, "a")
            (self.key_action.key_down(Keys.SHIFT).press(el).release().key_up(
                Keys.SHIFT).perform())

        self.marionette.navigate(inline("<a href='#'>Click</a>"))
        new_window = self.open_window(trigger=open_window_with_action)

        self.marionette.switch_to_window(new_window)
        self.marionette.close_chrome_window()

        self.marionette.switch_to_window(self.start_window)
コード例 #14
0
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)
コード例 #15
0
ファイル: test_touchcaret.py プロジェクト: DINKIN/Waterfox
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)
コード例 #16
0
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)