【问题标题】:How to navigate to local file with ChromeDriver using a file path?如何使用文件路径使用 ChromeDriver 导航到本地文件?
【发布时间】:2017-04-12 02:02:34
【问题描述】:

我正在为自动化框架构建一组测试,但在导航到我创建的本地 HTML 页面时遇到了问题。

这里是我创建 ChromeDriver 实例的地方。

if (AllowFileAccessAcrossFiles)
{
   ChromeOptions options = new ChromeOptions();
   // Have tried, none, individually, as well as both.
   options.AddArgument("--allow-file-access-from-files");
   options.AddArgument("--enable-local-file-accesses ");
   driver = new ChromeDriver(options);
}

这个ChromeDriver 实例稍后被传递到NgWebDriver 类中,这样我就可以在我的测试中使用Protractor-net 以及抽象测试工具。

internal TestWebDriver(RemoteWebDriver driver, TestConfiguration configuration)
{
    // ...

    _driver = new NgWebDriver(driver);

    // ...
}

当框架调用驱动程序以导航到页面时,它会传递正确的文件路径(“file:/// ...”),但它永远不会进入浏览器 URL 并且不会被导航到。 (即网址显示data;)

如何导航到文件路径为ChromeDriver 的本地 HTML 页面?

【问题讨论】:

    标签: c# .net automated-tests selenium-chromedriver protractor-net


    【解决方案1】:

    事实证明,这个问题的解决方案源于NgWebDriver。 NgWebDriver 遵循 IE、Edge、PhantomJS、Firefox 和 Safari 的驱动程序来导航到 URL,但如果是其他任何东西,它就会运行:this.ExecuteScript("window.name += '" + AngularDeferBootstrap + "'; window.location.href = '" + value + "';");

    被调用的JavaScript method 不仅仅处理传入本地路径,它需要一个http(s) 字符串来导航。所以能不能传入本地路径,就看具体驱动实现Url属性的set方法了。

    下面是相关的Protractor-net 属性。

    public class NgWebDriver : IWebDriver, IWrapsDriver, IJavaScriptExecutor
    {
        private const string AngularDeferBootstrap = "NG_DEFER_BOOTSTRAP!";
    
        private IWebDriver driver;
        private IJavaScriptExecutor jsExecutor;
        private string rootElement;
        private IList<NgModule> mockModules;
    
        // constructors and stuff
    
        /// <summary>
        /// Gets or sets the URL the browser is currently displaying.
        /// </summary>
        public string Url
        {
            get
            {
                this.WaitForAngular();
                return this.driver.Url;
            }
            set
            {
                // Reset URL
                this.driver.Url = "about:blank";
    
                // TODO: test Android
                IHasCapabilities hcDriver = this.driver as IHasCapabilities;
                if (hcDriver != null &&
                    (hcDriver.Capabilities.BrowserName == "internet explorer" ||
                     hcDriver.Capabilities.BrowserName == "MicrosoftEdge" ||
                     hcDriver.Capabilities.BrowserName == "phantomjs" ||
                     hcDriver.Capabilities.BrowserName == "firefox" ||
                     hcDriver.Capabilities.BrowserName.ToLower() == "safari"))
                {
                    this.ExecuteScript("window.name += '" + AngularDeferBootstrap + "';");
                    this.driver.Url = value;
                }
                else
                {
                    this.ExecuteScript("window.name += '" + AngularDeferBootstrap + "'; window.location.href = '" + value + "';");
                }
    
                if (!this.IgnoreSynchronization)
                {
                    try
                    {
                        // Make sure the page is an Angular page.
                        long? angularVersion = this.ExecuteAsyncScript(ClientSideScripts.TestForAngular) as long?;
                        if (angularVersion.HasValue)
                        {
                            if (angularVersion.Value == 1)
                            {
                                // At this point, Angular will pause for us, until angular.resumeBootstrap is called.
    
                                // Add default module for Angular v1
                                this.mockModules.Add(new Ng1BaseModule());
    
                                // Register extra modules
                                foreach (NgModule ngModule in this.mockModules)
                                {
                                    this.ExecuteScript(ngModule.Script);
                                }
                                // Resume Angular bootstrap
                                this.ExecuteScript(ClientSideScripts.ResumeAngularBootstrap,
                                    String.Join(",", this.mockModules.Select(m => m.Name).ToArray()));
                            }
                            else if (angularVersion.Value == 2)
                            {
                                if (this.mockModules.Count > 0)
                                {
                                    throw new NotSupportedException("Mock modules are not supported in Angular 2");
                                }
                            }
                        }
                    }
                    catch (WebDriverTimeoutException wdte)
                    {
                        throw new InvalidOperationException(
                            String.Format("Angular could not be found on the page '{0}'", value), wdte);
                    }
                }
            }
        }
    

    由于此属性假定应用程序正在使用 Angular,因此在使用 Navigate().GoToUrl() 导航时,您必须再次包括应用程序是否通过 bool 使用 Angular。

    在我们的例子中,我们没有使用 Angular 并将其传递给 GoToUrl() 方法调用,直接通过 INavigation 传递给包装的 IWebDriver。此包装的驱动程序正确处理本地文件。

    下面是 Protractor-net 中的navigation class:

    public class NgNavigation : INavigation
    {
        private NgWebDriver ngDriver;
        private INavigation navigation;
    
        // irrelevant constructors and such
    
        /// <summary>
        /// Load a new web page in the current browser window.
        /// </summary>
        /// <param name="url">The URL to load. It is best to use a fully qualified URL</param>
        /// <param name="ensureAngularApp">Ensure the page is an Angular page by throwing an exception.</param>
        public void GoToUrl(string url, bool ensureAngularApp)
        {
            if (ensureAngularApp)
            {
                this.ngDriver.Url = url;
            }
            else
            {
                this.navigation.GoToUrl(url);
            }
        }
    

    【讨论】:

    • 很好的发现。浏览位于其他 WebDriver 之上的 NgWebDriver 的复杂性总是很有趣...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 1970-01-01
    • 2018-01-12
    • 2018-02-23
    • 2013-08-17
    • 1970-01-01
    相关资源
    最近更新 更多