我正在自动化一个简单的Windows窗体应用程序,并且尝试使用其内部文本查找WindowsElement
。我的WindowsElement
看起来像这样:
ControlType = DataItem
Name = 'Identifier'
ValuePattern.Value = 'Text'
LegacyIAccessiblePattern.Value = 'Text'
AutomationId = blank
除了
Name
,ControlType
(我在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来解决。