Turn on incognito Chrome extension via CLI flags?

I use selenium to test the chrome extension, and part of the extension requires the user to be in incognito mode. Currently, I could not enable the extension in incognito mode at startup, except for adding the user-data-dir=/path/to/directory argument.

The problem is that it loads the extension from the depths of my file system, and not in a way that I can check on git.

I also tried navigating selenium on the chrome extension settings page, but it seems that selenium cannot manage chrome:// pages.

Any ideas on how to enable incognito on the chrome extension when loading the chrome driver?

+6
source share
4 answers

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

  1. Go to chrome://extensions
  2. Click on the Details button for the desired extension

enter image description here

  1. Copy URL (contains id your extension)

Now we have to go to the above URL and then click on the allow in incognito switch.

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 the Chrome browser improvements, Google has moved all the Chrome options to shadow dom . Thus, you cannot access the allow in incognito switch element as find_element to the selenium find_element method, which will point to the source domain of the page. Thus, we must switch to shadow dom and access the elements in the shadow tree .

Details:

Shadow DOM: enter image description here

Note: we will refer to the terms shown in the picture. Therefore, please follow the picture for a better understanding.

Decision:

To work with the shadow element first , we need to find the shadow host to which the shadow house is attached. Here is an easy way to get the shadow root based on 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 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")); 

In order to simplify all of the above steps, the method below has been created.

 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 in one method call

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

And do the operations as usual, for example .click() , .getText() .

 shadowTreeElement.click() 

It looks simple when you have only one level of shadow DOM. But here, in this case, we have several levels of shadow houses. Therefore, we must access the element by reaching each shadow host and root. enter image description here

Below is a code snippet using the methods mentioned above (getShadowElement and 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(); 

You can complete all of the above steps in a single js call, as mentioned at the beginning of the answer (added below only to reduce 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')"); 
+1
source

If you are trying to enable an already installed extension in incodnito, try the code below. 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(); } 
0
source

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 extra name.

0
source

I'm still new to coding, but I crisper.js another method by looking in chrome crisper.js for chrome://extensions/ .

First you need to know the extension identifier. You can do this by setting id id here or using pako method to get identifiers. For me, this is "lmpekldgmhemmmbllpdmafmlofflampm"

Then launch Chrome using --incognito and addExtension, then execute JavaScript to enable it in incognito mode.

Example:

  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); } } 

Hope it helps :)

0
source

Source: https://habr.com/ru/post/1209401/


All Articles