I'm working on a Rails site using jQuery, and after reading
this great post discussing the similarities between the Given/When/Then integration testing pattern and finite state machines, I've decided to try implementing all my AJAX as a FSM.
The benefits of treating AJAX as an FSM is that if you can define all the possible states (S) and the transitions between them (T), then you can also describe all the expected outcomes with S * T tests. This seems like a really powerful observation; it not only allows you to know when your web page is fully tested, it encourages you to develop pages with well-defined behaviors (by reducing the number of states and/or transitions).
A huge problem I've had in the past with interactive UI's is that keeping state in JS variables can lead to problems when odd combinations of actions are performed. My goal is to move all state out of JS variables and into the DOM, in other words I'd like the state of the UI to be uniquely determined by the DOM. This approach means that we can test if the UI's state can be validated through DOM inspection.
It seems like the biggest implication of using the DOM this way is that element behavior is static - events listeners should never be changed (changing an element's behavior would be accomplished by replacing the element in the DOM).
I'm planning to use pluginaweek's state_machine rails plugin as the basis for the jQuery plugin. The basic API allows you to define a state machine and then add a set of states and state transitions (as well as callbacks, etc). In the case of the plugin, I'm thinking that states would be defined as named DOM tests (ie checking to see if element #foo has class .bar), and transitions would be defined as named DOM manipulations (ie insert $foo below #bar). State transitions would be performed by calling the transition name on the state machine. Complex AJAX interactions would be accomplished by updating the state machine's transitions.
Anyway - is there any interest in something like this? Any suggestions? I'd love some feedback - I've blocked out the code on
github, but I'm still very early in the process.
One thing I'm still working through in my head is the implications of dynamically changing the transition definitions. For example, if taking some action (say logging in) influences how future transitions should be executed (say, by allowing something to happen), does this cause problems?