# -*- coding: utf-8 -*- # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from marionette_driver.marionette import Actions, errors class CaretActions(Actions): def __init__(self, marionette): super(CaretActions, self).__init__(marionette) self._reset_action_chain() def _reset_action_chain(self): # Release the action so that two consecutive clicks won't become a # double-click. self.release() self.mouse_chain = self.sequence( "pointer", "pointer_id", {"pointerType": "mouse"} ) self.key_chain = self.sequence("key", "keyboard_id") def move(self, element, x, y, duration=None): """Queue a pointer_move action. :param element: an element where its top-left corner is the origin of the coordinates. :param x: Destination x-axis coordinate in CSS pixels. :param y: Destination y-axis coordinate in CSS pixels. :param duration: Number of milliseconds over which to distribute the move. If None, remote end defaults to 0. """ rect = element.rect el_x, el_y = rect["x"], rect["y"] # Add the element's top-left corner (el_x, el_y) to make the coordinate # relative to the viewport. dest_x, dest_y = int(el_x + x), int(el_y + y) self.mouse_chain.pointer_move(dest_x, dest_y, duration=duration) return self def click(self, element=None): """Queue a click action. If an element is given, move the pointer to that element first, otherwise click current pointer coordinates. :param element: Optional element to click. """ self.mouse_chain.click(element=element) return self def flick(self, element, x1, y1, x2, y2, duration=200): """Queue a flick gesture on the target element. :param element: The element to perform the flick gesture on. Its top-left corner is the origin of the coordinates. :param x1: Starting x-axis coordinate of the flick in CSS Pixels. :param y1: Starting y-axis coordinate of the flick in CSS Pixels. :param x2: Ending x-axis coordinate of the flick in CSS Pixels. :param y2: Ending y-axis coordinate of the flick in CSS Pixels. """ self.move(element, x1, y1, duration=0) self.mouse_chain.pointer_down() self.move(element, x2, y2, duration=duration) self.mouse_chain.pointer_up() return self def send_keys(self, keys): """Perform a keyDown and keyUp action for each character in `keys`. :param keys: String of keys to perform key actions with. """ self.key_chain.send_keys(keys) return self def perform(self): """Perform the action chain built so far to the server side for execution and clears the current chain of actions. Warning: This method performs all the mouse actions before all the key actions! """ self.mouse_chain.perform() self.key_chain.perform() self._reset_action_chain() class SelectionManager(object): """Interface for manipulating the selection and carets of the element. We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as caret for short. Simple usage example: :: element = marionette.find_element(By.ID, 'input') sel = SelectionManager(element) sel.move_caret_to_front() """ def __init__(self, element): self.element = element def _input_or_textarea(self): """Return True if element is either or