11

Ho bisogno di installare e configurare un'estensione in Chrome per modificare tutte le intestazioni delle richieste durante l'esecuzione del test del selenio. Sono stato in grado di seguire un esempio da questo support article in Saucelabs che mostra come farlo per Firefox localmente, ma non sono sicuro di come farlo per Chrome.Come configurare programmaticamente l'estensione di Chrome tramite Selenium WebDriver

La documentazione di ChromeDriver per extensions va solo nell'installazione, non nella configurazione.

Domande

  • Qualcuno mi può indicare alcuni documenti che spiegano come questo può essere realizzato o postare un esempio qui?
  • Come verrebbero aggiornate le impostazioni?
  • Come scoprire quali proprietà delle impostazioni sono disponibili per qualsiasi estensione specificata?
  • Esistono differenze tra l'esecuzione locale e quella remota, poiché si tratta di uno dei problemi riscontrati con lo Firefox method?

Piano è quello di eseguire questo contro SauceLabs. Proverò a utilizzare l'estensione chrome ModHeader per impostare i valori dell'intestazione necessari.

EDIT 1

provato a installare la versione Chrome dell'estensione MODHeader, ma incorrere in problemi simili. In grado di ottenere l'estensione installata localmente, ma nelle esecuzioni remote viene visualizzato un errore.

private static IWebDriver GetRemoteDriver(string browser) 
{ 

    ChromeOptions options = new ChromeOptions(); 
    options.AddExtensions("Tools/Chrome_ModHeader_2_0_6.crx"); 

    DesiredCapabilities capabilities = DesiredCapabilities.Chrome(); 
    capabilities.SetCapability(ChromeOptions.Capability, options); 


    capabilities.SetCapability("name", buildContext); 
    capabilities.SetCapability(CapabilityType.BrowserName, "Chrome"); 
    capabilities.SetCapability(CapabilityType.Version, ""); 
    capabilities.SetCapability(CapabilityType.Platform, "Windows 10"); 
    capabilities.SetCapability("screen-resolution", "1280x1024"); 
    capabilities.SetCapability("username", "SaucelabsUserName"); 
    capabilities.SetCapability("accessKey", "SaucelabsAccessKey"); 
    capabilities.SetCapability("build", "BuildNumber"); 
    capabilities.SetCapability("seleniumVersion", "2.50.1"); 


    return new RemoteWebDriver(new Uri("http://ondemand.saucelabs.com/wd/hub"), capabilities); 
} 

errore visualizzato in SauceLabs log è

[1.968][INFO]: RESPONSE InitSession unknown error: cannot parse capability: chromeOptions 
from unknown error: unrecognized chrome option: Arguments 
+0

Domanda veloce per confermare la mia comprensione: devi farlo utilizzando un'estensione piuttosto che, diciamo, un proxy Browsermob, attraverso il quale è possibile convogliare tutto il traffico di selenium e riscrivere la maggior parte degli aspetti della richiesta/risposta? Avrei sicuramente provato a evitare di creare qualcosa di specifico per il browser. –

+1

Inoltre * è necessario * utilizzare ModHeader? L'API WebRequest (https://developer.chrome.com/extensions/webRequest) non è complessa, quindi probabilmente è molto più semplice implementare un'estensione dedicata personalizzata, a cui è possibile inviare i propri messaggi, piuttosto che provare a controllare un esistente. –

+0

Grazie per i commenti @AndrewRegan. Sguardo rapido su Browsermob, i documenti non menzionano nulla sull'utilizzo di questo in un ambiente C#, quindi è un no go per me, ma potrebbe essere una buona opzione per gli altri. Il suggerimento di WebRequest API sembra che tu debba creare un'estensione chrome per ottenere questa funzionalità, che è più complessa di quanto volessi introdurre come soluzione. Ho trovato il metodo Firefox collegato sopra funzionante, che era l'approccio più semplice. Qualcosa di simile dovrebbe essere semplice da fare in Chrome, ma non sono riuscito a trovare documenti o esempi su come farlo. – Jerry

risposta

0

Dal momento che si parla che il problema è soprattutto sul telecomando e ho notato che si sta utilizzando SauceLabs, avete controllare questo articolo da loro?

https://support.saucelabs.com/customer/en/portal/articles/2200902-creating-custom-firefox-profiles-and-chrome-instances-for-your-automated-testing

Installing an Firefox Extension such as Modify Headers(You would need download the .xpi file on your machine first): 

DesiredCapabilities caps = new DesiredCapabilities(); 
FirefoxProfile profile = new FirefoxProfile(); 
profile.addExtension(new File("path\of\Modify Headers xpi file")); 
profile.setPreference("general.useragent.override", "UA-STRING"); 
profile.setPreference("extensions.modify_headers.currentVersion", "0.7.1.1-signed"); 
profile.setPreference("modifyheaders.headers.count", 1); 
profile.setPreference("modifyheaders.headers.action0", "Add"); 
profile.setPreference("modifyheaders.headers.name0", "X-Forwarded-For"); 
profile.setPreference("modifyheaders.headers.value0", "161.76.79.1"); 
profile.setPreference("modifyheaders.headers.enabled0", true); 
profile.setPreference("modifyheaders.config.active", true); 
profile.setPreference("modifyheaders.config.alwaysOn", true); 
profile.setPreference("modifyheaders.config.start", true); 
caps.setCapability(FirefoxDriver.PROFILE, profile); 

NOTE: If you trying to do the same using C#, you would need to use the ToBase64String() method. 
+0

Mi sono collegato a quell'articolo nella mia domanda e ho detto che ero in grado di farlo funzionare in Firefox localmente. Nel mio altro link, sono riuscito a farlo funzionare anche da remoto in Firefox. Questo problema riguarda il recupero remoto di un'estensione installata in Chrome. – Jerry

0

sono riuscito a installare un'estensione su un browser Chrome in Saucelabs come segue:

ChromeOptions options = new ChromeOptions(); 
options.addExtensions(new File("/path/to/myextrension.crx")); 
DesiredCapabilities capabilities = new DesiredCapabilities(); 
capabilities.setCapability(ChromeOptions.CAPABILITY, options); 
capabilities.setBrowserName(DesiredCapabilities.chrome().getBrowserName()); 

// Rest of capabilities config (version, platform, name, ...) 

WebDriver driver = new RemoteWebDriver(new URL("http://saucelabs-url/wd/hub"), capabilities); 
0

ho trovato la soluzione di questo problema. Funziona con il mio Selenium GRID con browser Chrome remoti. Prima di tutto ero diventato per memorizzare l'estensione ModHeader (versione 1.2.4) scompattata nelle risorse del mio progetto. Sembra così

enter image description here

Se ho bisogno di modificare intestazione in Chrome che faccio seguenti fasi:

1) decomprimere cartella con estensione da risorse nella cartella temporanea

2) Impostare le chiavi di intestazione e valori nell'intestazione.JSON

3) imballare questa estensione per file zip utilizzando Java

4) aggiungere file zip per ChromeOptions

public static IDriver getDriverWithCustomHeader(List<HeaderElement> headerList) { 
    Logger.info(StringUtils.buildString("Create new instance of Driver with header.")); 
    IDriver driver; 
    DesiredCapabilities capabilities; 
    switch (GlobalConfig.getInstance().getDriverType()) { 
     case CHROME: 
      // define path to resources 
      String unpackedExtensionPath = FileUtils.getResourcePath("chrome_extension", true); 
      // setting headers for extension in unpackaged kind 
      FileUtils.writeToJson(StringUtils.buildString(unpackedExtensionPath, File.separator, "header.json"), headerList); 
      // packing prepared extension to ZIP with crx extension 
      String crxExtensionPath = ZipUtils.packZipWithNameOfFolder(unpackedExtensionPath, "crx"); 
      // creating capability based on packed extension 
      capabilities = CapabilityFactory.getChromeCapabilitiesWithExtension(crxExtensionPath); 
      driver = new AppiumDriver(GlobalConfig.getInstance().getHost(), GlobalConfig.getInstance().getPort(), 
        capabilities); 
      break; 
     default: 
      throw new CommonTestRuntimeException("Unsupported Driver Type for changing head args."); 
    } 

    drivers.add(driver); 
    if (defaultDriver != null) { 
     closeDefaultDriver(); 
    } 

    defaultDriver.set(driver); 
    return driver; 
} 

fileutils

public static String getResourcePath(String resourceName, boolean isDir) { 
    String jarFileName = new File(FileUtils.class.getClassLoader().getResource(resourceName).getPath()).getAbsolutePath() 
      .replaceAll("(!|file:\\\\)", ""); 
    if (!(jarFileName.contains(".jar"))) { 
     return getResourcePath(resourceName); 
    } 
    if (isDir) { 
     return getDirPath(resourceName); 
    } 
    return getFilePath(resourceName); 
} 

private static String getResourcePath(String resourceName) { 
    String resourcePath = FileUtils.class.getClassLoader().getResource(resourceName).getPath(); 
    if (platformIsWindows()) { 
     resourcePath = resourcePath.substring(1); 
    } 
    return resourcePath; 
} 

private static boolean platformIsWindows() { 
    boolean platformIsWindows = (File.separatorChar == '\\') ? true : false; 
    return platformIsWindows; 
} 

private static String getDirPath(String dirName) { 
    JarFile jarFile = null; 
    //check created or no tmp directory 
    //and if the directory created already we return "it + dirName" 
    //else we create tmp directory and copy target resources 
    if (directoryPath.get() == null) { 
     //set directory path for each thread 
     directoryPath.set(Files.createTempDir().getAbsolutePath()); 
    } 
    //copying resources 
    if (!new File(directoryPath.get() + File.separator + dirName.replaceAll("/", "")).exists()) { 
     try { 
      List<JarEntry> dirEntries = new ArrayList<JarEntry>(); 
      File directory = null; 
      String jarFileName = new File(FileUtils.class.getClassLoader().getResource(dirName).getPath()).getParent() 
        .replaceAll("(!|file:\\\\)", "").replaceAll("(!|file:)", ""); 
      jarFile = new JarFile(URLDecoder.decode(jarFileName, "UTF-8")); 
      Enumeration<JarEntry> entries = jarFile.entries(); 
      while (entries.hasMoreElements()) { 
       JarEntry jarEntry = entries.nextElement(); 
       if (jarEntry.getName().startsWith(dirName)) { 
        if (jarEntry.getName().replaceAll("/", "").equals(dirName.replaceAll("/", ""))) { 
         directory = new File(directoryPath.get() + File.separator + dirName.replaceAll("/", "")); 
         directory.mkdirs(); 
        } else 
         dirEntries.add(jarEntry); 
       } 
      } 
      if (directory == null) { 
       throw new CommonTestRuntimeException(StringUtils.buildString("There is no directory ", dirName, 
         "in the jar file")); 
      } 
      for (JarEntry dirEntry : dirEntries) { 
       if (!dirEntry.isDirectory()) { 
        File dirFile = new File(directory.getParent() + File.separator + dirEntry.getName()); 
        dirFile.createNewFile(); 
        convertStreamToFile(dirEntry.getName(), dirFile); 
       } else { 
        File dirFile = new File(directory.getParent() + File.separator + dirEntry.getName()); 
        dirFile.mkdirs(); 
       } 
      } 
      return directory.getAbsolutePath(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } finally { 
      try { 
       jarFile.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     throw new CommonTestRuntimeException("There are problems in creation files in directory " + directoryPath); 
    } else { 
     return directoryPath.get() + File.separator + dirName.replaceAll("/", ""); 
    } 
} 

private static String getFilePath(String fileName) { 
    try { 
     String[] fileType = fileName.split("\\."); 
     int typeIndex = fileType.length; 
     File file = File.createTempFile(StringUtils.generateRandomString("temp"), 
       StringUtils.buildString(".", fileType[typeIndex - 1])); 
     file.deleteOnExit(); 
     convertStreamToFile(fileName, file); 
     return file.getAbsolutePath(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    throw new CommonTestRuntimeException("Impossible to get file path"); 
} 

private static void convertStreamToFile(String resourceFileName, File file) throws IOException { 
    try (InputStream in = FileUtils.class.getClassLoader().getResourceAsStream(resourceFileName); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF8")); 
     FileOutputStream fos = new FileOutputStream(file); 
     OutputStreamWriter fileOutputStreamWriter = new OutputStreamWriter(fos, "UTF8"); 
     BufferedWriter fileWriter = new BufferedWriter(fileOutputStreamWriter); 
    ) { 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      fileWriter.write(line + "\n"); 
     } 
    } 
} 

public static void writeToJson(String jsonFilePath, Object object) { 
    try { 
     Gson gson = new Gson(); 
     FileWriter fileWriter = new FileWriter(jsonFilePath); 
     fileWriter.write(gson.toJson(object)); 
     fileWriter.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

ZipUtils

public static String packZipWithNameOfFolder(String folder, String extension) { 
    String outZipPath = folder + "." + extension; 
    try { 
     try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outZipPath))) { 
      File file = new File(folder); 
      doZip(file, zos); 
     } 
    } catch (IOException e) { 
     throw new CommonTestRuntimeException("Fail of packaging of folder. ", e); 
    } 
    return outZipPath; 
} 

private static void doZip(File dir, ZipOutputStream out) throws IOException { 
    for (File f: dir.listFiles()) { 
     if (f.isDirectory()) { 
      doZip(f, out); 
     } else { 
      out.putNextEntry(new ZipEntry(f.getName())); 
      try (FileInputStream in = new FileInputStream(f)) { 
       write(in, out); 
      } 
     } 
    } 
} 

private static void write (InputStream in, OutputStream out) throws IOException { 
    byte[] buffer = new byte[1024]; 
    int len; 
    while ((len = in.read(buffer)) >= 0) { 
     out.write(buffer, 0, len); 
    } 
} 

Capacità Factory.getChromeCapabilitiesWithExtension (...)

public static DesiredCapabilities getChromeCapabilitiesWithExtension(String crxExtensionPath) { 
    DesiredCapabilities chromeCapabilities = getChromeCapabilities(); 
    Logger.info("Extension path: " + crxExtensionPath); 
    ChromeOptions options = new ChromeOptions(); 
    options.addExtensions(new File(crxExtensionPath)); 
    options.addArguments("--start-maximized"); 
    chromeCapabilities.setCapability(ChromeOptions.CAPABILITY, options); 
    return chromeCapabilities; 
} 
-1
public void AddHeaderFirefox(FirefoxProfile profile) 
{ 
String directory = System.getProperty("user.dir"); 
FirefoxProfile profile = new FirefoxProfile(); 
try 
{ 
profile.addExtension(new File(directory+"/modify-headers-0.7.1.1.xpi")); 
} 
catch(IOException e) 
{ 
    System.out.println(e); 
} 
String HeadersName[]=new String[10]; 
String HeadersValue[]=new String[10]; 

if(ConfigDetails.HeadersName.contains(",") && ConfigDetails.HeadersValue.contains(",")) 
{ 
HeadersName=ConfigDetails.HeadersName.split(","); 
HeadersValue=ConfigDetails.HeadersValue.split(","); 
length=HeadersName.length; 
       } 

You have to parametrise the header USING Split function of java to set 
multiple headers. 

for(int i=0;i<length;i++) 
{ 
profile.setPreference("modifyheaders.headers.count",i+1); 
profile.setPreference("modifyheaders.headers.action"+i, "Add"); 
profile.setPreference("modifyheaders.headers.name"+i,HeadersName[i]); 
profile.setPreference("modifyheaders.headers.value"+i,HeadersValue[i]); 
profile.setPreference("modifyheaders.headers.enabled"+i, true); 
profile.setPreference("modifyheaders.config.active", true); 
profile.setPreference("modifyheaders.config.alwaysOn", true); 

}

0
public void AddHeaderChrome() 
    { 
    ChromeOptions options = new ChromeOptions(); 
    options.addExtensions(new File("C:\\Downloads\\ModHeader_v2.0.9.crx")); 
    DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer(); 

    capabilities.setCapability(CapabilityType.options); 
    // launch the browser 
    WebDriver driver = new ChromeDriver(options); 
    String HeadersName[]=new String[10]; 
    String HeadersValue[]=new String[10];; 
    int length; 
    if(ConfigDetails.HeadersName.contains(",")) 
    { 
    HeadersName=ConfigDetails.HeadersName.split(","); 
    HeadersValue=ConfigDetails.HeadersValue.split(","); 
    length=HeadersName.length; 
    } 
    else 
    { 
     HeadersName[0]=ConfigDetails.HeadersName; 
     HeadersValue[0]=ConfigDetails.HeadersValue; 
     length=1; 
    } 
    int field_no=1; 
    for(int i=0;i<length;i++) 
    { 
    driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/popup.html"); 
    driver.findElement(By.xpath("//input[@id='fl-input-"+field_no+"']")).sendKeys(HeadersName[i]); 
    driver.findElement(By.xpath("//input[@id='fl-input-"+(field_no+1)+"']")).sendKeys(HeadersValue[i]); 
    field_no+=2 
    }