How to install a ".xpi" browser extension through remote session of Selenium WebDriver C# binding for testing it.
Tags: webdev, testing, selenium
Published: 2022-10-31 12:57:20

## Prologue

The "GeckoDriver" (a.k.a "FirefoxDriver"), one of the WebDriver to remote-operate Web browsers, provides us with the ability to install a ".xpi" Mozilla browser extension file in its remote-operation session.

This feature is convenient for conducting End-to-End tests for a ".xpi" Mozilla browser extension.

Unfortunately, I ran into some pitfalls when I tried to do that. So I'll explain the best way to install a ".xpi" file via Selenium GeckoDriver in this article.

By the way, I'm a .NET guy, so I'll explain based on the C# binding of Selenium.

## Don't use the "FirefoxProfile.AddExtension"

First, you might notice that there is the "AddExtension()" method in the "FirefoxProfile" class. The name of that method seems good to use the installing an extension.

However, unexpectedly, the "FirefoxProfile.AddExtension()" method didn't work correctly. I don't know why this method doesn't work, but anyway, I've never succeeded in installing an extension with that method.

```csharp
// ⚠️ Don't do this.
var profile = new FirefoxProfile();
profile.AddExtension(pathToXpiFile);
```

## Use the "FirefoxDriver.InstallAddOnFromFile"

Instead, please use the "InstallAddOnFromFile()" method of the "FirefoxDriver". The argument of this method is a path to a ".xpi" file. The "FirefoxDriver.InstallAddOnFromFile" method will work fine as we expected, and there is nothing too difficult.

```csharp
// 👍 Do this.
using var driver = new FirefoxDriver();
driver.InstallAddOnFromFile(pathToXpiFile);
```

The "FirefoxDriver" class also exposes the "InstallAddOn()" method, and this method accepts the binary contents of the browser extension as a base64 encoded string.

## Don't use the "FirefoxProfile.SetPreference"

Usually, during the End-to-End testing of a browser extension, the ".xpi" browser extension file is not signed because it is in the development phase before submitting it for store review. But web browsers usually reject installing an unsigned browser extension file. So we have to disable this restriction of browsers during the testing.

To do that, you may find a way to set the preference "xpinstall.signatures.required" to false from the Internet search result.

However, the code below that uses the "SetPreference" method of the "FirefoxProfile" class will never work.

```csharp
// ⚠️ Don't do this.
var profile = new FirefoxProfile();
profile.AddExtension(pathToXpiFile);
```

If you do that, you will run into an exception like this:

```
"System.ArgumentException: Preference xpinstall.signatures.required may not be overridden: frozen value=False, requested value=False"
```

## Use the "FirefoxOptions.SetPreference"

Instead, please use the "SetPreference" method of the "FirefoxOptions" class, not of the "FirefoxProfile" class. This way will work fine.

```csharp
// 👍 Do this.
var option = new FirefoxOptions();
option.SetPreference("xpinstall.signatures.required", false);
using var driver = new FirefoxDriver(option);
```

## Don't use the normal edition of Firefox

After doing the above step, you will still see an unexpected error at runtime like the bellow, even though you set the "xpinstall.signatures.required" preference to false:

```
"Could not install add-on: ....xpi: ERROR_SIGNEDSTATE_REQUIRED: The addon must be signed and isn't."
```

Because Firefox Browser of the normal edition is designed as it never allows us to install an unsigned ".xpi" browser extension file.

## Use the Developer or Enterprise edition of Firefox

Instead, you must install the Developer Edition or Enterprise Edition of Firefox web browser on your PC for this scenario.Please follow the link below for more details about the Firefox Developer Edition.

https://www.mozilla.org/firefox/developer/

## Conclusion

I'm not sure why there are some pitfalls that are hard to notice to install a ".xpi" browser extension file via Selenium WebDriver. So I hope this article will save the time of other developers.

You can see the entire sample code of this article in the following GitHub repository.

https://github.com/sample-by-jsakamoto/InstallAddOnTestOnSeleniumAndFirefox

Have a nice coding :)