On Sun, Nov 4, 2012 at 7:39 PM, Lloyd Hilaiel <
ll...@mozilla.com> wrote:
> On Nov 4, 2012, at 6:11 PM, Jared Hirsch <
ja...@jaredhirsch.com> wrote:
>
> > * if you supply a callback parameter, your .onError handler will not be
> automatically invoked
> > * If in your supplied callback you wish to halt processing of remaining
> items in the chain, you can manually invoke .haltChain() on the (web
> driver) browser object.
>
> Even more fantastic. I think this should get upstreamed for sure, this is
> a significant gotcha with the chain() function. I will open an issue
> upstream
>
> I expect that there is no way to "abort" the chain cause this feature is
> built on caolan/async's queue - who itself does not support removing work
> (and I think that might be because the queue is designed to support
> parallelism).
>
> More generally, the hacks we've made to chaining might be distasteful
> upstream because we formalize the every chainable method must be async
> (last arg callback) and follows typical node error conventions (non-falsey
> first arg indicates error). But then again, maybe not.
>
> Then I wonder if there's a well written promise/seq/chain/future
> implementation that we could consider which handles stuff like this and we
> can adopt to reduce pyramids of doom all over the place, and hopefully
> reduce the amount of manual error checking code we have while improving
> readability (yeah, I realize I might be a little late to this party -
> you've been hinting in this direction for a while now, Jared. I'm slow).
>
> I don't think this is the kinda thing we want to launch a major effort
> for, or pause progress on tests and features, but seems like someone doing
> a little research and writing a blog post with a suggestion could be good.
>
You know, a robust Promises implementation (of node libraries, I'm most
familiar with kriskowal's Q) can handle the stuff we're talking about
without needing to put the flow control bits inside the upstream project. Q
has lots of nice features, like built-in helpers to interact with
node-style functions. The thing about it is, it's one of those big
conceptual leaps that is a process of head-wrapping-around. Takes a while.
If you look at the testSetup.setup function, I use Q to create separate
personatestusers via parallel network calls, handle any errors via one
fail() call, and only return after all the promises have resolved. I use
the ncall function to convert a node-style API to a chainable promise-style
API. See the 15 or so lines below here:
https://github.com/mozilla/browserid/blob/kapow/automation-tests/lib/test-setup.js#L131
Here's a thread on flow control from the nodejs mailing list with decent
signal/noise ratio and some excellent links:
https://groups.google.com/forum/?fromgroups=#!topic/nodejs/mWtqFE0spWk
Brian seems to have had his mind warped into Promisey shape at some point
in the past, so I'm sure he would be happy to sing their praises, too :-)
Oh also, speaking of hacking on upstream, there's an unmaintained fork of
wd that uses Q for chaining, so you can check that out:
https://github.com/Stuk/q-wd
>
> > Finally, notice that there's now a third parameter to runner:
> >
>
https://github.com/mozilla/browserid/blob/kapow/automation-tests/tests/returning-user.js#L130-133
> >
> > a cleanup will be invoked when all the tests are complete, whether or
> they failed.
>
> Not in front of a laptop atm, but I think we can do one better:
> testSetup.setup() is what creates browsers, so we should be able to have it
> do "for browser in this.fixtures.browsers, browser.quit()". And we might
> even be able to build that into the runner somehow (wishing for explicit
> dependency injection at this point, or just refactoring all these little
> includes into one setup object)
>
> This sounds great! the only thing I'm wondering is if we want to keep a
> subset of the selenium test framework general so we can gradually apply it
> to our backend tests. I think we've spend a lot more time up front on
> ergonomics and readability for the selenium stuff, while backend API tests
> were written under time pressure while learning. Maybe vows_harness.js is
> the potentially re-usable bit?
>
Hmm, interesting question. I'd personally like to see all the test runner
and test setup stuff tightened up and merged into the harness code, I could
definitely see that being reusable for unit tests: setup, runner,
reporting, fixture management. I should get out a copy of Meszaros' xUnit
book and look for patterns we can apply.
>
> lloyd
>
>