Работая над несколькими расширениями Chrome, я придумал sinon-chrome
проект, который позволяет запускать юнит-тесты с использованием mocha
, nodejs
и phantomjs
.
По сути, он создает макеты sinon для всех chrome.*
API, в которые вы можете поместить любые предопределенные ответы json.
Затем вы загружаете свои скрипты, используя узлы vm.runInNewContext
для фоновой страницы иphantomjs
для всплывающих окон / опций рендера.
И, наконец, вы утверждаете, что Chrome API был вызван с необходимыми аргументами.
Давайте рассмотрим пример.
Предположим, у нас есть простое расширение Chrome, которое отображает количество открытых вкладок в значке кнопки.
фоновая страница:
chrome.tabs.query({}, function(tabs) {
chrome.browserAction.setBadgeText({text: String(tabs.length)});
});
Чтобы проверить это нам нужно:
- макет
chrome.tabs.query
для возврата предварительно определенного ответа, например, две вкладки.
- впрыснуть наш глумленный
chrome.*
API в какую-то среду
- запустить наш код расширения в этой среде
- утверждать, что значок кнопки равен «2»
Фрагмент кода следующий:
const vm = require('vm');
const fs = require('fs');
const chrome = require('sinon-chrome');
// 1. mock `chrome.tabs.query` to return predefined response
chrome.tabs.query.yields([
{id: 1, title: 'Tab 1'},
{id: 2, title: 'Tab 2'}
]);
// 2. inject our mocked chrome.* api into some environment
const context = {
chrome: chrome
};
// 3. run our extension code in this environment
const code = fs.readFileSync('src/background.js');
vm.runInNewContext(code, context);
// 4. assert that button badge equals to '2'
sinon.assert.calledOnce(chrome.browserAction.setBadgeText);
sinon.assert.calledWithMatch(chrome.browserAction.setBadgeText, {
text: "2"
});
Теперь мы можем обернуть его в describe..it
функции мокко и запустить из терминала:
$ mocha
background page
✓ should display opened tabs count in button badge
1 passing (98ms)
Вы можете найти полный пример здесь .
Кроме того, sinon-chrome позволяет запускать любое событие chrome с предопределенным ответом, например
chrome.tab.onCreated.trigger({url: 'http://google.com'});