允许 Selenium Webdriver 在 cygwin 和标准安装中查找 Firefox 路径

Posted

技术标签:

【中文标题】允许 Selenium Webdriver 在 cygwin 和标准安装中查找 Firefox 路径【英文标题】:Allow Selenium Webdriver to find Firefox path in cygwin and standard installs 【发布时间】:2013-05-14 06:44:38 【问题描述】:

我正在运行一个 Win2k8 EC2 实例,目的是在从 Fabric 部署到 *nux 盒子后运行一些浏览器自动化任务。

我在 Mac 和 Linux 上运行的脚本在 cygwin 下使用 cygwin Python 时出现以下错误:

File "/home/Myuser/.virtualenvs/myproject/lib/python2.7/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 141, in _get_firefox_start_cmd
    " Please specify the firefox binary location or install firefox")
RuntimeError: Could not find firefox in your system PATH. Please specify the firefox binary location or install firefox

在 cygwin (selenium) 下支持 Webdriver 存在已知的错误/缺乏兴趣。

一位 SO 用户更有帮助,在这里有一个解决方案:https://***.com/a/11104952/1668057

该方法似乎会破坏我在 Mac/*nix 下的代码。

我怎样才能实现它并保持代码的可移植性?

(我的 Selenium 是从 PIP 安装的,因此宁愿覆盖该方法而不是编辑任何模块文件)

编辑:

看到 Jeff 的回答建议使用更 Pythonic 的方式,我想出了以下内容(注意我的脚本已经继承/覆盖了 FirefoxProfile 类以禁用图像):

from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from subprocess import Popen, PIPE

class CygwinFirefoxProfile(FirefoxProfile):

    @property
    def path(self):

        path = self.profile_dir

        try:
            proc = Popen(['cygpath','-d',path], stdout=PIPE, stderr=PIPE)
            stdout, stderr = proc.communicate()
            path = stdout.split('\n', 1)[0]
            print("cygwin path found")

        except OSError:
            print("No cygwin path found")

        return path

class CarServiceOnlineBookingsTest(unittest.TestCase):    

    def setUp(self):

        firefoxProfile = CygwinFirefoxProfile()

        ## Disable CSS
        firefoxProfile.set_preference('permissions.default.stylesheet', 2)
        ## Disable images
        firefoxProfile.set_preference('permissions.default.image', 2)
        ## Disable Flash
        firefoxProfile.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false')

        self.driver = webdriver.Firefox(firefoxProfile)

在我的 Mac 上,这现在会捕获异常并正常继续,但在检测到 cygwin 路径的 Win2k8 机器上,它仍然失败并出现以下错误:

Traceback (most recent call last):
  File "myscript.py", line 45, in setUp
    self.driver = webdriver.Firefox(firefoxProfile)
  File "/home/Myuser/.virtualenvs/myenv/lib/python2.7/site-packages/selenium/webdriver/firefox/webdriver.py", line 50, in __init__
    self.binary = FirefoxBinary()
  File "/home/Myuser/.virtualenvs/myenv/lib/python2.7/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 33, in __init__
    self._start_cmd = self._get_firefox_start_cmd()
  File "/home/Myuser/.virtualenvs/myenv/lib/python2.7/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 141, in _get_firefox_start_cmd
    " Please specify the firefox binary location or install firefox")
RuntimeError: Could not find firefox in your system PATH. Please specify the firefox binary location or install firefox

我完全不熟悉 Popen 或我期望返回的积极结果。即,我应该期待像C:\Program Files (x86)\Firefox\Firefox.exe 这样的东西吗?

下一个调试步骤在哪里?

编辑 #2:

从 cygwin bash shell 执行此命令确实会打开 Firefox:

/cygdrive/c/Program\ Files\ \(x86\)/Mozilla\ Firefox/firefox.exe

我认为我的下一步是将其硬编码到脚本中,看看它是否允许 Selenium 通过 cygwin bash 在本地或通过 SSH 远程启动 Firefox...

【问题讨论】:

【参考方案1】:

好的,有点明显,但是在 Win2k8 cygwin 上手动设置 PATH 变量后,Jeff 的答案中的代码有效,我现在很高兴通过远程 Linux 机器在 Win2k8 机器上运行 Firefox。

我没有手动设置 PATH,认为这是作弊,但如果我想要完全自动化,即使是这样也可以作为 Fabric 脚本的一部分来完成...

这是现在在 Mac 和 Windows 上都可以正常工作的代码:

from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from subprocess import Popen, PIPE

class CygwinFirefoxProfile(FirefoxProfile):

    @property
    def path(self):

        path = self.profile_dir

        # cygwin requires to manually specify Firefox path a below:
        # PATH=/cygdrive/c/Program\ Files\ \(x86\)/Mozilla\ Firefox/:$PATH
        try:
            proc = Popen(['cygpath','-d',path], stdout=PIPE, stderr=PIPE)
            stdout, stderr = proc.communicate()
            path = stdout.split('\n', 1)[0]

        except OSError:
            print("No cygwin path found")

        return path

class CarServiceOnlineBookingsTest(unittest.TestCase):    

    def setUp(self):

        firefoxProfile = CygwinFirefoxProfile()

        ## Disable CSS
        firefoxProfile.set_preference('permissions.default.stylesheet', 2)
        ## Disable images
        firefoxProfile.set_preference('permissions.default.image', 2)
        ## Disable Flash
        firefoxProfile.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false')

        self.driver = webdriver.Firefox(firefoxProfile)

希望这段旅程能帮助做类似事情的人。

【讨论】:

以上是关于允许 Selenium Webdriver 在 cygwin 和标准安装中查找 Firefox 路径的主要内容,如果未能解决你的问题,请参考以下文章

在 Selenium WebDriver 中按 Ctrl + A

如何使用 Selenium Webdriver 处理浏览器级别的通知

java selenium webdriver处理JS操作窗口滚动条

python selenium webdriver入门基本操作

Selenium RC(十三)

Selenium WebDriver - Chrome - C# - 无法在隐身模式下启动selenium浏览器作为最大化的浏览器