Junior QASeleniumFree question
How do you write dynamic XPath? Explain XPath axes and functions.
60-second answer
Dynamic XPath uses functions and relationships instead of fixed positions, so it survives UI changes. Useful functions are contains, starts-with, text and normalize-space, for example a button whose id starts with "submit", or a link containing the text "Logout". Axes let me navigate from a stable element to the one I need: parent, child, ancestor, descendant, following-sibling and preceding-sibling. For example, find the row containing "Order 1024" and then the "Cancel" button in that same row. I always prefer relative XPath starting with double slash.
Explanation
Functions:
//input[contains(@id,'email')]//button[starts-with(@id,'btn-save')]//a[text()='Logout']and//span[normalize-space()='Total']//input[@type='text' and @name='city']
Axes:
//label[text()='Email']/following-sibling::input//td[text()='Order 1024']/parent::tr//button[text()='Cancel']//input[@id='qty']/ancestor::form(//div[@class='card'])[last()]
Example
A table of orders has auto-generated IDs. Anchor on the visible order number and walk to the button in that row instead of using the generated ID.
Sample code
By cancelForOrder(String orderNo) {
return By.xpath("//td[normalize-space()='" + orderNo + "']"
+ "/ancestor::tr//button[text()='Cancel']");
}
driver.findElement(By.xpath("//label[text()='Email']/following-sibling::input"))
.sendKeys("qa@x.com");
driver.findElement(cancelForOrder("1024")).click();