acvetkov / sinon-chrome

Testing chrome extensions with Node.js
ISC License
435 stars 46 forks source link

browser.runtime.connect returns undefined making testing difficults #61

Closed MatonAnthony closed 5 years ago

MatonAnthony commented 7 years ago

Hello,

I'm not sure to understand everything yet but I'm currently trying to write test on my webextension using sinon-chrome and I got difficulties because it stubs browser.runtime.connect() to undefined where browser.runtime.connect() returns a runtime.Port which contains event and methods.

A workaround like this is working for a test file when I'm testing if thing arrives on the event

import sinon from 'sinon';
import ChromeEvent from 'sinon-chrome/events';

export default () => {
    return {
        onMessage: new ChromeEvent(),
        onDisconnect: new ChromeEvent(),
        postMessage: sinon.stub()
    };
};
describe("sidebar", function() {
      it("should register a listener on sidebar", function() {
        let port = Port();
        port.name = "sidebar";
        port.onMessage.addListener = sinon.stub();
        onConnectListener(port);
        sinon.assert.calledOnce(port.onMessage.addListener);
      });
    });

But on another test file I don't manage to get it to work and I don't really understand how I'm supposed to do.

Here is my method

const port = browser.runtime.connect({name: "worker"});

export function runTest(testObj, id, rootElement) {
  // Only run the test suite if there's a root element
  // (e.g. when in source view there's no root element set)
  if (rootElement) {
    let contentTest = testObj.check(rootElement);
    testObj.errors = contentTest;

    /* TODO: Follow progress on bug https://bugzilla.mozilla.org/show_bug.cgi?id=1370884 */

    port.postMessage({
      type: "processTestResult",
      test: JSON.stringify(testObj),
      id
    });
  }
}

And here is my "test"

  describe("runTest", function(){
    it("should postMessage on port", function(){
      let port = Port();
      let testObj = {
        check: (any) => true,
        errors: "There is no errors"
      }

      runTest(testObj, 0, true);
      sinon.assert.calledOnce(port.postMessage);
    });
  });

Javascript wise, I'm pretty sure there is an issue with scope but I don't really have any idea about how to do in an other way.

My experience with testing is very limited (and considering how important it is, I'm kinda sad about it), sorry if it's a very simple question.

acvetkov commented 7 years ago

@MatonAnthony hi!

You should define behavior for browser.runtime.connect. Before your test

browser.runtime.connect.returns(require('your-port-object-stub.js'))
ddehghan commented 5 years ago

also there is a solution in https://github.com/acvetkov/sinon-chrome/issues/50