概要

Chrome拡張機能は、ブラウザに追加機能を追加するための優れた方法です。他のソフトウェアと同様に、テストも行う必要があります。このガイドでは、Nightwatchを使用してChrome拡張機能をテストする方法に焦点を当てています。

基本的なChrome拡張機能のテストを含むサンプルプロジェクトは、こちらにあります (tests/testInstalledExtension.jsを参照)。

初期化

Chrome拡張機能は、Nightwatchを使用して他のWebサイトと同じようにテストできます。そのため、開始するには、initコマンドを使用してNightwatchの通常のセットアップを行います (質問されたら、必ず「Chrome」ブラウザを選択してください)。

cd /path/to/project/directory
npm init nightwatch

設定

最初のNightwatchセットアップの後、生成されたnightwatch.conf.jsファイルで、Nightwatchに次の2つのことを伝えるために最小限の変更が必要です。

  • テスト実行中にブラウザにインストールされるChrome拡張機能の場所。
  • インストールされたChrome拡張機能にアクセスできる場所からDevToolsウィンドウを自動的に開きます。

Chrome拡張機能自体には、パック形式と非パック形式の2つの形式があります。パック形式の拡張機能は、.crx拡張子を持つ単一のファイルです。一方、非パック形式の拡張機能は、manifest.jsonファイルを含む拡張機能を含むディレクトリです。

テスト対象の拡張機能の形式に応じて、nightwatch.conf.jsファイルで拡張機能へのパスを異なる方法で指定する必要があります。

パック形式 (.crxファイル)

テスト対象の拡張機能が既にパックされている場合は、nightwatch.conf.jsファイルに次の変更を加えます。

test_settings > chrome > desiredCapabilities > 'goog:chromeOptions'内に入り、以下のように配列値を持つextensionsキーを追加します。

nightwatch.conf.js
chrome: {
  desiredCapabilities: {
    browserName: 'chrome',
    'goog:chromeOptions': {
      args: [
        //'--headless',
        'auto-open-devtools-for-tabs'
      ],
      // load extension from .crx file.
      extensions: [
        require('fs').readFileSync('path/to/extension.crx', {encoding: 'base64'})
      ]
    }
  },
}

また、テスト実行中にDevToolsウィンドウを自動的に開くために(重要)"auto-open-devtools-for-tabs"goog:chromeOptions > argsに追加します。

非パック形式 (ディレクトリ)

テスト対象の拡張機能が非パック形式(manifest.jsonファイルを含むディレクトリ)の場合は、nightwatch.conf.jsファイルに次の変更を加えます。

test_settings > chrome > desiredCapabilities > 'goog:chromeOptions' > args内に入り、以下のように--load-extensionフラグを追加します。

nightwatch.conf.js
chrome: {
  desiredCapabilities: {
    browserName: 'chrome',
    'goog:chromeOptions': {
      args: [
        //'--headless',
        'auto-open-devtools-for-tabs',
        //
        // load extension from unpacked directory.
        '--load-extension=/path/to/extension/directory',
        //
        // if extension is present in the `src/` dir of same project.
        // `--load-extension=${__dirname}/src`,
      ],
    }
  },
}

また、テスト実行中にDevToolsウィンドウを自動的に開くために(重要)"auto-open-devtools-for-tabs"goog:chromeOptions > argsに追加します。

最初のテストを記述する

Chrome拡張機能の自動化とアサーションのサンプルテストは、こちらにあります。

テスト実行中にブラウザが最初に開くと、ブラウザータブのコンテキストで開きます。このコンテキストは、Chrome拡張機能にアクセスしてテストできるDevToolsウィンドウに変更する必要があります。

そのため、実際の拡張機能をテストする前に実行する必要があるいくつかの手順があります。上記で共有したサンプルテストでは、これらの手順はすべてテストケース(itブロック)自体で実行されます。ただし、これらの手順はテストスイートごとに1回だけ実行する必要があるため、以下のようにbeforeフックに入れることもできます。

tests/sampleTest.js
describe('test Chrome Extension inside DevTools', function() {
  before(async function() {
    // navigate to the website you want to test the extension against
    await browser.navigateTo('https://google.com');
    
// get all targets (contexts) we can possibly switch to const targets = await browser.driver.sendAndGetDevToolsCommand('Target.getTargets', {});
const devToolsTarget = targets.targetInfos.find(target => { return target.type === 'page' && target.url.includes('devtools://devtools/bundled/devtools_app.html'); });
// switch to DevTools window context await browser.window.switchTo(devToolsTarget.targetId);
// switch to last tab in pane (our extension) await browser.sendKeys('body', [browser.Keys.COMMAND, '[']); // for macos await browser.sendKeys('body', [browser.Keys.CONTROL, '[']); // for windows/linux
// switch to the iframe inside the tab await browser.frame('iframe[src*="index.html"]'); });
it('checks the header text of the extension', async function() { // run automation on the extension await browser.element('header').getText().assert.equals('My Extension');
// to visualize the extension during test run // await browser.pause(1000); }); });

同様に、テストスイート(テストファイル)にテストケースを追加でき、通常のWebサイトと同じようにChrome拡張機能をテストおよびアサートできます。

テストの実行

テストを実行するには、以下のように通常のnpx nightwatchコマンドを使用します。

npx nightwatch tests/sampleTest.js --env chrome
[test Chrome Extension inside DevTools] Test Suite
───────────────────────────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (1459ms).
  Using: chrome (127.0.6533.88) on MAC.


  Running checks the header text of the extension:
───────────────────────────────────────────────────────────────────────────────
  ✔ Testing if element 'My Extension'

  ✨ PASSED. 1 assertions. (1.024s)