我正在自动化一个简单的Windows窗体应用程序,并且尝试使用其内部文本查找WindowsElement。我的WindowsElement看起来像这样:

ControlType = DataItem
    Name = 'Identifier'
    ValuePattern.Value = 'Text'
    LegacyIAccessiblePattern.Value = 'Text'
    AutomationId = blank


除了NameControlType(我在XPath中使用的)和ValuePattern.Value(其中包含我要搜索的所需文本)之外,该元素没有其他属性。我想使用'Text'ValuePattern.Value基于LegacyIAccessiblePattern.Value定位元素,但是我似乎无法编写成功使用这些属性的XPath。我不能使用@Name来定位元素,因为其他几个元素共享相同的@Name属性值。 Text是唯一的唯一属性。

在Selenium WebDriver中,我可以这样通过文本定位元素:

driver.FindElement(By.XPath("//*[text()='Text']"));


在Appium中,我可以使用以下代码:

driver.FindElement(By.XPath("//*[@text='Text']")


在WinAppDriver中,我正在尝试:

driver.FindElementByXPath("//DataItem[text()='Text']");


我也尝试过:

driver.FindElementByXPath("//DataItem[@ValuePattern.Value='Text']");


这两个都抛出一个NoSuchElementException。但是,我能够在WebDriverWait上成功调用TextToBePresentInElement,并且可以正常工作:

// 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'));


这也可以打印正确的文本:

var elements = Driver.FindElementsByXPath("//DataItem[@Name='Identifier']");
var text = elements.First().Text;


但是,这只是一个调试场景,我在其中获取列表并打印第一个列表的文本-这仅仅是测试,以验证元素具有有效的.Text属性。我无法在最终代码中使用此定位器,因为无法保证它会选择正确的元素。

我查看了WinAppDriver存储库示例,但找不到任何实际使用文本的东西-每个人都使用@Name@AutomationId-我的元素名称不是唯一的,并且没有自动化ID,所以这样做不适合我。

我知道我可以使用LINQ来解决此问题,例如:

var elements = driver.FindElementsByXPath("//DataItem[@Name='Identifier']");
var elementToClick = elements.FirstOrDefault(e => e.Text == 'Text');


但这听起来像是个棘手的解决方法,如果可能的话,我想避免这种情况。

如何使用元素的文本定位元素?最好使用//DataItem[@Text='Text']之类的东西(我也尝试过,btw),在这里我可以将'Text'作为参数传递。

最佳答案

在使用菜单项时,我遇到了同样的问题,首先,我使用了foreach循环来检查文本值。后来我将其重构为别致的LINQ表达式。
但是我相信没有办法解决这个问题,您必须使用循环或LINQ来解决。

10-05 20:43
查看更多