You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET环境下iOS类链/谓词的页面对象模型语法及扩展方法问询

实现iOS Class Chain/Predicate String定位的页面对象方案

不需要扩展OpenQA.Selenium.Appium.PageObjects.Attributes.Abstract类,Appium的.NET PageObjects框架允许通过自定义FindsByAttribute子类的方式,轻松支持iOS Class Chain和Predicate String定位策略,以下是两种可行方案:

方案一:自定义独立定位属性类

分别创建对应两种定位策略的属性类,封装Appium内置的By.IOSClassChain()和By.IOSPredicateString()方法,使用时语义更清晰:

1. 定义Class Chain属性类

using OpenQA.Selenium.Appium.PageObjects.Attributes;
using OpenQA.Selenium;

public class FindsByIOSClassChainAttribute : FindsByAttribute
{
    public FindsByIOSClassChainAttribute(string classChain)
    {
        How = How.Custom;
        Using = classChain;
        CustomFinderType = typeof(ClassChainLocator);
    }

    private class ClassChainLocator : IBy
    {
        public By GetBy(string usingValue)
        {
            return By.IOSClassChain(usingValue);
        }
    }
}

2. 定义Predicate String属性类

using OpenQA.Selenium.Appium.PageObjects.Attributes;
using OpenQA.Selenium;

public class FindsByIOSPredicateStringAttribute : FindsByAttribute
{
    public FindsByIOSPredicateStringAttribute(string predicate)
    {
        How = How.Custom;
        Using = predicate;
        CustomFinderType = typeof(PredicateLocator);
    }

    private class PredicateLocator : IBy
    {
        public By GetBy(string usingValue)
        {
            return By.IOSPredicateString(usingValue);
        }
    }
}

3. 页面对象中使用

[FindsByIOSClassChain("**/XCUIElementTypeImage[`name == 'ic_login_logo'`]")]
// 或者用Predicate String
[FindsByIOSPredicateString("name == 'ic_login_logo'")]
private IWebElement mlogo_logo;

方案二:扩展单属性支持多参数

如果希望保持你示例中的写法(同一个属性类的不同参数),可以创建一个整合两种策略的属性类:

using OpenQA.Selenium.Appium.PageObjects.Attributes;
using OpenQA.Selenium;

public class FindsByIOSAttribute : FindsByAttribute
{
    private string _iosClassChain;
    private string _iosPredicateString;

    public string IosClassChain
    {
        get => _iosClassChain;
        set
        {
            _iosClassChain = value;
            SetLocatorStrategy();
        }
    }

    public string IosPredicateString
    {
        get => _iosPredicateString;
        set
        {
            _iosPredicateString = value;
            SetLocatorStrategy();
        }
    }

    private void SetLocatorStrategy()
    {
        if (!string.IsNullOrEmpty(IosClassChain))
        {
            How = How.Custom;
            Using = IosClassChain;
            CustomFinderType = typeof(ClassChainLocator);
        }
        else if (!string.IsNullOrEmpty(IosPredicateString))
        {
            How = How.Custom;
            Using = IosPredicateString;
            CustomFinderType = typeof(PredicateLocator);
        }
    }

    private class ClassChainLocator : IBy
    {
        public By GetBy(string usingValue) => By.IOSClassChain(usingValue);
    }

    private class PredicateLocator : IBy
    {
        public By GetBy(string usingValue) => By.IOSPredicateString(usingValue);
    }
}

页面对象中使用

[FindsByIOS(IosClassChain = "something")]
[FindsByIOS(IosPredicateString = "name == 'ic_login_logo'")]
private IWebElement mlogo_logo;

核心原理

Appium.NET的PageObjects框架通过FindsByAttribute及其子类识别定位策略,自定义属性类只需继承FindsByAttribute,并通过CustomFinderType指定封装了目标定位逻辑的IBy实现类,即可自动集成到页面对象的初始化流程中,无需修改底层的Abstract类。

内容的提问来源于stack exchange,提问作者skinnyWill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:35:08