mojotech / pioneer

Integration Testing
MIT License
527 stars 35 forks source link

Make Widget requireable #275

Open tomhicks-bsf opened 10 years ago

tomhicks-bsf commented 10 years ago

I find the use of this.Widgets and the 'autoloading' of widgets via the require block in pioneer.json a bit old-school. Adding widgets to a namespace using this.Widgets = this.Widgets || {} feels like it's actively working against the CommonJS module system.

What I've ended up doing is something like:

in pioneer.json:

require: ['test/steps', 'test/_env/setup.js']

in test/_env/setup.js:

module.exports = function () { global.Widget = this.Widget; }

in test/widgets/_base.js:

require('../_env/setup');
module.exports = global.Widget;
delete global.Widget;

At this point we can now get a reference to Widget...

in test/widgets/thingy.js:

var Widget = require('./_base');
module.exports = Widget.extend({...});

in test/steps/some-step.js

var ThingyWidget = require('../widgets/thingy');
// now use ThingyWidget in some way

This seems like rather a painful way of extracting Widget, but it does allow me to write my steps and Widgets like normal programs, requiring in what I need, and not worrying about naming collisions.

Can we expose Widget in a more natural way? Is there already a way of doing this that I'm missing?

samccone commented 10 years ago

Again this is a pain point that we have hit with Pioneer, in the sense that every module must export a method that is invoked with the this context of the world.

That said, requires work just fine in step files so requiring enabling require to work with the widgets should be trivial, in that we need to export in this style

module.exports = fn;

fn = function(){};

fn.Widget = 
fn.Widget.List = 
tomhicks-bsf commented 10 years ago

Where would that be? Is it inside Pioneer so I can do something like:

var Widget = require('pioneer').Widget;

or are you saying this is how to export our own custom widgets?