Reanimator
Capture and replay JavaScript applications
Reanimator captures non-deterministic input to a JavaScript application in a log that can replayed at a later date. It was originally designed for recording web application crashes in the wild for later debugging, but it may be useful for other purposes, such as usability testing and tutorials.
Reanimator consists of a core, which is responsible for capture setup and driving the replay, and one or more plugins, which are responsible for capturing and replaying non-deterministic input.
Reanimator ships with plugins for capturing and replaying random numbers, dates, and timer interrupts. In addition, Reanimator provides plugins for capturing and replaying callback invocations in the following frameworks:
- jQuery 1.8.3
Reanimator was inspired by Mugshot by James Mickens, Jeremy Elson, and Jon Howell.
Demos
Tile game There is a functional block demo included in the demos/ directory.
Development
Building
You can build Reanimator with the following instructions in the source directory.
npm install
make
The built files will be placed in the dist/ directory. The demos will use the files in dist/ when run.
Plugins
Existing plugins
date.js
The date plugin captures all calls to get the current system time and records them for replay. The plugin overwrite the Date object to ensure that all calls are recorded. During replay, the Date object is replaced with one that returns the recorded values.
document-create-event.js
This plugin replaces document.createEvent with a function that sets some reanimator-specific properties to ensure correct recording.
dom-content-loaded.js
Replay the DOMContentLoaded event at the appropriate time. The plugin saves the details from the recording, but waits until the DOM is loaded to replay the event.
dom.js
Record DOM events through JQuery and replay them at the appropriate time.
form.js
Record form change events and replay them, including inserting the data into text boxes and textareas on replay.
hashchange.js
Record and replay hashchange events in order to faciliate proper navigation during replay.
interrupts.js
Handles recording and replay of time-related functions, including setTimeout and setInterval.
local-storage.js
Resets the state of localStorage during load and reverts it on page unload to ensure that the replay has accurate localStorage. Requires a splash page to push the previous localStorage into localStorage before the replay page is loaded.
markend.js
Marks the end of the replay in the log. Will trigger a reanimator-finished event on the document object when the replay is completed. Listeners for this event can cause actions to occur after the replay is complete.
random.js
Records and replays all calls to the Math.random function to ensure that the replay is accurate.
scroll.js
Records scroll events and replays them during the replay. Only works on body scrolling.
xhr.js
Records XmlHttpRequests and replays them at the appropriate time during the replay.
Adding plugins
Plugins can be added by adding a file in lib/reanimator/plugins which contains the plugin, then adding a line to lib/reanimator.js to tell the build script to include the plugin in the build.
Limitations
At this time, CSS mouse-related (notably, hover) events are not recorded or replayed. Form data may not be filled in correctly during replay, although textboxes and textareas should be fine. Any pages using frames or iframes will likely not replay correctly.
Scrolling in areas other than the window will not be replayed.
You currently must use the included JQuery 1.8.3 library.
Currently, there is no infrastructure for easy record/replay. This is in progress but not done.
Attaching recording capability to an existing application make take significant work to ensure that all sources of non-determinism are properly eliminated.
API
Reanimator.capture
Capture non-deterministic input
Call this method to begin logging non-deterministic input to your
JavaScript application. To capture a useful log, you must call
Reanimator.capture
before such input occurs, but after libraries like
jQuery have been loaded.
The log is reset whenever this method is called.
Reanimator.replay
Replay a log of non-deterministic input
Arguments
log
- object - the log to replay, in the format emitted byReanimator.flush
config
- object - configuration object-
config.delay
- string | integer - how long Reanimator should wait before replaying the next event in the logFor a fixed delay, specify the number of ms between steps (the default is 0). If the string
'realtime'
is specified, Reanimator will make a good faith effort to replay the events with the actual delays recorded in the log.
-
Reanimator.flush
Return a copy of the current log
Returns a copy of the current log as an object with the following properties:
-
dates
- [ number ] - captured dates, specified in ms since the epoch -
random
- [ number ] - captured random numbers generated byMath.random
-
events
- [ object ] - captured callback invocationsEach element is an object with the following properties:
type
- string - the type of the recorded callbacktime
- number - the time the callback was fired (ms since the epoch)details
- any - any additional details necessary to replay the callback
Reanimator.cleanUp
Stop capturing or replaying and restore native methods and objects
This method does not clear the most recent log.
Reanimator.plug
Install a plugin to capture and replay some non-deterministic input
Arguments
type
- string - a unique string corresponding to thetype
property of any events the plugin will logplugin
- object - the plugin to install
A plugin is an object that implements the following methods:
-
init
: initialize the pluginCalled once, by
plug
Arguments
native
- object - an object to store a reference to any native methods or objects the plugin interposes on
-
capture
: prepare to capture the input the plugin is responsible forCalled by
Reanimator.capture
-
cleanUp
- restore any native methods or objects the plugin interposed on -
beforeReplay
- prepare to replayOptional; called by
Reanimator.replay
immediately before the first event is replayedArguments
log
- object - the log to be replayedconfig
- object - the replay configuration
-
replay
- replay a captured eventRequired if the plugin logs to
events
, optional otherwiseArguments
event
- object - the event to replay, in the format specified above inReanimator.flush
License
Reanimator is made available under the MIT License.
Acknowledgements and Attribution
Thanks to James Mickens, Jeremy Elson, and Jon Howell for their excellent work on Mugshot, which inspired Reanimator.
The image demos/tile-game/img/reanimator.jpg
is the work [Re-Animator]
(http://fav.me/d24n0v9) and is copyright (c) 2009
~cool-slayer and made available under an
Attribution-Noncommercial-No Derivative Works 3.0
License.