marko-js-archive/marko-widgets

Combining split renderer and widget for functional testing

Closed this issue · 4 comments

Right now, when a template is bound to a widget but the renderer and widget logic is split, there is an additional function:

function __registerWidget() {
    if (typeof window != "undefined") {
      __markoWidgets.registerWidget(__widget, require("./widget"));
    }
  }

in the template.marko.js
This causes template.render to not work and it throws the following error:
__markoWidgets does not have function registerWidget

The purpose of this is to enable functional testing. If I can combine the renderer and widget logic, I can render the widget directly and interact with the component and the event handlers associated. If you have a better approach to functional testing rather than combining the two, that would be awesome too.
Currently I am using mocha for testing run on karma.

Hey @sidsakhadeo, if I am understanding your problem correctly, it looks like in your case, the window global variable is defined on the server. This is causing marko-widgets to think that it is running in the browser and that is causing the non-existent __markoWidgets.registerWidget(...) method to be called. We can definitely change the code to guard against that, but why is the window global being set on the server?

Can you confirm that the error you are seeing is being thrown on the server (and not in the browser)? Can you also confirm that the window global variable is being set on the server? I can put in a fix to make the registerWidget(...) method a no-op on the server, but normally that would not be needed since that code should only run in the browser. Let me now. Thanks for reporting the problem!

Yo, thanks for getting back to me. In Mocha, we have setup a global window object. So yeah, when I render the template client side in unit and functional tests, we have this error.

The scenario we are dealing with is, we render the template server side and run unit tests on the code. For the functional tests on the client side, ideally it would be best if we extended the widget logic with the render function, rendered the template client side and ran the tests. Or we could render the template server side and appended the rendered html to the document on client and then run tests.

I could use some advice regarding this approach for unit + functional testing too. The main issue for us is we are trying to replicate both server and client at the same time but functional tests on karma is just client and unit tests run are just on the server.

My advice: don't use Karma. Karma makes it impossible to write tests against an HTML page your app generates. Instead, Karma only allows you to load your JavaScript code into the HTML page that it provides.

Instead, use mocha-phantomjs. mocha-phantomjs let's you load any HTML page into a page and will simple run all of the mocha tests that are loaded. You can also load your HTML page in any regular browser to run your tests. This is the strategy we are using for Marko WIdgets. I would recommend taking a closer look at the testing harness we are using for marko-widgets...it's not perfect but it incorporates for UI components rendered on the server and in the browser.

Finally, I'll go ahead and make registerWidget() a no-op on the server. This will solve the problem you are seeing due to the window global existing on the server.

New version published: marko-widgets@5.0.9

Please let me know if you see any other issues or have any other questions.