Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

DOM Comparator

DOM Comparator is a library that, simply put, compares two strings of DOM nodes (which are called stringA and stringB), and returns an output containing the minimal number of steps that must be taken (like attribute changes, style changes, text changes and DOM manimpulation) to convert stringA into stringB.

The output returned by DOM Comparator is an array of VWO.Operation objects, which can also be expressed as jQuery code. Here's a simple example:

var stringA = '<ul><li class="active">list item 1</li><li>list item 2</li></ul>';
var stringB = '<ul><li>list item 1</li><li>list item 2</li></ul>';

// Compare the two strings
var result = VWO.DOMComparator.create({
	stringA: stringA,
	stringB: stringB

// Expect an array of VWO.Operation objects to be returned.

// Expect the first operation to be a 'removeAttr' operation.

// The operation is on an element identified by the following selector path
expect(result[0].selectorPath).toEqual('UL:first-child > LI:first-child');

// With below content
expect(result[0].content).toEqual({class: 'active'});

Setting Up


  • To install all the dependencies run npm install.
  • Then run bower install for jasmine, jquery and underscore library dependencies.
  • Install grunt globally, which is a Javascript Task Runner npm install -g grunt-cli.


Live Demo

A live demo can be found here:

Running Tests

  • For testing, we use Jasmine.
  • Tests are written in the test/unit folder. Each file in the src directory have different test cases files associataed with them in the test/unit directory. The majority of the test cases that test the library as a black box are in dom-comparator.spec.js.
  • To run tests, run grunt; testem server; (from the root directory of the repository)
  • To see the final outputs open http://localhost:7357/ in the browser, open the JavaScript console and look for the final_results array.

Cases which don't work

  • If there are multiple occurrences of a node in the DOM. For example:


<div style="display: block;">
	<ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;">
	<div class="clr">ORIGINAL TEXT</div>


<div class="clr">ORIGINAL TEXT</div>
<div style="display: block;">
	<ul class="navigation vwo_1405423029796" style="cursor: auto; display: INLINE;">
	<div class="clr">ORIGINAL TEXT</div>

Here, since there are 2 occurrences of <div class="clr">ORIGINAL TEXT</div> in nodeB, the exact match of it cannot be found in nodeA, due to which the resulted output is not as expected.

  • When the wrapping of the original node is changed. For example:


<div style="display: block;">
	<div class="clr">ORIGINAL TEXT</div>


	<div style="display: block;">
		<div class="clr">ORIGINAL TEXT</div>

Here, since the wrapping of nodeB is changed (wrapped by <div> ... </div>), the whole content in nodeB would be considered as inserted (because matching heirarchy is top to bottom).


The general usage documentation can be found on



The MIT License

Copyright (c) 2014-16 Wingify Software Pvt. Ltd.


A JS Library that compares two DOM Nodes and outputs what changed between the two.


You can’t perform that action at this time.