0

我一直在测试一个桌面应用程序(WPF)。使用中:C#、Appium、WinAppDriver。一个菜单中有多个数字文本框。我在这里遇到的问题是我无法访问此页面上特定文本框的 UpButton,因为所有 Up/Down 按钮都具有相同的 ID,即“PART_IncreaseButton”。

它是一个数字文本框,具有内置的上下控制。一个菜单中有几个。 文本框

我使用 inspect.exe 来识别对象。检查器中的树: 检查屏幕截图

因此,在自定义下是文本框“编辑”、“按钮”、“按钮”的 3 个控件,使用“Root_0_Blue_AutomationId” 我可以访问文本框,例如在框中写入一些内容。

但是,如果我检查特定文本框的向上按钮,它具有自动化ID "Part_IncreaseButton"。并且其他文本框的 upcontrols 具有相同的 ID。只有rootID的AutomationID不同,upcontrols的ID保持不变,例如:

根 ID(文本框):“Root_0_Blue_AutomationId” UpControl ID:“Part_Increasebutton”

根 ID(第二个文本框,绿色通道不同): “Root_0_Green_AutomationId” UpControl ID:“Part_Increasebutton”

如何管理它以访问第二个文本框的 UpControl?

4

3 回答 3

1

页面上的多个元素完全有可能具有相同的自动化 ID。

当这种情况发生时,可以做 3 件事来识别和定位单个元素。

  1. 重构应用程序,使每个元素都有不同的自动化 ID。
  2. 使用替代定位策略来唯一标识元素。
  3. 找到仅包含 1 个具有目标 ID 的元素的父元素,然后在其子元素中搜索您要定位的唯一元素。

如果您正在使用设计良好的应用程序选项 3 是推荐的方法。它允许您使用通用逻辑与任何向上/向下按钮进行交互,同时通过包含它们的文本框唯一地识别它们。

于 2019-10-31T17:00:59.740 回答
1

非常感谢您的支持。

我通过以下方式(2个步骤)做到了:

首先找到父元素:

WindowsElement TB1 = Editor.FindElementByAccessibilityId("Root_0_Blue_AutomationId");

然后找到其他控件:

AppiumWebElement TB1UpControl = TB1.FindElementByAccessibilityId("PART_IncreaseButton");

点击UpControl:

动作生成器 = 新动作(编辑器);

builder.Click(TB1UpControl).Perform();

此致!

于 2019-11-05T12:31:29.123 回答
0

这是我的实现。为了简单起见,我没有添加错误处理。代码可以编译,但我还没有测试过。向上/向下按钮和文本框包含在一个对象中,因此它与您的其他代码很好地分开。

using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using System.Collections.ObjectModel;
using System.Linq;

namespace Example
{
    class SpinControl
    {
        public int Value {
            get
            {
                //call _textBox here to get the value from your control.
                return 0;
            }
        }

    private readonly AppiumWebElement _increaseButton;
    private readonly AppiumWebElement _decreaseButton;
    private readonly AppiumWebElement _textBox;

    public SpinControl(string automationID, WindowsDriver<WindowsElement> Driver)
    {
        WindowsElement customControl = Driver.FindElementByAccessibilityId(automationID);
        ReadOnlyCollection<AppiumWebElement> customControlChildren = customControl.FindElementsByXPath(".//*");

        _increaseButton = customControlChildren.First(e => e.FindElementByAccessibilityId("Part_IncreaseButton").Id == "Part_IncreaseButton");
        _decreaseButton = customControlChildren.First(e => e.FindElementByAccessibilityId("Part_DecreaseButton").Id == "Part_DecreaseButton");
        _textBox = customControlChildren.First(e => e != _increaseButton && e != _decreaseButton);
    }

    public void Increase()
    {
        //call _increaseButton here
    }

    public void Decrease()
    {
        //call _decreaseButton here
    }

    public void Input(int number)
    {
        //call _textBox here
    }
}

}

可以这样使用:

        SpinControl sp = new SpinControl("customControlAutomationID", Driver);

        sp.Increase();
        sp.Decrease();
        sp.Input(5);
        int value = sp.Value;
于 2019-11-05T14:01:54.080 回答