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:
- get_item_2: Locates 'Item 2' using a relative XPath child from the list with id 'menu'.
- get_parent_of_item_2: Uses the
parent:: axis to get the parent ul element of 'Item 2'. - get_following_sibling_of_item_2: Uses
following-sibling:: axis to get the next sibling list item. - get_child_subitem_of_item_2: Uses
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:
- Elements are visible
- Parent element has correct id
- Sibling and child elements have expected text
Explicit waits ensure elements are present and visible before interaction, improving test stability.