aquality-automation / aquality-selenium-dotnet

Aquality Selenium is a library built over Selenium WebDriver tool that allows to automate work with web browsers. Selenium WebDriver requires some skill and experience. So, Aquality Selenium suggests simplified and most importantly safer and more stable way to work with Selenium WebDriver.
Apache License 2.0
47 stars 14 forks source link

Support FindElements (Multiple) from ShadowRoot #235

Closed mialeska closed 7 months ago

mialeska commented 1 year ago

Instead of XPath generation, we can try to generate css selector:

  function generateSelector(element) {
     let selectors = [];
     while (element) {
        let selector = '';
        if (element.id) {
           selector = '#' + element.id;
        } else {
           selector = element.tagName;
        }
        selectors.unshift(selector);
        element = element.parentNode;
     }
     return selectors.join(' > ');
  }

https://www.tutorialspoint.com/how-to-create-a-function-generateselector-to-generate-css-selector-path-of-a-dom-element

or

        const generateSelector = (target) => {
        const selectorPath = [];

        while (target.tagName) {
            let i = 0;

            if (target.parentNode) {
                const children = target.parentNode.children;

                while (i < children.length && children[i] !== target) {
                    i++;
                }
            }

            selectorPath.unshift(target.nodeName + (
                i > 0 ? `:nth-child(${i + 1})` : ''));
            target = target.parentNode;
        }

        return selectorPath.join(' > ');
    }

https://www.geeksforgeeks.org/how-to-create-a-function-generateselector-to-generate-css-selector-path-of-a-dom-element/

or https://dev.to/aniket_chauhan/generate-a-css-selector-path-of-a-dom-element-4aim or https://stackoverflow.com/questions/3620116/get-css-path-from-dom-element

mialeska commented 1 year ago

Decided to use the most compatible script (based on this answer https://stackoverflow.com/a/28997302):

function previousElementSibling (element) {
  if (element.previousElementSibling !== 'undefined') {
    return element.previousElementSibling;
  } else {
    // Loop through ignoring anything not an element
    while (element = element.previousSibling) {
      if (element.nodeType === 1) {
        return element;
      }
    }
  }
}
function getPath (element) {
  // False on non-elements
  if (!(element instanceof HTMLElement)) { return false; }
  var path = [];
  while (element.nodeType === Node.ELEMENT_NODE) {
    var selector = element.nodeName;
    if (element.id) { selector += ('#' + element.id); }
    else {
      // Walk backwards until there is no previous sibling
      var sibling = element;
      // Will hold nodeName to join for adjacent selection
      var siblingSelectors = [];
      while (sibling !== null && sibling.nodeType === Node.ELEMENT_NODE) {
        siblingSelectors.unshift(sibling.nodeName);
        sibling = previousElementSibling(sibling);
      }
      // :first-child does not apply to HTML
      if (siblingSelectors[0] !== 'HTML') {
        siblingSelectors[0] = siblingSelectors[0] + ':first-child';
      }
      selector = siblingSelectors.join(' + ');
    }
    path.unshift(selector);
    element = element.parentNode;
  }
  return path.join(' > ');
}