【问题标题】:Enabling Chrome Extension in Incognito Mode via CLI flags?通过 CLI 标志在隐身模式下启用 Chrome 扩展程序?
【发布时间】:2015-02-16 12:55:17
【问题描述】:

我正在使用 selenium 来测试 chrome 扩展,并且部分扩展要求用户处于隐身模式。目前,除了添加参数 user-data-dir=/path/to/directory 之外,我无法在启动时启用在隐身模式下允许的扩展。

这个问题是它从我的文件系统的深处加载扩展,而不是我可以检查到 git 的方式。

我也尝试将 selenium 导航到 chrome 扩展设置页面,但似乎 selenium 无法驱动 chrome:// 页面。

关于如何在 chrome 驱动程序启动时在 chrome 扩展上启用隐身功能有什么想法吗?

【问题讨论】:

  • @gui47 不完全是重复的:该问题询问是否从扩展中启用,这里它要求从命令行启用。
  • 嗯,我明白了。我认为有一种方法可以通过创建快捷方式并添加两个开关来运行和打开扩展。 "C:\Users\%user%\AppData\Local\Google\Chrome\Application\chrome.exe" --incognito --enable-extensions

标签: google-chrome selenium google-chrome-extension selenium-webdriver


【解决方案1】:

这是适用于最新版本 Chrome 74 的解决方案。

  1. 导航到chrome://extensions
  2. 单击详细信息按钮以获取所需的扩展

  1. 复制网址(其中包含您的扩展名id

现在我们必须导航到上面的 url,然后点击 allow in incognito 切换。

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 浏览器增强功能的一部分,谷歌将所有 chrome 选项移至shadow dom。所以你不能访问 allow in incognito 切换元素作为 selenium find_element 方法,它将指向页面的原始 dom。所以我们必须切换到shadow dom 并访问shadow tree 中的元素。

详情:

影子 DOM:

注意:我们将参考图片中显示的术语。所以请仔细阅读图片以便更好地理解。

解决方案:

为了使用 shadow 元素,首先我们必须找到 shadow dom 所附加的shadow host。下面是基于shadowHost获取shadow root的简单方法。

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 时,这看起来很简单。但是在这里,在这种情况下,我们有多个级别的 shadow dom。所以我们必须通过到达每个影子主机和根来访问元素。

下面是使用上面提到的方法(getShadowElement和getShadowRoot)的sn-p

// 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')");

【讨论】:

    【解决方案2】:

    我还是编码新手,但在查看 chrome 的 crisper.js chrome://extensions/ 后,我想出了另一种方法。

    首先您需要知道扩展 ID。您可以通过将 id 设为常量here 或使用 pako 的方法获取 id 来实现。我的是"lmpekldgmhemmmbllpdmafmlofflampm"

    然后使用 --incognito 和 addExtension 启动 chrome,然后执行 javascript 以启用 incognito。

    例子:

        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】:

      在 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'; 行更改为您的扩展名。

      【讨论】:

        【解决方案4】:

        如果您尝试在 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();
          }
        

        【讨论】:

        • 他们更改了新扩展中的所有内容,现在您的解决方案不再适用。它变得越来越复杂丑陋。
        猜你喜欢
        • 2013-06-30
        • 2016-11-05
        • 2022-01-19
        • 1970-01-01
        • 2019-12-16
        • 2017-05-17
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        相关资源
        最近更新 更多