Reputation: 203
I am using Robotframework to create test scripts for an application. This application requires many keyboard click/action combinations that are unavoidable. Right now I am using the PyAutoGui library to simulate these actions and they are working fine, but when I run them through a headless browser on Jenkins, those actions are not registered.
The error that I get is "PyAutoGUI fail-safe triggered from mouse moving to upper-left corner. To disable this fail-safe, set pyautogui.FAILSAFE to False." However, even after changing the Failsafe value to false, the keyboard action is still not captured.
The weird thing is that if someone is physically logged into the Jenkins box while the tests are running, the library works perfectly fine, but when running headless, the library breaks.
Is there another library I can possible use or a possible work around for this situation?
Thanks in advance!
Upvotes: 6
Views: 4044
Reputation: 786
The reason for such behaviour is that when there is no user logged in (physically or via RDP), there is no active desktop (think about all GUI elements, profiles, etc.) We had such issues in our environment. Here is a working solution:
From the technical details of job 1, we have our WinVM nodes named with the WIN prefix, so to get all Windows nodes, we query Jenkins via the Jenkins API.
Once we have a list of WinVMs (IP or hostnames), we run the following command on the Linux node looping with all discovered WinVMs nodes.
Basic command for one node :
BUILD_ID=dontKillMe vncserver -kill :100 || true
BUILD_ID=dontKillMe rm -rf /tmp/.X11-unix/X100 || true
BUILD_ID=dontKillMe vncserver :100
BUILD_ID=dontKillMe DISPLAY=localhost:100
BUILD_ID=dontKillMe export DISPLAY
yum install -y freerdp
## loop through WinVMs below:
nohup xfreerdp -g <resolution> -u <user> -p <pas> <IP/hostname>
## end of loop
The magic is with nohup, as it runs the RDP session in the background after the job has been finished.
This is Centos with vncserver and xfreerdp installed.
#edit
You can ask the admin to create a WinVM for running tests, separating Jenkins with dev/test environment. In such way you could the open an RDP session on the node from anywhere or from Jenkins itself. For stability and performance, it is considered as a good practice not to run anything on the master.
Upvotes: 2
Reputation: 203
I was able to figure out a solution/work-around for my problem. I came across this post on google groups about multiple key combinations in robotframework automation and it was able to help me find a viable solution. Instead of trying to use the pyautogui library, we can use sendKeys to build a custom keyword to combine multiple keyboard actions. This approach worked perfectly for me, the only drawback is that now I have to pass a selector to focus on every time I want to use my custom keyword, but for my application that was not a huge issue.
I took the code from this Discussion and made a few slight modifications:
def customPressKey(self, locator, keys):
keys = keys.split(' + ')
i = 0
named_keys = []
named_key_sequence = []
named_key_seq_as_string = ''
unnamed = ''
for key in keys:
try:
named_key = getattr(Keys, keys[i])
print "%s. named key is %s." % (i + 1, key)
named_keys.append(keys[i])
i = i + 1
except:
print "The rest '%s' is unnamed." % key
unnamed = str(key).lower()
i = i + 1
print "NAMED KEY(s):", named_keys
for key in named_keys:
named_key_sequence.append('Keys.%s' % key)
named_key_seq_as_string = ','.join(named_key_sequence)
print "NAMED KEY SEQUENCE:", named_key_sequence
print "NAMED KEY SEQUENCE as STRING:", named_key_seq_as_string
print "element.send_keys() call should look like this:"
print "element.send_keys(%s, '%s')" % (named_key_seq_as_string, unnamed)
element = self.find_element(locator)
if unnamed:
exec("element.send_keys(%s, '%s')" % (named_key_seq_as_string, unnamed))
else:
exec("element.send_keys(%s)" % (named_key_seq_as_string))
Upvotes: 0
Reputation: 457
You can workaround this by installing VNC server and run jenkins slave within it. Then browser will start with gui and test will work.
Upvotes: 0
Reputation: 141
I have been automating a lot of web applications at work.
I too started with PyAutoGUI, and had similar problems that you are experiencing going from my laptop to our production server that was running the scripts.
The solution I found was Selenium Webdriver. If what you are testing has an ip address, this may be the solution. In my opinion it is actually easier than PyAutoGUI.
Upvotes: 1