I do like how clean it is. After getting the typing to work, I realized all my robot instructions had to be utilizing system.util.invokeLater otherwise while I was still logging on, the mouse would start moving due to the next function call. I chose the convention that each function returns the ms needed for the next call of system.util.invokeLater, and have a constant DELAY_FACTOR
to easily shorten or lengthen time between actions. My setup is like this -
DELAY_FACTOR = 200
WINDOW_SELECT_PIXELS = {
"Privileged Access": (1300, 1050),
"Overview": (500, 1050),
"Print Screen": (1900,1050),
"Login": (1400,40)
}
def goToWindow(window, initial_delay=0):
"""
Goes to a specific window via bottom navigation.
Args:
window: str, which window do you want to go to?
Returns:
None, moves mouse and clicks button, or throws KeyError if bad window name
"""
x, y = WINDOW_SELECT_PIXELS[window]
def leftClickForWindow(x=x, y=y):
leftClick(x, y)
system.util.invokeLater(leftClickForWindow, initial_delay)
return initial_delay+DELAY_FACTOR
def pressTab(initial_delay=0):
def pressVKTab():
rob.keyPress(KeyEvent.VK_TAB)
rob.keyRelease(KeyEvent.VK_TAB)
system.util.invokeLater(pressVKTab, initial_delay)
return initial_delay+DELAY_FACTOR
def pressEnter(initial_delay=0):
def pressVKEnter():
rob.keyPress(KeyEvent.VK_ENTER)
rob.keyRelease(KeyEvent.VK_ENTER)
system.util.invokeLater(pressVKEnter, initial_delay)
return initial_delay+DELAY_FACTOR
def type_on_keyboard(message, initial_delay=0):
"""
message: str, the key strokes you want simulated
initial_delay: int, - for the first thing you type in, but probably otherwise. needed for chaining
"""
str_message = String(message)
key_presses = [KeyEvent.getExtendedKeyCodeForChar(k) for k in str_message.chars().iterator()]
maxDelay = None
for num, key_to_press in enumerate(key_presses):
delay = ((num+1) * DELAY_FACTOR) + initial_delay
maxDelay = delay
def typeKey(key=key_to_press):
rob.keyPress(key)
rob.keyRelease(key)
system.util.invokeLater(typeKey, delay)
return maxDelay + DELAY_FACTOR
def moveMouse(x, y, initial_delay=0):
"""
Call leftClick at a specified pixel.
"""
def moveMouseDelay(x=x, y=y):
rob.mouseMove(x, y)
system.util.invokeLater(moveMouseDelay, initial_delay)
return initial_delay+DELAY_FACTOR
def loginAsMe(initial_delay=0):
wait_0 = goToWindow("Login", initial_delay=initial_delay)
wait_1 = type_on_keyboard("secretusername")
wait_2 = pressTab(initial_delay=wait_1)
wait_3 = type_on_keyboard("secretpassword", initial_delay=wait_2)
wait_4 = pressEnter(initial_delay=wait_3)
return wait_4
This works for me. It looks like a realistic user at 200 ms delay. I wish my loginAsMe
function looked nicer, as I’m always getting the result of the previous function and feeding it to the next initial_delay
, but it’s readable enough and works. Just posting this here for comments/concerns/posterity, as I haven’t seen too many posts on trying to write end to end tests with Robot.