1

Je construis un ensemble de tests pour un framework d'automatisation, mais je suis confronté à un problème de navigation vers une page HTML locale que j'ai créée.Comment naviguer vers un fichier local avec ChromeDriver en utilisant un chemin de fichier?

Voici où je crée l'instance 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); 
} 

Cette instance ChromeDriver est passé plus tard dans la classe NgWebDriver pour que je suis en mesure d'utiliser Protractor-net dans mes tests, ainsi que abstraire les outils de test.

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

    _driver = new NgWebDriver(driver); 

    // ... 
} 

Lorsque le cadre remet en pilote pour accéder à la page, il passe le chemin de fichier correct (« file: /// ... »), mais il ne fait jamais dans l'URL du navigateur et n'est pas navigué vers. (c'est-à-dire que l'URL indique data;)

Comment accéder à une page HTML locale avec un chemin de fichier avec ChromeDriver?

Répondre

2

Il s'avère que cette résolution à ce problème est ancrée dans NgWebDriver. NgWebDriver aux pilotes diffère pour IE, Edge, PhantomJS, Firefox et Safari pour accéder à l'URL, mais si elle est autre chose alors il court ceci: this.ExecuteScript("window.name += '" + AngularDeferBootstrap + "'; window.location.href = '" + value + "';");

Le JavaScript method qui est appelé ne gère pas seulement passant dans un chemin local, il a besoin d'une chaîne http (s) pour naviguer. Donc, que nous puissions transmettre un chemin local dépend de l'implémentation du pilote spécifique de la méthode set pour la propriété Url.

Voici la propriété Protractor-net correspondante.

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

Depuis cette propriété suppose qu'une application utilise angulaire, lors de la navigation avec Navigate().GoToUrl() vous devez inclure, encore une fois, si l'application utilise angulaire par un bool.

Dans notre cas, nous n'utilisaient pas angulaire et le passage que dans la méthode GoToUrl() appelle directement dans le IWebDriver enveloppé par INavigation. Ce pilote encapsulé gère correctement les fichiers locaux.

Ci-dessous le navigation class net dans Protractor:

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); 
     } 
    } 
+0

Bonne trouvaille. Toujours amusant de naviguer dans les subtilités du NgWebDriver posé au-dessus des autres WebDrivers ... –