Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow Selenium Webdriver to find Firefox path in cygwin and standard installs

I am running a Win2k8 EC2 instance for the purpose of running a few browser automation tasks after deployment from Fabric on a *nux box.

My script which works on Mac and Linux presents the following error under cygwin with 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

There is a known bug/lack of interest in supporting Webdriver under cygwin (selenium).

A fellow SO user is more helpful and has a solution here: https://stackoverflow.com/a/11104952/1668057

That method seems like it will break my code under Mac/*nix.

How can I implement that and keep the code portable?

(my Selenium is installed from PIP, so would prefer to override the method than edit any module files)

EDIT:

Seeing the more pythonic way suggested to Jeff's answer, I came up with the following (note my script already subclassed/overrode the FirefoxProfile class for disabling images):

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)

On my Mac, this now catches the exception and continues as normal, but on the Win2k8 box, where the cygwin path is detected, it still fails with the following error:

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

I'm not at all familiar with Popen or what I'm expecting to be returned for a positive result. ie, should I expect something like C:\Program Files (x86)\Firefox\Firefox.exe?

Where is the next debug step?

EDIT #2:

Executing this command from the cygwin bash shell does open Firefox:

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

I think my next step is to hardcode this into the script and see if it will allow Selenium to launch Firefox either locally through cygwin bash or remotely via SSH...

like image 579
ljs.dev Avatar asked Oct 05 '22 02:10

ljs.dev


1 Answers

OK, kind of blatantly obvious, but after manually setting the PATH variable on the Win2k8 cygwin, the code from Jeff's answer works and I am now happily running Firefox on the Win2k8 machine via a remote Linux machine.

I hadn't manually set the PATH, thinking that was cheating, but even that can be done as part of the Fabric script if I want full automation...

Here is the code which is now working fine on both Mac and 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)

Hopefully that journey will help someone doing something similar.

like image 190
ljs.dev Avatar answered Oct 13 '22 12:10

ljs.dev