3

我正在自动化一个简单的 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');

但这感觉像是一种 hacky 解决方法,如果可能的话,我想避免它。

如何使用其文本定位元素?像//DataItem[@Text='Text'](我也尝试过,顺便说一句)这样的东西更可取,我可以将 my'Text'作为参数传入。

4

1 回答 1

1

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

于 2020-01-09T16:48:02.107 回答