CSS Selector to XPath Converter
Convert selectors between CSS and XPath for Playwright, Selenium and Cypress, with ready made locator code.
Convert selectors between CSS and XPath for Playwright, Selenium and Cypress, in both directions.
XPath
#app .card:hover .title
//*[@id='app']//*[contains(concat(' ', normalize-space(@class), ' '), ' card ')]//*[contains(concat(' ', normalize-space(@class), ' '), ' title ')]
form > input[type='email']
//form/input[@type='email']
nav ul li a.active
//nav//ul//li//a[contains(concat(' ', normalize-space(@class), ' '), ' active ')]
[data-testid='submit']
//*[@data-testid='submit']
.list li:nth-child(3)
//*[contains(concat(' ', normalize-space(@class), ' '), ' list ')]//li[position()=3]
Prefer CSS where both work: it is shorter and every runner optimises it. XPath earns its keep for the things CSS cannot express, such as selecting a parent or matching on visible text. Those directions have no CSS equivalent, so converting back from them is always partial.
//*[@id='app']//*[contains(concat(' ', normalize-space(@class), ' '), ' card ')]//*[contains(concat(' ', normalize-space(@class), ' '), ' title ')]
//form/input[@type='email']
//nav//ul//li//a[contains(concat(' ', normalize-space(@class), ' '), ' active ')]
//*[@data-testid='submit']
//*[contains(concat(' ', normalize-space(@class), ' '), ' list ')]//li[position()=3]About the css selector to xpath converter
Test suites end up with a mix of both. Playwright and Cypress prefer CSS, older Selenium code is full of XPath, and moving between them by hand is where flaky selectors come from.
Converting CSS to XPath is mechanical and reliable. Converting the other way is not always possible, because XPath can select a parent or match on visible text and CSS can do neither. Those cases are flagged rather than silently mistranslated.
How to use it
- 1Choose the direction.
- 2Paste your selectors, one per line.
- 3Read the converted output and any warnings.
- 4Copy the ready made locator for your test runner.
Questions
Should I use CSS or XPath?
CSS where both work. It is shorter, easier to read, and every runner optimises it. XPath earns its place for what CSS cannot express: selecting a parent, or matching an element by its visible text.
Why can some XPath not become CSS?
Because CSS has no parent or ancestor selector and cannot match text content. An XPath using those has no equivalent, so the conversion is partial and says so.
Why is the class check so long in XPath?
XPath has no class concept, so matching one class inside a multi-class attribute needs the concat and normalize-space pattern. A plain contains would match partly, so button-primary would wrongly match a search for button.
Are these selectors good practice?
Converting them does not make them robust. A selector tied to layout breaks the moment the markup shifts. Prefer a data-testid attribute, which both CSS and XPath address cleanly.