code: function generateSelector(elm, options, doc) {
  	/*eslint no-loop-func:0*/
  	if (!axe._selectorData) {
  		throw new Error('Expect axe._selectorData to be set up');
  	}
  	const { toRoot = false } = options;
  	let selector;
  	let similar;
  
  	/**
  	 * Try to find a unique selector by filtering out all the clashing
  	 * nodes by adding ancestor selectors iteratively.
  	 * This loop is much faster than recursing and using querySelectorAll
  	 */
  	do {
  		let features = getElmId(elm);
  		if (!features) {
  			features = getThreeLeastCommonFeatures(elm, axe._selectorData);
  			features += getNthChildString(elm, features);
  		}
  		if (selector) {
  			selector = features + ' > ' + selector;
  		} else {
  			selector = features;
  		}
  		if (!similar) {
  			similar = Array.from(doc.querySelectorAll(selector));
  		} else {
  			similar = similar.filter(item => {
  				return axe.utils.matchesSelector(item, selector);
  			});
  		}
  		elm = elm.parentElement;
  	} while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11);
  
  	if (similar.length === 1) {
  		return selector;
  	} else if (selector.indexOf(' > ') !== -1) {
  		// For the odd case that document doesn't have a unique selector
  		return ':root' + selector.substring(selector.indexOf(' > '));
  	}
  	return ':root';
  }
docs: generates a single selector for an element
  @param {Element} elm			The element for which to generate a selector
  @param {Object} options	 Options for how to generate the selector
  @param {RootNode} doc		 The root node of the document or document fragment
  @returns {String}				 The selector