5 Easy Steps to Test Browser Extensions with Selenium


Fast-paced software development environments can create time and cost constraints that make it strenuous to comprehensively test new applications upon deployment. Over recent years, Continuous Integration (CI) has become a good best practice for software development, making the process much easier, as it tends to find issues earlier, offering risk mitigation and boosted confidence benefits.

This is mostly relevant when it comes to automatic testing for web, mobiles sites, applications and much more. For instance, a browser extension, be it Firefox, Chrome, Opera, Internet Explorer or Safari.

What are the Obstacles You May Find When Testing Browser Extensions?

Browser extensions can be defined as embedded add-ons in your browser, which provides the web browser with additional integrated features. Since the extensions aren’t standard HTML files, they are out of scope and the tester cannot inspect the extension elements, such as simulating user clicks.

Let us suppose you want to perform the end-user client testing in your browser. This can be easily accomplished on a web-site page using Selenium to mimic user interaction. However, for Selenium to be able to simulate user interaction with the installed extension, you need to figure out the location of the extension pages, and then how to switch to these elements, so you could interact with them as DOM elements.

In this blog post, I will show you a very simple workaround to this issue. By following the below steps, you would be able to interact with the extension just like with a normal web-page. This means that you can automate the process of testing your browser extensions and thus moving one step closer to flawless testing.

The examples shown below are specifically for Firefox extensions, however, the same principles still apply for all other browsers like Chrome, Internet Explorer, Safari, etc.

Testing Your Firefox Extension using Selenium

 1.       Download your Firefox Extension

To do the following, go to the Firefox add-on page and search for the extension required. Once the extension has been found, right-click on the ‘Add to Firefox’ button and press the ‘Save Link as’ button to download the XPI file. In this particular example, I am going to use Adblock Plus


Note: An XPI file is a compressed installation archive used by Firefox applications. It usually contains software, such as web browser extensions. The file extension format would vary on different browser platforms. For instance, Chrome does not make use of XPI file extensions but rather CRX file extensions.

      2.      Unpack your Firefox Extension

Once the XPI has been installed, you need to rename the file extension to .ZIP, so you could then extract it, to view all the XPI file contents. Now, you will be able to see a list of all files (javascript, images, etc), including pages accessible to you in XPI:



 3.       Determine the Page You Want to Test

In order to load a specific page, you will need to extract the unique ID of the XPI file in that particular Firefox extension.

First of all, acquire the unique ID of your Firefox extension you’re going to use. This can be done by using the about:memory in-built Firefox command, and by clicking the Measure button under ‘Show Memory Reports’ :


You will soon get a list of memory processes, where if you scroll down enough [or even search] you will find the specific process representing your extension with the respective extension ID as such:


Now go back to the XPI file resource list and find the particular page that you’re looking for. In my case, it is the popup.html file (this is also the general case):


Finally, to open this page, you would need to follow this link structure:

FROM: moz-extension://UNIQUE-ID/popup.html
TO: moz-extension://411335cf-2ee6-4396-bf8b-46cabacbc088/popup.html

This will open the popup extension page as an HTML page:

   4.    Create Script to Create a New Firefox Driver with Your Installed Extension

   C#:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    public class ExtendedFirefoxDriver : FirefoxDriver
    {
        // NOTE: Add constructor overloads to support the instantiations your tests require.
        public ExtendedFirefoxDriver(FirefoxDriverService driverService, FirefoxOptions options) : base(driverService, options)
        {
            CommandExecutor.CommandInfoRepository.TryAddCommand("installAddOn", new CommandInfo(CommandInfo.PostCommand, "/session/{sessionId}/moz/addon/install"));
        }

        public void InstallAddOnFromFile(string addOnFileToInstall)
        {
            if (string.IsNullOrEmpty(addOnFileToInstall))
            {
                throw new ArgumentNullException("addOnFileToInstall", "Add-on file name must not be null or the empty string");
            }

            if (!File.Exists(addOnFileToInstall))
            {
                throw new ArgumentException("File " + addOnFileToInstall + " does not exist", "addOnFileToInstall");
            }

            var addOnBytes = File.ReadAllBytes(addOnFileToInstall);
            var base64AddOn = Convert.ToBase64String(addOnBytes);
            InstallAddOn(base64AddOn);

            Thread.Sleep(1000);
        }

        public void InstallAddOn(string base64EncodedAddOn)
        {
            if (string.IsNullOrEmpty(base64EncodedAddOn))
            {
                throw new ArgumentNullException("base64EncodedAddOn", "Base64 encoded add-on must not be null or the empty string");
            }

            var parameters = new Dictionary<string, object>();
            parameters["addon"] = base64EncodedAddOn;
            Execute("installAddOn", parameters);
        }
    }

1
2
3
4
5
6
7
      #region firefox driver configuration
      var firefoxDriverService = FirefoxDriverService.CreateDefaultService(ConfigurationManager.AppSettings["GeckoDriverDirectory"]);
      firefoxDriverService.FirefoxBinaryPath = ConfigurationManager.AppSettings["FirefoxBinaryDirectory"];

      var firefoxDriver = new ExtendedFirefoxDriver(firefoxDriverService, new FirefoxOptions());
      firefoxDriver.InstallAddOnFromFile(ConfigurationManager.AppSettings["XpiPathAdblockPlus"]);
      #endregion

   5.    Utilize Configured Selenium Driver to Interact with the Extension Elements


You can now locate and interact with your page’s HTML elements by using Selenium’s navigation methods:

1
       firefoxDriver.Navigate().GoToUrl(By.XPath(Element));

Closure

This is a straightforward way to get your Browser Extensions into the testing scope so you can interact with them as you would do with a normal web page.

If you have problems when trying to attempt the above steps and would like to ask some questions, do not hesitate to share your experience in the comment section below.

Comments