</>

Technology

Selenium

Difficulty

Intermediate

Interview Question

What is the difference between XPath and CSS Selector in Selenium? Which is faster?

Answer

XPath vs CSS Selector in Selenium

CSS Selectors (Preferred for Most Cases)

Java
// ID
By.cssSelector("#submit-btn")         // faster than By.id()

// Class
By.cssSelector(".error-message")
By.cssSelector(".btn.btn-primary")    // multiple classes

// Attribute
By.cssSelector("[data-testid='login']")
By.cssSelector("input[type='email']")
By.cssSelector("[placeholder='Enter email']")
By.cssSelector("[href*='login']")     // href CONTAINS 'login'
By.cssSelector("[class^='btn-']")     // class STARTS WITH 'btn-'
By.cssSelector("[class$='-primary']") // class ENDS WITH '-primary'

// Parent → Child (direct)
By.cssSelector("form > input")        // input is DIRECT child of form

// Ancestor → Descendant
By.cssSelector("div.container input") // input anywhere inside div.container

// nth-child
By.cssSelector("table tr:nth-child(2)")   // 2nd row
By.cssSelector("ul li:first-child")
By.cssSelector("ul li:last-child")

// Combination
By.cssSelector("div.login-form input[type='password']")

XPath Selectors

Java
// Absolute (fragile — never use)
By.xpath("/html/body/div/form/input")   // ❌ breaks on any DOM change

// Relative (always use)
By.xpath("//input[@id='email']")
By.xpath("//button[@type='submit']")
By.xpath("//div[@class='login-form']//input[@type='email']")

// By TEXT CONTENT (XPath unique advantage)
By.xpath("//button[text()='Submit']")
By.xpath("//button[contains(text(),'Sign')]")
By.xpath("//label[normalize-space(text())='Email Address']")

// Parent traversal (XPath unique advantage)
By.xpath("//input[@id='email']/parent::div")             // go UP to parent
By.xpath("//input[@id='email']/ancestor::form")          // go UP to ancestor
By.xpath("//label[text()='Email']/following-sibling::input")  // sibling
By.xpath("//tr[td[text()='Alice']]//button[@class='edit']")   // row by cell

// Index (1-based in XPath!)
By.xpath("(//input[@type='text'])[2]")   // 2nd text input

// contains() — partial match
By.xpath("//div[contains(@class,'error')]")
By.xpath("//a[contains(@href,'logout')]")

// Multiple conditions (and / or)
By.xpath("//input[@type='text' and @required]")
By.xpath("//button[@id='ok' or @id='confirm']")

// starts-with()
By.xpath("//input[starts-with(@id,'user-')]")

Key Differences

CSS SelectorXPath
SpeedFaster (browser-native)Slightly slower
ReadabilityCleanerVerbose
Text matching❌ Not supportedtext(), contains(text())
Parent traversal❌ Not supportedparent::, ancestor::
Preceding sibling❌ Not supportedpreceding-sibling::
Index:nth-child(n)[n] (1-based)
Browser supportAll browsersAll browsers

When to Use Each

Java
// Use CSS when:
// - ID, class, attribute, or structural location
By.cssSelector("[data-testid='login-btn']")    // attribute
By.cssSelector("table tr:nth-child(3) td")     // table cell
By.cssSelector(".nav-menu > li:first-child a") // nested structure

// Use XPath when:
// - Need to match by text
By.xpath("//button[text()='Delete']")

// - Need to traverse UP the DOM (find parent)
By.xpath("//input[@id='search']/ancestor::form")

// - Need preceding-sibling
By.xpath("//td[text()='Alice']/preceding-sibling::td[1]")

// - Dynamic content where text is the only stable identifier
By.xpath("//span[contains(text(),'Order #')]")

Best Practice Hierarchy

  1. By.id() — most reliable, fastest
  2. By.cssSelector("[data-testid='x']") — test-specific attributes
  3. By.cssSelector() — general CSS
  4. By.xpath() — when text matching or parent traversal needed
  5. Never: By.xpath("/html/body/...") — absolute paths

Follow AutomateQA

Related Topics