Search code examples
javascriptseleniumgoogle-chrome-extensionnightwatch.jsmod-headers

Enabling and modifying Chome Extensions in default NightWatch browser instance (specifically ModHeader extension)


I am using NightWatch.js and for some UI tests and I want to start the default browser instance with the some extra desiredCapabilities (i.e. an extension is enabled with some specific values applied).

Note: I can perform the actions but not within the default browser instance.

To be totally clear, doing the actions manually looks like: ModHeader-Extension Link to Extension: https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj

I am able to enable the extension and also update the values using this command stored inside a pageObject file:

setChromeOptions(url) {
  const chromeCapabilities = webdriver.Capabilities.chrome();

  // setting chrome options
  const chromeOptions = {
    args:

    // path to local ModHeader extension
    ['--load-extension=/Users/raja.bellebon/AppData/Local/Google/Chrome/User Data/Default/Extensions/idgpnmonknjnojddfkpgkljpfnnfcklj/2.1.2_0/'],
  };

  chromeCapabilities.set('chromeOptions', chromeOptions);
  const driver = new webdriver.Builder().withCapabilities(chromeCapabilities).build();
  driver.get('chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/_generated_background_page.html');

  // setup ModHeader extension with the header value
  driver.executeScript(`
    localStorage.setItem('profiles', JSON.stringify([{ /* eslint-env browser*/
      title: 'Selenium',
      hideComment: true,
      appendMode: '',
      headers: [
      { enabled: true, name: 'X-Static-Homepage', value: 'true' },
      ],
      respHeaders: [],
      filters: [],
    }]))`);
  driver.get(url);
  return this;
}

The function is called at the beginning of the test (as first step or inside a before). When I execute the code, a second browser window opens and the actions are performed inside. Meanwhile, the main (or default) browser instance has no extension. How can I modify extensions within the main browser instance?

After reading a few blogs, I found that I may need to modify the conf.js and apply my code there but I am not able to get/modify the current driver.

I am stuck with a massive headache... Any help would be appreciated, Thanks!


Solution

  • Sorry for the late reply. I just figured out how to do it, so wanted to share if you need it in future.

    Firstly, in your nightwatch.json file, set desired capability as shown below:

    "desiredCapabilities": {
        "javascriptEnabled": true,
        "acceptSslCerts": true,
        "browserName": "chrome",
        "chromeOptions": {
          "args": ["--load-extension=/home/pratik/.config/google-chrome/Default/Extensions/idgpnmonknjnojddfkpgkljpfnnfcklj/2.1.2_0"]
        }
      }
    

    Then in your test,

    before: (client) => {
      modHeaderPage = client.page.modHeaderPage();
      modHeaderPage.setHeader();
      homePage = client.page.homePage();
    }
    

    And your page object would look as below:

    module.exports = { 
      elements: {},
      commands: [{
        setHeader() {
    
          // set the context on the extension so the localStorage can be accessed
          const url = 'chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/2.1.2_0/settings.tmpl.html'; // modHeader extension
          this.navigate(url).waitForElementPresent('body', 20000);
    
          // setup ModHeader with header
          this.api.execute(`
            localStorage.setItem('profiles', JSON.stringify([{ /* eslint-env browser*/
              title: 'Selenium',
              hideComment: true,
              appendMode: '',
              headers: [
                { enabled: true, name: 'Header_Name', value: 'Header_Value' },
              ],
              respHeaders: [],
              filters: [],
         }]))`);
        },
      }],
    };