Skip to content

Comingle/sinon-chrome

 
 

Repository files navigation

Build Status Coverage Status Code Climate npm version

What is it?

Mocks for chrome.* extensions api via sinon stubs. Run unit tests for chrome extensions in node or browser.

Features

  1. Stubs for all chrome.* methods and properties
  2. Manual events triggering
  3. Plugins to emulate cookies storage behavior, opened tabs, etc

How to install

Npm:

npm install sinon-chrome

Direct download:
You can download sinon-chrome bundle from release page.

How to use

Node

before(function () {
   global.chrome = require('sinon-chrome');
});

Browser

Just add sinon-chrome bundle to your page.

<script src="/path/to/sinon-chrome.latest.js">

Write tests

You can use all sinon stub api to create chrome methods behavior.

For example

var domainACookies = [
   {
      name: 'a',
      value: 'b',
      domain: 'domainA.com'
   }
];

var domainBCookies = [
   {
      name: 'b',
      value: 'c',
      domain: 'domainB.com'
   }
];

var allCookies = domainACookies.concat(domainBCookies);

before(function () {
   chrome.cookies.getAll.withArgs({domain: 'domainA.com'}).yields(domainACookies);
   chrome.cookies.getAll.withArgs({domain: 'domainB.com'}).yields(domainBCookies);
   chrome.cookies.getAll.withArgs({}).yields(allCookies);
});

it('should return correct cookies for domain A', function () {
   chrome.cookies.getAll({domain: 'domainA.com'}, function (list) {
      assert.deepEqual(list, domainACookies);
   });
});

it('should return correct cookies for domain B', function () {
   chrome.cookies.getAll({domain: 'domainB.com'}, function (list) {
      assert.deepEqual(list, domainBCookies);
   });
});

it('should return correct cookies for all domains', function () {
   chrome.cookies.getAll({}, function (list) {
      assert.deepEqual(list, allCookies);
   });
});

Properties

You can define chrome api property values.

For example

chrome.runtime.id = 'test';
chrome.runtime.lastError = new Error('some error');
chrome.windows.WINDOW_ID_CURRENT = 100;

console.log(chrome.runtime.id); // test
console.log(chrome.runtime.lastError); // Error: some error(…)
console.log(chrome.windows.WINDOW_ID_CURRENT); // 100

chrome.flush();

console.log(chrome.runtime.id); // undefined
console.log(chrome.runtime.lastError); // undefined
console.log(chrome.windows.WINDOW_ID_CURRENT); // undefined

Events

You can can manipulate by chrome events by manual triggering with custom params.

For example

var handler = sinon.spy();
chrome.cookies.onChanged.addListener(handler);

chrome.cookies.onChanged.trigger(1, 2, 3);
handler.withArgs(1, 2, 3).callCount; // 1

chrome.cookies.onChanged.trigger(1, 2, 3);
handler.withArgs(1, 2, 3).callCount; // 2

// remove listener
chrome.cookies.onChanged.removeListener(handler);
chrome.cookies.onChanged.trigger(1, 2, 3);
chrome.cookies.onChanged.trigger(1, 2, 3);
handler.withArgs(1, 2, 3).callCount; // 2

To reset stubs data, you should call chrome.reset.

For example

chrome.tabs.getAll();
chrome.tabs.getAll();

chrome.runtime.id = 'test_id';

console.log(chrome.tabs.getAll.callCount); // 2

chrome.reset();
console.log(chrome.tabs.getAll.callCount); // 0

To reset stubs behavior, you should call chrome.flush or chrome.[namespace].[method].resetBehavior

For example

chrome.runtime.getURL.returns('url');
chrome.tabs.query.yields([1, 2, 3]);
console.log(chrome.runtime.getURL()); // url
chrome.tabs.query({}, function tabsHandler(list) {
   console.log(list); // [1, 2, 3]
});

chrome.flush();
console.log(chrome.runtime.getURL()); // undefined
chrome.tabs.query({}, function tabsHandler(list) {
   // unreachable point. Function tabsHandler will never be called
});

Difference from 0.2 version

We remove all predefined properties and behavior. You must define all stubs behavior by yourself.

For example

before(function () {
   chrome.runtime.id = 'my_test_id';
   chrome.runtime.getURL = function (path) {
      return 'chrome-extension://' + chrome.runtime.id + '/' + path;
   };
});

Checkout example page for more info.

Plugins

Sinon chrome module supports plugins.

Supported namespaces

  1. chrome.alarms
  2. chrome.bookmarks
  3. chrome.browserAction
  4. chrome.browsingData
  5. chrome.certificateProvider
  6. chrome.commands
  7. chrome.contentSettings
  8. chrome.contextMenus
  9. chrome.cookies
  10. chrome.debugger
  11. chrome.declarativeContent
  12. chrome.desktopCapture
  13. chrome.devtools.inspectedWindow
  14. chrome.devtools.network
  15. chrome.devtools.panels
  16. chrome.downloads
  17. chrome.extension
  18. chrome.extensionTypes
  19. chrome.fontSettings
  20. chrome.gcm
  21. chrome.history
  22. chrome.i18n
  23. chrome.identity
  24. chrome.idle
  25. chrome.instanceID
  26. chrome.management
  27. chrome.notifications
  28. chrome.omnibox
  29. chrome.pageAction
  30. chrome.pageCapture
  31. chrome.permissions
  32. chrome.printerProvider
  33. chrome.privacy
  34. chrome.proxy
  35. chrome.runtime
  36. chrome.sessions
  37. chrome.storage
  38. chrome.system.cpu
  39. chrome.system.display
  40. chrome.system.memory
  41. chrome.system.storage
  42. chrome.tabCapture
  43. chrome.tabs
  44. chrome.topSites
  45. chrome.tts
  46. chrome.ttsEngine
  47. chrome.webNavigation
  48. chrome.webRequest
  49. chrome.windows

Development and pull request.

Fork this repo and install all dependencies. Don't forget check your code style and run tests before send pull request.

code checking

npm run lint

run tests

npm test

Any questions?

Feel free to open issue.

Contributors

  1. Vitaly Potapov
  2. Aleksey Tsvetkov

About

Testing chrome extensions with Node.js

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%