如何使用文件路径使用 ChromeDriver 导航到本地文件?
How to navigate to local file with ChromeDriver using a file path?
我正在为自动化框架构建一组测试,但在导航到我创建的本地 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
class 以便我能够在我的测试中使用 Protractor-net
以及抽象测试工具。
internal TestWebDriver(RemoteWebDriver driver, TestConfiguration configuration)
{
// ...
_driver = new NgWebDriver(driver);
// ...
}
当框架调用驱动程序导航到页面时,它会传递正确的文件路径 ("file:/// ..."),但它永远不会进入浏览器 URL,也不会导航到。 (即 URL 表示 data;
)
如何导航到文件路径为 ChromeDriver
的本地 HTML 页面?
事实证明,此问题的解决方案源于 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()
导航时,您必须再次包括该应用程序是否正在使用 Angular 通过 bool
.
在我们的例子中,我们没有使用 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);
}
}
我正在为自动化框架构建一组测试,但在导航到我创建的本地 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
class 以便我能够在我的测试中使用 Protractor-net
以及抽象测试工具。
internal TestWebDriver(RemoteWebDriver driver, TestConfiguration configuration)
{
// ...
_driver = new NgWebDriver(driver);
// ...
}
当框架调用驱动程序导航到页面时,它会传递正确的文件路径 ("file:/// ..."),但它永远不会进入浏览器 URL,也不会导航到。 (即 URL 表示 data;
)
如何导航到文件路径为 ChromeDriver
的本地 HTML 页面?
事实证明,此问题的解决方案源于 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()
导航时,您必须再次包括该应用程序是否正在使用 Angular 通过 bool
.
在我们的例子中,我们没有使用 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);
}
}