function getNodeSelector(element) {
  /**
   * @param {Element} element
   */
  function getSelectorPart(element) {
    let part = element.tagName.toLowerCase();
    if (element.id) {
      part += '#' + element.id;
    } else if (element.classList.length > 0) {
      part += '.' + element.classList[0];
    }
    return part;
  }

  const parts = [];
  while (parts.length < 4) {
    parts.unshift(getSelectorPart(element));
    if (!element.parentElement) {
      break;
    }
    element = element.parentElement;
    if (element.tagName === 'HTML') {
      break;
    }
  }
  return parts.join(' > ');
}
@param {Element} element
@return {string}

Note: CSS Selectors having no standard mechanism to describe shadow DOM piercing. So we can't.

If the node resides within shadow DOM, the selector *only* starts from the shadow root.
For example, consider this img within a <section> within a shadow root..
 - DOM: <html> <body> <div> #shadow-root <section> <img/>
 - nodePath: 0,HTML,1,BODY,1,DIV,a,#document-fragment,0,SECTION,0,IMG
 - nodeSelector: section > img