I am automating a simple Windows Form Application and I am attempting to locate a WindowsElement
using its inner text. My WindowsElement
looks like this:
ControlType = DataItem
Name = 'Identifier'
ValuePattern.Value = 'Text'
LegacyIAccessiblePattern.Value = 'Text'
AutomationId = blank
The element has no properties other than Name
, ControlType
(which I am using in an XPath), and ValuePattern.Value
which contains the desired text I am searching on. I would like to locate the element based on 'Text'
, using ValuePattern.Value
or LegacyIAccessiblePattern.Value
, but I can't seem to write an XPath that successfully uses these attributes. I cannot use @Name
to locate the element, because several other elements share the same @Name
attribute value. Text
is the only unique attribute.
In Selenium WebDriver, I can locate an element through text as such:
driver.FindElement(By.XPath("//*[text()='Text']"));
In Appium, I can use this:
driver.FindElement(By.XPath("//*[@text='Text']")
In WinAppDriver, I am attempting:
driver.FindElementByXPath("//DataItem[text()='Text']");
I have also tried:
driver.FindElementByXPath("//DataItem[@ValuePattern.Value='Text']");
Both of these throw a NoSuchElementException
. However, I AM able to successfully invoke WebDriverWait
on the TextToBePresentInElement
and this is working:
// my locator
private WindowsElement IdentifierSearchResult => Driver.FindElementByXPath("//DataItem[@Name='Identifier']");
// webdriverwait using the above locator, wait for 'Text' to be present in this element.
new WebDriverWait(Driver, TimeSpan.FromSeconds(20)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.TextToBePresentInElement(IdentifierSearchResult, 'Text'));
This is also printing the correct text:
var elements = Driver.FindElementsByXPath("//DataItem[@Name='Identifier']");
var text = elements.First().Text;
However, this is just a debugging scenario where I am retrieving a list, and printing the text of the first one -- this is simply a test to verify that the element has a valid .Text
attribute. I cannot use this locator for my final code, because there is no guarantee it is choosing the correct element.
I've looked around the WinAppDriver repository samples, but I can't find anything actually using text -- everyone uses @Name
or @AutomationId
-- my element name is not unique, and it has no automation ID, so this does not work for me.
I know that I can use LINQ to work around the issue as such:
var elements = driver.FindElementsByXPath("//DataItem[@Name='Identifier']");
var elementToClick = elements.FirstOrDefault(e => e.Text == 'Text');
But that feels like a hacky workaround, and I'd like to avoid it if possible.
How can I locate the element using its text? Something like //DataItem[@Text='Text']
(I've tried that too, btw) is preferable, where I can pass in my 'Text'
as a parameter.