Reloading a Chrome Extension using Selenium WebDriver

Some automated tests require browser extensions to complete an action. For instance, testing whether a login ‘Remember Me’ works via a cookie.

However, not all browser extensions work immediately. Some of Chrome’s must be refreshed first, for it to work as expected.

This tutorial will show you a script that will refresh a Chrome extension before a test begins.

The Scenario

We want to log in to a sample site with a cookie. To store this cookie, I will use the Chrome ModHeader extension in this tutorial. First, start Chrome with the extension (I used this tutorial for how to drive Chrome with Extensions using Selenium WebDriver).

Following this, just running the basic test will give you this window:

ModHeader extension’s link displays “Your file couldn’t be accessed”.

It knows we are trying to open ModHeader (in the top bar), but cannot access it.

If we manually go to the Extension Manager (chrome://extensions), there is a reload option for each extension (highlighted in red below).

Chrome Extension Manager, with reload icon highlighted in red

Click it to see a “Reloaded” toast. Now if we return to ModHeader again, it will have loaded properly.

ModHeader extension page loaded correctly

These are the basic steps we want our script to be able to replicate.

In summary, to load an extension properly we want to write a script that will:

  1. Navigate to the Extension Manager
  2. Reload Affected Extension
  3. Return to the Extension’s Page

Navigate to the Extension Manager

This step should be familiar! Just navigate to the extensions page.

 driver.get(“chrome://extensions”)

Reload Affected Extension

Here is the tricky part, we just want to click the ‘reload’ button. However, Chrome’s extension manager makes use of nested shadow roots (see my previous tutorial on automating Shadow DOM with Selenium WebDriver).

Chrome Extension Manager page with inspect element’s relevant shadow roots for the reload button highlighted.

In the above screenshot, the reload button is actually under three shadow roots!

Some keen readers may notice that there is another shadow root under the<cr-view-manager> tag. Good spotting, but the reload button is not nested under it so we can ignore it for this tutorial.

Like the previous tutorial, we will execute JavaScript to isolate the shadow roots; but this time do it three times over.

# first shadow root, call from driver
elem1 = driver.find_element(:tag_name, "extensions-manager")
shadow_root1 = driver.execute_script("return arguments[0].shadowRoot", elem1)
# second shadow_root, call from shadow_root1
elem2 = shadow_root1.find_element(:tag_name, "extensions-item-list")
shadow_root2 = driver.execute_script("return arguments[0].shadowRoot", elem2)
# third shadow_root, call from shadow_root2
elem3 = shadow_root2.find_element(:tag_name, "extensions-item")
shadow_root3 = driver.execute_script("return arguments[0].shadowRoot", elem3)

It is important to note that we get our inner shadow root from it’s direct shadow root parent (or driver if it is the outermost).

Finally, within our focused shadow root, shadow_root3, we can click the reload button to reload our extension.

reload_button = shadow_root3.find_element(:tag_name, "cr-icon-button")
reload_button.click # click first reload button

What if I have more than one extensions to reload?

In this scenario, I only had one extension to reload, so I stopped there. In the case of multiple extensions you will want to continue using shadow_root2 to locate each extension and their corresponding shadow root.

Return to the Extension’s Page

Again, referencing the prior tutorial (Drive Chrome with Extensions using Selenium WebDriver), use the extension’s ID to return to the extension’s page.

driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/popup.html")
ModHeader extension page loaded correctly

And presto! ModHeader has now loaded correctly and from here, you may continue testing with the aid of Chrome extensions.

Here is a gif of the start of my cookie test running:

The script in this tutorial in action!

The Code

As you only need to reload extensions once, I recommend putting it in the before(:all) call. I have included the full code of my before(:all) below:

before(:all) do
@driver = $driver = Selenium::WebDriver.for(browser_type, browser_options)
driver.manage().window().resize_to(1280, 720)
# first shadow root, call from driver
elem1 = driver.find_element(:tag_name, "extensions-manager")
shadow_root1 = driver.execute_script("return arguments[0].shadowRoot", elem1)
# second shadow_root, call from shadow_root1
elem2 = shadow_root1.find_element(:tag_name, "extensions-item-list")
shadow_root2 = driver.execute_script("return arguments[0].shadowRoot", elem2)
# third shadow_root, call from shadow_root2
elem3 = shadow_root2.find_element(:tag_name, "extensions-item")
shadow_root3 = driver.execute_script("return arguments[0].shadowRoot", elem3)
# click reload button
reload_button = shadow_root3.find_element(:tag_name, "cr-icon-button")
reload_button.click
driver.get(site_url)
end

Note: it would be a good idea to refactor the extension reload section out in a real project.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store