function getNodeDetails(element) {
  // This bookkeeping is for the FullPageScreenshot gatherer.
  if (!window.__lighthouseNodesDontTouchOrAllVarianceGoesAway) {
    window.__lighthouseNodesDontTouchOrAllVarianceGoesAway = new Map();
  }

  element = element instanceof ShadowRoot ? element.host : element;
  const selector = getNodeSelector(element);

  // Create an id that will be unique across all execution contexts.
  //
  // Made up of 3 components:
  //   - prefix unique to specific execution context
  //   - nth unique node seen by this function for this execution context
  //   - node tagName
  //
  // Every page load only has up to two associated contexts - the page context
  // (denoted as `__lighthouseExecutionContextUniqueIdentifier` being undefined)
  // and the isolated context. The id must be unique to distinguish gatherers running
  // on different page loads that identify the same logical element, for purposes
  // of the full page screenshot node lookup; hence the prefix.
  //
  // The id could be any arbitrary string, the exact value is not important.
  // For example, tagName is added only because it might be useful for debugging.
  // But execution id and map size are added to ensure uniqueness.
  // We also dedupe this id so that details collected for an element within the same
  // pass and execution context will share the same id. Not technically important, but
  // cuts down on some duplication.
  let lhId = window.__lighthouseNodesDontTouchOrAllVarianceGoesAway.get(element);
  if (!lhId) {
    lhId = [
      window.__lighthouseExecutionContextUniqueIdentifier === undefined ?
        'page' :
        window.__lighthouseExecutionContextUniqueIdentifier,
      window.__lighthouseNodesDontTouchOrAllVarianceGoesAway.size,
      element.tagName,
    ].join('-');
    window.__lighthouseNodesDontTouchOrAllVarianceGoesAway.set(element, lhId);
  }

  const details = {
    lhId,
    devtoolsNodePath: getNodePath(element),
    selector: selector,
    boundingRect: getBoundingClientRect(element),
    snippet: getOuterHTMLSnippet(element),
    nodeLabel: getNodeLabel(element) || selector,
  };

  return details;
}
@param {Element|ShadowRoot} element
@return {LH.Artifacts.NodeDetails}