Search code examples
rubyfirefoxseleniumselenium-webdriverwatir-webdriver

Specify a custom user data directory in Firefox using Watir-Webdriver/Selenium


I can do the following using Chrome Driver:

b = Watir::Browser.new :chrome, :switches => ['--user-data-dir=C:/some_folder/'] # same philosophy for selenium, just a bit of a different syntax.

Which is going to create a new user data directory where all the cookies, bookmarks, cache etc. will be stored. Basically, create a new profile. If such a folder doesn't exist, it will create it. If it does exist, it will load the cookies/all related files from it.

Is there a way to do the same thing using Firefox Driver? I've been looking into ways to create a Firefox profile and all I found was this article: Creating a new Firefox Profile which doesn't solve my problem because I'm looking to do it automatically, like with Chrome driver above. Also, it seems you can create a new profile with:

profile = Selenium::WebDriver::Firefox::Profile.new

but I haven't found a way to SAVE that profile with a name I specify.


Solution

  • Based on Selenium Issue 1954 and Issue 7374, the Firefox driver does not currently have this functionality. It is hard to tell if it will be implemented given that some of the project members are opposing the idea.

    For now, I think you will have to monkey-patch your Selenium-WebDiver version to add this functionality. I reached the same conclusion as @shri046's answer, which is to modify the layout_on_disk method.

    After you have required Selenium-WebDriver, add the following monkey patch for the Selenium::WebDriver::FirefoxProfile. The logic in this patch is that:

    • If a profile directory is not specified, use the normal/existing behaviour, which means copying an existing profile and deleting it on exit.
    • If a profile directory is specified:
      • If the directory exists, use that directory for the profile. It is assumed that the directory is a valid profile (ie I did not add checks to ensure it was valid).
      • If the directory does not exist, a copy of an existing profile will be created (ie the normal behaviour). This profile will then be moved to the specified directory. The profile is not deleted on exit and therefore can be re-used again later.

    Patch:

    require 'watir-webdriver'
    require 'selenium-webdriver'
    
    module Selenium
      module WebDriver
        module Firefox
          class Profile
            class << self
              attr_accessor :webdriver_profile_directory
            end
    
            def layout_on_disk
              # When a directory is specified, ensure it is not deleted at exit
              if Profile.webdriver_profile_directory
                FileReaper.reap = false
              end
    
              # Use the specified directory if it already exists (ie assuming an existing profile)
              if Profile.webdriver_profile_directory && Dir.exists?(Profile.webdriver_profile_directory)
                return Profile.webdriver_profile_directory
              end
    
              # Create the profile directory as usual when it does not exist
              profile_dir = @model ? create_tmp_copy(@model) : Dir.mktmpdir("webdriver-profile")
              FileReaper << profile_dir
    
              install_extensions(profile_dir)
              delete_lock_files(profile_dir)
              delete_extensions_cache(profile_dir)
              update_user_prefs_in(profile_dir)
    
              # If a directory is specified, move the created profile to that directory
              if Profile.webdriver_profile_directory
                FileUtils.cp_r(profile_dir, Profile.webdriver_profile_directory)
                profile_dir = Profile.webdriver_profile_directory
              end
    
              profile_dir
            end
          end # Profile
        end # Firefox
      end # WebDriver
    end # Selenium
    

    To specify the profile location to use do the following:

    Selenium::WebDriver::Firefox::Profile.webdriver_profile_directory = 'C:/temp/test-profile'
    browser = Watir::Browser.new :firefox
    

    This patch may have limitations and untested areas. For example, it probably will not handle creating multiple instances of Firefox. However, for a single instance, it at least seems to work with reloading bookmarks created (which was the limit of my testing).