Enabling Chrome Extension in Incognito Mode via CLI flags? Enabling Chrome Extension in Incognito Mode via CLI flags? selenium selenium

Enabling Chrome Extension in Incognito Mode via CLI flags?


Here is the solution that will work with the latest version of Chrome 74.

  1. Navigate to chrome://extensions
  2. Click on Details button for your desired extension

enter image description here

  1. Copy the url (This contains your extension id)

Now we have to navigate to the above url and then click on the allow in incognito toggle.

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()");

Continue Reading, if you want to know how and why

Root Cause:

As part of enhancements to the chrome browser, google moved all the chrome option in to shadow dom. So you can not access allow in incognito toggle element as selenium find_element method which will point to the original dom of the page. So we have to switch to the shadow dom and access the elements in the shadow tree.

Details:

Shadow DOM:enter image description here

Note: We will be referring to the terms shown in the picture. So please go through the picture for better understanding.

Solution:

In order to work with shadow element first we have to find the shadow host to which the shadow dom is attached. Here is the simple method to get the shadow root based on the shadowHost.

private static WebElement getShadowRoot(WebDriver driver,WebElement shadowHost) {    JavascriptExecutor js = (JavascriptExecutor) driver;    return (WebElement) js.executeScript("return arguments[0].shadowRoot", shadowHost);}

And then you can access the shadow tree element using the shadowRoot Element.

// get the shadowHost in the original dom using findElementWebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS"));// get the shadow rootWebElement shadowRoot = getShadowRoot(driver,shadowHost);// access shadow tree elementWebElement shadowTreeElement = shadowRoot.findElement(By.cssSelector("shadow_tree_element_css"));

In order to simplify all the above steps created the below method.

public static WebElement getShadowElement(WebDriver driver,WebElement shadowHost, String cssOfShadowElement) {    WebElement shardowRoot = getShadowRoot(driver, shadowHost);    return shardowRoot.findElement(By.cssSelector(cssOfShadowElement));}

Now you can get the shadowTree Element with single method call

WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS_Goes_here));WebElement shadowTreeElement = getShadowElement(driver,shadowHost,"shadow_tree_element_css");

And perform the operations as usual like .click(), .getText().

shadowTreeElement.click()

This Looks simple when you have only one level of shadow DOM. But here, in this case we have multiple levels of shadow doms. So we have to access the element by reaching each shadow host and root. enter image description here

Below is the snippet using the methods that mentioned above (getShadowElement and getShadowRoot)

// Locate shadowHost on the current domWebElement shadowHostL1 = driver.findElement(By.cssSelector("extensions-manager"));// now locate the shadowElement by traversing all shadow levelsWebElement 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();

You can achieve all the above steps in single js call as at mentioned at the beginning of the answer (added below just to reduce the confusion).

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


In chrome version 69 this code works (Python version):

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)

Just remember to change var extensionName = 'TestRevolution'; line to your extension name.


If you are trying to enable the already installed extension in incodnito, then try the below code . It should work with chrome.

 driver.get("chrome://extensions-frame");  WebElement checkbox = driver.findElement(By.xpath("//label[@class='incognito-control']/input[@type='checkbox']"));  if (!checkbox.isSelected()) {    checkbox.click();  }