fix: duplicate ID segments in full-path selector generation (#241)
This commit is contained in:
@@ -26,7 +26,12 @@ class SelectorsGeneration:
|
|||||||
if target.parent:
|
if target.parent:
|
||||||
if target.attrib.get("id"):
|
if target.attrib.get("id"):
|
||||||
# id is enough
|
# id is enough
|
||||||
part = f"#{target.attrib['id']}" if css else f"[@id='{target.attrib['id']}']"
|
if css:
|
||||||
|
part = f"#{target.attrib['id']}"
|
||||||
|
elif full_path:
|
||||||
|
part = f"*[@id='{target.attrib['id']}']"
|
||||||
|
else:
|
||||||
|
part = f"[@id='{target.attrib['id']}']"
|
||||||
selectorPath.append(part)
|
selectorPath.append(part)
|
||||||
if not full_path:
|
if not full_path:
|
||||||
return " > ".join(reversed(selectorPath)) if css else "//*" + "/".join(reversed(selectorPath))
|
return " > ".join(reversed(selectorPath)) if css else "//*" + "/".join(reversed(selectorPath))
|
||||||
|
|||||||
@@ -321,6 +321,50 @@ def test_selectors_generation(page):
|
|||||||
_traverse(page)
|
_traverse(page)
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_path_selector_no_duplicate_ids():
|
||||||
|
"""Test that full path selectors don't duplicate id segments (regression test)"""
|
||||||
|
html = '<html><body><div id="main"><p id="target">Hello</p></div></body></html>'
|
||||||
|
page = Selector(html)
|
||||||
|
target = page.css("#target").first
|
||||||
|
|
||||||
|
# CSS full path should not duplicate id selectors
|
||||||
|
css_full = target.generate_full_css_selector
|
||||||
|
assert css_full.count("#target") == 1, f"Duplicate #target in CSS full path: {css_full}"
|
||||||
|
assert css_full.count("#main") == 1, f"Duplicate #main in CSS full path: {css_full}"
|
||||||
|
|
||||||
|
# XPath full path should not duplicate id selectors
|
||||||
|
xpath_full = target.generate_full_xpath_selector
|
||||||
|
assert xpath_full.count("@id='target'") == 1, f"Duplicate @id='target' in XPath full path: {xpath_full}"
|
||||||
|
assert xpath_full.count("@id='main'") == 1, f"Duplicate @id='main' in XPath full path: {xpath_full}"
|
||||||
|
|
||||||
|
# The generated CSS selector should actually select the correct element
|
||||||
|
result = page.css(css_full)
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result.first.text == "Hello"
|
||||||
|
|
||||||
|
# The generated XPath selector should also select the correct element
|
||||||
|
result = page.xpath(xpath_full)
|
||||||
|
assert len(result) == 1, f"XPath '{xpath_full}' selected {len(result)} elements, expected 1"
|
||||||
|
assert result.first.text == "Hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_path_selector_mixed_id_and_no_id():
|
||||||
|
"""Test full path selectors with a mix of elements with and without ids"""
|
||||||
|
html = '<html><body><div id="wrapper"><section><p>Text</p></section></div></body></html>'
|
||||||
|
page = Selector(html)
|
||||||
|
target = page.css("p").first
|
||||||
|
|
||||||
|
css_full = target.generate_full_css_selector
|
||||||
|
# p has no id, so it should appear as a tag name; div has id
|
||||||
|
assert "#wrapper" in css_full
|
||||||
|
assert css_full.count("#wrapper") == 1
|
||||||
|
|
||||||
|
# Verify the selector works
|
||||||
|
result = page.css(css_full)
|
||||||
|
assert len(result) == 1
|
||||||
|
assert result.first.text == "Text"
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous Tests
|
# Miscellaneous Tests
|
||||||
def test_getting_all_text(page):
|
def test_getting_all_text(page):
|
||||||
"""Test getting all text from the page"""
|
"""Test getting all text from the page"""
|
||||||
|
|||||||
Reference in New Issue
Block a user