【问题标题】:Starting a specific Firefox Profile with Selenium 3使用 Selenium 3 启动特定的 Firefox 配置文件
【发布时间】:2017-04-06 11:07:40
【问题描述】:

我正在尝试从 Selenium 2 升级到 Selenium 3,但是非常简单快速的旧处理方式不再起作用(并且文档似乎不存在)

这是目前的程序,我想要的是使用配置文件打开一个 Firefox 驱动程序:SELENIUM

遗憾的是它不起作用并且总是因错误而关闭:

“System.InvalidOperationException”类型的未处理异常 > 发生在 WebDriver.dll 中

附加信息:损坏的 deflate 流

这是我目前的程序:

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();
}

无需加载配置文件,它只适用于新的 FirefoxDriver(_service),但配置文件是强制性的。

在 Selenium 2 中,我使用以下代码处理它:

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

快速简单,但由于驱动程序不支持具有服务和配置文件的构造函数,我真的不知道如何使其工作,任何帮助将不胜感激

【问题讨论】:

    标签: c# .net selenium firefox selenium-webdriver


    【解决方案1】:

    此异常是由 .Net 库中的错误引起的。生成配置文件 Zip 的代码未能提供正确的 Zip。

    解决此问题的一种方法是重载 FirefoxOptions 并使用来自 .Net 框架 (System.IO.Compression.ZipArchive) 的存档器,而不是错误的 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;
        }
    
    }
    

    并按名称获取配置文件的目录:

    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;
    

    【讨论】:

    • 谢谢,我真的放弃了使用 Selenium 3 ... 这样 - 我会说,Lowlevel Basic - 这不起作用真的很痛苦...... 并且对此一无所获任何地方的问题都更多。对于重载版本,我现在需要知道 SELENIUM 配置文件的路径,这对我来说并不适用,因为我们有多个不同的测试计算机与配置文件,但在其他位置等等。 (new FirefoxProfileManager()).GetProfile("SELENIUM").ProfileDirectory 当我尝试这个时,ProfileDirectory 总是空的,它只存储在一个非公共变量中
    • @Dominik Lemberger,每个配置文件的路径可以通过 FirefoxProfileManager 实例上的反射访问:var profiles = (Dictionary&lt;string, string&gt;)manager.GetType().GetField("profiles", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(manager);
    • 在我的情况下看起来如何? FirefoxProfile 配置文件 = new FirefoxProfileManager().GetProfile("SELENIUM"); var profile = (Dictionary)profile.GetType().GetField("ProfileDirectory", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(profile); options.Profile = 似乎无法让它工作(ps:以前没有使用过反射)
    • @Dominik Lemberger,查看更新以通过反射获取配置文件。
    • 感谢就像一个魅力 - 即使我基本上什么都不明白那里发生了什么:) 我想在接下来的几个小时里尝试阅读它哈哈
    猜你喜欢
    • 2018-01-13
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 2016-09-11
    • 2011-11-28
    • 2011-07-26
    相关资源
    最近更新 更多