Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting a specific Firefox Profile with Selenium 3

I am trying to upgrade from Selenium 2 to Selenium 3 but the old handling, which was pretty easy and fast doesn't work anymore (and the documentation is nonexisting as it seems)

This is the program at the moment and what I want is to open a Firefox driver with the profile: SELENIUM

Sadly it doesn't work and always shuts down with the Error:

An unhandled exception of type 'System.InvalidOperationException' > occurred in WebDriver.dll

Additional information: corrupt deflate stream

This is my program at the moment:

public Program()
{
    FirefoxOptions _options = new FirefoxOptions();
    FirefoxProfileManager _profileIni = new FirefoxProfileManager();
    FirefoxDriverService _service = FirefoxDriverService.CreateDefaultService(@"C:\Programme\IMaT\Output\Release\Bin");
    _service.FirefoxBinaryPath = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
    try
    {
        if ((_options.Profile = _profileIni.GetProfile("SELENIUM")) == null)
        {
            Console.WriteLine("SELENIUM PROFILE NOT FOUND");
            _profile.SetPreference("network.proxy.type", 0); // disable proxy
            _profile = new FirefoxProfile();
        }
    }
    catch
    {
        throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
    }
    IWebDriver driver = new FirefoxDriver(_service,_options,new System.TimeSpan(0,0,30));        
    driver.Navigate().GoToUrl("ld-hybrid.fronius.com");
    Console.Write("rtest");
}

static void Main(string[] args)
{
    new Program();
}

Without Loading the Profile it works with just new FirefoxDriver(_service) but the profile is mandatory.

In Selenium 2 I handled it with this code:

FirefoxProfileManager _profileIni = new FirefoxProfileManager();
// use custom temporary profile
try { 
    if ((_profile = _profileIni.GetProfile("SELENIUM")) == null)
    {
        Console.WriteLine("SELENIUM PROFILE NOT FOUND");
        _profile.SetPreference("network.proxy.type", 0); // disable proxy
        _profile = new FirefoxProfile();
    }
}
catch
{
    throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
}

_profile.SetPreference("intl.accept_languages", _languageConfig);
_driver = new FirefoxDriver(_profile);

Fast and simple, but as the Driver doesn't support a Constructor with service and profile I don't really know how to get this to work, any help would be appreciated

like image 755
Dominik Lemberger Avatar asked Apr 06 '17 11:04

Dominik Lemberger


People also ask

How do I open Firefox as a different user?

Built-in Profile ManagerInside Firefox, type or paste about:profiles in the address bar and press Enter/Return to load it. Click the "Create a New Profile" button, then click Next. Assign a name like Work, ignore the option to relocate the profile folder, and click the Finish button.

How do I create a shortcut for a specific Firefox profile?

Right-click on the new shortcut and select Properties. On the Shortcut tab, type a space after the Target and then type: -p <profile name>, replacing “<profile name> with the name of the profile you want to use. For example, I created a profile called LoriWork so I added -p LoriWork to the end of the Target. Click OK.

What is the use of Firefox profile in Selenium WebDriver?

Firefox profiles include custom preferences that you would like to simulate an environment for your test script. For example, you might want to create a profile that sets preferences to handle the download popup programmatically during your test run.


1 Answers

This exception is due to a bug in the .Net library. The code generating the Zip of the profile is failing to provide a proper Zip.

One way to overcome this issue would be to overload FirefoxOptions and use the archiver from .Net framework (System.IO.Compression.ZipArchive) instead of the faulty ZipStorer:

var options = new FirefoxOptionsEx();
options.Profile = @"C:\Users\...\AppData\Roaming\Mozilla\Firefox\Profiles\ez3krw80.Selenium";
options.SetPreference("network.proxy.type", 0);

var service = FirefoxDriverService.CreateDefaultService(@"C:\downloads", "geckodriver.exe");

var driver = new FirefoxDriver(service, options, TimeSpan.FromMinutes(1));
class FirefoxOptionsEx : FirefoxOptions {

    public new string Profile { get; set; }

    public override ICapabilities ToCapabilities() {

        var capabilities = (DesiredCapabilities)base.ToCapabilities();
        var options = (IDictionary)capabilities.GetCapability("moz:firefoxOptions");
        var mstream = new MemoryStream();

        using (var archive = new ZipArchive(mstream, ZipArchiveMode.Create, true)) {
            foreach (string file in Directory.EnumerateFiles(Profile, "*", SearchOption.AllDirectories)) {
                string name = file.Substring(Profile.Length + 1).Replace('\\', '/');
                if (name != "parent.lock") {
                    using (Stream src = File.OpenRead(file), dest = archive.CreateEntry(name).Open())
                        src.CopyTo(dest);
                }
            }
        }

        options["profile"] = Convert.ToBase64String(mstream.GetBuffer(), 0, (int)mstream.Length);

        return capabilities;
    }

}

And to get the directory for a profile by name:

var manager = new FirefoxProfileManager();
var profiles = (Dictionary<string, string>)manager.GetType()
    .GetField("profiles", BindingFlags.Instance | BindingFlags.NonPublic)
    .GetValue(manager);

string directory;
if (profiles.TryGetValue("Selenium", out directory))
    options.Profile = directory;
like image 67
Florent B. Avatar answered Oct 27 '22 00:10

Florent B.