Verify navigation using XPath axes parent, child, and sibling
Preconditions (2)
✅ Expected Result: The test should confirm that the XPath axes parent, child, and sibling correctly locate the elements and all elements are visible on the page
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class MenuPage: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def get_item_2(self): xpath = "//ul[@id='menu']/li[normalize-space(text())='Item 2']" return self.wait.until(EC.visibility_of_element_located((By.XPATH, xpath))) def get_parent_of_item_2(self): # Using parent axis xpath = "//ul[@id='menu']/li[normalize-space(text())='Item 2']/parent::ul" return self.wait.until(EC.visibility_of_element_located((By.XPATH, xpath))) def get_following_sibling_of_item_2(self): # Using following-sibling axis xpath = "//ul[@id='menu']/li[normalize-space(text())='Item 2']/following-sibling::li[1]" return self.wait.until(EC.visibility_of_element_located((By.XPATH, xpath))) def get_child_subitem_of_item_2(self): # Using child axis xpath = "//ul[@id='menu']/li[normalize-space(text())='Item 2']/child::ul/li[normalize-space(text())='Subitem 2.1']" return self.wait.until(EC.visibility_of_element_located((By.XPATH, xpath))) def test_xpath_axes(): driver = webdriver.Chrome() driver.get("https://example.com/sample-menu") # Replace with actual URL menu_page = MenuPage(driver) item_2 = menu_page.get_item_2() assert item_2.is_displayed(), "Item 2 should be visible" parent = menu_page.get_parent_of_item_2() assert parent.get_attribute('id') == 'menu', f"Parent id should be 'menu', got {parent.get_attribute('id')}" sibling = menu_page.get_following_sibling_of_item_2() assert sibling.text.strip() == 'Item 3', f"Following sibling text should be 'Item 3', got {sibling.text.strip()}" child_subitem = menu_page.get_child_subitem_of_item_2() assert child_subitem.text.strip() == 'Subitem 2.1', f"Child subitem text should be 'Subitem 2.1', got {child_subitem.text.strip()}" assert child_subitem.is_displayed(), "Child subitem should be visible" driver.quit()
This script uses Selenium with Python to automate the test case for XPath axes.
The MenuPage class encapsulates element locators using XPath axes:
parent:: axis to get the parent ul element of 'Item 2'.following-sibling:: axis to get the next sibling list item.child:: axis to get the nested sub-item 'Subitem 2.1'.The test function test_xpath_axes opens the webpage, creates the page object, and performs assertions to verify:
Explicit waits ensure elements are present and visible before interaction, improving test stability.
Now add data-driven testing with 3 different list items: 'Item 1', 'Item 2', and 'Item 3', verifying their parent, sibling, and child elements accordingly.
parent:: axis selects the direct parent of the current node.<li> elements of a <ul> element?child:: axis selects direct children of the current node.li elements//ul/child::li selects all li children of ul.<div> <h2>Title</h2> <p>Paragraph 1</p> <p>Paragraph 2</p> </div>
//h2/following-sibling::p[1] select?following-sibling::p[1] selects the first p sibling after the h2 node.h2, the first p is "Paragraph 1", so it selects that element.p instead of the firstdiv element://div/preceding-sibling::div[1]preceding-sibling::div[1] selects the immediate previous sibling div element.div has no preceding sibling div.span elements that are children of a div whose immediate parent is a section. Which XPath expression correctly uses axes to achieve this?span elements are children of div, and that div is a child of section.//section/child::div/child::span selects span children of div children of section.//div/parent::section/child::span selects span children of section, which is incorrect. //section/parent::div/child::span and D misuse axes or order.Pass the test and this pattern moves unknown