是否可以在不使用jenkins上的“PyAutoGUI”库的情况下使用键盘操作?

时间:2018-02-07 01:45:06

标签: python selenium jenkins automation robotframework

我正在使用Robotframework为应用程序创建测试脚本。此应用程序需要许多不可避免的键盘点击/动作组合。现在我正在使用PyAutoGui库来模拟这些操作并且它们工作正常,但是当我通过Jenkins上的无头浏览器运行它们时,这些操作没有注册。

我得到的错误是“鼠标移动到左上角触发了PyAutoGUI故障安全。要禁用此故障安全,请将pyautogui.FAILSAFE设置为False。” 但是,即使将Failsafe值更改为false,仍然不会捕获键盘操作。

奇怪的是,如果有人在测试运行时实际登录Jenkins框,那么库工作得非常好,但是当无头运行时,库会中断。

是否有其他可以使用的库或可能解决这种情况?

提前致谢!

4 个答案:

答案 0 :(得分:0)

我在工作中自动化了很多Web应用程序。

我也开始使用PyAutoGUI,并遇到类似的问题,您正在从我的笔记本电脑到运行脚本的生产服务器。

我找到的解决方案是Selenium Webdriver。如果您测试的是IP地址,这可能是解决方案。在我看来,它实际上比PyAutoGUI更容易。

答案 1 :(得分:0)

此类行为的原因是,当没有用户登录时(物理上或通过RDP),没有活动桌面(考虑所有GUI元素,配置文件等)我们在env中遇到过这样的问题,这里工作正常溶液:

  1. 创建一个将在WindowsVM上建立RDP会话的作业,这样就会有活动桌面。 Job无法结束RDP会话,它需要在后台运行(通常没问题,如果其他人将使用相同的usr登录,会话将切换到新用户但桌面将处于活动状态)。
  2. 确保每当您在Win VM上运行测试作业时,已经打开了RDP.Schedule作业1.在Win VMs上进行测试之前运行
  3. 从作业1的技术细节来看,我们的WinVM节点以WIN前缀命名,因此要获取所有Windows节点,我们通过Jenkins API查询Jenkins。 获得WinVM(IP或主机名)列表后,我们在linux节点上运行以下命令,并使用所有发现的WinVM节点进行循环。

    一个节点的基本命令:

       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
    

    魔法是 nohup ,因为它在作业完成后在后台运行RDP会话。

    这是安装了 vncserver xfreerdp 的Centos。

    #edit

    您可以请求admin为运行测试创建WinVM,将Jenkins与dev / test环境分开。通过这种方式,您可以从任何地方或从Jenkins本身打开节点上的RDP会话。为了稳定性和性能,不要在maser上运行任何东西是一种好习惯。

答案 2 :(得分:0)

您可以通过安装VNC服务器并在其中运行jenkins slave来解决此问题。然后浏览器将以gui开始,测试将起作用。

答案 3 :(得分:0)

我能够找到解决方案/解决我的问题。我在谷歌小组上发现了关于机器人框架自动化中多个关键组合的这篇文章,它能够帮助我找到可行的解决方案。我们可以使用sendKeys构建自定义关键字来组合多个键盘操作,而不是尝试使用pyautogui库。这种方法对我来说非常有效,唯一的缺点是现在我必须通过一个选择器来关注每次我想使用自定义关键字,但对于我的应用程序来说这不是一个大问题。

我从这个Discussion中获取了代码并进行了一些修改:

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))