Skip to content

Commit

Permalink
Merge pull request #20 from FlaUI/support-xpath
Browse files Browse the repository at this point in the history
Support X-Path selectors
  • Loading branch information
aristotelos authored Apr 23, 2024
2 parents e1f7914 + e9eab1e commit 3b03baa
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand All @@ -118,6 +119,7 @@ await driver.$('.TextBox').click();
await driver.$('=Button').click();
await driver.$('*=Button').click();
await driver.$('<RadioButton />').click();
await driver.$('//RadioButton').click();
```

## Windows
Expand Down
11 changes: 11 additions & 0 deletions src/FlaUI.WebDriver.UITests/FindElementsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
24 changes: 20 additions & 4 deletions src/FlaUI.WebDriver/Controllers/FindElementsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,16 @@ public async Task<ActionResult> FindElementsFromElement([FromRoute] string sessi

private static async Task<ActionResult> FindElementFrom(Func<AutomationElement> 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)
{
Expand All @@ -73,8 +81,16 @@ private static async Task<ActionResult> FindElementFrom(Func<AutomationElement>

private static async Task<ActionResult> FindElementsFrom(Func<AutomationElement> 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)
{
Expand Down

0 comments on commit 3b03baa

Please sign in to comment.