Closed tvpavan closed 8 years ago
@tvpavan, hi!
Yes, it's good idea, but you can test message passing as usual chrome events.
For example
var spy = sinon.spy();
chrome.runtime.onMessage.addListener(spy);
// trigger event manually instead of postMessage
chrome.runtime.onMessage.trigger(1, 2, 3);
console.log(spy.withArgs(1, 2, 3).callCount); // 1
Another example
function handler(data) {
console.log(data);
}
var obj = {a: 1, b: 2};
chrome.runtime.onMessageExternal.addListener(handler);
// trigger event manually
chrome.runtime.onMessageExternal.trigger(obj);
// function handler will be called with obj argument
Thansk @acvetkov . I will go with chrome.runtime.onMessage.trigger(1, 2, 3) method. Was wondering if a specail stub / spy can do a "on"+methodName.captializeFirstLetter().trigger so that main app code needn't be changed for testing.
main app code needn't be changed for testing.
@tvpavan, can you write example for this case? I don't understand for what reason your app code need to be changed.
To test our background.js i am simulating an user click as chrome.browserAction.onClicked.trigger() from test script. Code of background.js uses postMessage and has AddListener calls on tab ports to communicate with our injected content script on tabs. I can change the code of background.js as if(testmode) { chrome.tabs.connect(id).onMessage.trigger({data:"hello"}); } else { chrome.tabs.connect(id).postMessage({data:"hello"}); } this works. But I thought if we can simulate/stub these calls , i can avoid the if(testmode) code change.
@tvpavan, I think, it's not TDD way. You should test your background page apart from content-script.
In background you should make sure that port object send correct message to content-script. In content script you should make sure that it works correct with correct input params.
For example
// background.js
chrome.browserAction.onClicked.addListener(clickHandler);
function clickHandler() {
chrome.tabs.connect('1').postMessage({data:"hello"});
}
Let's test it
// background.test.js
var fakePort = {
postMessage: sinon.spy()
};
before(function () {
chrome.tabs.connect.returns(fakePort);
});
it('should send correct message to content script', function () {
// simulate click
chrome.browserAction.onClicked.trigger();
assert.calledOnce(fakePort.postMessage.withArgs({data:"hello"}));
});
Content script
// content-script.js
var port = chrome.runtime.connect({name: 'content'});
var port.onMessage.addListener(function () {
// do something
});
test
// content-script.test.js
var ChromeEvent = require('sinon-chrome/out/events');
var fakePort = {
onMessage: new ChromeEvent()
};
before(function () {
chrome.runtime.connect.returns(fakePort);
});
it('should works', function () {
// run you content script
fakePort.onMessage.trigger({});
// test reaction
});
It would be good, if we have an example to test message passing. Most of the plugins have a postMessage and onMessage callbacks. eg. chromeobject.postMessage("hello") chromeobject.onMessage.AddListener(function(data){ console.log(data) }) A call to postMessage or message needs to trigger callback registered via onMessage.AddListener.