diff --git a/README.md b/README.md
index 6782a08..e834017 100644
--- a/README.md
+++ b/README.md
@@ -95,7 +95,7 @@ On Windows, the recommended selectors, in order of reliability are:
| Link text selector | `"link text"` | :white_check_mark: |
| Partial link text selector | `"partial link text"` | :white_check_mark: |
| Tag name | `"tag name"` | :white_check_mark: |
-| XPath selector | `"xpath"` | |
+| XPath selector | `"xpath"` | :white_check_mark: |
| CSS selector | `"css selector"` | Only ID, class or `name` attribute selectors. IDs are interpreted as automation IDs. |
Using the Selenium C# client, the selectors are:
@@ -107,6 +107,7 @@ driver.FindElement(By.ClassName("TextBox")).Click();
driver.FindElement(By.LinkText("Button")).Click();
driver.FindElement(By.PartialLinkText("Button")).Click();
driver.FindElement(By.TagName("RadioButton")).Click();
+driver.FindElement(By.XPath("//RadioButton")).Click();
```
Using the WebdriverIO JavaScript client (see [WebdriverIO Selectors guide](https://webdriver.io/docs/selectors):
@@ -118,6 +119,7 @@ await driver.$('.TextBox').click();
await driver.$('=Button').click();
await driver.$('*=Button').click();
await driver.$('').click();
+await driver.$('//RadioButton').click();
```
## Windows
diff --git a/src/FlaUI.WebDriver.UITests/FindElementsTests.cs b/src/FlaUI.WebDriver.UITests/FindElementsTests.cs
index f84dce2..b090ef2 100644
--- a/src/FlaUI.WebDriver.UITests/FindElementsTests.cs
+++ b/src/FlaUI.WebDriver.UITests/FindElementsTests.cs
@@ -8,6 +8,17 @@ namespace FlaUI.WebDriver.UITests
{
public class FindElementsTests
{
+ [Test]
+ public void FindElement_ByXPath_ReturnsElement()
+ {
+ var driverOptions = FlaUIDriverOptions.TestApp();
+ using var driver = new RemoteWebDriver(WebDriverFixture.WebDriverUrl, driverOptions);
+
+ var element = driver.FindElement(By.XPath("//Text"));
+
+ Assert.That(element, Is.Not.Null);
+ }
+
[Test]
public void FindElement_ByAccessibilityId_ReturnsElement()
{
diff --git a/src/FlaUI.WebDriver/Controllers/FindElementsController.cs b/src/FlaUI.WebDriver/Controllers/FindElementsController.cs
index 940885a..91ccc5b 100644
--- a/src/FlaUI.WebDriver/Controllers/FindElementsController.cs
+++ b/src/FlaUI.WebDriver/Controllers/FindElementsController.cs
@@ -56,8 +56,16 @@ public async Task FindElementsFromElement([FromRoute] string sessi
private static async Task FindElementFrom(Func startNode, FindElementRequest findElementRequest, Session session)
{
- var condition = GetCondition(session.Automation.ConditionFactory, findElementRequest.Using, findElementRequest.Value);
- AutomationElement? element = await Wait.Until(() => startNode().FindFirstDescendant(condition), element => element != null, session.ImplicitWaitTimeout);
+ AutomationElement? element;
+ if (findElementRequest.Using == "xpath")
+ {
+ element = await Wait.Until(() => startNode().FindFirstByXPath(findElementRequest.Value), element => element != null, session.ImplicitWaitTimeout);
+ }
+ else
+ {
+ var condition = GetCondition(session.Automation.ConditionFactory, findElementRequest.Using, findElementRequest.Value);
+ element = await Wait.Until(() => startNode().FindFirstDescendant(condition), element => element != null, session.ImplicitWaitTimeout);
+ }
if (element == null)
{
@@ -73,8 +81,16 @@ private static async Task FindElementFrom(Func
private static async Task FindElementsFrom(Func startNode, FindElementRequest findElementRequest, Session session)
{
- var condition = GetCondition(session.Automation.ConditionFactory, findElementRequest.Using, findElementRequest.Value);
- AutomationElement[] elements = await Wait.Until(() => startNode().FindAllDescendants(condition), elements => elements.Length > 0, session.ImplicitWaitTimeout);
+ AutomationElement[] elements;
+ if (findElementRequest.Using == "xpath")
+ {
+ elements = await Wait.Until(() => startNode().FindAllByXPath(findElementRequest.Value), elements => elements.Length > 0, session.ImplicitWaitTimeout);
+ }
+ else
+ {
+ var condition = GetCondition(session.Automation.ConditionFactory, findElementRequest.Using, findElementRequest.Value);
+ elements = await Wait.Until(() => startNode().FindAllDescendants(condition), elements => elements.Length > 0, session.ImplicitWaitTimeout);
+ }
if (elements.Length == 0)
{