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ì

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;
}
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. –
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. –
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