Rework Selectors generation

- Renamed both `css_selector` and `xpath_selector` both to `generate_css_selector` and `generate_xpath_selector` for clarity and not interrupting the auto-completion while coding.
- Added `generate_full_css_selector` and `generate_full_xpath_selector` methods
This commit is contained in:
Karim shoair
2024-11-10 18:19:48 +02:00
parent de2d65856c
commit 3d4b427168
2 changed files with 24 additions and 9 deletions
+22 -7
View File
@@ -4,7 +4,7 @@ class SelectorsGeneration:
Trying to generate selectors like Firefox or maybe cleaner ones!? Ehm Trying to generate selectors like Firefox or maybe cleaner ones!? Ehm
Inspiration: https://searchfox.org/mozilla-central/source/devtools/shared/inspector/css-logic.js#591""" Inspiration: https://searchfox.org/mozilla-central/source/devtools/shared/inspector/css-logic.js#591"""
def __general_selection(self, selection: str = 'css') -> str: def __general_selection(self, selection: str = 'css', full_path=False) -> str:
"""Generate a selector for the current element. """Generate a selector for the current element.
:return: A string of the generated selector. :return: A string of the generated selector.
""" """
@@ -20,10 +20,11 @@ class SelectorsGeneration:
else f"[@id='{target.attrib['id']}']" else f"[@id='{target.attrib['id']}']"
) )
selectorPath.append(part) selectorPath.append(part)
return ( if not full_path:
" > ".join(reversed(selectorPath)) if css return (
else '//*' + "/".join(reversed(selectorPath)) " > ".join(reversed(selectorPath)) if css
) else '//*' + "/".join(reversed(selectorPath))
)
else: else:
part = f'{target.tag}' part = f'{target.tag}'
# We won't use classes anymore because I some websites share exact classes between elements # We won't use classes anymore because I some websites share exact classes between elements
@@ -60,15 +61,29 @@ class SelectorsGeneration:
) )
@property @property
def css_selector(self) -> str: def generate_css_selector(self) -> str:
"""Generate a CSS selector for the current element """Generate a CSS selector for the current element
:return: A string of the generated selector. :return: A string of the generated selector.
""" """
return self.__general_selection() return self.__general_selection()
@property @property
def xpath_selector(self) -> str: def generate_full_css_selector(self) -> str:
"""Generate a complete CSS selector for the current element
:return: A string of the generated selector.
"""
return self.__general_selection(full_path=True)
@property
def generate_xpath_selector(self) -> str:
"""Generate a XPath selector for the current element """Generate a XPath selector for the current element
:return: A string of the generated selector. :return: A string of the generated selector.
""" """
return self.__general_selection('xpath') return self.__general_selection('xpath')
@property
def generate_full_xpath_selector(self) -> str:
"""Generate a complete XPath selector for the current element
:return: A string of the generated selector.
"""
return self.__general_selection('xpath', full_path=True)
+2 -2
View File
@@ -169,8 +169,8 @@ class TestParser(unittest.TestCase):
def test_selectors_generation(self): def test_selectors_generation(self):
"""Try to create selectors for all elements in the page""" """Try to create selectors for all elements in the page"""
def _traverse(element: Adaptor): def _traverse(element: Adaptor):
self.assertTrue(type(element.css_selector) is str) self.assertTrue(type(element.generate_css_selector) is str)
self.assertTrue(type(element.xpath_selector) is str) self.assertTrue(type(element.generate_xpath_selector) is str)
for branch in element.children: for branch in element.children:
_traverse(branch) _traverse(branch)