我使用selenium来测试Chrome扩展程序,部分扩展程序要求用户处于隐身模式。目前,除非添加参数user-data-dir=/path/to/directory
,否则我无法在启动时允许以隐身模式启用扩展程序。
这个问题是它从我的文件系统的深度加载扩展,而不是我可以检查git的方式。
我还尝试将selenium导航到Chrome扩展程序设置页面,但似乎selenium无法驱动chrome://
页。
有关在启动Chrome驱动程序时如何在Chrome扩展程序上启用隐身功能的任何想法?
答案 0 :(得分:0)
如果您尝试在incodnito中启用已安装的扩展程序,请尝试以下代码。它应该与chrome一起使用。
driver.get("chrome://extensions-frame");
WebElement checkbox = driver.findElement(By.xpath("//label[@class='incognito-control']/input[@type='checkbox']"));
if (!checkbox.isSelected()) {
checkbox.click();
}
答案 1 :(得分:0)
在chrome版本69中,此代码有效(Python版本):
driver.get('chrome://extensions')
go_to_extension_js_code = '''
var extensionName = 'TestRevolution';
var extensionsManager = document.querySelector('extensions-manager');
var extensionsItemList = extensionsManager.shadowRoot.querySelector(
'extensions-item-list');
var extensions = extensionsItemList.shadowRoot.querySelectorAll(
'extensions-item');
for (var i = 0; i < extensions.length; i += 1) {
var extensionItem = extensions[i].shadowRoot;
if (extensionItem.textContent.indexOf(extensionName) > -1) {
extensionItem.querySelector('#detailsButton').click();
}
}
'''
enable_incognito_mode_js_code = '''
var extensionsManager = document.querySelector('extensions-manager');
var extensionsDetailView = extensionsManager.shadowRoot.querySelector(
'extensions-detail-view');
var allowIncognitoRow = extensionsDetailView.shadowRoot.querySelector(
'#allow-incognito');
allowIncognitoRow.shadowRoot.querySelector('#crToggle').click();
'''
driver.execute_script(go_to_extension_js_code)
driver.execute_script(enable_incognito_mode_js_code)
只需记住将var extensionName = 'TestRevolution';
行更改为您的扩展名。
答案 2 :(得分:0)
我仍然是编码方面的新手,但在crisper.js
中查看了chrome的chrome://extensions/
之后,我想出了另一种方法。
首先,您需要知道扩展名。您可以通过将id设置为常数here或使用pako的方法获取ID来实现。我的是"lmpekldgmhemmmbllpdmafmlofflampm"
然后使用--incognito和addExtension启动chrome,然后执行javascript以隐身方式启用。
示例:
public class test2 {
static String dir = System.getProperty("user.dir");
static WebDriver driver;
static JavascriptExecutor js;
public static void main(String[] args) throws InterruptedException, IOException{
ChromeOptions options = new ChromeOptions();
options.addArguments("--incognito");
options.addExtensions(new File(dir + "\\randua.crx"));
System.setProperty("webdriver.chrome.driver",dir + "\\chromedriver73.exe");
driver = new ChromeDriver(options);
js = (JavascriptExecutor) driver;
String extID = "lmpekldgmhemmmbllpdmafmlofflampm";
driver.get("chrome://extensions-frame/");
new WebDriverWait(driver, 60).until(webDriver -> js.executeScript("return document.readyState").equals("complete"));
js.executeScript("chrome.developerPrivate.updateExtensionConfiguration({extensionId: \"" + extID + "\",incognitoAccess: true})");
Thread.sleep(1000);
}
}
希望它会有所帮助:)
答案 3 :(得分:0)
以下是可与最新版本的 Chrome 74 一起使用的解决方案。
chrome://extensions
id
)现在,我们必须导航到上面的URL,然后单击以隐身方式允许切换。
Java:
driver.get("chrome://extensions/?id=bhghoamapcdpbohphigoooaddinpkbai");
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.querySelector('extensions-manager').shadowRoot.querySelector('#viewManager > extensions-detail-view.active').shadowRoot.querySelector('div#container.page-container > div.page-content > div#options-section extensions-toggle-row#allow-incognito').shadowRoot.querySelector('label#label input').click()");
Python:
driver.get("chrome://extensions/?id=bhghoamapcdpbohphigoooaddinpkbai")
driver.execute_script("return document.querySelector('extensions-manager').shadowRoot.querySelector('#viewManager > extensions-detail-view.active').shadowRoot.querySelector('div#container.page-container > div.page-content > div#options-section extensions-toggle-row#allow-incognito').shadowRoot.querySelector('label#label input').click()");
继续阅读,如果您想知道如何以及为什么
根本原因:
作为chrome浏览器增强功能的一部分,google将所有chrome选项都移到了shadow dom
中。因此,您不能以硒find_element
方法访问隐身模式下的 allow 切换元素,该方法将指向页面的原始dom。因此,我们必须切换到shadow dom
并访问shadow tree
中的元素。
详细信息:
注意:我们将参考图片中显示的术语。因此,请仔细阅读图片以更好地理解。
解决方案:
首先要使用 shadow元素,我们必须找到连接阴影域的shadow host
。这是基于shadowHost获取影子根的简单方法。
private static WebElement getShadowRoot(WebDriver driver,WebElement shadowHost) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return (WebElement) js.executeScript("return arguments[0].shadowRoot", shadowHost);
}
然后您可以使用shadowRoot元素访问影子树元素。
// get the shadowHost in the original dom using findElement
WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS"));
// get the shadow root
WebElement shadowRoot = getShadowRoot(driver,shadowHost);
// access shadow tree element
WebElement shadowTreeElement = shadowRoot.findElement(By.cssSelector("shadow_tree_element_css"));
为了简化上述所有步骤,创建了以下方法。
public static WebElement getShadowElement(WebDriver driver,WebElement shadowHost, String cssOfShadowElement) {
WebElement shardowRoot = getShadowRoot(driver, shadowHost);
return shardowRoot.findElement(By.cssSelector(cssOfShadowElement));
}
现在您可以通过单个方法调用来获取shadowTree元素
WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS_Goes_here));
WebElement shadowTreeElement = getShadowElement(driver,shadowHost,"shadow_tree_element_css");
并像往常一样执行.click()
,.getText()
之类的操作。
shadowTreeElement.click()
当您只有一个级别的影子DOM时,这看起来很简单。但是在这里,在这种情况下,我们有多个级别的阴影域。因此,我们必须通过到达每个影子主机和根来访问元素。
下面是使用上述方法(getShadowElement和getShadowRoot)的代码段
// Locate shadowHost on the current dom
WebElement shadowHostL1 = driver.findElement(By.cssSelector("extensions-manager"));
// now locate the shadowElement by traversing all shadow levels
WebElement shadowElementL1 = getShadowElement(driver, shadowHostL1, "#viewManager > extensions-detail-view.active");
WebElement shadowElementL2 = getShadowElement(driver, shadowElementL1,"div#container.page-container > div.page-content > div#options-section extensions-toggle-row#allow-incognito");
WebElement allowToggle = shadowElementL2.findElement(By.cssSelector("label#label input"));
allowToggle.click();
您可以按照答案开头所述在单个js调用中完成上述所有步骤(以下添加只是为了减少混乱)。
WebElement allowToggle = (WebElement) js.executeScript("return document.querySelector('extensions-manager').shadowRoot.querySelector('#viewManager > extensions-detail-view.active').shadowRoot.querySelector('div#container.page-container > div.page-content > div#options-section extensions-toggle-row#allow-incognito').shadowRoot.querySelector('label#label input')");