Module pyseext.input_helper
Module that contains our InputHelper class.
Expand source code
"""
Module that contains our InputHelper class.
"""
import logging
import random
from typing import Union
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.remote.webelement import WebElement
class InputHelper:
"""A class to help with user input."""
INPUT_SLEEP_MINIMUM: float = 0.0001
"""The minimum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.0001 seconds."""
INPUT_SLEEP_MAXIMUM: float = 0.002
"""The maximum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.002 seconds."""
def __init__(self, driver: WebDriver):
"""Initialises an instance of this class
Args:
driver (WebDriver): The webdriver to use
"""
self._logger = logging.getLogger(__name__)
"""The Logger instance for this class instance"""
self._driver = driver
"""The WebDriver instance for this class instance"""
self._action_chains = ActionChains(driver)
"""The ActionChains instance for this class instance"""
def type_into_element(self, element: WebElement, text: str, delay: Union[float, None] = None, tab_off: Union[bool, None] = False, disable_realistic_typing: bool = False, clear_first: bool = True):
"""Types into an input element in a realistic manner, unless web driver is remote.
Args:
element (WebElement): The element to type into.
text (str): The text to type.
delay (float, optional): The number of seconds to delay after typing. Defaults to None.
tab_off (bool, optional): Indicates whether to tab off the field after typing, and delay. Defaults to False.
disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False.
clear_first (bool, optional): Indicates whether to clear the element first. Defaults to True.
"""
# If text is None then use empty string
if text is None:
text = ''
# Ensure text really is a string
text = str(text)
if clear_first:
# Clear the element first, in case has something in it
element.clear()
# First move to and click on element to give it focus
self._action_chains.move_to_element(element)
self._action_chains.click()
self._action_chains.perform()
# Now type each character
self.type(text, disable_realistic_typing)
if delay:
self._action_chains.pause(delay)
self._action_chains.perform()
if tab_off:
self.type_tab()
def type(self, text: str, disable_realistic_typing: bool = False):
"""Types into the currently focused element in a realistic manner, unless our webdriver is remote, then just sends the complete string.
Args:
text (str): The text to type.
disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False.
"""
# If we are remote, then typing a character at a time involves a roundtrip for every character.
# This is not ideal, since slows down the test massively.
if not disable_realistic_typing and not self._driver._is_remote: # pylint: disable=protected-access
for character in text:
self._action_chains.send_keys(character)
self._action_chains.pause(random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM))
self._action_chains.perform()
else:
self._action_chains.send_keys(text)
self._action_chains.perform()
def type_tab(self, pause_time: Union[float, None] = None):
"""Type a tab character into the currently focused element.
Args:
pause_time (float, optional): The amount of time to pause after hitting tab (when web driver is not remote).
Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
"""
self._action_chains.send_keys(Keys.TAB)
if not self._driver._is_remote: # pylint: disable=protected-access
if pause_time is None:
pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)
self._action_chains.pause(pause_time)
self._action_chains.perform()
def type_return(self, pause_time: Union[float, None] = None):
"""Types a return character into the currently focused element.
Args:
pause_time (float, optional): The amount of time to pause after hitting return (when web driver is not remote).
Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
"""
self._action_chains.send_keys(Keys.RETURN)
if not self._driver._is_remote: # pylint: disable=protected-access
if pause_time is None:
pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)
self._action_chains.pause(pause_time)
self._action_chains.perform()
def type_escape(self, pause_time: Union[float, None] = None):
"""Types an escape character into the currently focused element.
Args:
pause_time (float, optional): The amount of time to pause after hitting escape (when web driver is not remote).
Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
"""
self._action_chains.send_keys(Keys.ESCAPE)
if not self._driver._is_remote: # pylint: disable=protected-access
if pause_time is None:
pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)
self._action_chains.pause(pause_time)
self._action_chains.perform()
def type_delete(self, pause_time: Union[float, None] = None):
"""Types a delete character into the currently focused element.
Args:
pause_time (float, optional): The amount of time to pause after hitting delete (when web driver is not remote).
Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
"""
self._action_chains.send_keys(Keys.DELETE)
if not self._driver._is_remote: # pylint: disable=protected-access
if pause_time is None:
pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)
self._action_chains.pause(pause_time)
self._action_chains.perform()
Classes
class InputHelper (driver: selenium.webdriver.remote.webdriver.WebDriver)
-
A class to help with user input.
Initialises an instance of this class
Args
driver
:WebDriver
- The webdriver to use
Expand source code
class InputHelper: """A class to help with user input.""" INPUT_SLEEP_MINIMUM: float = 0.0001 """The minimum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.0001 seconds.""" INPUT_SLEEP_MAXIMUM: float = 0.002 """The maximum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.002 seconds.""" def __init__(self, driver: WebDriver): """Initialises an instance of this class Args: driver (WebDriver): The webdriver to use """ self._logger = logging.getLogger(__name__) """The Logger instance for this class instance""" self._driver = driver """The WebDriver instance for this class instance""" self._action_chains = ActionChains(driver) """The ActionChains instance for this class instance""" def type_into_element(self, element: WebElement, text: str, delay: Union[float, None] = None, tab_off: Union[bool, None] = False, disable_realistic_typing: bool = False, clear_first: bool = True): """Types into an input element in a realistic manner, unless web driver is remote. Args: element (WebElement): The element to type into. text (str): The text to type. delay (float, optional): The number of seconds to delay after typing. Defaults to None. tab_off (bool, optional): Indicates whether to tab off the field after typing, and delay. Defaults to False. disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False. clear_first (bool, optional): Indicates whether to clear the element first. Defaults to True. """ # If text is None then use empty string if text is None: text = '' # Ensure text really is a string text = str(text) if clear_first: # Clear the element first, in case has something in it element.clear() # First move to and click on element to give it focus self._action_chains.move_to_element(element) self._action_chains.click() self._action_chains.perform() # Now type each character self.type(text, disable_realistic_typing) if delay: self._action_chains.pause(delay) self._action_chains.perform() if tab_off: self.type_tab() def type(self, text: str, disable_realistic_typing: bool = False): """Types into the currently focused element in a realistic manner, unless our webdriver is remote, then just sends the complete string. Args: text (str): The text to type. disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False. """ # If we are remote, then typing a character at a time involves a roundtrip for every character. # This is not ideal, since slows down the test massively. if not disable_realistic_typing and not self._driver._is_remote: # pylint: disable=protected-access for character in text: self._action_chains.send_keys(character) self._action_chains.pause(random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)) self._action_chains.perform() else: self._action_chains.send_keys(text) self._action_chains.perform() def type_tab(self, pause_time: Union[float, None] = None): """Type a tab character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting tab (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.TAB) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform() def type_return(self, pause_time: Union[float, None] = None): """Types a return character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting return (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.RETURN) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform() def type_escape(self, pause_time: Union[float, None] = None): """Types an escape character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting escape (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.ESCAPE) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform() def type_delete(self, pause_time: Union[float, None] = None): """Types a delete character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting delete (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.DELETE) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform()
Class variables
var INPUT_SLEEP_MAXIMUM : float
-
The maximum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.002 seconds.
var INPUT_SLEEP_MINIMUM : float
-
The minimum amount of time in seconds to wait between key presses when typing or other inputs. Defaults to 0.0001 seconds.
Methods
def type(self, text: str, disable_realistic_typing: bool = False)
-
Types into the currently focused element in a realistic manner, unless our webdriver is remote, then just sends the complete string.
Args
text
:str
- The text to type.
disable_realistic_typing
:bool
, optional- Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False.
Expand source code
def type(self, text: str, disable_realistic_typing: bool = False): """Types into the currently focused element in a realistic manner, unless our webdriver is remote, then just sends the complete string. Args: text (str): The text to type. disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False. """ # If we are remote, then typing a character at a time involves a roundtrip for every character. # This is not ideal, since slows down the test massively. if not disable_realistic_typing and not self._driver._is_remote: # pylint: disable=protected-access for character in text: self._action_chains.send_keys(character) self._action_chains.pause(random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM)) self._action_chains.perform() else: self._action_chains.send_keys(text) self._action_chains.perform()
def type_delete(self, pause_time: Optional[None] = None)
-
Types a delete character into the currently focused element.
Args
pause_time
:float
, optional- The amount of time to pause after hitting delete (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
Expand source code
def type_delete(self, pause_time: Union[float, None] = None): """Types a delete character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting delete (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.DELETE) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform()
def type_escape(self, pause_time: Optional[None] = None)
-
Types an escape character into the currently focused element.
Args
pause_time
:float
, optional- The amount of time to pause after hitting escape (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
Expand source code
def type_escape(self, pause_time: Union[float, None] = None): """Types an escape character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting escape (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.ESCAPE) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform()
def type_into_element(self, element: selenium.webdriver.remote.webelement.WebElement, text: str, delay: Optional[None] = None, tab_off: Optional[bool] = False, disable_realistic_typing: bool = False, clear_first: bool = True)
-
Types into an input element in a realistic manner, unless web driver is remote.
Args
element
:WebElement
- The element to type into.
text
:str
- The text to type.
delay
:float
, optional- The number of seconds to delay after typing. Defaults to None.
tab_off
:bool
, optional- Indicates whether to tab off the field after typing, and delay. Defaults to False.
disable_realistic_typing
:bool
, optional- Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False.
clear_first
:bool
, optional- Indicates whether to clear the element first. Defaults to True.
Expand source code
def type_into_element(self, element: WebElement, text: str, delay: Union[float, None] = None, tab_off: Union[bool, None] = False, disable_realistic_typing: bool = False, clear_first: bool = True): """Types into an input element in a realistic manner, unless web driver is remote. Args: element (WebElement): The element to type into. text (str): The text to type. delay (float, optional): The number of seconds to delay after typing. Defaults to None. tab_off (bool, optional): Indicates whether to tab off the field after typing, and delay. Defaults to False. disable_realistic_typing (bool, optional): Indicates whether to disable typing in a 'realistic' manner when not remote. Defaults to False. clear_first (bool, optional): Indicates whether to clear the element first. Defaults to True. """ # If text is None then use empty string if text is None: text = '' # Ensure text really is a string text = str(text) if clear_first: # Clear the element first, in case has something in it element.clear() # First move to and click on element to give it focus self._action_chains.move_to_element(element) self._action_chains.click() self._action_chains.perform() # Now type each character self.type(text, disable_realistic_typing) if delay: self._action_chains.pause(delay) self._action_chains.perform() if tab_off: self.type_tab()
def type_return(self, pause_time: Optional[None] = None)
-
Types a return character into the currently focused element.
Args
pause_time
:float
, optional- The amount of time to pause after hitting return (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
Expand source code
def type_return(self, pause_time: Union[float, None] = None): """Types a return character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting return (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.RETURN) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform()
def type_tab(self, pause_time: Optional[None] = None)
-
Type a tab character into the currently focused element.
Args
pause_time
:float
, optional- The amount of time to pause after hitting tab (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM.
Expand source code
def type_tab(self, pause_time: Union[float, None] = None): """Type a tab character into the currently focused element. Args: pause_time (float, optional): The amount of time to pause after hitting tab (when web driver is not remote). Defaults to None, in which case a random wait time is used between INPUT_SLEEP_MINIMUM and INPUT_SLEEP_MAXIMUM. """ self._action_chains.send_keys(Keys.TAB) if not self._driver._is_remote: # pylint: disable=protected-access if pause_time is None: pause_time = random.uniform(self.INPUT_SLEEP_MINIMUM, self.INPUT_SLEEP_MAXIMUM) self._action_chains.pause(pause_time) self._action_chains.perform()